|
3 | 3 | use caliptra_builder::firmware::{APP_WITH_UART, FMC_WITH_UART};
|
4 | 4 | use caliptra_builder::{firmware, ImageOptions};
|
5 | 5 | use caliptra_common::mailbox_api::{
|
6 |
| - GetFmcAliasCertReq, GetLdevCertReq, GetRtAliasCertReq, ResponseVarSize, |
| 6 | + CommandId, GetFmcAliasCertReq, GetLdevCertReq, GetRtAliasCertReq, InvokeDpeReq, InvokeDpeResp, |
| 7 | + MailboxReq, MailboxReqHeader, ResponseVarSize, StashMeasurementReq, |
7 | 8 | };
|
8 | 9 | use caliptra_common::RomBootStatus;
|
9 | 10 | use caliptra_drivers::CaliptraError;
|
10 |
| -use caliptra_hw_model::{BootParams, HwModel, InitParams, SecurityState}; |
| 11 | +use caliptra_hw_model::{BootParams, DefaultHwModel, HwModel, InitParams, SecurityState}; |
11 | 12 | use caliptra_hw_model_types::{DeviceLifecycle, Fuses, RandomEtrngResponses, RandomNibbles};
|
12 |
| -use caliptra_test::derive::{PcrRtCurrentInput, RtAliasKey}; |
| 13 | +use caliptra_test::derive::{DpeAliasKey, PcrRtCurrentInput, RtAliasKey}; |
13 | 14 | use caliptra_test::{derive, redact_cert, run_test, RedactOpts, UnwrapSingle};
|
14 | 15 | use caliptra_test::{
|
15 | 16 | derive::{DoeInput, DoeOutput, FmcAliasKey, IDevId, LDevId, Pcr0, Pcr0Input},
|
16 | 17 | swap_word_bytes, swap_word_bytes_inplace,
|
17 | 18 | x509::{DiceFwid, DiceTcbInfo},
|
18 | 19 | };
|
| 20 | +use dpe::commands::{CertifyKeyCmd, Command}; |
| 21 | +use dpe::commands::{CertifyKeyFlags, CommandHdr}; |
| 22 | +use dpe::context::ContextHandle; |
| 23 | +use dpe::response::CertifyKeyResp; |
19 | 24 | use openssl::nid::Nid;
|
20 | 25 | use openssl::sha::{sha384, Sha384};
|
21 | 26 | use rand::rngs::StdRng;
|
22 | 27 | use rand::SeedableRng;
|
23 | 28 | use regex::Regex;
|
24 | 29 | use std::mem;
|
25 |
| -use zerocopy::AsBytes; |
| 30 | +use zerocopy::{AsBytes, FromBytes}; |
26 | 31 |
|
27 | 32 | #[track_caller]
|
28 | 33 | fn assert_output_contains(haystack: &str, needle: &str) {
|
@@ -429,13 +434,13 @@ fn smoke_test() {
|
429 | 434 | "Manifest digest is {:02x?}",
|
430 | 435 | image.manifest.runtime.digest.as_bytes()
|
431 | 436 | );
|
432 |
| - let expected_rt_alias_key = RtAliasKey::derive( |
433 |
| - &PcrRtCurrentInput { |
434 |
| - runtime_digest: image.manifest.runtime.digest, |
435 |
| - manifest: image.manifest, |
436 |
| - }, |
437 |
| - &expected_fmc_alias_key, |
438 |
| - ); |
| 437 | + |
| 438 | + let pcr_rt_input = PcrRtCurrentInput { |
| 439 | + runtime_digest: image.manifest.runtime.digest, |
| 440 | + manifest: image.manifest, |
| 441 | + }; |
| 442 | + |
| 443 | + let expected_rt_alias_key = RtAliasKey::derive(&pcr_rt_input, &expected_fmc_alias_key); |
439 | 444 |
|
440 | 445 | // Check that the rt-alias key has the rt measurements input above mixed into it
|
441 | 446 | // If a firmware change causes this assertion to fail, it is likely that the
|
@@ -550,6 +555,59 @@ fn smoke_test() {
|
550 | 555 | .read()
|
551 | 556 | .mbox_ecc_unc());
|
552 | 557 |
|
| 558 | + let measurement: [u8; 48] = [0xdeadbeef_u32; 12].as_bytes().try_into().unwrap(); |
| 559 | + let tci_type = [0xABu8; 4]; |
| 560 | + let stash_req = StashMeasurementReq { |
| 561 | + measurement, |
| 562 | + hdr: MailboxReqHeader { chksum: 0 }, |
| 563 | + metadata: tci_type, |
| 564 | + context: [0xCD; 48], |
| 565 | + svn: 0xEF01, |
| 566 | + }; |
| 567 | + hw.mailbox_execute_req(stash_req).unwrap(); |
| 568 | + |
| 569 | + let mut cmd = CertifyKeyCmd { |
| 570 | + handle: ContextHandle::default(), |
| 571 | + label: [ |
| 572 | + 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, |
| 573 | + 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, |
| 574 | + 3, 2, 1, |
| 575 | + ], |
| 576 | + flags: CertifyKeyFlags::empty(), |
| 577 | + format: CertifyKeyCmd::FORMAT_X509, |
| 578 | + }; |
| 579 | + |
| 580 | + let cert_key_response = execute_certify_key_cmd(&mut hw, &mut cmd); |
| 581 | + let dpe_cert = openssl::x509::X509::from_der( |
| 582 | + &cert_key_response.cert[..cert_key_response.cert_size as usize], |
| 583 | + ) |
| 584 | + .unwrap(); |
| 585 | + let dpe_cert_txt = String::from_utf8(rt_alias_cert.to_text().unwrap()).unwrap(); |
| 586 | + |
| 587 | + // Get the MBOX PAUSER settings |
| 588 | + let mbox_valid_pauser: [u32; DpeAliasKey::PAUSER_COUNT] = |
| 589 | + hw.soc_ifc().cptra_mbox_valid_pauser().read(); |
| 590 | + let mut mbox_pauser_lock: [bool; DpeAliasKey::PAUSER_COUNT] = Default::default(); |
| 591 | + for (i, lock) in mbox_pauser_lock.iter_mut().enumerate() { |
| 592 | + *lock = hw.soc_ifc().cptra_mbox_pauser_lock().at(i).read().lock(); |
| 593 | + } |
| 594 | + |
| 595 | + let expected_dpe_alias_key = DpeAliasKey::derive( |
| 596 | + &pcr_rt_input, |
| 597 | + &expected_rt_alias_key, |
| 598 | + &measurement, |
| 599 | + &tci_type, |
| 600 | + &cmd.label, |
| 601 | + &mbox_valid_pauser, |
| 602 | + &mbox_pauser_lock, |
| 603 | + ); |
| 604 | + |
| 605 | + assert!(expected_dpe_alias_key |
| 606 | + .derive_public_key() |
| 607 | + .public_eq(&dpe_cert.public_key().unwrap())); |
| 608 | + |
| 609 | + println!("dpe cert: {dpe_cert_txt}"); |
| 610 | + |
553 | 611 | // Hitlessly update to the no-uart runtime firmware
|
554 | 612 |
|
555 | 613 | let image2 = caliptra_builder::build_and_sign_image(
|
@@ -857,3 +915,40 @@ fn test_fmc_wdt_timeout() {
|
857 | 915 | // error_internal_intr_r must be 0b01000000 since the error_wdt_timer1_timeout_sts bit must be set
|
858 | 916 | assert_eq!(error_internal_intr_r, 0b01000000);
|
859 | 917 | }
|
| 918 | + |
| 919 | +fn execute_certify_key_cmd(model: &mut DefaultHwModel, cmd: &mut CertifyKeyCmd) -> CertifyKeyResp { |
| 920 | + // Put the header and data into a unified buffer |
| 921 | + let mut cmd_data: [u8; 512] = [0u8; InvokeDpeReq::DATA_MAX_SIZE]; |
| 922 | + let dpe_cmd_id = Command::CERTIFY_KEY; |
| 923 | + let cmd_hdr = CommandHdr::new_for_test(dpe_cmd_id); |
| 924 | + let cmd_hdr_buf = cmd_hdr.as_bytes(); |
| 925 | + cmd_data[..cmd_hdr_buf.len()].copy_from_slice(cmd_hdr_buf); |
| 926 | + let cmd_buf = cmd.as_bytes(); |
| 927 | + cmd_data[cmd_hdr_buf.len()..cmd_hdr_buf.len() + cmd_buf.len()].copy_from_slice(cmd_buf); |
| 928 | + |
| 929 | + let mut mbox_cmd = MailboxReq::InvokeDpeCommand(InvokeDpeReq { |
| 930 | + hdr: MailboxReqHeader { chksum: 0 }, |
| 931 | + data: cmd_data, |
| 932 | + data_size: (cmd_hdr_buf.len() + cmd_buf.len()) as u32, |
| 933 | + }); |
| 934 | + mbox_cmd.populate_chksum().unwrap(); |
| 935 | + |
| 936 | + let resp = model.mailbox_execute( |
| 937 | + u32::from(CommandId::INVOKE_DPE), |
| 938 | + mbox_cmd.as_bytes().unwrap(), |
| 939 | + ); |
| 940 | + let resp = resp.unwrap().expect("We should have received a response"); |
| 941 | + |
| 942 | + assert!(resp.len() <= std::mem::size_of::<InvokeDpeResp>()); |
| 943 | + let mut resp_hdr = InvokeDpeResp::default(); |
| 944 | + resp_hdr.as_bytes_mut()[..resp.len()].copy_from_slice(&resp); |
| 945 | + |
| 946 | + assert!(caliptra_common::checksum::verify_checksum( |
| 947 | + resp_hdr.hdr.chksum, |
| 948 | + 0x0, |
| 949 | + &resp[core::mem::size_of_val(&resp_hdr.hdr.chksum)..], |
| 950 | + )); |
| 951 | + |
| 952 | + let resp_bytes = &resp_hdr.data[..resp_hdr.data_size as usize]; |
| 953 | + CertifyKeyResp::read_from(resp_bytes).unwrap() |
| 954 | +} |
0 commit comments