Skip to content

[WIP] rt: add FMC compatibility checks #1983

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions error/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,8 @@ impl CaliptraError {
pub const RUNTIME_REVOKE_EXPORTED_CDI_HANDLE_NOT_FOUND: CaliptraError =
CaliptraError::new_const(0x000E005A);

pub const RUNTIME_FMC_NOT_COMPATIBLE: CaliptraError = CaliptraError::new_const(0x000E005B);

/// FMC Errors
pub const FMC_GLOBAL_NMI: CaliptraError = CaliptraError::new_const(0x000F0001);
pub const FMC_GLOBAL_EXCEPTION: CaliptraError = CaliptraError::new_const(0x000F0002);
Expand Down
51 changes: 51 additions & 0 deletions runtime/src/compatibility.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*++

Licensed under the Apache-2.0 license.

File Name:

compatibility.rs

Abstract:

File contains compatibility functions to to check if the runtime is
compatible with FMC.

--*/

use caliptra_common::{cprint, FirmwareHandoffTable};
use caliptra_image_types::ImageManifest;

// From the official documentation:
// "The Major and Minor version numbers of the Firmware Handoff Table.
// All FHT versions with the same Major version number must remain backward compatible.""
pub fn is_fmc_compatible(fht: &FirmwareHandoffTable, manifest: &ImageManifest) -> bool {
cprint!(
"[rt] FHT major: {}, Manifest FMC version: {}\n",
fht.fht_major_ver,
manifest.fmc.version
);
u32::from(fht.fht_major_ver) == manifest.fmc.version
}

#[test]
fn test_is_fmc_compatible() {
let mut fht = FirmwareHandoffTable::default();
let mut manifest = ImageManifest::default();

fht.fht_major_ver = 1;
fht.fht_minor_ver = 0;
manifest.fmc.version = 1;

assert!(is_fmc_compatible(&fht, &manifest));

// change minor version should not affect compatibility
fht.fht_minor_ver = 1;
assert!(is_fmc_compatible(&fht, &manifest));

fht.fht_minor_ver = 0xff;
assert!(is_fmc_compatible(&fht, &manifest));

fht.fht_major_ver = 2;
assert!(!is_fmc_compatible(&fht, &manifest));
}
1 change: 1 addition & 0 deletions runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Abstract:
mod authorize_and_stash;
mod capabilities;
mod certify_key_extended;
pub mod compatibility;
pub mod dice;
mod disable;
mod dpe_crypto;
Expand Down
19 changes: 14 additions & 5 deletions runtime/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ Abstract:
core::arch::global_asm!(include_str!("ext_intr.S"));

use caliptra_cfi_lib_git::CfiCounter;
use caliptra_common::{cprintln, handle_fatal_error};
use caliptra_common::{cprintln, handle_fatal_error, FirmwareHandoffTable};
use caliptra_cpu::{log_trap_record, TrapRecord};
use caliptra_error::CaliptraError;
use caliptra_image_types::ImageManifest;
use caliptra_registers::soc_ifc::SocIfcReg;
use caliptra_runtime::Drivers;
use caliptra_runtime::{compatibility, Drivers};
use core::hint::black_box;

#[cfg(feature = "std")]
Expand Down Expand Up @@ -76,11 +77,19 @@ pub extern "C" fn entry_point() -> ! {
handle_fatal_error(e.into());
});

if !drivers.persistent_data.get().fht.is_valid() {
cprintln!("[rt] RT can't load FHT");
let fht: &FirmwareHandoffTable = &drivers.persistent_data.get().fht;
if !fht.is_valid() {
cprintln!("[rt] Runtime can't load FHT");
handle_fatal_error(caliptra_drivers::CaliptraError::RUNTIME_HANDOFF_FHT_NOT_LOADED.into());
}
cprintln!("[rt] RT listening for mailbox commands...");

let manifest: &ImageManifest = &drivers.persistent_data.get().manifest1;
if !compatibility::is_fmc_compatible(fht, manifest) {
cprintln!("[rt] Runtime is not compatible with FMC");
handle_fatal_error(caliptra_drivers::CaliptraError::RUNTIME_FMC_NOT_COMPATIBLE.into());
}

cprintln!("[rt] Runtime listening for mailbox commands...");
if let Err(e) = caliptra_runtime::handle_mailbox_commands(&mut drivers) {
handle_fatal_error(e.into());
}
Expand Down
Loading