Skip to content

Commit 2e6758b

Browse files
committed
chore: move quote gen and node tls config to common crate
1 parent fe21d76 commit 2e6758b

File tree

9 files changed

+214
-225
lines changed

9 files changed

+214
-225
lines changed

Cargo.lock

Lines changed: 4 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

common/Cargo.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,16 @@ asn1-rs = { version = "0.5", default-features = false }
9393
# For constructing/parsing ASN.1 data in x509 certs
9494
yasna = { version = "0.5", default-features = false, features = ["num-bigint"] }
9595

96+
[target.'cfg(target_env = "sgx")'.dependencies]
97+
# For verifying SGX Report MACs
98+
aes = { version = "0.8", features = ["zeroize"] }
99+
# A client for the Intel AESM service. Used in the attestation process to get quoted.
100+
aesm-client = "=0.5.4"
101+
# For casting byte buffers to/from the AESM client from/to actual structured data.
102+
bytemuck = { version = "1.9.1", default-features = false, features = ["derive", "min_const_generics"] }
103+
# For verifying SGX Report MACs
104+
cmac = { version = "0.7", features = ["std", "zeroize"] }
105+
96106
[dev-dependencies]
97107
# property based testing
98108
proptest = { version = "1", default-features = false, features = ["alloc"] }

common/src/attest/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
pub mod cert;
2+
mod quote;
23
pub mod verify;
34

5+
pub use cert::AttestationCert;
6+
pub use quote::quote_enclave;
47
pub use verify::{EnclavePolicy, ServerCertVerifier};

node/src/attest/quote.rs renamed to common/src/attest/quote.rs

Lines changed: 134 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,6 @@
33
//!
44
//! On non-SGX platforms, we just return a dummy extension for now.
55
6-
#![allow(dead_code)]
7-
8-
use std::fmt;
9-
10-
use bytemuck::{Pod, Zeroable};
11-
use common::ed25519;
12-
136
#[rustfmt::skip]
147
#[cfg(target_env = "sgx")]
158
pub use sgx::quote_enclave;
@@ -18,22 +11,23 @@ pub use not_sgx::quote_enclave;
1811

1912
#[cfg(target_env = "sgx")]
2013
mod sgx {
14+
use std::fmt;
2115
use std::net::TcpStream;
2216

2317
use aes::Aes128;
2418
use aesm_client::sgx::AesmClientExt;
2519
use aesm_client::AesmClient;
2620
use anyhow::{ensure, format_err, Context, Result};
21+
use bytemuck::{Pod, Zeroable};
2722
use cmac::digest::generic_array::GenericArray;
2823
use cmac::{Cmac, Mac};
29-
use common::attest::cert::SgxAttestationExtension;
30-
use common::attest::verify::EnclavePolicy;
31-
use common::rng::Crng;
32-
use common::{ed25519, hex, sha256};
3324
use rcgen::CustomExtension;
3425
use sgx_isa::{Report, Targetinfo};
3526

36-
use super::{ErrString, QlAttKeyIdExt, ReportData};
27+
use crate::attest::cert::SgxAttestationExtension;
28+
use crate::attest::verify::EnclavePolicy;
29+
use crate::rng::Crng;
30+
use crate::{ed25519, hex, sha256};
3731

3832
pub fn quote_enclave(
3933
rng: &mut dyn Crng,
@@ -169,151 +163,152 @@ mod sgx {
169163
};
170164
Ok(attestation.to_cert_extension())
171165
}
172-
}
173166

174-
#[cfg(not(target_env = "sgx"))]
175-
mod not_sgx {
176-
use anyhow::Result;
177-
use common::attest::cert::SgxAttestationExtension;
178-
use common::ed25519;
179-
use common::rng::Crng;
180-
use rcgen::CustomExtension;
167+
// dumb error type compatibility hack
181168

182-
pub fn quote_enclave(
183-
_rng: &mut dyn Crng,
184-
_cert_pk: &ed25519::PublicKey,
185-
) -> Result<CustomExtension> {
186-
// TODO(phlip9): use a different dummy extension?
169+
#[derive(Debug)]
170+
struct ErrString(String);
187171

188-
let dummy_attestation = SgxAttestationExtension::dummy();
189-
Ok(dummy_attestation.to_cert_extension())
172+
impl ErrString {
173+
fn new(err: impl fmt::Display) -> Self {
174+
Self(format!("{:#}", err))
175+
}
190176
}
191-
}
192-
193-
// dumb error type compatibility hack
194177

195-
#[derive(Debug)]
196-
struct ErrString(String);
178+
impl fmt::Display for ErrString {
179+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
180+
f.write_str(&self.0)
181+
}
182+
}
197183

