Skip to content
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

[feat] Image generator and verifier updates for Caliptra 2.0 FW ECC + LMS image #1694

Open
wants to merge 7 commits into
base: main-2.x
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
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.

5 changes: 4 additions & 1 deletion builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use caliptra_image_elf::ElfExecutable;
use caliptra_image_gen::{
ImageGenerator, ImageGeneratorConfig, ImageGeneratorOwnerConfig, ImageGeneratorVendorConfig,
};
use caliptra_image_types::{ImageBundle, ImageRevision, RomInfo};
use caliptra_image_types::{FwImageType, ImageBundle, ImageRevision, RomInfo};
use elf::endian::LittleEndian;
use nix::fcntl::FlockArg;
use zerocopy::AsBytes;
Expand Down Expand Up @@ -444,6 +444,7 @@ pub struct ImageOptions {
pub app_svn: u32,
pub vendor_config: ImageGeneratorVendorConfig,
pub owner_config: Option<ImageGeneratorOwnerConfig>,
pub fw_image_type: FwImageType,
}
impl Default for ImageOptions {
fn default() -> Self {
Expand All @@ -454,6 +455,7 @@ impl Default for ImageOptions {
app_svn: Default::default(),
vendor_config: caliptra_image_fake_keys::VENDOR_CONFIG_KEY_0,
owner_config: Some(caliptra_image_fake_keys::OWNER_CONFIG),
fw_image_type: FwImageType::EccLms,
}
}
}
Expand All @@ -476,6 +478,7 @@ pub fn build_and_sign_image(
runtime: ElfExecutable::new(&app_elf, opts.app_version, opts.app_svn, image_revision()?)?,
vendor_config: opts.vendor_config,
owner_config: opts.owner_config,
fw_image_type: opts.fw_image_type,
})?;
Ok(image)
}
Expand Down
53 changes: 50 additions & 3 deletions common/src/verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,56 @@ impl<'a, 'b> ImageVerificationEnv for &mut FirmwareImageVerificationEnv<'a, 'b>
Lms::default().verify_lms_signature_cfi(self.sha256, &message, pub_key, sig)
}

/// Retrieve Vendor Public Key Digest
fn vendor_pub_key_digest(&self) -> ImageDigest {
self.soc_ifc.fuse_bank().vendor_pub_key_hash().into()
/// Retrieve Vendor Public Key Info Digest
fn vendor_pub_key_info_digest_fuses(&self) -> ImageDigest {
self.soc_ifc.fuse_bank().vendor_pub_key_info_hash().into()
}

/// Retrieve Vendor Public Key Info Digest
fn vendor_pub_key_info_digest_from_image(
&mut self,
ecc_key_desc: (u32, u32),
ecc_pub_key_hashes: (u32, u32),
lms_key_desc: (u32, u32),
lms_pub_key_hashes: (u32, u32),
) -> CaliptraResult<ImageDigest> {
let err = CaliptraError::IMAGE_VERIFIER_ERR_DIGEST_OUT_OF_BOUNDS;
let ecc_key_desc = self
.image
.get(ecc_key_desc.0 as usize..)
.ok_or(err)?
.get(..ecc_key_desc.1 as usize)
.ok_or(err)?;

let ecc_pub_key_hashes = self
.image
.get(ecc_pub_key_hashes.0 as usize..)
.ok_or(err)?
.get(..ecc_pub_key_hashes.1 as usize)
.ok_or(err)?;

let lms_key_desc = self
.image
.get(lms_key_desc.0 as usize..)
.ok_or(err)?
.get(..lms_key_desc.1 as usize)
.ok_or(err)?;

let lms_pub_key_hashes = self
.image
.get(lms_pub_key_hashes.0 as usize..)
.ok_or(err)?
.get(..lms_pub_key_hashes.1 as usize)
.ok_or(err)?;

let mut digest = Array4x12::default();
let mut op = self.sha384.digest_init()?;
op.update(ecc_key_desc)?;
op.update(ecc_pub_key_hashes)?;
op.update(lms_key_desc)?;
op.update(lms_pub_key_hashes)?;
op.finalize(&mut digest)?;
Ok(digest.0)
}

/// Retrieve Vendor ECC Public Key Revocation Bitmask
Expand Down
6 changes: 3 additions & 3 deletions drivers/src/fuse_bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,15 +179,15 @@ impl FuseBank<'_> {
subject_key_id
}

