Skip to content

Commit

Permalink
Add is_certificate and export_cdi flags to DeriveContext
Browse files Browse the repository at this point in the history
As well as other boiler plate work to make sure the invariants laid out
in the spec are enforced.
  • Loading branch information
clundin25 committed Jan 13, 2025
1 parent af0251e commit 53a3535
Show file tree
Hide file tree
Showing 6 changed files with 172 additions and 2 deletions.
1 change: 1 addition & 0 deletions dpe/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ disable_csr = []
disable_internal_info = []
disable_internal_dice = []
disable_retain_parent_context = []
disable_export_cdi = []
no-cfi = ["crypto/no-cfi"]

[dependencies]
Expand Down
136 changes: 135 additions & 1 deletion dpe/src/commands/derive_context.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Licensed under the Apache-2.0 license.
use super::CommandExecution;
use crate::{
context::{ActiveContextArgs, Context, ContextHandle, ContextState},
context::{ActiveContextArgs, Context, ContextHandle, ContextState, ContextType},
dpe_instance::{DpeEnv, DpeInstance, DpeTypes},
response::{DeriveContextResp, DpeErrorCode, Response, ResponseHdr},
tci::TciMeasurement,
Expand Down Expand Up @@ -36,6 +36,8 @@ bitflags! {
const INPUT_ALLOW_CA = 1u32 << 26;
const INPUT_ALLOW_X509 = 1u32 << 25;
const RECURSIVE = 1u32 << 24;
const EXPORT_CDI = 1u32 << 23;
const CREATE_CERTIFICATE = 1u32 << 22;
}
}

Expand Down Expand Up @@ -91,6 +93,14 @@ impl DeriveContextCmd {
self.flags.contains(DeriveContextFlags::RECURSIVE)
}

pub const fn allows_exports_cdi(&self) -> bool {
self.flags.contains(DeriveContextFlags::EXPORT_CDI)
}

pub const fn allows_create_certificate(&self) -> bool {
self.flags.contains(DeriveContextFlags::CREATE_CERTIFICATE)
}

