Skip to content

Commit

Permalink
Add DPE commands to execute_all_services_rt
Browse files Browse the repository at this point in the history
  • Loading branch information
jlmahowa-amd authored and jhand2 committed Apr 9, 2024
1 parent f53d58a commit b72c293
Show file tree
Hide file tree
Showing 4 changed files with 212 additions and 1 deletion.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ openssl.workspace = true
rand.workspace = true
zerocopy.workspace = true
caliptra-hw-model.workspace = true
dpe.workspace = true

[dev-dependencies]
caliptra-builder.workspace = true
Expand Down
78 changes: 78 additions & 0 deletions test/tests/fips_test_suite/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ use caliptra_builder::firmware::{APP_WITH_UART, FMC_WITH_UART};
use caliptra_builder::ImageOptions;
use caliptra_common::mailbox_api::*;
use caliptra_hw_model::{BootParams, DefaultHwModel, HwModel, ModelError};
use dpe::{
commands::*,
response::{
CertifyKeyResp, DeriveContextResp, GetCertificateChainResp, GetProfileResp, NewHandleResp,
Response, ResponseHdr, SignResp,
},
};
use zerocopy::{AsBytes, FromBytes};

// =================================
Expand Down Expand Up @@ -230,6 +237,77 @@ pub fn mbx_send_and_check_resp_hdr<T: HwModel, U: FromBytes + AsBytes>(
//Ok(U::read_from(resp_bytes.as_bytes()).unwrap())
}

fn get_cmd_id(dpe_cmd: &mut Command) -> u32 {
match dpe_cmd {
Command::GetProfile => Command::GET_PROFILE,
Command::InitCtx(_) => Command::INITIALIZE_CONTEXT,
Command::DeriveContext(_) => Command::DERIVE_CONTEXT,
Command::CertifyKey(_) => Command::CERTIFY_KEY,
Command::Sign(_) => Command::SIGN,
Command::RotateCtx(_) => Command::ROTATE_CONTEXT_HANDLE,
Command::DestroyCtx(_) => Command::DESTROY_CONTEXT,
Command::GetCertificateChain(_) => Command::GET_CERTIFICATE_CHAIN,
}
}
pub fn as_bytes(dpe_cmd: &mut Command) -> &[u8] {
match dpe_cmd {
Command::CertifyKey(cmd) => cmd.as_bytes(),
Command::DeriveContext(cmd) => cmd.as_bytes(),
Command::GetCertificateChain(cmd) => cmd.as_bytes(),
Command::DestroyCtx(cmd) => cmd.as_bytes(),
Command::GetProfile => &[],
Command::InitCtx(cmd) => cmd.as_bytes(),
Command::RotateCtx(cmd) => cmd.as_bytes(),
Command::Sign(cmd) => cmd.as_bytes(),
}
}

pub fn parse_dpe_response(dpe_cmd: &mut Command, resp_bytes: &[u8]) -> Response {
match dpe_cmd {
Command::CertifyKey(_) => {
Response::CertifyKey(CertifyKeyResp::read_from(resp_bytes).unwrap())
}
Command::DeriveContext(_) => {
Response::DeriveContext(DeriveContextResp::read_from(resp_bytes).unwrap())
}
Command::GetCertificateChain(_) => {
Response::GetCertificateChain(GetCertificateChainResp::read_from(resp_bytes).unwrap())
}
Command::DestroyCtx(_) => Response::DestroyCtx(ResponseHdr::read_from(resp_bytes).unwrap()),
Command::GetProfile => Response::GetProfile(GetProfileResp::read_from(resp_bytes).unwrap()),
Command::InitCtx(_) => Response::InitCtx(NewHandleResp::read_from(resp_bytes).unwrap()),
Command::RotateCtx(_) => Response::RotateCtx(NewHandleResp::read_from(resp_bytes).unwrap()),
Command::Sign(_) => Response::Sign(SignResp::read_from(resp_bytes).unwrap()),
}
}

