Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

runtime: Refactor attestation-related types #5728

Merged
merged 2 commits into from
Jun 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changelog/5728.internal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
runtime: Add VerifiedAttestation with more metadata

Since verified attestations generated from TEE capabilities can include
additional metadata like the enclave's view of consensus layer height at
time of attestation, this allows such data to be used by callers.
2 changes: 1 addition & 1 deletion keymanager/src/churp/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1272,7 +1272,7 @@ impl Churp {
fn remote_enclave(ctx: &RpcContext) -> Result<&EnclaveIdentity> {
let si = ctx.session_info.as_ref();
let si = si.ok_or(Error::NotAuthenticated)?;
Ok(&si.verified_quote.identity)
Ok(&si.verified_attestation.quote.identity)
}

/// Returns true if key manager policies should be ignored.
Expand Down
2 changes: 1 addition & 1 deletion keymanager/src/runtime/secrets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,7 @@ impl Secrets {
fn authenticate(ctx: &RpcContext) -> Result<&EnclaveIdentity> {
let si = ctx.session_info.as_ref();
let si = si.ok_or(KeyManagerError::NotAuthenticated)?;
Ok(&si.verified_quote.identity)
Ok(&si.verified_attestation.quote.identity)
}

/// Fetch current epoch from the consensus layer.
Expand Down
62 changes: 48 additions & 14 deletions runtime/src/consensus/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ impl CapabilityTEE {
&self,
policy: &sgx::QuotePolicy,
node_id: &signature::PublicKey,
) -> anyhow::Result<sgx::VerifiedQuote> {
) -> anyhow::Result<VerifiedAttestation> {
match self.hardware {
TEEHardware::TEEHardwareInvalid => bail!("invalid TEE hardware"),
TEEHardware::TEEHardwareIntelSGX => {
Expand Down Expand Up @@ -216,12 +216,12 @@ impl EndorsedCapabilityTEE {
self.verify_endorsement()?;

// Verify TEE capability.
let verified_quote = self
let verified_attestation = self
.capability_tee
.verify(policy, &self.node_endorsement.public_key)?;

Ok(VerifiedEndorsedCapabilityTEE {
verified_quote,
verified_attestation,
node_id: Some(self.node_endorsement.public_key),
})
}
Expand All @@ -230,16 +230,25 @@ impl EndorsedCapabilityTEE {
/// A verified endorsed CapabilityTEE structure.
#[derive(Clone, Debug, Default)]
pub struct VerifiedEndorsedCapabilityTEE {
/// Verified TEE quote.
pub verified_quote: sgx::VerifiedQuote,
/// Verified TEE remote attestation.
pub verified_attestation: VerifiedAttestation,
/// Optional identifier of the node that endorsed the TEE capability.
pub node_id: Option<signature::PublicKey>,
}

impl From<VerifiedAttestation> for VerifiedEndorsedCapabilityTEE {
fn from(verified_attestation: VerifiedAttestation) -> Self {
Self {
verified_attestation,
node_id: None,
}
}
}

impl From<sgx::VerifiedQuote> for VerifiedEndorsedCapabilityTEE {
fn from(verified_quote: sgx::VerifiedQuote) -> Self {
Self {
verified_quote,
verified_attestation: verified_quote.into(),
node_id: None,
}
}
Expand Down Expand Up @@ -701,13 +710,17 @@ pub enum SGXConstraints {
}

impl SGXConstraints {
/// Checks whether the given enclave identity is whitelisted.
pub fn contains_enclave(&self, eid: &sgx::EnclaveIdentity) -> bool {
let enclaves = match self {
/// Identities of allowed enclaves.
pub fn enclaves(&self) -> &Vec<sgx::EnclaveIdentity> {
match self {
Self::V0 { ref enclaves, .. } => enclaves,
Self::V1 { ref enclaves, .. } => enclaves,
};
enclaves.contains(eid)
}
}

/// Checks whether the given enclave identity is whitelisted.
pub fn contains_enclave(&self, eid: &sgx::EnclaveIdentity) -> bool {
self.enclaves().contains(eid)
}

/// SGX quote policy.
Expand All @@ -730,6 +743,24 @@ impl SGXConstraints {
}
}

/// Verified remote attestation.
#[derive(Clone, Debug, Default)]
pub struct VerifiedAttestation {
/// Verified enclave quote.
pub quote: sgx::VerifiedQuote,
/// Enclave's view of the consensus layer height at the time of attestation.
pub height: Option<u64>,
}

impl From<sgx::VerifiedQuote> for VerifiedAttestation {
fn from(quote: sgx::VerifiedQuote) -> Self {
Self {
quote,
height: None,
}
}
}

/// Intel SGX remote attestation.
#[derive(Clone, Debug, cbor::Encode, cbor::Decode)]
#[cbor(tag = "v")]
Expand Down Expand Up @@ -783,7 +814,7 @@ impl SGXAttestation {
node_id: &signature::PublicKey,
rak: &signature::PublicKey,
rek: &x25519::PublicKey,
) -> anyhow::Result<sgx::VerifiedQuote> {
) -> anyhow::Result<VerifiedAttestation> {
// Verify the quote.
let verified_quote = self.quote().verify(policy)?;

Expand All @@ -797,11 +828,14 @@ impl SGXAttestation {
} => {
let h = Self::hash(&verified_quote.report_data, node_id, *height, rek);
signature.verify(rak, ATTESTATION_SIGNATURE_CONTEXT, &h)?;

Ok(VerifiedAttestation {
quote: verified_quote,
height: Some(*height),
})
}
_ => bail!("V0 attestation not supported"),
}

Ok(verified_quote)
}
}

Expand Down
14 changes: 7 additions & 7 deletions runtime/src/enclave_rpc/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ use crate::{
common::{
crypto::signature::{self, PublicKey, Signature, Signer},
namespace::Namespace,
sgx::{ias, EnclaveIdentity, Quote, QuotePolicy, VerifiedQuote},
sgx::{ias, EnclaveIdentity, Quote, QuotePolicy},
},
consensus::{
registry::{EndorsedCapabilityTEE, VerifiedEndorsedCapabilityTEE},
registry::{EndorsedCapabilityTEE, VerifiedAttestation, VerifiedEndorsedCapabilityTEE},
state::registry::ImmutableState as RegistryState,
verifier::Verifier,
},
Expand Down Expand Up @@ -53,8 +53,8 @@ enum SessionError {
pub struct SessionInfo {
/// RAK binding.
pub rak_binding: RAKBinding,
/// Verified TEE quote.
pub verified_quote: VerifiedQuote,
/// Verified TEE remote attestation.
pub verified_attestation: VerifiedAttestation,
/// Identifier of the node that endorsed the TEE.
pub endorsed_by: Option<PublicKey>,
}
Expand Down Expand Up @@ -281,7 +281,7 @@ impl Session {

Ok(Some(Arc::new(SessionInfo {
rak_binding,
verified_quote: vect.verified_quote,
verified_attestation: vect.verified_attestation,
endorsed_by: vect.node_id,
})))
}
Expand Down Expand Up @@ -428,11 +428,11 @@ impl RAKBinding {

// Ensure that the report data includes the hash of the node's RAK.
// NOTE: For V2 this check is part of verify_inner so it is not really needed.
Identity::verify_binding(&vect.verified_quote, &self.rak_pub())?;
Identity::verify_binding(&vect.verified_attestation.quote, &self.rak_pub())?;

// Verify MRENCLAVE/MRSIGNER.
if let Some(ref remote_enclaves) = remote_enclaves {
if !remote_enclaves.contains(&vect.verified_quote.identity) {
if !remote_enclaves.contains(&vect.verified_attestation.quote.identity) {
return Err(SessionError::MismatchedEnclaveIdentity.into());
}
}
Expand Down
Loading