/// Whether it is okay to make a default context.
///
/// When a default context is in a locality, it MUST be the only context in the locality. This
Expand Down Expand Up @@ -196,6 +206,8 @@ impl CommandExecution for DeriveContextCmd {
|| (!dpe.support.internal_dice() && self.uses_internal_dice_input())
|| (!dpe.support.retain_parent_context() && self.retains_parent())
|| (!dpe.support.x509() && self.allows_x509())
|| (!dpe.support.cdi_export()
&& (self.allows_create_certificate() && self.allows_exports_cdi()))
|| (!dpe.support.recursive() && self.is_recursive())
{
return Err(DpeErrorCode::ArgumentNotSupported);
Expand All @@ -204,6 +216,11 @@ impl CommandExecution for DeriveContextCmd {
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())
|| (self.allows_exports_cdi() && !self.allows_create_certificate())
|| (self.allows_exports_cdi() && self.is_recursive())
|| (self.allows_exports_cdi() && self.changes_locality())
|| (self.allows_exports_cdi()
&& dpe.contexts[parent_idx].context_type == ContextType::Simulation)
|| (self.is_recursive() && self.retains_parent())
{
return Err(DpeErrorCode::InvalidArgument);
Expand Down Expand Up @@ -267,6 +284,8 @@ impl CommandExecution for DeriveContextCmd {
Err(DpeErrorCode::ArgumentNotSupported)?
}
}
} else if self.allows_create_certificate() && self.allows_exports_cdi() {
todo!("(clundin): Generate ECA certificiate / export random CDI")
} else {
let child_idx = dpe
.get_next_inactive_context_pos()
Expand Down Expand Up @@ -784,6 +803,7 @@ mod tests {
handle,
parent_handle,
resp_hdr,
..
}) = DeriveContextCmd {
handle: dpe.contexts[old_default_idx].handle,
data: [0; DPE_PROFILE.get_tci_size()],
Expand Down Expand Up @@ -996,4 +1016,118 @@ mod tests {
let digest = hasher_2.finish().unwrap();
assert_eq!(digest.bytes(), dpe.contexts[child_idx].tci.tci_cumulative.0);
}

#[test]
fn test_cdi_export_flags() {
CfiCounter::reset_for_test();
let mut env = DpeEnv::<TestTypes> {
crypto: OpensslCrypto::new(),
platform: DefaultPlatform,
};
let mut dpe = DpeInstance::new(
&mut env,
Support::AUTO_INIT
| Support::CDI_EXPORT
| Support::X509
| Support::RECURSIVE
| Support::SIMULATION,
)
.unwrap();

// When `DeriveContextFlags::EXPORT_CDI` is set, `DeriveContextFlags::CREATE_CERTIFICATE` MUST
// also be set, or `DpeErrorCode::InvalidArgument` is raised.
assert_eq!(
Err(DpeErrorCode::InvalidArgument),
DeriveContextCmd {
handle: ContextHandle::default(),
data: [0; DPE_PROFILE.get_tci_size()],
flags: DeriveContextFlags::EXPORT_CDI | DeriveContextFlags::CHANGE_LOCALITY,
tci_type: 0,
target_locality: TEST_LOCALITIES[1]
}
.execute(&mut dpe, &mut env, TEST_LOCALITIES[0])
);
assert_eq!(
Err(DpeErrorCode::InvalidArgument),
DeriveContextCmd {
handle: ContextHandle::default(),
data: [0; DPE_PROFILE.get_tci_size()],
flags: DeriveContextFlags::EXPORT_CDI | DeriveContextFlags::RECURSIVE,
tci_type: 0,
target_locality: TEST_LOCALITIES[0]
}
.execute(&mut dpe, &mut env, TEST_LOCALITIES[0])
);

let simulation_handle = match InitCtxCmd::new_simulation()
.execute(&mut dpe, &mut env, TEST_LOCALITIES[0])
.unwrap()
{
Response::InitCtx(resp) => resp.handle,
_ => panic!("Wrong response type."),
};
// DPE must return an `DpeErrorCode::InvalidArgument` error if the context-handle refers to a simulation context.
assert_eq!(
Err(DpeErrorCode::InvalidArgument),
DeriveContextCmd {
handle: simulation_handle,
data: [0; DPE_PROFILE.get_tci_size()],
flags: DeriveContextFlags::CREATE_CERTIFICATE | DeriveContextFlags::EXPORT_CDI,
tci_type: 0,
target_locality: TEST_LOCALITIES[0]
}
.execute(&mut dpe, &mut env, TEST_LOCALITIES[0])
);

// DPE must return an `DpeErrorCode::InvalidArgument` if `DeriveContextFlags::EXPORT_CDI` and `DeriveContextFlags::RECURSIVE` are set.
assert_eq!(
Err(DpeErrorCode::InvalidArgument),
DeriveContextCmd {
handle: ContextHandle::default(),
data: [0; DPE_PROFILE.get_tci_size()],
flags: DeriveContextFlags::CREATE_CERTIFICATE
| DeriveContextFlags::EXPORT_CDI
| DeriveContextFlags::RECURSIVE,
tci_type: 0,
target_locality: TEST_LOCALITIES[0]
}
.execute(&mut dpe, &mut env, TEST_LOCALITIES[0])
);

dpe = DpeInstance::new(
&mut env,
Support::AUTO_INIT | Support::CDI_EXPORT | Support::X509,
)
.unwrap();

// Happy case!
assert!(DeriveContextCmd {
handle: ContextHandle::default(),
data: [0; DPE_PROFILE.get_tci_size()],
flags: DeriveContextFlags::EXPORT_CDI | DeriveContextFlags::CREATE_CERTIFICATE,
tci_type: 0,
target_locality: TEST_LOCALITIES[0]
}
.execute(&mut dpe, &mut env, TEST_LOCALITIES[0])
.is_ok());

let mut dpe = DpeInstance::new(
&mut env,
Support::AUTO_INIT | Support::INTERNAL_INFO | Support::INTERNAL_DICE | Support::X509,
)
.unwrap();

// `DpeInstance` needs `Support::EXPORT_CDI` to use `DeriveContextFlags::EXPORT_CDI`.
assert_eq!(
Err(DpeErrorCode::ArgumentNotSupported),
DeriveContextCmd {
handle: ContextHandle::default(),
data: [0; DPE_PROFILE.get_tci_size()],
flags: DeriveContextFlags::CREATE_CERTIFICATE | DeriveContextFlags::EXPORT_CDI,
tci_type: 0,
target_locality: TEST_LOCALITIES[0]
}
.execute(&mut dpe, &mut env, TEST_LOCALITIES[0])
);
}
}
2 changes: 2 additions & 0 deletions dpe/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ pub mod x509;

use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};

const MAX_EXPORTED_CDI_SIZE: usize = 256;

