diff --git a/dpe/src/commands/certify_key.rs b/dpe/src/commands/certify_key.rs index 275eaf9e..06980b6d 100644 --- a/dpe/src/commands/certify_key.rs +++ b/dpe/src/commands/certify_key.rs @@ -41,18 +41,18 @@ impl CommandExecution for CertifyKeyCmd { let idx = dpe.get_active_context_pos(&self.handle, locality)?; let context = &dpe.contexts[idx]; - if self.uses_is_ca() && !dpe.support.is_ca { + if self.uses_is_ca() && !dpe.support.is_ca() { return Err(DpeErrorCode::ArgumentNotSupported); } - if self.uses_is_ca() && !context.allow_ca { + if self.uses_is_ca() && !context.allow_ca() { return Err(DpeErrorCode::InvalidArgument); } if self.format == Self::FORMAT_X509 { - if !dpe.support.x509 { + if !dpe.support.x509() { return Err(DpeErrorCode::ArgumentNotSupported); } - if !context.allow_x509 { + if !context.allow_x509() { return Err(DpeErrorCode::InvalidArgument); } } @@ -130,7 +130,7 @@ impl CommandExecution for CertifyKeyCmd { u32::try_from(bytes_written).map_err(|_| DpeErrorCode::InternalError)? } Self::FORMAT_CSR => { - if !dpe.support.csr { + if !dpe.support.csr() { return Err(DpeErrorCode::ArgumentNotSupported); } return Err(DpeErrorCode::ArgumentNotSupported); @@ -159,6 +159,7 @@ mod tests { commands::{Command, CommandHdr, InitCtxCmd}, dpe_instance::tests::{TestTypes, SIMULATION_HANDLE, TEST_LOCALITIES}, support::Support, + U8Bool, }; use crypto::OpensslCrypto; use platform::DefaultPlatform; @@ -195,7 +196,7 @@ mod tests { let mut dpe = DpeInstance::new( &mut env, Support { - x509: true, + x509: U8Bool::new(true), ..Support::default() }, ) @@ -242,8 +243,8 @@ mod tests { let mut dpe = DpeInstance::new( &mut env, Support { - x509: true, - is_ca: true, + x509: U8Bool::new(true), + is_ca: U8Bool::new(true), ..Support::default() }, ) diff --git a/dpe/src/commands/derive_child.rs b/dpe/src/commands/derive_child.rs index 95b3fb18..61ddc780 100644 --- a/dpe/src/commands/derive_child.rs +++ b/dpe/src/commands/derive_child.rs @@ -88,19 +88,20 @@ impl CommandExecution for DeriveChildCmd { locality: u32, ) -> Result { // Make sure the operation is supported. - if (!dpe.support.internal_info && self.uses_internal_info_input()) - || (!dpe.support.internal_dice && self.uses_internal_dice_input()) + if (!dpe.support.internal_info() && self.uses_internal_info_input()) + || (!dpe.support.internal_dice() && self.uses_internal_dice_input()) { return Err(DpeErrorCode::ArgumentNotSupported); } - if (!dpe.support.is_ca && self.allows_ca()) || (!dpe.support.x509 && self.allows_x509()) { + if (!dpe.support.is_ca() && self.allows_ca()) || (!dpe.support.x509() && self.allows_x509()) + { return Err(DpeErrorCode::ArgumentNotSupported); } let parent_idx = dpe.get_active_context_pos(&self.handle, locality)?; - if (!dpe.contexts[parent_idx].allow_ca && self.allows_ca()) - || (!dpe.contexts[parent_idx].allow_x509 && self.allows_x509()) + if (!dpe.contexts[parent_idx].allow_ca() && self.allows_ca()) + || (!dpe.contexts[parent_idx].allow_x509() && self.allows_x509()) { return Err(DpeErrorCode::InvalidArgument); } @@ -109,8 +110,8 @@ impl CommandExecution for DeriveChildCmd { .get_next_inactive_context_pos() .ok_or(DpeErrorCode::MaxTcis)?; - dpe.contexts[parent_idx].uses_internal_input_info = self.uses_internal_info_input(); - dpe.contexts[parent_idx].uses_internal_input_dice = self.uses_internal_dice_input(); + dpe.contexts[parent_idx].uses_internal_input_info = self.uses_internal_info_input().into(); + dpe.contexts[parent_idx].uses_internal_input_dice = self.uses_internal_dice_input().into(); let target_locality = if !self.changes_locality() { locality @@ -171,7 +172,7 @@ mod tests { commands::{tests::TEST_DIGEST, Command, CommandHdr, InitCtxCmd}, dpe_instance::tests::{TestTypes, SIMULATION_HANDLE, TEST_LOCALITIES}, support::Support, - MAX_HANDLES, + U8Bool, MAX_HANDLES, }; use crypto::OpensslCrypto; use platform::DefaultPlatform; @@ -232,7 +233,7 @@ mod tests { let mut dpe = DpeInstance::new( &mut env, Support { - auto_init: true, + auto_init: U8Bool::new(true), ..Support::default() }, ) @@ -274,7 +275,7 @@ mod tests { let mut dpe = DpeInstance::new( &mut env, Support { - auto_init: true, + auto_init: U8Bool::new(true), ..Support::default() }, ) @@ -315,7 +316,7 @@ mod tests { let mut dpe = DpeInstance::new( &mut env, Support { - auto_init: true, + auto_init: U8Bool::new(true), ..Support::default() }, ) @@ -349,7 +350,7 @@ mod tests { let mut dpe = DpeInstance::new( &mut env, Support { - auto_init: true, + auto_init: U8Bool::new(true), ..Support::default() }, ) @@ -399,7 +400,7 @@ mod tests { let mut dpe = DpeInstance::new( &mut env, Support { - auto_init: true, + auto_init: U8Bool::new(true), ..Support::default() }, ) diff --git a/dpe/src/commands/extend_tci.rs b/dpe/src/commands/extend_tci.rs index d3c9159c..20c76e8a 100644 --- a/dpe/src/commands/extend_tci.rs +++ b/dpe/src/commands/extend_tci.rs @@ -24,7 +24,7 @@ impl CommandExecution for ExtendTciCmd { locality: u32, ) -> Result { // Make sure this command is supported. - if !dpe.support.extend_tci { + if !dpe.support.extend_tci() { return Err(DpeErrorCode::InvalidCommand); } @@ -47,6 +47,7 @@ mod tests { commands::{tests::TEST_DIGEST, Command, CommandHdr, InitCtxCmd}, dpe_instance::tests::{TestTypes, SIMULATION_HANDLE, TEST_LOCALITIES}, support::Support, + U8Bool, }; use crypto::OpensslCrypto; use platform::{DefaultPlatform, AUTO_INIT_LOCALITY}; @@ -87,7 +88,7 @@ mod tests { ); // Turn on support. - dpe.support.extend_tci = true; + dpe.support.extend_tci = U8Bool::new(true); InitCtxCmd::new_use_default() .execute(&mut dpe, &mut env, TEST_LOCALITIES[0]) .unwrap(); @@ -126,7 +127,7 @@ mod tests { // Make sure cached private key is invalidated let sim_local = TEST_LOCALITIES[1]; - dpe.support.simulation = true; + dpe.support.simulation = U8Bool::new(true); InitCtxCmd::new_simulation() .execute(&mut dpe, &mut env, sim_local) .unwrap(); diff --git a/dpe/src/commands/get_tagged_tci.rs b/dpe/src/commands/get_tagged_tci.rs index 73d62f2a..989293a3 100644 --- a/dpe/src/commands/get_tagged_tci.rs +++ b/dpe/src/commands/get_tagged_tci.rs @@ -20,7 +20,7 @@ impl CommandExecution for GetTaggedTciCmd { _: u32, ) -> Result { // Make sure this command is supported. - if !dpe.support.tagging { + if !dpe.support.tagging() { return Err(DpeErrorCode::InvalidCommand); } @@ -29,7 +29,7 @@ impl CommandExecution for GetTaggedTciCmd { let ctx = dpe .contexts .iter() - .find(|c| c.has_tag && c.tag == self.tag) + .find(|c| c.has_tag() && c.tag == self.tag) .ok_or(DpeErrorCode::BadTag)?; Ok(Response::GetTaggedTci(GetTaggedTciResp { diff --git a/dpe/src/commands/initialize_context.rs b/dpe/src/commands/initialize_context.rs index 28bf7e00..9acc4f3f 100644 --- a/dpe/src/commands/initialize_context.rs +++ b/dpe/src/commands/initialize_context.rs @@ -47,8 +47,8 @@ impl CommandExecution for InitCtxCmd { locality: u32, ) -> Result { // This function can only be called once for non-simulation contexts. - if (self.flag_is_default() && dpe.has_initialized) - || (self.flag_is_simulation() && !dpe.support.simulation) + if (self.flag_is_default() && dpe.has_initialized()) + || (self.flag_is_simulation() && !dpe.support.simulation()) { return Err(DpeErrorCode::ArgumentNotSupported); } @@ -64,7 +64,7 @@ impl CommandExecution for InitCtxCmd { .get_next_inactive_context_pos() .ok_or(DpeErrorCode::MaxTcis)?; let (context_type, handle) = if self.flag_is_default() { - dpe.has_initialized = true; + dpe.has_initialized = true.into(); (ContextType::Normal, ContextHandle::default()) } else { // Simulation. @@ -95,6 +95,7 @@ mod tests { context::ContextState, dpe_instance::tests::{TestTypes, TEST_LOCALITIES}, support::Support, + U8Bool, }; use crypto::OpensslCrypto; use platform::DefaultPlatform; @@ -154,7 +155,7 @@ mod tests { let mut dpe = DpeInstance::new( &mut env, Support { - simulation: true, + simulation: U8Bool::new(true), ..Support::default() }, ) diff --git a/dpe/src/commands/rotate_context.rs b/dpe/src/commands/rotate_context.rs index 858cf333..24e05985 100644 --- a/dpe/src/commands/rotate_context.rs +++ b/dpe/src/commands/rotate_context.rs @@ -30,7 +30,7 @@ impl CommandExecution for RotateCtxCmd { env: &mut DpeEnv, locality: u32, ) -> Result { - if !dpe.support.rotate_context { + if !dpe.support.rotate_context() { return Err(DpeErrorCode::InvalidCommand); } let idx = dpe.get_active_context_pos(&self.handle, locality)?; @@ -64,6 +64,7 @@ mod tests { commands::{Command, CommandHdr, InitCtxCmd}, dpe_instance::tests::{TestTypes, SIMULATION_HANDLE, TEST_HANDLE, TEST_LOCALITIES}, support::Support, + U8Bool, }; use crypto::OpensslCrypto; use platform::DefaultPlatform; @@ -109,7 +110,7 @@ mod tests { let mut dpe = DpeInstance::new( &mut env, Support { - rotate_context: true, + rotate_context: U8Bool::new(true), ..Support::default() }, ) diff --git a/dpe/src/commands/sign.rs b/dpe/src/commands/sign.rs index 7c5eb549..51cb3bc2 100644 --- a/dpe/src/commands/sign.rs +++ b/dpe/src/commands/sign.rs @@ -78,7 +78,7 @@ impl CommandExecution for SignCmd { locality: u32, ) -> Result { // Make sure the operation is supported. - if !dpe.support.is_symmetric && self.uses_symmetric() { + if !dpe.support.is_symmetric() && self.uses_symmetric() { return Err(DpeErrorCode::InvalidArgument); } @@ -121,6 +121,7 @@ mod tests { }, dpe_instance::tests::{TestTypes, SIMULATION_HANDLE, TEST_LOCALITIES}, support::{test::SUPPORT, Support}, + U8Bool, }; use crypto::OpensslCrypto; use openssl::x509::X509; @@ -309,8 +310,8 @@ mod tests { let mut dpe = DpeInstance::new( &mut env, Support { - auto_init: true, - is_symmetric: true, + auto_init: U8Bool::new(true), + is_symmetric: U8Bool::new(true), ..Support::default() }, ) diff --git a/dpe/src/commands/tag_tci.rs b/dpe/src/commands/tag_tci.rs index 741b5bb0..a11b692d 100644 --- a/dpe/src/commands/tag_tci.rs +++ b/dpe/src/commands/tag_tci.rs @@ -22,24 +22,28 @@ impl CommandExecution for TagTciCmd { locality: u32, ) -> Result { // Make sure this command is supported. - if !dpe.support.tagging { + if !dpe.support.tagging() { return Err(DpeErrorCode::InvalidCommand); } // Make sure the tag isn't used by any other contexts. - if dpe.contexts.iter().any(|c| c.has_tag && c.tag == self.tag) { + if dpe + .contexts + .iter() + .any(|c| c.has_tag() && c.tag == self.tag) + { return Err(DpeErrorCode::BadTag); } let idx = dpe.get_active_context_pos(&self.handle, locality)?; - if dpe.contexts[idx].has_tag { + if dpe.contexts[idx].has_tag() { return Err(DpeErrorCode::BadTag); } // Because handles are one-time use, let's rotate the handle, if it isn't the default. dpe.roll_onetime_use_handle(env, idx)?; let context = &mut dpe.contexts[idx]; - context.has_tag = true; + context.has_tag = true.into(); context.tag = self.tag; Ok(Response::TagTci(NewHandleResp { @@ -56,6 +60,7 @@ mod tests { commands::{Command, CommandHdr, InitCtxCmd}, dpe_instance::tests::{TestTypes, SIMULATION_HANDLE, TEST_HANDLE, TEST_LOCALITIES}, support::Support, + U8Bool, }; use crypto::OpensslCrypto; use platform::DefaultPlatform; @@ -99,8 +104,8 @@ mod tests { let mut dpe = DpeInstance::new( &mut env, Support { - tagging: true, - simulation: true, + tagging: U8Bool::new(true), + simulation: U8Bool::new(true), ..Support::default() }, ) diff --git a/dpe/src/context.rs b/dpe/src/context.rs index 8b235417..19a7461b 100644 --- a/dpe/src/context.rs +++ b/dpe/src/context.rs @@ -1,31 +1,40 @@ // Licensed under the Apache-2.0 license. -use crate::{response::DpeErrorCode, tci::TciNodeData, MAX_HANDLES}; +use crate::{response::DpeErrorCode, tci::TciNodeData, U8Bool, MAX_HANDLES}; use core::mem::size_of; +use zerocopy::{AsBytes, FromBytes}; #[repr(C, align(4))] +#[derive(AsBytes, FromBytes)] pub(crate) struct Context { pub handle: ContextHandle, pub tci: TciNodeData, /// Bitmap of the node indices that are children of this node pub children: u32, - /// Index in DPE instance of the parent context. 0xFF if this node is the root - pub parent_idx: u8, - pub context_type: ContextType, - pub state: ContextState, + /// Which hardware locality owns the context. pub locality: u32, - /// Whether a tag has been assigned to the context. - pub has_tag: bool, /// Optional tag assigned to the context. pub tag: u32, + + /// Whether a tag has been assigned to the context. + pub has_tag: U8Bool, + + /// Index in DPE instance of the parent context. 0xFF if this node is the root + pub parent_idx: u8, + + /// The type of this context + pub context_type: ContextType, + + /// The current state of this context + pub state: ContextState, /// Whether we should hash internal input info consisting of major_version, minor_version, vendor_id, vendor_sku, max_tci_nodes, flags, and DPE_PROFILE when deriving the CDI - pub uses_internal_input_info: bool, + pub uses_internal_input_info: U8Bool, /// Whether we should hash internal dice info consisting of the certificate chain when deriving the CDI - pub uses_internal_input_dice: bool, + pub uses_internal_input_dice: U8Bool, /// Whether this context can emit certificates with IsCA = True - pub allow_ca: bool, + pub allow_ca: U8Bool, /// Whether this context can emit certificates in X.509 format - pub allow_x509: bool, + pub allow_x509: U8Bool, } impl Context { @@ -40,15 +49,31 @@ impl Context { context_type: ContextType::Normal, state: ContextState::Inactive, locality: 0, - has_tag: false, + has_tag: U8Bool::new(false), tag: 0, - uses_internal_input_info: false, - uses_internal_input_dice: false, - allow_ca: false, - allow_x509: false, + uses_internal_input_info: U8Bool::new(false), + uses_internal_input_dice: U8Bool::new(false), + allow_ca: U8Bool::new(false), + allow_x509: U8Bool::new(false), } } + pub fn has_tag(&self) -> bool { + self.has_tag.get() + } + pub fn uses_internal_input_info(&self) -> bool { + self.uses_internal_input_info.get() + } + pub fn uses_internal_input_dice(&self) -> bool { + self.uses_internal_input_dice.get() + } + pub fn allow_ca(&self) -> bool { + self.allow_ca.get() + } + pub fn allow_x509(&self) -> bool { + self.allow_x509.get() + } + /// Resets all values to a freshly initialized state. /// /// # Arguments @@ -67,19 +92,19 @@ impl Context { self.context_type = args.context_type; self.state = ContextState::Active; self.locality = args.locality; - self.allow_ca = args.allow_ca; - self.allow_x509 = args.allow_x509 + self.allow_ca = args.allow_ca.into(); + self.allow_x509 = args.allow_x509.into(); } /// Destroy this context so it can no longer be used until it is re-initialized. The default /// context cannot be re-initialized. pub fn destroy(&mut self) { self.tci = TciNodeData::new(); - self.has_tag = false; + self.has_tag = false.into(); self.tag = 0; self.state = ContextState::Inactive; - self.uses_internal_input_info = false; - self.uses_internal_input_dice = false; + self.uses_internal_input_info = false.into(); + self.uses_internal_input_dice = false.into(); } /// Add a child to list of children in the context. @@ -133,7 +158,9 @@ impl TryFrom<&[u8]> for ContextHandle { } } -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq, AsBytes, FromBytes)] +#[repr(u8, align(1))] +#[rustfmt::skip] pub(crate) enum ContextState { /// Inactive or uninitialized. Inactive, @@ -144,14 +171,50 @@ pub(crate) enum ContextState { /// TCI data, but the handle is no longer valid. Because the handle is no longer valid, a client /// cannot command it to be destroyed. Retired, + // These are unused values to allow AsBytes and FromBytes to be able to use the enum. + _03, _04, _05, _06, _07, _08, _09, _0a, _0b, _0c, _0d, _0e, _0f, + _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _1a, _1b, _1c, _1d, _1e, _1f, + _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _2a, _2b, _2c, _2d, _2e, _2f, + _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _3a, _3b, _3c, _3d, _3e, _3f, + _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _4a, _4b, _4c, _4d, _4e, _4f, + _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _5a, _5b, _5c, _5d, _5e, _5f, + _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _6a, _6b, _6c, _6d, _6e, _6f, + _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _7a, _7b, _7c, _7d, _7e, _7f, + _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _8a, _8b, _8c, _8d, _8e, _8f, + _90, _91, _92, _93, _94, _95, _96, _97, _98, _99, _9a, _9b, _9c, _9d, _9e, _9f, + _A0, _A1, _A2, _A3, _A4, _A5, _A6, _A7, _A8, _A9, _Aa, _Ab, _Ac, _Ad, _Ae, _Af, + _B0, _B1, _B2, _B3, _B4, _B5, _B6, _B7, _B8, _B9, _Ba, _Bb, _Bc, _Bd, _Be, _Bf, + _C0, _C1, _C2, _C3, _C4, _C5, _C6, _C7, _C8, _C9, _Ca, _Cb, _Cc, _Cd, _Ce, _Cf, + _D0, _D1, _D2, _D3, _D4, _D5, _D6, _D7, _D8, _D9, _Da, _Db, _Dc, _Dd, _De, _Df, + _E0, _E1, _E2, _E3, _E4, _E5, _E6, _E7, _E8, _E9, _Ea, _Eb, _Ec, _Ed, _Ee, _Ef, + _F0, _F1, _F2, _F3, _F4, _F5, _F6, _F7, _F8, _F9, _Fa, _Fb, _Fc, _Fd, _Fe, _Ff, } -#[derive(Debug, PartialEq, Eq, Clone, Copy)] +#[derive(Debug, PartialEq, Eq, Clone, Copy, AsBytes, FromBytes)] +#[repr(u8, align(1))] +#[rustfmt::skip] pub(crate) enum ContextType { /// Typical context. Normal, /// Has limitations on what operations can be done. Simulation, + // These are unused values to allow AsBytes and FromBytes to be able to use the enum. + _02, _03, _04, _05, _06, _07, _08, _09, _0a, _0b, _0c, _0d, _0e, _0f, + _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _1a, _1b, _1c, _1d, _1e, _1f, + _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _2a, _2b, _2c, _2d, _2e, _2f, + _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _3a, _3b, _3c, _3d, _3e, _3f, + _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _4a, _4b, _4c, _4d, _4e, _4f, + _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _5a, _5b, _5c, _5d, _5e, _5f, + _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _6a, _6b, _6c, _6d, _6e, _6f, + _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _7a, _7b, _7c, _7d, _7e, _7f, + _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _8a, _8b, _8c, _8d, _8e, _8f, + _90, _91, _92, _93, _94, _95, _96, _97, _98, _99, _9a, _9b, _9c, _9d, _9e, _9f, + _A0, _A1, _A2, _A3, _A4, _A5, _A6, _A7, _A8, _A9, _Aa, _Ab, _Ac, _Ad, _Ae, _Af, + _B0, _B1, _B2, _B3, _B4, _B5, _B6, _B7, _B8, _B9, _Ba, _Bb, _Bc, _Bd, _Be, _Bf, + _C0, _C1, _C2, _C3, _C4, _C5, _C6, _C7, _C8, _C9, _Ca, _Cb, _Cc, _Cd, _Ce, _Cf, + _D0, _D1, _D2, _D3, _D4, _D5, _D6, _D7, _D8, _D9, _Da, _Db, _Dc, _Dd, _De, _Df, + _E0, _E1, _E2, _E3, _E4, _E5, _E6, _E7, _E8, _E9, _Ea, _Eb, _Ec, _Ed, _Ee, _Ef, + _F0, _F1, _F2, _F3, _F4, _F5, _F6, _F7, _F8, _F9, _Fa, _Fb, _Fc, _Fd, _Fe, _Ff, } pub(crate) struct ActiveContextArgs<'a> { diff --git a/dpe/src/dpe_instance.rs b/dpe/src/dpe_instance.rs index 8ba7386e..64790894 100644 --- a/dpe/src/dpe_instance.rs +++ b/dpe/src/dpe_instance.rs @@ -10,11 +10,11 @@ use crate::{ response::{DpeErrorCode, GetProfileResp, Response, ResponseHdr}, support::Support, tci::{TciMeasurement, TciNodeData}, - DPE_PROFILE, INTERNAL_INPUT_INFO_SIZE, MAX_HANDLES, + U8Bool, DPE_PROFILE, INTERNAL_INPUT_INFO_SIZE, MAX_HANDLES, }; use crypto::{Crypto, Digest, Hasher}; use platform::{Platform, MAX_CHUNK_SIZE}; -use zerocopy::AsBytes; +use zerocopy::{AsBytes, FromBytes}; pub trait DpeTypes { type Crypto<'a>: Crypto @@ -28,13 +28,15 @@ pub struct DpeEnv<'a, T: DpeTypes + 'a> { pub platform: T::Platform, } +#[repr(C, align(4))] +#[derive(AsBytes, FromBytes)] pub struct DpeInstance { pub(crate) contexts: [Context; MAX_HANDLES], pub(crate) support: Support, /// Can only successfully execute the initialize context command for non-simulation (i.e. /// `InitializeContext(simulation=false)`) once per reset cycle. - pub(crate) has_initialized: bool, + pub(crate) has_initialized: U8Bool, } impl DpeInstance { @@ -54,10 +56,10 @@ impl DpeInstance { let mut dpe = DpeInstance { contexts: [CONTEXT_INITIALIZER; MAX_HANDLES], support, - has_initialized: false, + has_initialized: false.into(), }; - if dpe.support.auto_init { + if dpe.support.auto_init() { let locality = env .platform .get_auto_init_locality() @@ -67,6 +69,10 @@ impl DpeInstance { Ok(dpe) } + pub fn has_initialized(&self) -> bool { + self.has_initialized.get() + } + pub fn get_profile( &self, platform: &mut impl Platform, @@ -175,7 +181,7 @@ impl DpeInstance { /// Recursive function that will return all of a context's descendants. Returns a u32 that is /// a bitmap of the node indices. pub(crate) fn get_descendants(&self, context: &Context) -> Result { - if matches!(context.state, ContextState::Inactive) { + if context.state == ContextState::Inactive { return Err(DpeErrorCode::InvalidHandle); } @@ -345,8 +351,10 @@ impl DpeInstance { .map_err(|_| DpeErrorCode::HashError)?; // Check if any context uses internal inputs - uses_internal_input_info = uses_internal_input_info || context.uses_internal_input_info; - uses_internal_input_dice = uses_internal_input_dice || context.uses_internal_input_dice; + uses_internal_input_info = + uses_internal_input_info || context.uses_internal_input_info(); + uses_internal_input_dice = + uses_internal_input_dice || context.uses_internal_input_dice(); } // Add internal input info to hash @@ -414,7 +422,7 @@ pub mod tests { use crate::commands::DeriveChildCmd; use crate::response::NewHandleResp; use crate::support::test::SUPPORT; - use crate::{commands::CommandHdr, CURRENT_PROFILE_MAJOR_VERSION}; + use crate::{commands::CommandHdr, U8Bool, CURRENT_PROFILE_MAJOR_VERSION}; use crypto::OpensslCrypto; use platform::{DefaultPlatform, AUTO_INIT_LOCALITY, MAX_CHUNK_SIZE, TEST_CERT_CHAIN}; use zerocopy::AsBytes; @@ -529,7 +537,7 @@ pub mod tests { let mut dpe = DpeInstance::new( &mut env, Support { - auto_init: true, + auto_init: U8Bool::new(true), ..Default::default() }, ) @@ -696,7 +704,7 @@ pub mod tests { let mut dpe = DpeInstance::new( &mut env, Support { - internal_info: true, + internal_info: U8Bool::new(true), ..SUPPORT }, ) @@ -723,7 +731,7 @@ pub mod tests { .derive_cdi(DPE_PROFILE.alg_len(), &digest, b"DPE") .unwrap(); let context = &dpe.contexts[parent_context_idx]; - assert!(context.uses_internal_input_info); + assert!(context.uses_internal_input_info()); let mut hasher = env.crypto.hash_initialize(DPE_PROFILE.alg_len()).unwrap(); @@ -753,7 +761,7 @@ pub mod tests { let mut dpe = DpeInstance::new( &mut env, Support { - internal_dice: true, + internal_dice: U8Bool::new(true), ..SUPPORT }, ) @@ -780,7 +788,7 @@ pub mod tests { .derive_cdi(DPE_PROFILE.alg_len(), &digest, b"DPE") .unwrap(); let context = &dpe.contexts[parent_context_idx]; - assert!(context.uses_internal_input_dice); + assert!(context.uses_internal_input_dice()); let mut hasher = env.crypto.hash_initialize(DPE_PROFILE.alg_len()).unwrap(); diff --git a/dpe/src/lib.rs b/dpe/src/lib.rs index 965dd365..666af982 100644 --- a/dpe/src/lib.rs +++ b/dpe/src/lib.rs @@ -20,6 +20,8 @@ use response::GetProfileResp; pub mod tci; pub mod x509; +use zerocopy::{AsBytes, FromBytes}; + const MAX_CERT_SIZE: usize = 2048; const MAX_HANDLES: usize = 24; const CURRENT_PROFILE_MAJOR_VERSION: u16 = 0; @@ -27,6 +29,39 @@ const CURRENT_PROFILE_MINOR_VERSION: u16 = 8; const INTERNAL_INPUT_INFO_SIZE: usize = size_of::() + size_of::(); +/// A type with u8 backing memory but bool semantics +/// This is needed to safely serialize booleans in the persisted DPE state +/// using zerocopy. +#[derive(Default, AsBytes, FromBytes)] +#[repr(C, align(1))] +pub struct U8Bool { + val: u8, +} + +impl U8Bool { + pub const fn new(val: bool) -> Self { + Self { val: val as u8 } + } + + pub fn get(&self) -> bool { + self.val != 0 + } + + pub fn set(&mut self, val: bool) { + self.val = val as u8; + } + + pub fn is_bool(&self) -> bool { + self.val == 0 || self.val == 1 + } +} + +impl From for U8Bool { + fn from(item: bool) -> Self { + Self { val: item as u8 } + } +} + pub enum DpeProfile { P256Sha256 = 1, P384Sha384 = 2, diff --git a/dpe/src/response.rs b/dpe/src/response.rs index b4861cb0..e3913876 100644 --- a/dpe/src/response.rs +++ b/dpe/src/response.rs @@ -188,4 +188,5 @@ pub enum DpeErrorCode { CryptoError = 0x1005, HashError = 0x1006, RandError = 0x1007, + InvalidInternalState = 0x1008, } diff --git a/dpe/src/support.rs b/dpe/src/support.rs index 5343d50b..63b6112e 100644 --- a/dpe/src/support.rs +++ b/dpe/src/support.rs @@ -1,21 +1,58 @@ // Licensed under the Apache-2.0 license. +use crate::U8Bool; +use zerocopy::{AsBytes, FromBytes}; -#[derive(Default)] +#[derive(Default, AsBytes, FromBytes)] +#[repr(C)] pub struct Support { - pub simulation: bool, - pub extend_tci: bool, - pub auto_init: bool, - pub tagging: bool, - pub rotate_context: bool, - pub x509: bool, - pub csr: bool, - pub is_symmetric: bool, - pub internal_info: bool, - pub internal_dice: bool, - pub is_ca: bool, + pub simulation: U8Bool, + pub extend_tci: U8Bool, + pub auto_init: U8Bool, + pub tagging: U8Bool, + pub rotate_context: U8Bool, + pub x509: U8Bool, + pub csr: U8Bool, + pub is_symmetric: U8Bool, + pub internal_info: U8Bool, + pub internal_dice: U8Bool, + pub is_ca: U8Bool, } impl Support { + pub fn simulation(&self) -> bool { + self.simulation.get() + } + pub fn extend_tci(&self) -> bool { + self.extend_tci.get() + } + pub fn auto_init(&self) -> bool { + self.auto_init.get() + } + pub fn tagging(&self) -> bool { + self.tagging.get() + } + pub fn rotate_context(&self) -> bool { + self.rotate_context.get() + } + pub fn x509(&self) -> bool { + self.x509.get() + } + pub fn csr(&self) -> bool { + self.csr.get() + } + pub fn is_symmetric(&self) -> bool { + self.is_symmetric.get() + } + pub fn internal_info(&self) -> bool { + self.internal_info.get() + } + pub fn internal_dice(&self) -> bool { + self.internal_dice.get() + } + pub fn is_ca(&self) -> bool { + self.is_ca.get() + } + /// Returns all the flags bit-wise OR'ed together in the same configuration as the `GetProfile` /// command. pub fn get_flags(&self) -> u32 { @@ -32,37 +69,37 @@ impl Support { | self.get_is_ca_flag() } fn get_simulation_flag(&self) -> u32 { - u32::from(self.simulation) << 31 + u32::from(self.simulation.get()) << 31 } fn get_extend_tci_flag(&self) -> u32 { - u32::from(self.extend_tci) << 30 + u32::from(self.extend_tci.get()) << 30 } fn get_auto_init_flag(&self) -> u32 { - u32::from(self.auto_init) << 29 + u32::from(self.auto_init.get()) << 29 } fn get_tagging_flag(&self) -> u32 { - u32::from(self.tagging) << 28 + u32::from(self.tagging.get()) << 28 } fn get_rotate_context_flag(&self) -> u32 { - u32::from(self.rotate_context) << 27 + u32::from(self.rotate_context.get()) << 27 } fn get_x509_flag(&self) -> u32 { - u32::from(self.x509) << 26 + u32::from(self.x509.get()) << 26 } fn get_csr_flag(&self) -> u32 { - u32::from(self.csr) << 25 + u32::from(self.csr.get()) << 25 } fn get_is_symmetric_flag(&self) -> u32 { - u32::from(self.is_symmetric) << 24 + u32::from(self.is_symmetric.get()) << 24 } fn get_internal_info_flag(&self) -> u32 { - u32::from(self.internal_info) << 23 + u32::from(self.internal_info.get()) << 23 } fn get_internal_dice_flag(&self) -> u32 { - u32::from(self.internal_dice) << 22 + u32::from(self.internal_dice.get()) << 22 } fn get_is_ca_flag(&self) -> u32 { - u32::from(self.is_ca) << 21 + u32::from(self.is_ca.get()) << 21 } } @@ -71,98 +108,98 @@ pub mod test { use super::*; pub const SUPPORT: Support = Support { - simulation: true, - extend_tci: false, - auto_init: true, - tagging: true, - rotate_context: true, - x509: true, - csr: false, - is_symmetric: false, - internal_info: false, - internal_dice: false, - is_ca: false, + simulation: U8Bool::new(true), + extend_tci: U8Bool::new(false), + auto_init: U8Bool::new(true), + tagging: U8Bool::new(true), + rotate_context: U8Bool::new(true), + x509: U8Bool::new(true), + csr: U8Bool::new(false), + is_symmetric: U8Bool::new(false), + internal_info: U8Bool::new(false), + internal_dice: U8Bool::new(false), + is_ca: U8Bool::new(false), }; #[test] fn test_get_support_flags() { // Supports simulation flag. let flags = Support { - simulation: true, + simulation: U8Bool::new(true), ..Support::default() } .get_flags(); assert_eq!(flags, 1 << 31); // Supports extended TCI flag. let flags = Support { - extend_tci: true, + extend_tci: U8Bool::new(true), ..Support::default() } .get_flags(); assert_eq!(flags, 1 << 30); // Supports auto-init. let flags = Support { - auto_init: true, + auto_init: U8Bool::new(true), ..Support::default() } .get_flags(); assert_eq!(flags, 1 << 29); // Supports tagging. let flags = Support { - tagging: true, + tagging: U8Bool::new(true), ..Support::default() } .get_flags(); assert_eq!(flags, 1 << 28); // Supports rotate context. let flags = Support { - rotate_context: true, + rotate_context: U8Bool::new(true), ..Support::default() } .get_flags(); assert_eq!(flags, 1 << 27); // Supports certify key. let flags = Support { - x509: true, + x509: U8Bool::new(true), ..Support::default() } .get_flags(); assert_eq!(flags, 1 << 26); // Supports certify csr. let flags = Support { - csr: true, + csr: U8Bool::new(true), ..Support::default() } .get_flags(); assert_eq!(flags, 1 << 25); // Supports is symmetric. let flags = Support { - is_symmetric: true, + is_symmetric: U8Bool::new(true), ..Support::default() } .get_flags(); assert_eq!(flags, 1 << 24); // Supports internal info. let flags = Support { - internal_info: true, + internal_info: U8Bool::new(true), ..Support::default() } .get_flags(); assert_eq!(flags, 1 << 23); // Supports internal DICE. let flags = Support { - internal_dice: true, + internal_dice: U8Bool::new(true), ..Support::default() } .get_flags(); assert_eq!(flags, 1 << 22); // Supports a couple combos. let flags = Support { - simulation: true, - auto_init: true, - rotate_context: true, - csr: true, - internal_dice: true, + simulation: U8Bool::new(true), + auto_init: U8Bool::new(true), + rotate_context: U8Bool::new(true), + csr: U8Bool::new(true), + internal_dice: U8Bool::new(true), ..Support::default() } .get_flags(); @@ -171,11 +208,11 @@ pub mod test { (1 << 31) | (1 << 29) | (1 << 27) | (1 << 25) | (1 << 22) ); let flags = Support { - extend_tci: true, - tagging: true, - x509: true, - is_symmetric: true, - internal_info: true, + extend_tci: U8Bool::new(true), + tagging: U8Bool::new(true), + x509: U8Bool::new(true), + is_symmetric: U8Bool::new(true), + internal_info: U8Bool::new(true), ..Support::default() } .get_flags(); @@ -185,17 +222,17 @@ pub mod test { ); // Supports everything. let flags = Support { - simulation: true, - extend_tci: true, - auto_init: true, - tagging: true, - rotate_context: true, - x509: true, - csr: true, - is_symmetric: true, - internal_info: true, - internal_dice: true, - is_ca: true, + simulation: U8Bool::new(true), + extend_tci: U8Bool::new(true), + auto_init: U8Bool::new(true), + tagging: U8Bool::new(true), + rotate_context: U8Bool::new(true), + x509: U8Bool::new(true), + csr: U8Bool::new(true), + is_symmetric: U8Bool::new(true), + internal_info: U8Bool::new(true), + internal_dice: U8Bool::new(true), + is_ca: U8Bool::new(true), } .get_flags(); assert_eq!( diff --git a/dpe/src/tci.rs b/dpe/src/tci.rs index a44185c8..8c2a5d3d 100644 --- a/dpe/src/tci.rs +++ b/dpe/src/tci.rs @@ -1,10 +1,9 @@ // Licensed under the Apache-2.0 license. use crate::DPE_PROFILE; -use zerocopy::AsBytes; +use zerocopy::{AsBytes, FromBytes}; #[repr(C, align(4))] -#[derive(Default, Copy, Clone, AsBytes)] -#[cfg_attr(test, derive(zerocopy::FromBytes))] +#[derive(Default, Copy, Clone, AsBytes, FromBytes)] pub struct TciNodeData { pub tci_type: u32, pub tci_cumulative: TciMeasurement, @@ -24,8 +23,8 @@ impl TciNodeData { } #[repr(transparent)] -#[derive(Copy, Clone, Debug, AsBytes)] -#[cfg_attr(test, derive(PartialEq, Eq, zerocopy::FromBytes))] +#[derive(Copy, Clone, Debug, AsBytes, FromBytes)] +#[cfg_attr(test, derive(PartialEq, Eq))] pub struct TciMeasurement(pub [u8; DPE_PROFILE.get_tci_size()]); impl Default for TciMeasurement { diff --git a/simulator/src/main.rs b/simulator/src/main.rs index 8a91b00b..37183d41 100644 --- a/simulator/src/main.rs +++ b/simulator/src/main.rs @@ -141,17 +141,17 @@ fn main() -> std::io::Result<()> { .unwrap(); let support = Support { - simulation: args.supports_simulation, - extend_tci: args.supports_extend_tci, - auto_init: args.supports_auto_init, - tagging: args.supports_tagging, - rotate_context: args.supports_rotate_context, - x509: args.supports_x509, - csr: args.supports_csr, - is_ca: args.supports_is_ca, - is_symmetric: args.supports_is_symmetric, - internal_info: args.supports_internal_info, - internal_dice: args.supports_internal_dice, + simulation: args.supports_simulation.into(), + extend_tci: args.supports_extend_tci.into(), + auto_init: args.supports_auto_init.into(), + tagging: args.supports_tagging.into(), + rotate_context: args.supports_rotate_context.into(), + x509: args.supports_x509.into(), + csr: args.supports_csr.into(), + is_ca: args.supports_is_ca.into(), + is_symmetric: args.supports_is_symmetric.into(), + internal_info: args.supports_internal_info.into(), + internal_dice: args.supports_internal_dice.into(), }; let mut env = DpeEnv:: {