pub fn execute_dpe_cmd<T: HwModel>(hw: &mut T, dpe_cmd: &mut Command) -> Response {
let mut cmd_data: [u8; 512] = [0u8; InvokeDpeReq::DATA_MAX_SIZE];
let dpe_cmd_id = get_cmd_id(dpe_cmd);
let cmd_hdr = CommandHdr::new_for_test(dpe_cmd_id);
let cmd_hdr_buf = cmd_hdr.as_bytes();
cmd_data[..cmd_hdr_buf.len()].copy_from_slice(cmd_hdr_buf);
let dpe_cmd_buf = as_bytes(dpe_cmd);
cmd_data[cmd_hdr_buf.len()..cmd_hdr_buf.len() + dpe_cmd_buf.len()].copy_from_slice(dpe_cmd_buf);

let mut payload = MailboxReq::InvokeDpeCommand(InvokeDpeReq {
hdr: MailboxReqHeader { chksum: 0 },
data: cmd_data,
data_size: (cmd_hdr_buf.len() + dpe_cmd_buf.len()) as u32,
});
payload.populate_chksum().unwrap();

let resp = mbx_send_and_check_resp_hdr::<_, InvokeDpeResp>(
hw,
u32::from(CommandId::INVOKE_DPE),
payload.as_bytes().unwrap(),
)
.unwrap();

let resp_bytes = &resp.data[..resp.data_size as usize];
parse_dpe_response(dpe_cmd, resp_bytes)
}

