From 718229f7ee14d8bb3984b2817fbaba85c54d3064 Mon Sep 17 00:00:00 2001 From: Nick Santana Date: Tue, 28 Feb 2023 09:02:35 -0800 Subject: [PATCH] Add `Verifier` for `MrSigner` --- verifier/src/lib.rs | 13 ++++- verifier/src/report_body.rs | 94 +++++++++++++++++++++++++++++++++---- 2 files changed, 96 insertions(+), 11 deletions(-) diff --git a/verifier/src/lib.rs b/verifier/src/lib.rs index e3b1739..1a1bd2e 100644 --- a/verifier/src/lib.rs +++ b/verifier/src/lib.rs @@ -7,11 +7,13 @@ mod report_body; pub use report_body::{ AttributesVerifier, ConfigIdVerifier, ConfigSvnVerifier, IsvSvnVerifier, - MiscellaneousSelectVerifier, MrEnclaveVerifier, + MiscellaneousSelectVerifier, MrEnclaveVerifier, MrSignerVerifier, }; use core::fmt::Debug; -use mc_sgx_core_types::{Attributes, ConfigId, ConfigSvn, IsvSvn, MiscellaneousSelect, MrEnclave}; +use mc_sgx_core_types::{ + Attributes, ConfigId, ConfigSvn, IsvSvn, MiscellaneousSelect, MrEnclave, MrSigner, +}; use subtle::CtOption; /// Failed to verify. @@ -61,6 +63,13 @@ pub enum VerificationError { /// The actual measurement that was present actual: MrEnclave, }, + /// The MRSIGNER measurement did not match expected:{expected} actual:{actual} + MrSignerMismatch { + /// The expected measurement + expected: MrSigner, + /// The actual measurement that was present + actual: MrSigner, + }, } /// A verifier. These can chained together using the [`Or`] and [`And`] diff --git a/verifier/src/report_body.rs b/verifier/src/report_body.rs index 3d66e94..b753227 100644 --- a/verifier/src/report_body.rs +++ b/verifier/src/report_body.rs @@ -5,7 +5,7 @@ use crate::{VerificationError, Verifier}; use core::fmt::Debug; use mc_sgx_core_types::{ - Attributes, ConfigId, ConfigSvn, IsvSvn, Measurement, MiscellaneousSelect, MrEnclave, + Attributes, ConfigId, ConfigSvn, IsvSvn, Measurement, MiscellaneousSelect, MrEnclave, MrSigner, ReportBody, }; use subtle::{ConstantTimeLess, CtOption}; @@ -29,7 +29,7 @@ pub trait Accessor: Debug { /// [`Accessor`] for returning Self, i.e. T -> T macro_rules! self_accessor { - ($($type:ty)*) => {$( + ($($type:ty,)*) => {$( impl Accessor<$type> for $type { fn get(&self) -> $type { self.clone() @@ -55,7 +55,7 @@ macro_rules! report_body_member_accessors { } } - self_accessor! {$member_type} + self_accessor! {$member_type,} )*} } @@ -67,7 +67,7 @@ report_body_member_accessors! { MiscellaneousSelect, miscellaneous_select; } -self_accessor!(MrEnclave); +self_accessor!(MrEnclave, MrSigner,); /// Verify the attributes are as expected. #[derive(Clone, Debug, Eq, Hash, PartialEq)] @@ -234,17 +234,17 @@ impl> Verifier for MiscellaneousSelectVerifi /// Verify the [`MrEnclave`] is as expected. #[derive(Clone, Debug, Eq, PartialEq)] pub struct MrEnclaveVerifier { - expected_measurement: MrEnclave, + expected_mr_enclave: MrEnclave, } impl MrEnclaveVerifier { /// Create a new [`MrEnclaveVerifier`] instance. /// /// # Arguments: - /// * `expected_measurement` - The expected measurement. - pub fn new(expected_measurement: MrEnclave) -> Self { + /// * `expected_mr_enclave` - The expected MRENCLAVE measurement. + pub fn new(expected_mr_enclave: MrEnclave) -> Self { Self { - expected_measurement, + expected_mr_enclave, } } } @@ -262,7 +262,7 @@ impl> Verifier for MrEnclaveVerifier { type Error = VerificationError; fn verify(&self, evidence: &T) -> CtOption { - let expected = self.expected_measurement; + let expected = self.expected_mr_enclave; let actual = evidence.get(); // TODO - This should be a constant time comparison. @@ -274,6 +274,47 @@ impl> Verifier for MrEnclaveVerifier { } } +/// Verify the [`MrSigner`] is as expected. +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MrSignerVerifier { + expected_mr_signer: MrSigner, +} + +impl MrSignerVerifier { + /// Create a new [`MrSignerVerifier`] instance. + /// + /// # Arguments: + /// * `expected_mr_signer` - The expected MRSIGNER. + pub fn new(expected_mr_signer: MrSigner) -> Self { + Self { expected_mr_signer } + } +} + +impl Accessor for ReportBody { + fn get(&self) -> MrSigner { + let Measurement::MrSigner(mr_signer) = self.mr_signer() else { + panic!("`mr_signer()` should return a Measurement::MrSigner"); + }; + mr_signer + } +} + +impl> Verifier for MrSignerVerifier { + type Error = VerificationError; + + fn verify(&self, evidence: &T) -> CtOption { + let expected = self.expected_mr_signer; + let actual = evidence.get(); + + // TODO - This should be a constant time comparison. + let is_some = if expected == actual { 0 } else { 1 }; + CtOption::new( + VerificationError::MrSignerMismatch { expected, actual }, + is_some.into(), + ) + } +} + #[cfg(test)] mod test { use super::*; @@ -398,6 +439,23 @@ mod test { assert_eq!(verifier.verify(&report_body).is_some().unwrap_u8(), 1); } + #[test] + fn report_body_fails_due_to_mr_signer() { + let report_body = ReportBody::from(&REPORT_BODY_SRC); + let Measurement::MrSigner(mut mr_signer) = report_body.mr_signer() else { + panic!("mr_signer is not an MrSigner measurement"); + }; + let bytes: &mut [u8] = mr_signer.as_mut(); + bytes[0] += 1; + let verifier = And::new( + AttributesVerifier::new(report_body.attributes()), + And::new( + ConfigIdVerifier::new(report_body.config_id()), + MrSignerVerifier::new(mr_signer), + ), + ); + assert_eq!(verifier.verify(&report_body).is_some().unwrap_u8(), 1); + } #[test] fn attributes_success() { let attributes = Attributes::from(REPORT_BODY_SRC.attributes); @@ -512,4 +570,22 @@ mod test { assert_eq!(verifier.verify(&mr_enclave).is_some().unwrap_u8(), 1); } + + #[test] + fn mr_signer_success() { + let mr_signer = MrSigner::from(REPORT_BODY_SRC.mr_signer); + let verifier = MrSignerVerifier::new(mr_signer.clone()); + + assert_eq!(verifier.verify(&mr_signer).is_none().unwrap_u8(), 1); + } + + #[test] + fn mr_signer_fails() { + let mut mr_signer = MrSigner::from(REPORT_BODY_SRC.mr_signer); + let verifier = MrSignerVerifier::new(mr_signer.clone()); + let bytes: &mut [u8] = mr_signer.as_mut(); + bytes[0] = 1; + + assert_eq!(verifier.verify(&mr_signer).is_some().unwrap_u8(), 1); + } }