Skip to content

Commit

Permalink
Postpone self test execution
Browse files Browse the repository at this point in the history
  • Loading branch information
rusty1968 committed Aug 29, 2023
1 parent c837579 commit 6734392
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 13 deletions.
1 change: 1 addition & 0 deletions error/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ impl CaliptraError {
pub const RUNTIME_DISABLE_ATTESTATION_FAILED: CaliptraError =
CaliptraError::new_const(0x000E0011);
pub const RUNTIME_HANDOFF_INVALID_PARM: CaliptraError = CaliptraError::new_const(0x000E0012);
pub const RUNTIME_SELF_TEST_IN_PROGREESS: CaliptraError = CaliptraError::new_const(0x000E0013);

/// FMC Errors
pub const FMC_GLOBAL_NMI: CaliptraError = CaliptraError::new_const(0x000F0001);
Expand Down
24 changes: 17 additions & 7 deletions runtime/src/fips.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,21 @@ impl FipsVersionCmd {
#[cfg(feature = "fips_self_test")]
pub mod fips_self_test_cmd {
use super::*;
use crate::RtBootStatus::{RtFipSelfTestComplete, RtFipSelfTestStarted};
use caliptra_common::{verifier::FirmwareImageVerificationEnv, FMC_ORG, RUNTIME_ORG};
use caliptra_drivers::ResetReason;
use caliptra_image_verify::ImageVerifier;
use zerocopy::AsBytes;

pub enum SelfTestStatus {
Idle,
InProgress(fn(&mut Drivers) -> CaliptraResult<()>),
Done,
}

fn copy_and_verify_image(env: &mut Drivers) -> CaliptraResult<()> {
cprintln!("write dummy cmd");
env.mbox.write_cmd(0)?;
cprintln!("set dlen");
env.mbox
.set_dlen(env.manifest.size + env.manifest.fmc.size + env.manifest.runtime.size);
Expand All @@ -93,23 +102,24 @@ pub mod fips_self_test_cmd {
};

let mut verifier = ImageVerifier::new(&mut venv);
cprintln!("verify");
cprintln!("Verify started");
let _info = verifier.verify(
&env.manifest,
env.manifest.size + env.manifest.fmc.size + env.manifest.runtime.size,
ResetReason::UpdateReset,
)?;
cprintln!("verify done");
env.mbox.unlock();
cprintln!("[rt] Verify complete");
Ok(())
}

pub(crate) fn execute(env: &mut Drivers) -> CaliptraResult<MailboxResp> {
pub(crate) fn execute(env: &mut Drivers) -> CaliptraResult<()> {
caliptra_drivers::report_boot_status(RtFipSelfTestStarted.into());
cprintln!("[rt] FIPS self test");
caliptra_common::wdt::stop_wdt(&mut env.soc_ifc);
execute_kats(env)?;
copy_and_verify_image(env)?;

Ok(MailboxResp::default())
execute_kats(env)?;
caliptra_drivers::report_boot_status(RtFipSelfTestComplete.into());
Ok(())
}

/// Execute KAT for cryptographic algorithms implemented in H/W.
Expand Down
45 changes: 40 additions & 5 deletions runtime/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed under the Apache-2.0 license

#![no_std]
#![cfg_attr(not(feature = "fip-self-test"), allow(unused))]

pub mod dice;
mod disable;
Expand All @@ -24,23 +25,27 @@ pub use disable::DisableAttestationCmd;
use dpe_crypto::DpeCrypto;
pub use dpe_platform::{DpePlatform, VENDOR_ID, VENDOR_SKU};
#[cfg(feature = "fips_self_test")]
pub use fips::fips_self_test_cmd;
pub use fips::{fips_self_test_cmd, fips_self_test_cmd::SelfTestStatus};

pub use fips::{FipsShutdownCmd, FipsVersionCmd};

pub use info::FwInfoCmd;
pub use invoke_dpe::InvokeDpeCmd;
pub use stash_measurement::StashMeasurementCmd;
pub use verify::EcdsaVerifyCmd;
pub mod packet;
use caliptra_common::mailbox_api::CommandId;
use packet::Packet;

use caliptra_common::mailbox_api::CommandId;
#[cfg(feature = "fips_self_test")]
use caliptra_common::mailbox_api::MailboxResp;
use caliptra_common::memory_layout::{
FHT_ORG, FHT_SIZE, FMCALIAS_TBS_ORG, FMCALIAS_TBS_SIZE, FUSE_LOG_ORG, FUSE_LOG_SIZE,
LDEVID_TBS_ORG, LDEVID_TBS_SIZE, MAN1_ORG, MAN1_SIZE, MAN2_ORG, MAN2_SIZE, PCR_LOG_ORG,
PCR_LOG_SIZE,
};
use caliptra_common::{cprintln, FirmwareHandoffTable};

use caliptra_drivers::{
CaliptraError, CaliptraResult, DataVault, Ecc384, KeyVault, Lms, Sha1, SocIfc,
};
Expand Down Expand Up @@ -72,6 +77,8 @@ const RUNTIME_BOOT_STATUS_BASE: u32 = 0x600;
pub enum RtBootStatus {
// RtAlias Statuses
RtReadyForCommands = RUNTIME_BOOT_STATUS_BASE,
RtFipSelfTestStarted = RUNTIME_BOOT_STATUS_BASE + 1,
RtFipSelfTestComplete = RUNTIME_BOOT_STATUS_BASE + 2,
}

impl From<RtBootStatus> for u32 {
Expand Down Expand Up @@ -119,6 +126,9 @@ pub struct Drivers<'a> {
pub dpe: DpeInstance,

pub pcr_bank: PcrBank,

#[cfg(feature = "fips_self_test")]
pub self_test_status: SelfTestStatus,
}

pub struct CptraDpeTypes;
Expand Down Expand Up @@ -190,6 +200,8 @@ impl<'a> Drivers<'a> {
manifest,
dpe,
pcr_bank,
#[cfg(feature = "fips_self_test")]
self_test_status: SelfTestStatus::Idle,
})
}

Expand Down Expand Up @@ -217,7 +229,19 @@ impl<'a> Drivers<'a> {
}
}

fn wait_for_cmd(_mbox: &mut Mailbox) {
/// Run pending jobs and enter low power mode.
fn goto_idle(drivers: &mut Drivers) {
// Run pending jobs before entering low power mode.
#[cfg(feature = "fips_self_test")]
if let SelfTestStatus::InProgress(execute) = drivers.self_test_status {
if drivers.mbox.lock() == false {
match execute(drivers) {
Ok(_) => drivers.self_test_status = SelfTestStatus::Done,
Err(e) => caliptra_drivers::report_fw_error_non_fatal(e.into()),
}
}
}

// TODO: Enable interrupts?
//#[cfg(feature = "riscv")]
//unsafe {
Expand Down Expand Up @@ -268,7 +292,17 @@ fn handle_command(drivers: &mut Drivers) -> CaliptraResult<MboxStatusE> {
CommandId::TEST_ONLY_HMAC384_VERIFY => HmacVerifyCmd::execute(drivers, cmd_bytes),
CommandId::VERSION => FipsVersionCmd::execute(drivers),
#[cfg(feature = "fips_self_test")]
CommandId::SELF_TEST => fips_self_test_cmd::execute(drivers),
CommandId::SELF_TEST => match drivers.self_test_status {
SelfTestStatus::Idle => {
drivers.self_test_status = SelfTestStatus::InProgress(fips_self_test_cmd::execute);
Ok(MailboxResp::default())
}
SelfTestStatus::Done => {
drivers.self_test_status = SelfTestStatus::Idle;
Ok(MailboxResp::default())
}
_ => Err(CaliptraError::RUNTIME_SELF_TEST_IN_PROGREESS),
},
CommandId::SHUTDOWN => FipsShutdownCmd::execute(drivers),
_ => Err(CaliptraError::RUNTIME_UNIMPLEMENTED_COMMAND),
}?;
Expand All @@ -284,7 +318,7 @@ pub fn handle_mailbox_commands(drivers: &mut Drivers) -> ! {
drivers.soc_ifc.assert_ready_for_runtime();
caliptra_drivers::report_boot_status(RtBootStatus::RtReadyForCommands.into());
loop {
wait_for_cmd(&mut drivers.mbox);
goto_idle(drivers);
if drivers.mbox.is_cmd_ready() {
// TODO : Move start/stop WDT to wait_for_cmd when NMI is implemented.
caliptra_common::wdt::start_wdt(
Expand All @@ -301,6 +335,7 @@ pub fn handle_mailbox_commands(drivers: &mut Drivers) -> ! {
}
}
caliptra_common::wdt::stop_wdt(&mut drivers.soc_ifc);
} else {
}
}
}
Expand Down
26 changes: 25 additions & 1 deletion runtime/src/mailbox.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
// Licensed under the Apache-2.0 license

use caliptra_drivers::CaliptraResult;
use caliptra_registers::mbox::{enums::MboxStatusE, MboxCsr};
use caliptra_error::CaliptraError;
use caliptra_registers::mbox::{
enums::{MboxFsmE, MboxStatusE},
MboxCsr,
};
use zerocopy::{AsBytes, LayoutVerified, Unalign};

use crate::CommandId;
Expand Down Expand Up @@ -45,6 +49,26 @@ impl Mailbox {
CommandId(cmd_code)
}

pub fn lock(&mut self) -> bool {
let mbox = self.mbox.regs();
mbox.lock().read().lock()
}
pub fn unlock(&mut self) {
let mbox = self.mbox.regs_mut();
mbox.unlock().write(|_| 1.into());
}

pub fn write_cmd(&mut self, cmd: u32) -> CaliptraResult<()> {
let mbox = self.mbox.regs_mut();
match mbox.status().read().mbox_fsm_ps() {
MboxFsmE::MboxRdyForCmd => {
mbox.cmd().write(|_| cmd);
Ok(())
}
_ => Err(CaliptraError::RUNTIME_INTERNAL),
}
}

pub fn user(&self) -> u32 {
let mbox = self.mbox.regs();
mbox.user().read()
Expand Down
28 changes: 28 additions & 0 deletions test/tests/smoke_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -412,4 +412,32 @@ fn fips_self_test() {
&resp.as_bytes()[core::mem::size_of_val(&resp.chksum)..],
));
assert_eq!(resp.fips_status, MailboxRespHeader::FIPS_STATUS_APPROVED);

// Confirm we can't re-start the FIPS self test.
hw.step_until_boot_status(
caliptra_runtime::RtBootStatus::RtFipSelfTestStarted.into(),
true,
);
let _resp = hw
.mailbox_execute(u32::from(CommandId::SELF_TEST), payload.as_bytes())
.unwrap_err();

hw.step_until_boot_status(
caliptra_runtime::RtBootStatus::RtFipSelfTestComplete.into(),
true,
);

let resp = hw
.mailbox_execute(u32::from(CommandId::SELF_TEST), payload.as_bytes())
.unwrap()
.unwrap();

let resp = MailboxRespHeader::read_from(resp.as_slice()).unwrap();
// Verify checksum and FIPS status
assert!(caliptra_common::checksum::verify_checksum(
resp.chksum,
0x0,
&resp.as_bytes()[core::mem::size_of_val(&resp.chksum)..],
));
assert_eq!(resp.fips_status, MailboxRespHeader::FIPS_STATUS_APPROVED);
}

0 comments on commit 6734392

Please sign in to comment.