198-
impl ErrString {
199-
fn new(err: impl fmt::Display) -> Self {
200-
Self(format!("{:#}", err))
184+
impl std::error::Error for ErrString {
185+
fn description(&self) -> &str {
186+
&self.0
187+
}
201188
}
202-
}
203189

204-
impl fmt::Display for ErrString {
205-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
206-
f.write_str(&self.0)
190+
#[rustfmt::skip]
191+
// // C struct definitions from:
192+
// // <https://github.com/intel/linux-sgx/blob/master/common/inc/sgx_quote.h>
193+
//
194+
// typedef enum {
195+
// SGX_QL_ALG_EPID = 0, ///< EPID 2.0 - Anonymous
196+
// SGX_QL_ALG_RESERVED_1 = 1, ///< Reserved
197+
// SGX_QL_ALG_ECDSA_P256 = 2, ///< ECDSA-256-with-P-256 curve, Non - Anonymous
198+
// SGX_QL_ALG_ECDSA_P384 = 3, ///< ECDSA-384-with-P-384 curve (Note: currently not supported), Non-Anonymous
199+
// SGX_QL_ALG_MAX = 4
200+
// } sgx_ql_attestation_algorithm_id_t;
201+
//
202+
// typedef struct _sgx_ql_att_key_id_t {
203+
// uint16_t id; ///< Structure ID
204+
// uint16_t version; ///< Structure version
205+
// uint16_t mrsigner_length; ///< Number of valid bytes in MRSIGNER.
206+
// uint8_t mrsigner[48]; ///< SHA256 or SHA384 hash of the Public key that signed the QE.
207+
// ///< The lower bytes contain MRSIGNER. Bytes beyond mrsigner_length '0'
208+
// uint32_t prod_id; ///< Legacy Product ID of the QE
209+
// uint8_t extended_prod_id[16]; ///< Extended Product ID or the QE. All 0's for legacy format enclaves.
210+
// uint8_t config_id[64]; ///< Config ID of the QE.
211+
// uint8_t family_id[16]; ///< Family ID of the QE.
212+
// uint32_t algorithm_id; ///< Identity of the attestation key algorithm.
213+
// } sgx_ql_att_key_id_t;
214+
//
215+
// typedef struct _sgx_att_key_id_ext_t {
216+
// sgx_ql_att_key_id_t base;
217+
// uint8_t spid[16]; ///< Service Provider ID, should be 0s for ECDSA quote
218+
// uint16_t att_key_type; ///< For non-EPID quote, it should be 0
219+
// ///< For EPID quote, it equals to sgx_quote_sign_type_t
220+
// uint8_t reserved[80]; ///< It should have the same size of sgx_att_key_id_t
221+
// } sgx_att_key_id_ext_t;
222+
223+
/// ECDSA-256-with-P-256 curve, Non-Anonymous
224+
pub(crate) const SGX_QL_ALG_ECDSA_P256: u32 = 2;
225+
226+
/// An extended SGX attestation key.
227+
///
228+
/// Mirrors the C struct above [`sgx_quote.h/sgx_att_key_id_ext_t`](https://github.com/intel/linux-sgx/blob/master/common/inc/sgx_quote.h#L127).
229+
///
230+
/// This struct needs `repr(C, packed)` for the memory layout to match the C
231+
/// definition. The extra `packed` modifier is necessary, otherwise the
232+
/// standard alignment causes some extra padding between fields, which
233+
/// makes the struct larger than the original C struct.
234+
#[repr(C, packed)]
235+
#[derive(Copy, Clone, Pod, Zeroable)]
236+
pub(crate) struct QlAttKeyIdExt {
237+
// The original attestation key id type, `sgx_ql_att_key_id_t`.
238+
/// Structure ID
239+
pub id: u16,
240+
/// Structure Version
241+
pub version: u16,
242+
/// Number of valid bytes in `mrsigner`
243+
pub mrsigner_len: u16,
244+
/// SHA256 or SHA384 hash of the pk that signed the QE
245+
pub mrsigner: [u8; 48],
246+
247+
/// Legacy Product ID of the QE
248+
pub prod_id: u32,
249+
/// Extended Product ID of the QE
250+
pub extended_prod_id: [u8; 16],
251+
/// Config ID of the QE
252+
pub config_id: [u8; 64],
253+
/// Family ID of the QE
254+
pub family_id: [u8; 16],
255+
/// The attestation key algorithm ID
256+
pub algorithm_id: u32,
257+
258+
// The extended attestation key id type, `sgx_att_key_id_ext_t`.
259+
/// Service Provider ID, should be 0s for ECDSA quote
260+
pub spid: [u8; 16],
261+
/// For non-EPID quote, it should be 0
262+
/// For EPID quote, it equals `sgx_quote_sign_type_t`
263+
pub att_key_type: u16,
264+
/// Padding so this struct has the same size as `sgx_att_key_id_t`
265+
/// (read: 256 bytes).
266+
reserved: [u8; 80],
207267
}
208-
}
209268

210-
impl std::error::Error for ErrString {
211-
fn description(&self) -> &str {
212-
&self.0
269+
// Statically guarantee that the `QlAttKeyIdExt` struct is exactly 256 bytes
270+
// in size.
271+
const _: [(); 256] = [(); std::mem::size_of::<QlAttKeyIdExt>()];
272+
273+
impl QlAttKeyIdExt {
274+
pub fn is_ecdsa_p256(&self) -> bool {
275+
self.algorithm_id == SGX_QL_ALG_ECDSA_P256
276+
}
213277
}
214-
}
215278

216-
#[rustfmt::skip]
217-
// // C struct definitions from:
218-
// // <https://github.com/intel/linux-sgx/blob/master/common/inc/sgx_quote.h>
219-
//
220-
// typedef enum {
221-
// SGX_QL_ALG_EPID = 0, ///< EPID 2.0 - Anonymous
222-
// SGX_QL_ALG_RESERVED_1 = 1, ///< Reserved
223-
// SGX_QL_ALG_ECDSA_P256 = 2, ///< ECDSA-256-with-P-256 curve, Non - Anonymous
224-
// SGX_QL_ALG_ECDSA_P384 = 3, ///< ECDSA-384-with-P-384 curve (Note: currently not supported), Non-Anonymous
225-
// SGX_QL_ALG_MAX = 4
226-
// } sgx_ql_attestation_algorithm_id_t;
227-
//
228-
// typedef struct _sgx_ql_att_key_id_t {
229-
// uint16_t id; ///< Structure ID
230-
// uint16_t version; ///< Structure version
231-
// uint16_t mrsigner_length; ///< Number of valid bytes in MRSIGNER.
232-
// uint8_t mrsigner[48]; ///< SHA256 or SHA384 hash of the Public key that signed the QE.
233-
// ///< The lower bytes contain MRSIGNER. Bytes beyond mrsigner_length '0'
234-
// uint32_t prod_id; ///< Legacy Product ID of the QE
235-
// uint8_t extended_prod_id[16]; ///< Extended Product ID or the QE. All 0's for legacy format enclaves.
236-
// uint8_t config_id[64]; ///< Config ID of the QE.
237-
// uint8_t family_id[16]; ///< Family ID of the QE.
238-
// uint32_t algorithm_id; ///< Identity of the attestation key algorithm.
239-
// } sgx_ql_att_key_id_t;
240-
//
241-
// typedef struct _sgx_att_key_id_ext_t {
242-
// sgx_ql_att_key_id_t base;
243-
// uint8_t spid[16]; ///< Service Provider ID, should be 0s for ECDSA quote
244-
// uint16_t att_key_type; ///< For non-EPID quote, it should be 0
245-
// ///< For EPID quote, it equals to sgx_quote_sign_type_t
246-
// uint8_t reserved[80]; ///< It should have the same size of sgx_att_key_id_t
247-
// } sgx_att_key_id_ext_t;
248-
249-
/// ECDSA-256-with-P-256 curve, Non-Anonymous
250-
pub const SGX_QL_ALG_ECDSA_P256: u32 = 2;
251-
252-
/// An extended SGX attestation key.
253-
///
254-
/// Mirrors the C struct above [`sgx_quote.h/sgx_att_key_id_ext_t`](https://github.com/intel/linux-sgx/blob/master/common/inc/sgx_quote.h#L127).
255-
///
256-
/// This struct needs `repr(C, packed)` for the memory layout to match the C
257-
/// definition. The extra `packed` modifier is necessary, otherwise the standard
258-
/// alignment causes some extra padding between fields, which makes the struct
259-
/// larger than the original C struct.
260-
#[repr(C, packed)]
261-
#[derive(Copy, Clone, Pod, Zeroable)]
262-
pub struct QlAttKeyIdExt {
263-
// The original attestation key id type, `sgx_ql_att_key_id_t`.
264-
/// Structure ID
265-
pub id: u16,
266-
/// Structure Version
267-
pub version: u16,
268-
/// Number of valid bytes in `mrsigner`
269-
pub mrsigner_len: u16,
270-
/// SHA256 or SHA384 hash of the pk that signed the QE
271-
pub mrsigner: [u8; 48],
272-
273-
/// Legacy Product ID of the QE
274-
pub prod_id: u32,
275-
/// Extended Product ID of the QE
276-
pub extended_prod_id: [u8; 16],
277-
/// Config ID of the QE
278-
pub config_id: [u8; 64],
279-
/// Family ID of the QE
280-
pub family_id: [u8; 16],
281-
/// The attestation key algorithm ID
282-
pub algorithm_id: u32,
283-
284-
// The extended attestation key id type, `sgx_att_key_id_ext_t`.
285-
/// Service Provider ID, should be 0s for ECDSA quote
286-
pub spid: [u8; 16],
287-
/// For non-EPID quote, it should be 0
288-
/// For EPID quote, it equals `sgx_quote_sign_type_t`
289-
pub att_key_type: u16,
290-
/// Padding so this struct has the same size as `sgx_att_key_id_t`
291-
/// (read: 256 bytes).
292-
reserved: [u8; 80],
293-
}
279+
struct ReportData([u8; 64]);
294280

295-
// Statically guarantee that the `QlAttKeyIdExt` struct is exactly 256 bytes
296-
// in size.
297-
const _: [(); 256] = [(); std::mem::size_of::<QlAttKeyIdExt>()];
281+
impl ReportData {
282+
fn new(pk: &ed25519::PublicKey) -> Self {
283+
let mut report_data = [0u8; 64];
284+
// ed25519 pks are always 32 bytes. This will panic if this internal
285+
// invariant is somehow not true.
286+
report_data[..32].copy_from_slice(pk.as_bytes());
287+
Self(report_data)
288+
}
298289

299-
impl QlAttKeyIdExt {
300-
pub fn is_ecdsa_p256(&self) -> bool {
301-
self.algorithm_id == SGX_QL_ALG_ECDSA_P256
290+
fn as_inner(&self) -> &[u8; 64] {
291+
&self.0
292+
}
302293
}
303294
}
304295

305-
struct ReportData([u8; 64]);
296+
#[cfg(not(target_env = "sgx"))]
297+
mod not_sgx {
298+
use anyhow::Result;
299+
use rcgen::CustomExtension;
300+
301+
use crate::attest::cert::SgxAttestationExtension;
302+
use crate::ed25519;
303+
use crate::rng::Crng;
306304

307-
impl ReportData {
308-
fn new(pk: &ed25519::PublicKey) -> Self {
309-
let mut report_data = [0u8; 64];
310-
// ed25519 pks are always 32 bytes. This will panic if this internal
311-
// invariant is somehow not true.
312-
report_data[..32].copy_from_slice(pk.as_bytes());
313-
Self(report_data)
314-
}
305+
pub fn quote_enclave(
306+
_rng: &mut dyn Crng,
307+
_cert_pk: &ed25519::PublicKey,
308+
) -> Result<CustomExtension> {
309+
// TODO(phlip9): use a different dummy extension?
315310

316-
fn as_inner(&self) -> &[u8; 64] {
317-
&self.0
311+
let dummy_attestation = SgxAttestationExtension::dummy();
312+
Ok(dummy_attestation.to_cert_extension())
318313
}
319314
}

0 commit comments

Comments
 (0)