/// Get the vendor public key hash.
/// Get the vendor public key info hash.
///
/// # Arguments
/// * None
///
/// # Returns
/// vendor public key hash
/// vendor public key info hash
///
pub fn vendor_pub_key_hash(&self) -> Array4x12 {
pub fn vendor_pub_key_info_hash(&self) -> Array4x12 {
let soc_ifc_regs = self.soc_ifc.regs();
Array4x12::read_from_reg(soc_ifc_regs.fuse_key_manifest_pk_hash())
}
Expand Down
18 changes: 9 additions & 9 deletions drivers/src/pcr_log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,21 @@ pub const PCR_ID_STASH_MEASUREMENT: PcrId = PcrId::PcrId31;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PcrLogEntryId {
Invalid = 0,
DeviceStatus = 1, // data size = 9 bytes
VendorPubKeyHash = 2, // data size = 48 bytes
OwnerPubKeyHash = 3, // data size = 48 bytes
FmcTci = 4, // data size = 48 bytes
StashMeasurement = 5, // data size = 48 bytes
RtTci = 6, // data size = 48 bytes
FwImageManifest = 7, // data size = 48 bytes
DeviceStatus = 1, // data size = 9 bytes
VendorPubKeyInfoHash = 2, // data size = 48 bytes
OwnerPubKeyHash = 3, // data size = 48 bytes
FmcTci = 4, // data size = 48 bytes
StashMeasurement = 5, // data size = 48 bytes
RtTci = 6, // data size = 48 bytes
FwImageManifest = 7, // data size = 48 bytes
}

impl From<u16> for PcrLogEntryId {
/// Converts to this type from the input type.
fn from(id: u16) -> PcrLogEntryId {
match id {
1 => PcrLogEntryId::DeviceStatus,
2 => PcrLogEntryId::VendorPubKeyHash,
2 => PcrLogEntryId::VendorPubKeyInfoHash,
3 => PcrLogEntryId::OwnerPubKeyHash,
4 => PcrLogEntryId::FmcTci,
5 => PcrLogEntryId::StashMeasurement,
Expand Down Expand Up @@ -71,7 +71,7 @@ impl PcrLogEntry {
let data_len = match PcrLogEntryId::from(self.id) {
PcrLogEntryId::Invalid => 0,
PcrLogEntryId::DeviceStatus => 9,
PcrLogEntryId::VendorPubKeyHash => 48,
PcrLogEntryId::VendorPubKeyInfoHash => 48,
PcrLogEntryId::OwnerPubKeyHash => 48,
PcrLogEntryId::FmcTci => 48,
PcrLogEntryId::StashMeasurement => 48,
Expand Down
24 changes: 24 additions & 0 deletions error/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,30 @@ impl CaliptraError {
CaliptraError::new_const(0x000b0040);
pub const IMAGE_VERIFIER_ERR_DIGEST_OUT_OF_BOUNDS: CaliptraError =
CaliptraError::new_const(0x000b0041);
pub const IMAGE_VERIFIER_ERR_ECC_KEY_DESCRIPTOR_MARKER_MISMATCH: CaliptraError =
CaliptraError::new_const(0x000b0042);
pub const IMAGE_VERIFIER_ERR_ECC_KEY_DESCRIPTOR_VERSION_MISMATCH: CaliptraError =
CaliptraError::new_const(0x000b0043);
pub const IMAGE_VERIFIER_ERR_ECC_KEY_DESCRIPTOR_INTENT_MISMATCH: CaliptraError =
CaliptraError::new_const(0x000b0044);
pub const IMAGE_VERIFIER_ERR_ECC_KEY_DESCRIPTOR_TYPE_MISMATCH: CaliptraError =
CaliptraError::new_const(0x000b0045);
pub const IMAGE_VERIFIER_ERR_ECC_KEY_DESCRIPTOR_HASH_COUNT_GT_MAX: CaliptraError =
CaliptraError::new_const(0x000b0046);
pub const IMAGE_VERIFIER_ERR_LMS_KEY_DESCRIPTOR_MARKER_MISMATCH: CaliptraError =
CaliptraError::new_const(0x000b0047);
pub const IMAGE_VERIFIER_ERR_LMS_KEY_DESCRIPTOR_VERSION_MISMATCH: CaliptraError =
CaliptraError::new_const(0x000b0048);
pub const IMAGE_VERIFIER_ERR_LMS_KEY_DESCRIPTOR_INTENT_MISMATCH: CaliptraError =
CaliptraError::new_const(0x000b0049);
pub const IMAGE_VERIFIER_ERR_LMS_KEY_DESCRIPTOR_TYPE_MISMATCH: CaliptraError =
CaliptraError::new_const(0x000b004a);
pub const IMAGE_VERIFIER_ERR_LMS_KEY_DESCRIPTOR_HASH_COUNT_GT_MAX: CaliptraError =
CaliptraError::new_const(0x000b004b);
pub const IMAGE_VERIFIER_ERR_ECC_KEY_DESCRIPTOR_INVALID_HASH_COUNT: CaliptraError =
CaliptraError::new_const(0x000b004c);
pub const IMAGE_VERIFIER_ERR_LMS_KEY_DESCRIPTOR_INVALID_HASH_COUNT: CaliptraError =
CaliptraError::new_const(0x000b004d);

/// Driver Error: LMS
pub const DRIVER_LMS_INVALID_LMS_ALGO_TYPE: CaliptraError =
Expand Down
11 changes: 5 additions & 6 deletions image/app/src/create/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,19 @@ Abstract:
--*/

use anyhow::Context;
use caliptra_image_types::{VENDOR_ECC_KEY_COUNT, VENDOR_LMS_KEY_COUNT};
use serde_derive::{Deserialize, Serialize};
use std::path::PathBuf;

/// Vendor Key Configuration
#[derive(Default, Serialize, Deserialize)]
pub(crate) struct VendorKeyConfig {
pub ecc_pub_keys: [String; VENDOR_ECC_KEY_COUNT as usize],
pub ecc_pub_keys: Vec<String>,

pub lms_pub_keys: [String; VENDOR_LMS_KEY_COUNT as usize],
pub lms_pub_keys: Vec<String>,

pub ecc_priv_keys: Option<[String; VENDOR_ECC_KEY_COUNT as usize]>,
pub ecc_priv_keys: Option<Vec<String>>,

pub lms_priv_keys: Option<[String; VENDOR_LMS_KEY_COUNT as usize]>,
pub lms_priv_keys: Option<Vec<String>>,
}

/// Owner Key Configuration
Expand All @@ -41,7 +40,7 @@ pub(crate) struct OwnerKeyConfig {
pub lms_priv_key: Option<String>,
}

//Key Configuration
// Key Configuration
#[derive(Default, Serialize, Deserialize)]
pub(crate) struct KeyConfig {
pub vendor: VendorKeyConfig,
Expand Down
48 changes: 33 additions & 15 deletions image/app/src/create/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ fn check_date(from_date: &str, to_date: &str) -> anyhow::Result<bool> {

/// Run the command
pub(crate) fn run_cmd(args: &ArgMatches) -> anyhow::Result<()> {
let image_type: &u32 = args
.get_one::<u32>("image-type")
.with_context(|| "image-type arg not specified")?;

let config_path: &PathBuf = args
.get_one::<PathBuf>("key-config")
.with_context(|| "key-config arg not specified")?;
Expand Down Expand Up @@ -182,6 +186,11 @@ pub(crate) fn run_cmd(args: &ArgMatches) -> anyhow::Result<()> {
owner_config: owner_config(config_dir, &config.owner, own_from_date, own_to_date)?,
fmc,
runtime,
fw_image_type: if *image_type == 1 {
FwImageType::EccLms
} else {
FwImageType::EccMldsa
},
};

let gen = ImageGenerator::new(Crypto::default());
Expand Down Expand Up @@ -210,24 +219,31 @@ fn vendor_config(
to_date: [u8; 15],
) -> anyhow::Result<ImageGeneratorVendorConfig> {
let mut gen_config = ImageGeneratorVendorConfig::default();
let ecc_pub_keys = &config.ecc_pub_keys;

for (i, pem_file) in ecc_pub_keys
.iter()
.enumerate()
.take(VENDOR_ECC_KEY_COUNT as usize)
{
let ecc_key_count = config.ecc_pub_keys.len() as u32;
let lms_key_count = config.lms_pub_keys.len() as u32;

if ecc_key_count > VENDOR_ECC_MAX_KEY_COUNT {
return Err(anyhow!("Invalid ECC Public Key Count"));
}
if lms_key_count > VENDOR_LMS_MAX_KEY_COUNT {
return Err(anyhow!("Invalid LMS Public Key Count"));
}

if ecc_key_idx >= ecc_key_count {
return Err(anyhow!("Invalid ECC Public Key Index"));
}
if lms_key_idx >= lms_key_count {
return Err(anyhow!("Invalid LMS Public Key Index"));
}

let ecc_pub_keys = &config.ecc_pub_keys;
for (i, pem_file) in ecc_pub_keys.iter().enumerate().take(ecc_key_count as usize) {
let pub_key_path = path.join(pem_file);
gen_config.pub_keys.ecc_pub_keys[i] = Crypto::ecc_pub_key_from_pem(&pub_key_path)?;
}

let lms_pub_keys = &config.lms_pub_keys;

for (i, pem_file) in lms_pub_keys
.iter()
.enumerate()
.take(VENDOR_LMS_KEY_COUNT as usize)
{
for (i, pem_file) in lms_pub_keys.iter().enumerate().take(lms_key_count as usize) {
let pub_key_path = path.join(pem_file);
gen_config.pub_keys.lms_pub_keys[i] = lms_pub_key_from_pem(&pub_key_path)?;
}
Expand All @@ -237,7 +253,7 @@ fn vendor_config(
for (i, pem_file) in ecc_priv_keys
.iter()
.enumerate()
.take(VENDOR_ECC_KEY_COUNT as usize)
.take(ecc_key_count as usize)
{
let priv_key_path = path.join(pem_file);
priv_keys.ecc_priv_keys[i] = Crypto::ecc_priv_key_from_pem(&priv_key_path)?;
Expand All @@ -249,7 +265,7 @@ fn vendor_config(
for (i, pem_file) in lms_priv_keys
.iter()
.enumerate()
.take(VENDOR_LMS_KEY_COUNT as usize)
.take(lms_key_count as usize)
{
let priv_key_path = path.join(pem_file);
priv_keys.lms_priv_keys[i] = lms_priv_key_from_pem(&priv_key_path)?;
Expand All @@ -261,6 +277,8 @@ fn vendor_config(
gen_config.lms_key_idx = lms_key_idx;
gen_config.not_before = from_date;
gen_config.not_after = to_date;
gen_config.ecc_key_count = ecc_key_count;
gen_config.lms_key_count = lms_key_count;

Ok(gen_config)
}
Expand Down
8 changes: 5 additions & 3 deletions image/app/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ mod create;
fn main() {
let sub_cmds = vec![Command::new("create")
.about("Create a new firmware image bundle")
.arg(
arg!(--"image-type" <U32> "Type of image keys: 1: ECC + LMS; 2: ECC + MLDSA")
.required(true)
.value_parser(value_parser!(u32)),
)
.arg(
arg!(--"key-config" <FILE> "Key Configuration file")
.required(true)
Expand Down Expand Up @@ -114,7 +119,4 @@ fn main() {
};

result.unwrap();

// let exit_code = if result.is_ok() { 0 } else { -1 };
// std::process::exit(exit_code);
}
4 changes: 2 additions & 2 deletions image/elf/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Abstract:
--*/

use anyhow::{bail, Context};
use caliptra_image_gen::ImageGenratorExecutable;
use caliptra_image_gen::ImageGeneratorExecutable;
use caliptra_image_types::ImageRevision;
use elf::abi::PT_LOAD;
use elf::endian::AnyEndian;
Expand Down Expand Up @@ -108,7 +108,7 @@ impl ElfExecutable {
}
}

impl ImageGenratorExecutable for ElfExecutable {
impl ImageGeneratorExecutable for ElfExecutable {
/// Executable Version Number
fn version(&self) -> u32 {
self.version
Expand Down
4 changes: 3 additions & 1 deletion image/fake-keys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use caliptra_image_gen::{ImageGeneratorOwnerConfig, ImageGeneratorVendorConfig};
use caliptra_image_types::{
ImageEccPrivKey, ImageEccPubKey, ImageLmsPrivKey, ImageLmsPublicKey, ImageOwnerPrivKeys,
ImageOwnerPubKeys, ImageVendorPrivKeys, ImageVendorPubKeys, IMAGE_LMS_OTS_TYPE,
IMAGE_LMS_TREE_TYPE,
IMAGE_LMS_TREE_TYPE, VENDOR_ECC_MAX_KEY_COUNT, VENDOR_LMS_MAX_KEY_COUNT,
};
use caliptra_lms_types::bytes_to_words_6;

Expand Down Expand Up @@ -333,6 +333,8 @@ pub const OWNER_PRIVATE_KEYS: ImageOwnerPrivKeys = ImageOwnerPrivKeys {
};

pub const VENDOR_CONFIG_KEY_0: ImageGeneratorVendorConfig = ImageGeneratorVendorConfig {
ecc_key_count: VENDOR_ECC_MAX_KEY_COUNT,
lms_key_count: VENDOR_LMS_MAX_KEY_COUNT,
pub_keys: VENDOR_PUBLIC_KEYS,
ecc_key_idx: 0,
lms_key_idx: 0,
Expand Down
Loading
Loading