// Max cert size returned by CertifyKey
const MAX_CERT_SIZE: usize = 6144;
#[cfg(not(feature = "arbitrary_max_handles"))]
Expand Down
23 changes: 22 additions & 1 deletion dpe/src/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Abstract:
--*/
use crate::{
context::ContextHandle, validation::ValidationError, CURRENT_PROFILE_MAJOR_VERSION,
CURRENT_PROFILE_MINOR_VERSION, DPE_PROFILE, MAX_CERT_SIZE, MAX_HANDLES,
CURRENT_PROFILE_MINOR_VERSION, DPE_PROFILE, MAX_CERT_SIZE, MAX_EXPORTED_CDI_SIZE, MAX_HANDLES,
};
use crypto::CryptoError;
use platform::{PlatformError, MAX_CHUNK_SIZE};
Expand All @@ -18,6 +18,7 @@ pub enum Response {
GetProfile(GetProfileResp),
InitCtx(NewHandleResp),
DeriveContext(DeriveContextResp),
DeriveContextExportedCdi(DeriveContextExportedCdiResp),
RotateCtx(NewHandleResp),
CertifyKey(CertifyKeyResp),
Sign(SignResp),
Expand All @@ -32,6 +33,7 @@ impl Response {
Response::GetProfile(res) => res.as_bytes(),
Response::InitCtx(res) => res.as_bytes(),
Response::DeriveContext(res) => res.as_bytes(),
Response::DeriveContextExportedCdi(res) => res.as_bytes(),
Response::RotateCtx(res) => res.as_bytes(),
Response::CertifyKey(res) => res.as_bytes(),
Response::Sign(res) => res.as_bytes(),
Expand Down Expand Up @@ -141,6 +143,25 @@ pub struct DeriveContextResp {
pub parent_handle: ContextHandle,
}

#[repr(C)]
#[derive(
Debug,
PartialEq,
Eq,
zerocopy::IntoBytes,
zerocopy::FromBytes,
zerocopy::Immutable,
zerocopy::KnownLayout,
)]
pub struct DeriveContextExportedCdiResp {
pub resp_hdr: ResponseHdr,
pub handle: ContextHandle,
pub parent_handle: ContextHandle,
pub exported_cdi: [u8; MAX_EXPORTED_CDI_SIZE],
pub certificate_size: u32,
pub new_certificate: [u8; MAX_CERT_SIZE],
}

#[repr(C)]
#[derive(
Debug,
Expand Down
11 changes: 11 additions & 0 deletions dpe/src/support.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ bitflags! {
const INTERNAL_INFO = 1u32 << 22;
const INTERNAL_DICE = 1u32 << 21;
const RETAIN_PARENT_CONTEXT = 1u32 << 19;
const CDI_EXPORT = 1u32 << 18;
}
}

Expand Down Expand Up @@ -49,6 +50,9 @@ impl Support {
pub fn retain_parent_context(&self) -> bool {
self.contains(Support::RETAIN_PARENT_CONTEXT)
}
pub fn cdi_export(&self) -> bool {
self.contains(Support::CDI_EXPORT)
}

/// Disables supported features based on compilation features
pub fn preprocess_support(&self) -> Support {
Expand Down Expand Up @@ -90,6 +94,10 @@ impl Support {
{
support.insert(Support::RETAIN_PARENT_CONTEXT);
}
#[cfg(feature = "disable_export_cdi")]
{
support.insert(Support::CDI_EXPORT);
}
self.difference(support)
}
}
Expand Down Expand Up @@ -135,6 +143,8 @@ pub mod test {
assert_eq!(flags, 1 << 21);
let flags = Support::RETAIN_PARENT_CONTEXT.bits();
assert_eq!(flags, 1 << 19);
let flags = Support::CDI_EXPORT.bits();
assert_eq!(flags, 1 << 18);
// Supports a couple combos.
let flags = (Support::SIMULATION
| Support::AUTO_INIT
Expand All @@ -161,6 +171,7 @@ pub mod test {
| (1 << 22)
| (1 << 21)
| (1 << 19)
| (1 << 18)
);
}
}
1 change: 1 addition & 0 deletions simulator/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ fn handle_request(dpe: &mut DpeInstance, env: &mut DpeEnv<impl DpeTypes>, stream
Response::GetProfile(ref res) => res.resp_hdr.status,
Response::InitCtx(ref res) => res.resp_hdr.status,
Response::DeriveContext(ref res) => res.resp_hdr.status,
Response::DeriveContextExportedCdi(ref res) => res.resp_hdr.status,
Response::RotateCtx(ref res) => res.resp_hdr.status,
Response::CertifyKey(ref res) => res.resp_hdr.status,
Response::Sign(ref res) => res.resp_hdr.status,
Expand Down

0 comments on commit 53a3535

Please sign in to comment.