pub fn fips_fw_image() -> Vec<u8> {
match std::env::var("FIPS_TEST_FW_BIN") {
// Build default FW if not provided and no path is specified
Expand Down
133 changes: 132 additions & 1 deletion test/tests/fips_test_suite/services.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use caliptra_common::mailbox_api::*;
use caliptra_hw_model::{BootParams, HwModel, ShaAccMode};
use caliptra_image_types::ImageManifest;
use common::*;
use dpe::{commands::*, context::ContextHandle, response::Response, DPE_PROFILE};
use zerocopy::{AsBytes, FromBytes};

pub fn exec_cmd_version<T: HwModel>(hw: &mut T, fmc_version: u16, app_version: u32) {
Expand Down Expand Up @@ -412,6 +413,129 @@ pub fn exec_cmd_extend_pcr<T: HwModel>(hw: &mut T) {
.unwrap();
}

pub fn exec_dpe_get_profile<T: HwModel>(hw: &mut T) {
let resp = execute_dpe_cmd(hw, &mut Command::GetProfile);

let Response::GetProfile(get_profile_resp) = resp else {
panic!("Wrong response type!");
};

assert_eq!(get_profile_resp.resp_hdr.profile, DPE_PROFILE as u32);
}

pub fn exec_dpe_init_ctx<T: HwModel>(hw: &mut T) {
let resp = execute_dpe_cmd(hw, &mut Command::InitCtx(InitCtxCmd::new_simulation()));

let Response::InitCtx(init_ctx_resp) = resp else {
panic!("Wrong response type!");
};
assert!(contains_some_data(&init_ctx_resp.handle.0));
}

pub fn exec_dpe_derive_ctx<T: HwModel>(hw: &mut T) {
let derive_context_cmd = DeriveContextCmd {
handle: ContextHandle::default(),
data: [0u8; 48],
flags: DeriveContextFlags::RETAIN_PARENT_CONTEXT | DeriveContextFlags::CHANGE_LOCALITY,
tci_type: 0,
target_locality: 0,
};
let resp = execute_dpe_cmd(hw, &mut Command::DeriveContext(derive_context_cmd));
let Response::DeriveContext(derive_ctx_resp) = resp else {
panic!("Wrong response type!");
};

assert!(contains_some_data(&derive_ctx_resp.handle.0));
}

pub fn exec_dpe_certify_key<T: HwModel>(hw: &mut T) {
pub const TEST_LABEL: [u8; 48] = [
48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26,
25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,
];

let certify_key_cmd = CertifyKeyCmd {
handle: ContextHandle::default(),
label: TEST_LABEL,
flags: CertifyKeyFlags::empty(),
format: CertifyKeyCmd::FORMAT_CSR,
};
let resp = execute_dpe_cmd(hw, &mut Command::CertifyKey(certify_key_cmd));

let Response::CertifyKey(certify_key_resp) = resp else {
panic!("Wrong response type!");
};

assert_eq!(
certify_key_resp.new_context_handle.0,
[0u8; ContextHandle::SIZE]
);
assert!(contains_some_data(&certify_key_resp.derived_pubkey_x));
assert!(contains_some_data(&certify_key_resp.derived_pubkey_y));
assert_ne!(0, certify_key_resp.cert_size);
assert!(contains_some_data(&certify_key_resp.cert));
}

pub fn exec_dpe_sign<T: HwModel>(hw: &mut T) {
pub const TEST_LABEL: [u8; 48] = [
48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26,
25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,
];
pub const TEST_DIGEST: [u8; 48] = [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
];
let sign_cmd = SignCmd {
handle: ContextHandle::default(),
label: TEST_LABEL,
flags: SignFlags::empty(),
digest: TEST_DIGEST,
};

let resp = execute_dpe_cmd(hw, &mut Command::Sign(sign_cmd));

let Response::Sign(sign_resp) = resp else {
panic!("Wrong response type!");
};

assert!(contains_some_data(&sign_resp.sig_r_or_hmac));
assert!(contains_some_data(&sign_resp.sig_s));
}

pub fn exec_rotate_ctx<T: HwModel>(hw: &mut T) {
let rotate_ctx_cmd = RotateCtxCmd {
handle: ContextHandle::default(),
flags: RotateCtxFlags::empty(),
};
let resp = execute_dpe_cmd(hw, &mut Command::RotateCtx(rotate_ctx_cmd));

let Response::RotateCtx(rotate_ctx_resp) = resp else {
panic!("Wrong response type!");
};
assert!(contains_some_data(&rotate_ctx_resp.handle.0));
}

pub fn exec_get_cert_chain<T: HwModel>(hw: &mut T) {
let get_cert_chain_cmd = GetCertificateChainCmd {
offset: 0,
size: 2048,
};
let resp = execute_dpe_cmd(hw, &mut Command::GetCertificateChain(get_cert_chain_cmd));

let Response::GetCertificateChain(get_cert_chain_resp) = resp else {
panic!("Wrong response type!");
};
assert_ne!(0, get_cert_chain_resp.certificate_size);
assert!(contains_some_data(&get_cert_chain_resp.certificate_chain));
}

pub fn exec_destroy_ctx<T: HwModel>(hw: &mut T) {
let destroy_ctx_cmd = DestroyCtxCmd {
handle: ContextHandle::default(),
};
execute_dpe_cmd(hw, &mut Command::DestroyCtx(destroy_ctx_cmd));
}

pub fn exec_cmd_disable_attestation<T: HwModel>(hw: &mut T) {
let payload = MailboxReqHeader {
chksum: caliptra_common::checksum::calc_checksum(
Expand Down Expand Up @@ -554,7 +678,14 @@ pub fn execute_all_services_rt() {
exec_cmd_extend_pcr(&mut hw);

// INVOKE_DPE
// TODO: Invoke all supported DPE commands
exec_dpe_get_profile(&mut hw);
exec_dpe_init_ctx(&mut hw);
exec_dpe_derive_ctx(&mut hw);
exec_dpe_certify_key(&mut hw);
exec_dpe_sign(&mut hw);
exec_rotate_ctx(&mut hw);
exec_get_cert_chain(&mut hw);
exec_destroy_ctx(&mut hw);

// (Do these last)
// DISABLE_ATTESTATION
Expand Down

0 comments on commit b72c293

Please sign in to comment.