diff --git a/.gitignore b/.gitignore index 24087f3c36..bc2ebd52b1 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,5 @@ hw/fpga/vivado*.log # libcaliptra build artifacts libcaliptra/libcaliptra.a + +hw-latest/verilated/out/* diff --git a/Cargo.lock b/Cargo.lock index de5a4aade4..589bc2d11e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -654,7 +654,9 @@ dependencies = [ "bitflags 2.4.0", "caliptra-image-types", "caliptra-lms-types", + "fips204", "memoffset 0.8.0", + "rand", "zerocopy", ] diff --git a/builder/src/lib.rs b/builder/src/lib.rs index 7ffb0c5ff1..0c7bd7df70 100644 --- a/builder/src/lib.rs +++ b/builder/src/lib.rs @@ -20,7 +20,7 @@ use caliptra_image_elf::ElfExecutable; use caliptra_image_gen::{ ImageGenerator, ImageGeneratorConfig, ImageGeneratorOwnerConfig, ImageGeneratorVendorConfig, }; -use caliptra_image_types::{FwImageType, ImageBundle, ImageRevision, RomInfo}; +use caliptra_image_types::{FwVerificationPqcKeyType, ImageBundle, ImageRevision, RomInfo}; use elf::endian::LittleEndian; use nix::fcntl::FlockArg; use zerocopy::AsBytes; @@ -444,7 +444,7 @@ pub struct ImageOptions { pub app_svn: u32, pub vendor_config: ImageGeneratorVendorConfig, pub owner_config: Option, - pub fw_image_type: FwImageType, + pub pqc_key_type: FwVerificationPqcKeyType, } impl Default for ImageOptions { fn default() -> Self { @@ -455,7 +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, + pqc_key_type: FwVerificationPqcKeyType::LMS, } } } @@ -478,7 +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, + pqc_key_type: opts.pqc_key_type, })?; Ok(image) } diff --git a/common/src/lib.rs b/common/src/lib.rs index ba4e884d24..71c515490f 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -40,7 +40,7 @@ pub use pcr::{PcrLogEntry, PcrLogEntryId, RT_FW_CURRENT_PCR, RT_FW_JOURNEY_PCR}; pub const FMC_ORG: u32 = 0x40000000; pub const FMC_SIZE: u32 = 20 * 1024; pub const RUNTIME_ORG: u32 = FMC_ORG + FMC_SIZE; -pub const RUNTIME_SIZE: u32 = 97 * 1024; +pub const RUNTIME_SIZE: u32 = 98 * 1024; pub use memory_layout::{DATA_ORG, FHT_ORG, FHT_SIZE, MAN1_ORG}; pub use wdt::{restart_wdt, start_wdt, stop_wdt, WdtTimeout}; diff --git a/common/src/verifier.rs b/common/src/verifier.rs index 62d8a47205..17e99ecae6 100644 --- a/common/src/verifier.rs +++ b/common/src/verifier.rs @@ -16,6 +16,7 @@ use caliptra_drivers::*; use caliptra_image_types::*; use caliptra_image_verify::ImageVerificationEnv; use core::ops::Range; +use zerocopy::{AsBytes, FromBytes}; use caliptra_drivers::memory_layout::ICCM_RANGE; @@ -25,14 +26,15 @@ pub struct FirmwareImageVerificationEnv<'a, 'b> { pub sha2_512_384: &'a mut Sha2_512_384, pub soc_ifc: &'a mut SocIfc, pub ecc384: &'a mut Ecc384, + pub mldsa87: &'a mut Mldsa87, pub data_vault: &'a mut DataVault, pub pcr_bank: &'a mut PcrBank, pub image: &'b [u8], } impl<'a, 'b> ImageVerificationEnv for &mut FirmwareImageVerificationEnv<'a, 'b> { - /// Calculate Digest using SHA-384 Accelerator - fn sha384_digest(&mut self, offset: u32, len: u32) -> CaliptraResult { + /// Calculate 384 digest using SHA2 Engine + fn sha384_digest(&mut self, offset: u32, len: u32) -> CaliptraResult { let err = CaliptraError::IMAGE_VERIFIER_ERR_DIGEST_OUT_OF_BOUNDS; let data = self .image @@ -43,10 +45,22 @@ impl<'a, 'b> ImageVerificationEnv for &mut FirmwareImageVerificationEnv<'a, 'b> Ok(self.sha2_512_384.sha384_digest(data)?.0) } + /// Calculate 512 digest using SHA2 Engine + fn sha512_digest(&mut self, offset: u32, len: u32) -> CaliptraResult { + let err = CaliptraError::IMAGE_VERIFIER_ERR_DIGEST_OUT_OF_BOUNDS; + let data = self + .image + .get(offset as usize..) + .ok_or(err)? + .get(..len as usize) + .ok_or(err)?; + Ok(self.sha2_512_384.sha512_digest(data)?.0) + } + /// ECC-384 Verification routine fn ecc384_verify( &mut self, - digest: &ImageDigest, + digest: &ImageDigest384, pub_key: &ImageEccPubKey, sig: &ImageEccSignature, ) -> CaliptraResult> { @@ -67,7 +81,7 @@ impl<'a, 'b> ImageVerificationEnv for &mut FirmwareImageVerificationEnv<'a, 'b> fn lms_verify( &mut self, - digest: &ImageDigest, + digest: &ImageDigest384, pub_key: &ImageLmsPublicKey, sig: &ImageLmsSignature, ) -> CaliptraResult> { @@ -78,8 +92,38 @@ impl<'a, 'b> ImageVerificationEnv for &mut FirmwareImageVerificationEnv<'a, 'b> Lms::default().verify_lms_signature_cfi(self.sha256, &message, pub_key, sig) } + fn mldsa87_verify( + &mut self, + digest: &ImageDigest512, + pub_key: &ImageMldsaPubKey, + sig: &ImageMldsaSignature, + ) -> CaliptraResult { + // Public Key is received in hw format from the image. No conversion needed. + let pub_key_bytes: [u8; MLDSA87_PUB_KEY_BYTE_SIZE] = pub_key + .0 + .as_bytes() + .try_into() + .map_err(|_| CaliptraError::IMAGE_VERIFIER_ERR_MLDSA_TYPE_CONVERSION_FAILED)?; + let pub_key = Mldsa87PubKey::read_from(pub_key_bytes.as_bytes()) + .ok_or(CaliptraError::IMAGE_VERIFIER_ERR_MLDSA_TYPE_CONVERSION_FAILED)?; + + // Signature is received in hw format from the image. No conversion needed. + let sig_bytes: [u8; MLDSA87_SIGNATURE_BYTE_SIZE] = sig + .0 + .as_bytes() + .try_into() + .map_err(|_| CaliptraError::IMAGE_VERIFIER_ERR_MLDSA_TYPE_CONVERSION_FAILED)?; + let sig = Mldsa87Signature::read_from(sig_bytes.as_bytes()) + .ok_or(CaliptraError::IMAGE_VERIFIER_ERR_MLDSA_TYPE_CONVERSION_FAILED)?; + + // digest is received in hw format. No conversion needed. + let msg = digest.into(); + + self.mldsa87.verify(&pub_key, &msg, &sig) + } + /// Retrieve Vendor Public Key Info Digest - fn vendor_pub_key_info_digest_fuses(&self) -> ImageDigest { + fn vendor_pub_key_info_digest_fuses(&self) -> ImageDigest384 { self.soc_ifc.fuse_bank().vendor_pub_key_info_hash().into() } @@ -94,7 +138,7 @@ impl<'a, 'b> ImageVerificationEnv for &mut FirmwareImageVerificationEnv<'a, 'b> } /// Retrieve Owner Public Key Digest from fuses - fn owner_pub_key_digest_fuses(&self) -> ImageDigest { + fn owner_pub_key_digest_fuses(&self) -> ImageDigest384 { self.soc_ifc.fuse_bank().owner_pub_key_hash().into() } @@ -114,17 +158,17 @@ impl<'a, 'b> ImageVerificationEnv for &mut FirmwareImageVerificationEnv<'a, 'b> } /// Get the vendor LMS key index saved in data vault on cold boot - fn vendor_lms_pub_key_idx_dv(&self) -> u32 { - self.data_vault.lms_vendor_pk_index() + fn vendor_pqc_pub_key_idx_dv(&self) -> u32 { + self.data_vault.pqc_vendor_pk_index() } /// Get the owner public key digest saved in the dv on cold boot - fn owner_pub_key_digest_dv(&self) -> ImageDigest { + fn owner_pub_key_digest_dv(&self) -> ImageDigest384 { self.data_vault.owner_pk_hash().into() } // Get the fmc digest from the data vault on cold boot - fn get_fmc_digest_dv(&self) -> ImageDigest { + fn get_fmc_digest_dv(&self) -> ImageDigest384 { self.data_vault.fmc_tci().into() } diff --git a/drivers/src/data_vault.rs b/drivers/src/data_vault.rs index 53fde23469..09827120fb 100644 --- a/drivers/src/data_vault.rs +++ b/drivers/src/data_vault.rs @@ -73,7 +73,7 @@ pub enum ColdResetEntry4 { RomColdBootStatus = 1, FmcEntryPoint = 2, EccVendorPubKeyIndex = 3, - LmsVendorPubKeyIndex = 4, + PqcVendorPubKeyIndex = 4, } impl TryFrom for ColdResetEntry4 { @@ -83,7 +83,7 @@ impl TryFrom for ColdResetEntry4 { 0 => Ok(Self::FmcSvn), 2 => Ok(Self::FmcEntryPoint), 3 => Ok(Self::EccVendorPubKeyIndex), - 4 => Ok(Self::LmsVendorPubKeyIndex), + 4 => Ok(Self::PqcVendorPubKeyIndex), _ => Err(()), } } @@ -325,13 +325,13 @@ impl DataVault { self.read_cold_reset_entry4(ColdResetEntry4::EccVendorPubKeyIndex) } - /// Get the Lms vendor public key index used for image verification. + /// Get the PQC (LMS or MLDSA) vendor public key index used for image verification. /// /// # Returns /// /// * `u32` - Vendor public key index - pub fn lms_vendor_pk_index(&self) -> u32 { - self.read_cold_reset_entry4(ColdResetEntry4::LmsVendorPubKeyIndex) + pub fn pqc_vendor_pk_index(&self) -> u32 { + self.read_cold_reset_entry4(ColdResetEntry4::PqcVendorPubKeyIndex) } /// Get the rom cold boot status. diff --git a/drivers/src/fuse_log.rs b/drivers/src/fuse_log.rs index 3f73a1de2c..4b5f17b4ce 100644 --- a/drivers/src/fuse_log.rs +++ b/drivers/src/fuse_log.rs @@ -28,8 +28,8 @@ pub enum FuseLogEntryId { ManifestRtSvn = 6, // 4 bytes ManifestReserved1 = 7, // 4 bytes FuseRtSvn = 8, // 4 bytes - VendorLmsPubKeyIndex = 9, // 4 bytes (From Manifest) - VendorLmsPubKeyRevocation = 10, // 4 bytes (From Fuse) + VendorPqcPubKeyIndex = 9, // 4 bytes (From Manifest) + VendorPqcPubKeyRevocation = 10, // 4 bytes (From Fuse) } impl From for FuseLogEntryId { @@ -44,8 +44,8 @@ impl From for FuseLogEntryId { 6 => FuseLogEntryId::ManifestRtSvn, 7 => FuseLogEntryId::ManifestReserved1, 8 => FuseLogEntryId::FuseRtSvn, - 9 => FuseLogEntryId::VendorLmsPubKeyIndex, - 10 => FuseLogEntryId::VendorLmsPubKeyRevocation, + 9 => FuseLogEntryId::VendorPqcPubKeyIndex, + 10 => FuseLogEntryId::VendorPqcPubKeyRevocation, _ => FuseLogEntryId::Invalid, } } diff --git a/drivers/src/memory_layout.rs b/drivers/src/memory_layout.rs index d362ca5501..34f810c5af 100644 --- a/drivers/src/memory_layout.rs +++ b/drivers/src/memory_layout.rs @@ -65,8 +65,8 @@ pub const MBOX_SIZE: u32 = 128 * 1024; pub const ICCM_SIZE: u32 = 128 * 1024; pub const DCCM_SIZE: u32 = 256 * 1024; pub const ROM_DATA_SIZE: u32 = 996; -pub const MAN1_SIZE: u32 = 8 * 1024; -pub const MAN2_SIZE: u32 = 8 * 1024; +pub const MAN1_SIZE: u32 = 17 * 1024; +pub const MAN2_SIZE: u32 = 17 * 1024; pub const FHT_SIZE: u32 = 2 * 1024; pub const IDEVID_MLDSA_PUB_KEY_MAX_SIZE: u32 = 3 * 1024; pub const LDEVID_TBS_SIZE: u32 = 1024; @@ -79,7 +79,7 @@ pub const DPE_SIZE: u32 = 5 * 1024; pub const PCR_RESET_COUNTER_SIZE: u32 = 1024; pub const AUTH_MAN_IMAGE_METADATA_MAX_SIZE: u32 = 7 * 1024; pub const IDEVID_CSR_SIZE: u32 = 1024; -pub const DATA_SIZE: u32 = 148 * 1024; +pub const DATA_SIZE: u32 = 130 * 1024; pub const STACK_SIZE: u32 = 64 * 1024; pub const ROM_STACK_SIZE: u32 = 14 * 1024; pub const ESTACK_SIZE: u32 = 1024; diff --git a/drivers/src/mldsa87.rs b/drivers/src/mldsa87.rs index 8f3a684c5c..7309073fc2 100644 --- a/drivers/src/mldsa87.rs +++ b/drivers/src/mldsa87.rs @@ -20,11 +20,12 @@ use crate::{ }; #[cfg(not(feature = "no-cfi"))] use caliptra_cfi_derive::cfi_impl_fn; +use caliptra_cfi_derive::Launder; use caliptra_registers::mldsa::{MldsaReg, RegisterBlock}; #[must_use] #[repr(u32)] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Launder)] pub enum Mldsa87Result { Success = 0xAAAAAAAA, SigVerifyFailed = 0x55555555, diff --git a/error/src/lib.rs b/error/src/lib.rs index c580108c2d..ff0e8804ea 100644 --- a/error/src/lib.rs +++ b/error/src/lib.rs @@ -200,7 +200,7 @@ impl CaliptraError { CaliptraError::new_const(0x000b0019); pub const IMAGE_VERIFIER_ERR_OWNER_ECC_SIGNATURE_INVALID_ARG: CaliptraError = CaliptraError::new_const(0x000b001a); - pub const IMAGE_VERIFIER_ERR_VENDOR_PUB_KEY_DIGEST_INVALID_ARG: CaliptraError = + pub const IMAGE_VERIFIER_ERR_VENDOR_ECC_PUB_KEY_INVALID_ARG: CaliptraError = CaliptraError::new_const(0x000b001b); pub const IMAGE_VERIFIER_ERR_VENDOR_ECC_SIGNATURE_INVALID_ARG: CaliptraError = CaliptraError::new_const(0x000b001c); @@ -236,7 +236,7 @@ impl CaliptraError { CaliptraError::new_const(0x000b002e); pub const IMAGE_VERIFIER_ERR_IMAGE_LEN_MORE_THAN_BUNDLE_SIZE: CaliptraError = CaliptraError::new_const(0x000b002f); - pub const IMAGE_VERIFIER_ERR_VENDOR_LMS_PUB_KEY_INDEX_MISMATCH: CaliptraError = + pub const IMAGE_VERIFIER_ERR_VENDOR_PQC_PUB_KEY_INDEX_MISMATCH: CaliptraError = CaliptraError::new_const(0x000b0030); pub const IMAGE_VERIFIER_ERR_VENDOR_LMS_VERIFY_FAILURE: CaliptraError = CaliptraError::new_const(0x000b0031); @@ -256,7 +256,7 @@ impl CaliptraError { CaliptraError::new_const(0x000b003b); pub const IMAGE_VERIFIER_ERR_RUNTIME_SIZE_ZERO: CaliptraError = CaliptraError::new_const(0x000b003c); - pub const IMAGE_VERIFIER_ERR_UPDATE_RESET_VENDOR_LMS_PUB_KEY_IDX_MISMATCH: CaliptraError = + pub const IMAGE_VERIFIER_ERR_UPDATE_RESET_VENDOR_PQC_PUB_KEY_IDX_MISMATCH: CaliptraError = CaliptraError::new_const(0x000b003d); pub const IMAGE_VERIFIER_ERR_FMC_LOAD_ADDRESS_IMAGE_SIZE_ARITHMETIC_OVERFLOW: CaliptraError = CaliptraError::new_const(0x000b003e); @@ -266,28 +266,52 @@ 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(0x000b0042); + pub const IMAGE_VERIFIER_ERR_ECC_KEY_DESCRIPTOR_HASH_COUNT_GT_MAX: CaliptraError = CaliptraError::new_const(0x000b0043); - pub const IMAGE_VERIFIER_ERR_ECC_KEY_DESCRIPTOR_INTENT_MISMATCH: CaliptraError = + pub const IMAGE_VERIFIER_ERR_PQC_KEY_DESCRIPTOR_VERSION_MISMATCH: CaliptraError = CaliptraError::new_const(0x000b0044); - pub const IMAGE_VERIFIER_ERR_ECC_KEY_DESCRIPTOR_HASH_COUNT_GT_MAX: CaliptraError = + pub const IMAGE_VERIFIER_ERR_PQC_KEY_DESCRIPTOR_TYPE_MISMATCH: CaliptraError = + CaliptraError::new_const(0x000b0045); + pub const IMAGE_VERIFIER_ERR_PQC_KEY_DESCRIPTOR_HASH_COUNT_GT_MAX: CaliptraError = CaliptraError::new_const(0x000b0046); - pub const IMAGE_VERIFIER_ERR_LMS_KEY_DESCRIPTOR_MARKER_MISMATCH: CaliptraError = + pub const IMAGE_VERIFIER_ERR_ECC_KEY_DESCRIPTOR_INVALID_HASH_COUNT: CaliptraError = CaliptraError::new_const(0x000b0047); - pub const IMAGE_VERIFIER_ERR_LMS_KEY_DESCRIPTOR_VERSION_MISMATCH: CaliptraError = + pub const IMAGE_VERIFIER_ERR_PQC_KEY_DESCRIPTOR_INVALID_HASH_COUNT: CaliptraError = CaliptraError::new_const(0x000b0048); - pub const IMAGE_VERIFIER_ERR_LMS_KEY_DESCRIPTOR_INTENT_MISMATCH: CaliptraError = + pub const IMAGE_VERIFIER_ERR_FW_IMAGE_VERIFICATION_KEY_TYPE_INVALID: CaliptraError = CaliptraError::new_const(0x000b0049); - pub const IMAGE_VERIFIER_ERR_LMS_KEY_DESCRIPTOR_TYPE_MISMATCH: CaliptraError = + pub const IMAGE_VERIFIER_ERR_LMS_VENDOR_PUB_KEY_INVALID: CaliptraError = CaliptraError::new_const(0x000b004a); - pub const IMAGE_VERIFIER_ERR_LMS_KEY_DESCRIPTOR_HASH_COUNT_GT_MAX: CaliptraError = + pub const IMAGE_VERIFIER_ERR_LMS_VENDOR_SIG_INVALID: CaliptraError = CaliptraError::new_const(0x000b004b); - pub const IMAGE_VERIFIER_ERR_ECC_KEY_DESCRIPTOR_INVALID_HASH_COUNT: CaliptraError = + pub const IMAGE_VERIFIER_ERR_LMS_OWNER_PUB_KEY_INVALID: CaliptraError = CaliptraError::new_const(0x000b004c); - pub const IMAGE_VERIFIER_ERR_LMS_KEY_DESCRIPTOR_INVALID_HASH_COUNT: CaliptraError = + pub const IMAGE_VERIFIER_ERR_LMS_OWNER_SIG_INVALID: CaliptraError = CaliptraError::new_const(0x000b004d); + pub const IMAGE_VERIFIER_ERR_MLDSA_VENDOR_PUB_KEY_READ_FAILED: CaliptraError = + CaliptraError::new_const(0x000b004e); + pub const IMAGE_VERIFIER_ERR_MLDSA_VENDOR_SIG_READ_FAILED: CaliptraError = + CaliptraError::new_const(0x000b004f); + pub const IMAGE_VERIFIER_ERR_MLDSA_OWNER_PUB_KEY_READ_FAILED: CaliptraError = + CaliptraError::new_const(0x000b0050); + pub const IMAGE_VERIFIER_ERR_MLDSA_OWNER_SIG_READ_FAILED: CaliptraError = + CaliptraError::new_const(0x000b0051); + pub const IMAGE_VERIFIER_ERR_VENDOR_MLDSA_DIGEST_MISSING: CaliptraError = + CaliptraError::new_const(0x000b0052); + pub const IMAGE_VERIFIER_ERR_OWNER_MLDSA_DIGEST_MISSING: CaliptraError = + CaliptraError::new_const(0x000b0053); + pub const IMAGE_VERIFIER_ERR_VENDOR_MLDSA_VERIFY_FAILURE: CaliptraError = + CaliptraError::new_const(0x000b0054); + pub const IMAGE_VERIFIER_ERR_VENDOR_MLDSA_SIGNATURE_INVALID: CaliptraError = + CaliptraError::new_const(0x000b0055); + pub const IMAGE_VERIFIER_ERR_OWNER_MLDSA_VERIFY_FAILURE: CaliptraError = + CaliptraError::new_const(0x000b0056); + pub const IMAGE_VERIFIER_ERR_OWNER_MLDSA_SIGNATURE_INVALID: CaliptraError = + CaliptraError::new_const(0x000b0057); + pub const IMAGE_VERIFIER_ERR_MLDSA_TYPE_CONVERSION_FAILED: CaliptraError = + CaliptraError::new_const(0x000b0058); /// Driver Error: LMS pub const DRIVER_LMS_INVALID_LMS_ALGO_TYPE: CaliptraError = @@ -480,6 +504,10 @@ impl CaliptraError { CaliptraError::new_const(0x000E0051); pub const RUNTIME_GET_IDEV_ID_UNSUPPORTED_ROM: CaliptraError = CaliptraError::new_const(0x000E0052); + pub const RUNTIME_AUTH_MANIFEST_LMS_VENDOR_PUB_KEY_INVALID: CaliptraError = + CaliptraError::new_const(0x000E0053); + pub const RUNTIME_AUTH_MANIFEST_LMS_OWNER_PUB_KEY_INVALID: CaliptraError = + CaliptraError::new_const(0x000E0054); /// FMC Errors pub const FMC_GLOBAL_NMI: CaliptraError = CaliptraError::new_const(0x000F0001); diff --git a/fmc/Makefile b/fmc/Makefile index 04f2e7a761..2b8c27fbee 100644 --- a/fmc/Makefile +++ b/fmc/Makefile @@ -70,7 +70,7 @@ build-fw-image: gen-certs build-emu build-test-rt create \ --key-config $(TARGET_DIR)/keys.toml \ --ecc-pk-idx 3 \ - --lms-pk-idx 3 \ + --pqc-pk-idx 3 \ --fmc $(TARGET_DIR)/caliptra-fmc \ --fmc-version 0 \ --fmc-svn 0 \ diff --git a/image/app/src/create/config.rs b/image/app/src/create/config.rs index 5ee8d94209..8a5e132e4c 100644 --- a/image/app/src/create/config.rs +++ b/image/app/src/create/config.rs @@ -23,9 +23,13 @@ pub(crate) struct VendorKeyConfig { pub lms_pub_keys: Vec, + pub mldsa_pub_keys: Vec, + pub ecc_priv_keys: Option>, pub lms_priv_keys: Option>, + + pub mldsa_priv_keys: Option>, } /// Owner Key Configuration @@ -38,6 +42,10 @@ pub(crate) struct OwnerKeyConfig { pub lms_pub_key: String, pub lms_priv_key: Option, + + pub mldsa_pub_key: String, + + pub mldsa_priv_key: Option, } // Key Configuration diff --git a/image/app/src/create/mod.rs b/image/app/src/create/mod.rs index 6c660a4505..f16947b619 100644 --- a/image/app/src/create/mod.rs +++ b/image/app/src/create/mod.rs @@ -74,9 +74,9 @@ fn check_date(from_date: &str, to_date: &str) -> anyhow::Result { /// Run the command pub(crate) fn run_cmd(args: &ArgMatches) -> anyhow::Result<()> { - let image_type: &u32 = args - .get_one::("image-type") - .with_context(|| "image-type arg not specified")?; + let pqc_key_type: &u32 = args + .get_one::("pqc-key-type") + .with_context(|| "pqc-key-type arg not specified")?; let config_path: &PathBuf = args .get_one::("key-config") @@ -118,9 +118,9 @@ pub(crate) fn run_cmd(args: &ArgMatches) -> anyhow::Result<()> { .get_one::("ecc-pk-idx") .with_context(|| "ecc-pk-idx arg not specified")?; - let lms_key_idx: &u32 = args - .get_one::("lms-pk-idx") - .with_context(|| "lms-pk-idx arg not specified")?; + let pqc_key_idx: &u32 = args + .get_one::("pqc-pk-idx") + .with_context(|| "pqc-pk-idx arg not specified")?; let out_path: &PathBuf = args .get_one::("out") @@ -174,23 +174,32 @@ pub(crate) fn run_cmd(args: &ArgMatches) -> anyhow::Result<()> { .parent() .with_context(|| "Invalid parent path")?; + let pqc_key_type = if *pqc_key_type == 1 { + FwVerificationPqcKeyType::LMS + } else { + FwVerificationPqcKeyType::MLDSA + }; + let gen_config = ImageGeneratorConfig:: { + pqc_key_type, vendor_config: vendor_config( + pqc_key_type, config_dir, &config.vendor, *ecc_key_idx, - *lms_key_idx, + *pqc_key_idx, mfg_from_date, mfg_to_date, )?, - owner_config: owner_config(config_dir, &config.owner, own_from_date, own_to_date)?, + owner_config: owner_config( + pqc_key_type, + 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()); @@ -211,10 +220,11 @@ pub(crate) fn run_cmd(args: &ArgMatches) -> anyhow::Result<()> { /// Generate Vendor Config fn vendor_config( + pqc_key_type: FwVerificationPqcKeyType, path: &Path, config: &VendorKeyConfig, ecc_key_idx: u32, - lms_key_idx: u32, + pqc_key_idx: u32, from_date: [u8; 15], to_date: [u8; 15], ) -> anyhow::Result { @@ -222,31 +232,21 @@ fn vendor_config( let ecc_key_count = config.ecc_pub_keys.len() as u32; let lms_key_count = config.lms_pub_keys.len() as u32; + let mldsa_key_count = config.mldsa_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(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)?; - } let mut priv_keys = ImageVendorPrivKeys::default(); if let Some(ecc_priv_keys) = &config.ecc_priv_keys { @@ -261,30 +261,77 @@ fn vendor_config( gen_config.priv_keys = Some(priv_keys); } - if let Some(lms_priv_keys) = &config.lms_priv_keys { - for (i, pem_file) in lms_priv_keys + if pqc_key_type == FwVerificationPqcKeyType::LMS { + if lms_key_count > VENDOR_LMS_MAX_KEY_COUNT { + return Err(anyhow!("Invalid LMS Public Key Count")); + } + + if pqc_key_idx >= lms_key_count { + return Err(anyhow!("Invalid LMS Public Key Index")); + } + + let lms_pub_keys = &config.lms_pub_keys; + 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)?; + } + + if let Some(lms_priv_keys) = &config.lms_priv_keys { + for (i, pem_file) in lms_priv_keys + .iter() + .enumerate() + .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)?; + } + gen_config.priv_keys = Some(priv_keys); + } + } else { + if mldsa_key_count > VENDOR_MLDSA_MAX_KEY_COUNT { + return Err(anyhow!("Invalid MLDSA Public Key Count")); + } + if pqc_key_idx >= mldsa_key_count { + return Err(anyhow!("Invalid MLDSA Public Key Index")); + } + + let mldsa_pub_keys = &config.mldsa_pub_keys; + for (i, file) in mldsa_pub_keys .iter() .enumerate() - .take(lms_key_count as usize) + .take(mldsa_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)?; + let pub_key_path = path.join(file); + gen_config.pub_keys.mldsa_pub_keys[i] = Crypto::mldsa_pub_key_from_file(&pub_key_path)?; + } + + if let Some(mldsa_priv_keys) = &config.mldsa_priv_keys { + for (i, file) in mldsa_priv_keys + .iter() + .enumerate() + .take(mldsa_key_count as usize) + { + let priv_key_path = path.join(file); + priv_keys.mldsa_priv_keys[i] = Crypto::mldsa_priv_key_from_file(&priv_key_path)?; + } + gen_config.priv_keys = Some(priv_keys); } - gen_config.priv_keys = Some(priv_keys); } gen_config.ecc_key_idx = ecc_key_idx; - gen_config.lms_key_idx = lms_key_idx; + gen_config.pqc_key_idx = pqc_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; + gen_config.mldsa_key_count = mldsa_key_count; Ok(gen_config) } /// Generate owner config fn owner_config( + pqc_key_type: FwVerificationPqcKeyType, path: &Path, config: &Option, from_date: [u8; 15], @@ -292,16 +339,11 @@ fn owner_config( ) -> anyhow::Result> { if let Some(config) = config { let mut gen_config = ImageGeneratorOwnerConfig::default(); - let pem_file = &config.ecc_pub_key; + let pem_file = &config.ecc_pub_key; let pub_key_path = path.join(pem_file); gen_config.pub_keys.ecc_pub_key = Crypto::ecc_pub_key_from_pem(&pub_key_path)?; - let pem_file = &config.lms_pub_key; - - let pub_key_path = path.join(pem_file); - gen_config.pub_keys.lms_pub_key = lms_pub_key_from_pem(&pub_key_path)?; - let mut priv_keys = ImageOwnerPrivKeys::default(); if let Some(pem_file) = &config.ecc_priv_key { let pub_key_path = path.join(pem_file); @@ -309,10 +351,26 @@ fn owner_config( gen_config.priv_keys = Some(priv_keys); } - if let Some(pem_file) = &config.lms_priv_key { - let priv_key_path = path.join(pem_file); - priv_keys.lms_priv_key = lms_priv_key_from_pem(&priv_key_path)?; - gen_config.priv_keys = Some(priv_keys); + if pqc_key_type == FwVerificationPqcKeyType::LMS { + let pem_file = &config.lms_pub_key; + let pub_key_path = path.join(pem_file); + gen_config.pub_keys.lms_pub_key = lms_pub_key_from_pem(&pub_key_path)?; + + if let Some(pem_file) = &config.lms_priv_key { + let priv_key_path = path.join(pem_file); + priv_keys.lms_priv_key = lms_priv_key_from_pem(&priv_key_path)?; + gen_config.priv_keys = Some(priv_keys); + } + } else { + let file = &config.mldsa_pub_key; + let pub_key_path = path.join(file); + gen_config.pub_keys.mldsa_pub_key = Crypto::mldsa_pub_key_from_file(&pub_key_path)?; + + if let Some(file) = &config.mldsa_priv_key { + let priv_key_path = path.join(file); + priv_keys.mldsa_priv_key = Crypto::mldsa_priv_key_from_file(&priv_key_path)?; + gen_config.priv_keys = Some(priv_keys); + } } gen_config.not_before = from_date; gen_config.not_after = to_date; diff --git a/image/app/src/main.rs b/image/app/src/main.rs index 189d4b06b5..768f840205 100644 --- a/image/app/src/main.rs +++ b/image/app/src/main.rs @@ -22,7 +22,7 @@ fn main() { let sub_cmds = vec![Command::new("create") .about("Create a new firmware image bundle") .arg( - arg!(--"image-type" "Type of image keys: 1: ECC + LMS; 2: ECC + MLDSA") + arg!(--"pqc-key-type" "Type of image keys: 1: ECC + LMS; 2: ECC + MLDSA") .required(true) .value_parser(value_parser!(u32)), ) @@ -37,7 +37,7 @@ fn main() { .value_parser(value_parser!(u32)), ) .arg( - arg!(--"lms-pk-idx" "Vendor LMS Public Key Index") + arg!(--"pqc-pk-idx" "Vendor PQC (LMS or MLDSA) Public Key Index") .required(false) .value_parser(value_parser!(u32)), ) diff --git a/image/crypto/src/openssl.rs b/image/crypto/src/openssl.rs index 1ceca85956..9d6f4489f0 100644 --- a/image/crypto/src/openssl.rs +++ b/image/crypto/src/openssl.rs @@ -25,7 +25,7 @@ use openssl::{ ecdsa::EcdsaSig, nid::Nid, rand::rand_bytes, - sha::{Sha256, Sha384}, + sha::{Sha256, Sha384, Sha512}, }; use crate::{from_hw_format, sign_with_lms_key, to_hw_format, Sha256Hasher, SUPPORTED_LMS_Q_VALUE}; @@ -54,15 +54,21 @@ impl ImageGeneratorCrypto for OsslCrypto { OsslSha256Hasher(Sha256::default()) } - fn sha384_digest(&self, data: &[u8]) -> anyhow::Result { + fn sha384_digest(&self, data: &[u8]) -> anyhow::Result { let mut engine = Sha384::new(); engine.update(data); Ok(to_hw_format(&engine.finish())) } + fn sha512_digest(&self, data: &[u8]) -> anyhow::Result { + let mut engine = Sha512::new(); + engine.update(data); + Ok(to_hw_format(&engine.finish())) + } + fn ecdsa384_sign( &self, - digest: &ImageDigest, + digest: &ImageDigest384, priv_key: &ImageEccPrivKey, pub_key: &ImageEccPubKey, ) -> anyhow::Result { @@ -96,7 +102,7 @@ impl ImageGeneratorCrypto for OsslCrypto { fn lms_sign( &self, - digest: &ImageDigest, + digest: &ImageDigest384, priv_key: &ImageLmsPrivKey, ) -> anyhow::Result { let message: [u8; ECC384_SCALAR_BYTE_SIZE] = from_hw_format(digest); @@ -139,6 +145,18 @@ impl ImageGeneratorCrypto for OsslCrypto { Ok(to_hw_format(&priv_key)) } + + fn mldsa_pub_key_from_file(path: &Path) -> anyhow::Result { + let key_bytes = std::fs::read(path) + .with_context(|| format!("Failed to read public key file {}", path.display()))?; + Ok(ImageMldsaPubKey(to_hw_format(&key_bytes))) + } + + fn mldsa_priv_key_from_file(path: &Path) -> anyhow::Result { + let key_bytes = std::fs::read(path) + .with_context(|| format!("Failed to read private key file {}", path.display()))?; + Ok(ImageMldsaPrivKey(to_hw_format(&key_bytes))) + } } pub struct OpensslHasher(Sha256); diff --git a/image/fake-keys/src/lib.rs b/image/fake-keys/src/lib.rs index 733a7eddc4..9d6460e492 100644 --- a/image/fake-keys/src/lib.rs +++ b/image/fake-keys/src/lib.rs @@ -2,9 +2,10 @@ 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, VENDOR_ECC_MAX_KEY_COUNT, VENDOR_LMS_MAX_KEY_COUNT, + ImageEccPrivKey, ImageEccPubKey, ImageLmsPrivKey, ImageLmsPublicKey, ImageMldsaPrivKey, + ImageMldsaPubKey, ImageOwnerPrivKeys, ImageVendorPrivKeys, ImageVendorPubKeys, + OwnerPubKeyConfig, IMAGE_LMS_OTS_TYPE, IMAGE_LMS_TREE_TYPE, VENDOR_ECC_MAX_KEY_COUNT, + VENDOR_LMS_MAX_KEY_COUNT, VENDOR_MLDSA_MAX_KEY_COUNT, }; use caliptra_lms_types::bytes_to_words_6; @@ -199,6 +200,964 @@ pub const VENDOR_LMS_KEY_3_PUBLIC: ImageLmsPublicKey = ImageLmsPublicKey { ]), }; +pub const VENDOR_MLDSA_KEY_0_PUBLIC: ImageMldsaPubKey = ImageMldsaPubKey([ + 0xa4c34aad, 0x85990594, 0x3b3099eb, 0x1ecf176c, 0x65de9fd6, 0xd9a79023, 0x8a4aa333, 0xd15a8dd4, + 0x37a0aa4b, 0x0189a817, 0x6fabfe0e, 0xe492fb02, 0xca3b81bd, 0xb50c58ba, 0xfb11dff9, 0x2d477742, + 0xd566336c, 0xd1777f86, 0x0bb73cb4, 0x5ec59477, 0x9b29603f, 0x132b3c75, 0xcecdce3c, 0x6cf949f0, + 0xc4de84ed, 0x070e6a14, 0xc130ede6, 0x9a74116a, 0xdaf1de3e, 0x644faa5c, 0x26cc8d01, 0x60631c69, + 0xce5f9b28, 0x68668dd7, 0xc48858fd, 0x4baaf788, 0xca3433ac, 0x56a9075f, 0x4a1a745d, 0x22aa4649, + 0xa9892830, 0xd849f593, 0x3199e941, 0x844b76be, 0x5bde507d, 0xe356c318, 0xaf6948be, 0xf724d9e2, + 0x0199a2bf, 0xcfccd9eb, 0x533ee9ce, 0x34c404fa, 0x4806443c, 0x6efc17d5, 0x30351c61, 0x42dc875f, + 0x81f53daa, 0x209c95a4, 0x66660dad, 0x3f63c49a, 0x9ae324b1, 0x700520c1, 0x96f1e571, 0xaa5133fc, + 0xb9b80b01, 0x66ec0775, 0xa087606c, 0x678196ed, 0x7e139b1b, 0x544c2fea, 0x3beb95ce, 0xe7c889e9, + 0xd4a78996, 0x1180d253, 0xf0611137, 0xa9065c5b, 0x16ad085e, 0xec4eb2ba, 0x5115d3d0, 0xa5d9ecc6, + 0x48993da9, 0xc9863823, 0x6d696b10, 0xc14bd1aa, 0xd5c7002c, 0x59b76ce5, 0x10d66ed6, 0xd99a3012, + 0x15e32845, 0x64583adb, 0xf131cb8d, 0xa23be8b4, 0x5586c868, 0x0147a4e9, 0x027406d3, 0x38a34707, + 0xbb11d35c, 0x999706cc, 0xd49b4f2f, 0x3a2bffcd, 0xbb8ea26a, 0x6031a38f, 0xb2b81bb0, 0xdd6ae90c, + 0xc52aae9e, 0x40c7118b, 0x4f6f69ab, 0xf1b9fb4e, 0xe17eff23, 0xd4196251, 0xabda30b8, 0xcfe73bdf, + 0x3fd708e8, 0x1dfdc294, 0x91135cf4, 0xce6d3a30, 0xd2d7d0e6, 0xc3bf0052, 0x58489c38, 0x20f2346a, + 0xfd2fcb6d, 0xa1c107ab, 0xa56d7f4d, 0x4af058e5, 0xcee727f4, 0xf90d042e, 0x6e9782dd, 0x3629b653, + 0x714e7dad, 0xe4348b69, 0xaa85996d, 0x8aa5f122, 0xf19ab645, 0x04caa0b3, 0xacdd0b32, 0xad05675c, + 0xffff31eb, 0xa10645f5, 0xa863501a, 0x3911cf31, 0x033bce32, 0xb402a4ba, 0xbbc8e37a, 0x473b2032, + 0xad0a222c, 0xadd5778a, 0xedef07f2, 0x4c704acb, 0x22395a0a, 0x46ed325c, 0x8c241603, 0xc63579f2, + 0x5e171cf0, 0xc703cca8, 0xf0bf7ced, 0x95947386, 0xd118ea9a, 0xcf4061e9, 0x755fb6d7, 0xd34b8467, + 0x4c9e316c, 0x8efbaf5c, 0xaf8b6b3e, 0xf28805b5, 0x2738a2f6, 0xc1cc79fa, 0xc2bd26c5, 0xe26b439c, + 0xed195085, 0xd23091db, 0x9713c325, 0x50f0a173, 0x86a3be0e, 0x4a360d67, 0x934f7b28, 0x926678f0, + 0x62dc04c5, 0xa976ae51, 0x38491c4f, 0xe607a52b, 0xc8704ef4, 0x8dc70877, 0x68acb197, 0xf8893edf, + 0x79b754ab, 0x80e99d9a, 0x663d73e0, 0x49c877b5, 0x1f2a439e, 0x7fd843e6, 0x97e25f70, 0xee6b2ff3, + 0x6b2a5500, 0x4942e97d, 0xc6b07951, 0x669b5e38, 0x5ff06273, 0x60272b43, 0x033fb5c0, 0x27259270, + 0x171aee38, 0xa7484e7b, 0xc10a5c4e, 0xe3b43487, 0x6ddfb66c, 0xc6ef4e62, 0xf9b3589c, 0xc782ae18, + 0xf363227d, 0xaa8ac410, 0xe17eeb1f, 0xeea4133d, 0xa6dfd292, 0x5f08f536, 0x1fcd05e8, 0xe16efe1a, + 0x2e7a455e, 0xc72d6064, 0x5295fdb1, 0xb697a865, 0x8bc53087, 0xc08796f2, 0x2f2f6564, 0xb0a20df5, + 0xdc023426, 0x76987c49, 0x3cce098d, 0x88583c0d, 0x45b0950c, 0x0fe6a2c2, 0x25b2bb09, 0xfaf36bbe, + 0x2435bf9d, 0xb67048a5, 0x702c0f06, 0x2135a52a, 0x26287b18, 0x78cd8d26, 0x6bd42953, 0x726207fa, + 0xd2ebcc0e, 0x0cf25057, 0x06526617, 0xbffc320c, 0xd04bb69c, 0xc727b133, 0x2432b8e5, 0xd254bf04, + 0xb0edaf69, 0x4607caaf, 0xff728989, 0x78b8ce5b, 0xc308efb1, 0x5ed64e1c, 0xeeb02dcc, 0xf9eccf33, + 0xdfe64533, 0xdaf93cc6, 0x78b73c17, 0x9a98cd23, 0x3268ae29, 0x1da48aae, 0xbe5e4261, 0x625797f9, + 0xc16400e7, 0x27fe8157, 0x338cd9f9, 0xb6e767db, 0x82975ba6, 0x01478a92, 0x8c5cdfec, 0xaf7e993b, + 0x7d85b256, 0x9fa753df, 0xe9d265fc, 0xea6425d9, 0x998f95ac, 0x72a0b613, 0x195c598d, 0x2a0c41d8, + 0x5f04c2e9, 0xb46bf7c3, 0x7e6c48e0, 0x0288f1a9, 0xca6cb5f0, 0xe6d7b01d, 0x10c67516, 0xaca376b6, + 0x40ada0f3, 0x419032f3, 0xc48cfd07, 0xb4fdd654, 0xa7e8db89, 0x370a5b78, 0x92787949, 0x63421003, + 0x9ff61dbe, 0x41e91ecd, 0xc855adf9, 0x9debafb1, 0x26636426, 0xfe80dd85, 0xf9c53bb6, 0xae3c4ddb, + 0x188a110c, 0x26cda2b5, 0x9c9917bc, 0x42c0adad, 0x2f089433, 0x67d66b50, 0xa794832c, 0x5af545cc, + 0x2efa85bd, 0x98da9f58, 0x624e5a19, 0xf75ec35b, 0xc676e5a7, 0x2546bf59, 0x4f91107c, 0xb5036c40, + 0x70d7794a, 0xceb719a2, 0xceafdac4, 0x78673f8b, 0x0d9c3355, 0xea376196, 0x2e3c451f, 0x58fc6789, + 0x98843314, 0x10e05005, 0xa3ce45f7, 0xdc885fd2, 0x342e5ac2, 0x74e74b43, 0x6162978f, 0x5089904b, + 0xa4a8f931, 0x35d20a3f, 0x6f20b8be, 0x6d27bf2c, 0xd192dedc, 0x0e9a7c84, 0xbdfcdf99, 0x85d98eef, + 0xe28da928, 0x52bcfee1, 0x9c47918d, 0xc33cc88d, 0x99c8ebda, 0x5350bb28, 0x2fddd04e, 0xc2160cd0, + 0xd9648620, 0x618566d2, 0xf4a0bf7f, 0x5912e3b4, 0xa9c23354, 0x81cc09c1, 0x7b4b41cc, 0x9bdf60e5, + 0xb1adacbe, 0xcdbe6128, 0xa85e60fd, 0x09ec3faf, 0x904d4ca7, 0xb84b8e86, 0x763e058d, 0xca8a6df4, + 0x4f3ef01e, 0x8a982342, 0xb5a59cbc, 0xbc0224f6, 0x3422b3f6, 0xc6ed782b, 0xd74f55c6, 0x38951af4, + 0xb21db0fc, 0x99bc099e, 0xc6744fbc, 0x3cc0bac3, 0x6e6f28b0, 0x2977d2e4, 0x232359d0, 0x60152363, + 0xe75a98f8, 0xaf3ffb97, 0x1c969cde, 0xcbc41a17, 0x6665f99c, 0xb7b7c2db, 0x327317cd, 0x3a163243, + 0x92cfeaa5, 0x042bf3fb, 0x19cec4e4, 0x737a3dec, 0xf22df03f, 0x6c42b10d, 0xf13ebcff, 0x3b0bdf77, + 0x192d2e1c, 0xe8eb3b74, 0x52584a0d, 0xfabea3ea, 0xb8e02671, 0x3d04b140, 0x2b80ee27, 0x734d3032, + 0x4c6455c1, 0xc61e84b5, 0x01ad9944, 0x3ec96119, 0x6e5f95cd, 0x7352aacd, 0x88d2ac4b, 0x5467169e, + 0xd4168a36, 0x1da952aa, 0x2bc0e131, 0x5435ab85, 0xc721938c, 0xb604f118, 0x212cd772, 0x576f6f3c, + 0x69aa0827, 0xb04954e0, 0x1f257a5b, 0x32e882e6, 0xd1b37fcf, 0xde10e082, 0xaa97564f, 0x55210b99, + 0x777dde41, 0x65288b28, 0x5db9c9c8, 0x5252207e, 0xea63af88, 0xca4e4c70, 0x79148f92, 0xb3b3aea5, + 0x1c2a0bd8, 0x45badb6b, 0x020090a6, 0x9fea09ba, 0xae4cd583, 0xe7d105eb, 0x59eccce7, 0xcf6a7c88, + 0x2e5a9b33, 0xdee39d2e, 0xbc686d8c, 0xc7dfdfb7, 0x2462a62a, 0x148ef997, 0x28017beb, 0x9da516bc, + 0x02f99b56, 0xf1a8bdbd, 0x8450e8bc, 0x5a645fc6, 0x9c4d4c2e, 0xf8a77145, 0x80ca80ed, 0x70b7bc63, + 0x121b7a47, 0x606e46e2, 0xea4e0fd2, 0xb981091d, 0xfa705cd5, 0x6a805fb6, 0xf3ba2475, 0x6a22f4d5, + 0xe92c6b32, 0xb27666c1, 0x054b0277, 0x06362955, 0x0c8f72e8, 0x21c9eddd, 0x5e8ddb44, 0xd197a71e, + 0x1162a17a, 0xd5f1421b, 0x91685dd9, 0xe230b73c, 0x9a273985, 0xbec50fb5, 0xb016f4d8, 0x6d5c37fc, + 0x25dc6cac, 0xca3d51ae, 0x97004d3e, 0x5a194f4f, 0x005d47a0, 0xc7a853e4, 0x452ad686, 0x9114c0c3, + 0x65f93218, 0x6c2b60e2, 0xac044aeb, 0x2ddfda20, 0x4dd0276e, 0xc61a870e, 0xc95bfc2c, 0xda195076, + 0x354f97ca, 0x32137480, 0x87fe68b0, 0x6b22b28b, 0x4317ba5c, 0x03ed0d47, 0x97bd480d, 0x619de155, + 0x366693fe, 0xace200ce, 0x6546161d, 0x825a7e75, 0xd640f113, 0x3775386c, 0x6e9c25e5, 0x088a8be4, + 0x94b9b7b3, 0x39f1682d, 0x767efd2a, 0xea687310, 0x10352963, 0xf6ebb8ed, 0x7a05296a, 0xff5487e7, + 0x48509dfc, 0xf39e4cec, 0x8b203189, 0xb0a9570a, 0x1691e8bb, 0x610f37ef, 0xc021e846, 0x56f7c080, + 0xf7755ab4, 0x07864fa8, 0xe625d050, 0x1a81c9fa, 0xd474639e, 0x3f811615, 0x5961f68e, 0xa0f74879, + 0x8ab0aafb, 0x5a76cc37, 0x69adee7c, 0xcb2bd291, 0x98c16b0e, 0x5f4cf758, 0xade63d79, 0xdeeca28b, + 0x0663ae16, 0x31a0874d, 0xb9336dbb, 0x198579e2, 0x06b614c2, 0x5338c7b8, 0xd0ab40cc, 0x3fd1d9ca, + 0x86be3f79, 0xc73ea699, 0x8d76c562, 0x3fb4d865, 0x49fe05d1, 0x19f4d8bf, 0xc37cc553, 0x71354e62, + 0xf5034b0e, 0xd35120f8, 0xcc745c52, 0x2fc5244c, 0x1a88ac22, 0xbcf8175f, 0x36005e32, 0xf9636cdb, + 0xa56e213a, 0xa036b783, 0xda369deb, 0x5994b510, 0x9a0c5c1d, 0x005985ec, 0x30592bdc, 0xbfba60a5, + 0xae4371e8, 0x42d8f5c9, 0x11308268, 0x38ac064a, 0xb775f17a, 0x0068d63f, 0xa78cd9c8, 0xe943c524, + 0x728c9e63, 0x1999dd1b, 0x04bd23f2, 0x2ac632b4, 0x18672908, 0xb7735515, 0x97711e0d, 0xa32a65de, + 0xbdc4910c, 0x75575b2e, 0xfd4bf85d, 0x9c1494d7, 0x335bc800, 0x239953ae, 0x971fedc6, 0x8563f573, + 0xc64adead, 0xe022b3cc, 0xb04890d0, 0xc1ca889e, 0x844e0df5, 0x0059ccd6, 0xfa57851b, 0x0b7e4747, + 0xa0edca48, 0xd24d0309, 0x7bb51774, 0x0c8bb87b, 0xc1c260ce, 0x893359c7, 0xa8afb98c, 0xbca6933d, + 0x5facc0be, 0xd07dd74e, 0xdd2aabe5, 0xd93c1bfd, 0xd6724ba3, 0xea1c92fd, 0x808c0212, 0xc0057e86, + 0x18c116e6, 0x95ea19b6, 0x9971f126, 0xefb4c14c, 0x64087ba5, 0x6dbe8830, 0xa27661b3, 0xa9837201, + 0x4f164171, 0x9108b3d1, 0xf79c865e, 0x541e4696, 0x5c4c4977, 0x25fb4114, 0x7cdae73b, 0xace74be7, +]); + +pub const VENDOR_MLDSA_KEY_0_PRIVATE: ImageMldsaPrivKey = ImageMldsaPrivKey([ + 0xa4c34aad, 0x85990594, 0x3b3099eb, 0x1ecf176c, 0x65de9fd6, 0xd9a79023, 0x8a4aa333, 0xd15a8dd4, + 0xe39406df, 0x780e69d4, 0x58984cde, 0xf56451cf, 0xd7127ef3, 0xddabf144, 0x9b69cfe7, 0x09e93e5e, + 0x9d8af1bc, 0x7db9659f, 0xfae00502, 0xd8ca0ae3, 0x37195014, 0xceafe5a2, 0x8b887a5e, 0x8ecf604d, + 0xcdc9e51d, 0x2a2e0725, 0xf71d9455, 0xa7e9ec84, 0x421b6e1d, 0x4faeb14e, 0x041a3f5c, 0x46ce8a96, + 0x11064c92, 0x002524c7, 0x21894640, 0xa2126ec4, 0x382c1a08, 0x32541044, 0x58b89112, 0xc68cd9c2, + 0x69c8b269, 0xc2287240, 0x2084cb98, 0x2c83428e, 0xc4a66dc3, 0x8280d430, 0x1113c268, 0x54204854, + 0x2490c236, 0x080ba86d, 0x13a908d9, 0x20808836, 0x2820b249, 0xc0088924, 0xc9899902, 0x894c0026, + 0x94228dc2, 0x344813c5, 0x8d013649, 0xe0b42460, 0x28250838, 0x51094246, 0x614029c0, 0xc828c990, + 0x4942904c, 0x90208403, 0xb65103b5, 0x095c2866, 0x44866cc4, 0xa8218812, 0x62d33011, 0xdcc26509, + 0x38484298, 0x7193b490, 0x00150008, 0x0600a136, 0x80db4210, 0x1b188cda, 0x44440a82, 0x31192285, + 0x0b232a14, 0x1421c4c6, 0x31241409, 0x52948910, 0x248e0013, 0x41cb4020, 0x41824900, 0x494c2147, + 0x2c991830, 0x8c366d8b, 0xa28914c0, 0x291cc54d, 0x84a870d8, 0x1861a128, 0x62d3982c, 0xd9840553, + 0x14881228, 0x880a4005, 0x5c084e50, 0x92690815, 0x01189509, 0x09c971cc, 0x888cd8a0, 0x0801b020, + 0x09090449, 0x38646198, 0x2980486e, 0xa4a8601a, 0x346c5418, 0x31002385, 0xa1964850, 0xa84c02c2, + 0x0818342d, 0x93260c22, 0x440a2241, 0x7183b811, 0xa132854b, 0x468951c6, 0x60038769, 0x1a128603, + 0x48055144, 0x0541340d, 0x43382414, 0xb2886220, 0x6a0c4826, 0xcb908d08, 0xb904db88, 0x6d52100d, + 0x99a42088, 0x04008298, 0x280c3441, 0x6484610b, 0x27214b24, 0x4e4a0270, 0x102686cc, 0x121003a0, + 0x6409b344, 0x0ab405d4, 0x0686a1b6, 0x88a2224c, 0x02a46458, 0xc6519212, 0x018b444e, 0x22b80d1a, + 0xa35112b7, 0x88089609, 0x61a8249b, 0x060e8334, 0x31a3486d, 0x8c824d49, 0xb004a042, 0x42902282, + 0x50164a09, 0x012d10a9, 0x20142671, 0x22201153, 0x24481003, 0x2adb2024, 0xdba24900, 0x88251989, + 0x65984004, 0xa4908822, 0x87308c20, 0x8019482c, 0x62162d23, 0x252a1a17, 0x60a1a205, 0xe32861cb, + 0x242d2405, 0x8a1b0291, 0x929291a1, 0x226a4328, 0x2c14204d, 0xe34828dc, 0xa6800a16, 0x66623044, + 0x21a45191, 0x24861248, 0x650c0529, 0xd3347222, 0x166a5296, 0x8109052c, 0x5aa86908, 0x8468a294, + 0x8c84108a, 0x0c37420a, 0x054623b2, 0x25249305, 0xd4b41000, 0x311114b9, 0x9109b888, 0x20840103, + 0x426d42b0, 0x30180929, 0xa4480e10, 0x946c6126, 0x82192510, 0xd20404da, 0xa4115120, 0x66a11084, + 0xc9946412, 0x248e5a04, 0x4ad22804, 0x8a8029e0, 0x4466cc48, 0x82489810, 0xd0000509, 0x0071ca82, + 0x080b8470, 0x24804c18, 0xc281d802, 0x4cd8864d, 0xe3300513, 0xb10d0246, 0x40091289, 0x02b68921, + 0x2326a414, 0x70c3b645, 0x001921d3, 0x88510b23, 0x88e21271, 0x53a628a1, 0x200ed106, 0x8c09c965, + 0x82268cc3, 0xa4514ab0, 0x4918a78c, 0x2444211c, 0x1282d034, 0x92102012, 0xc3464213, 0xa38dca48, + 0x6d5a146a, 0x133648cb, 0x282161b6, 0x6051062c, 0x1c476211, 0x3049dc94, 0x8962402a, 0x08292443, + 0x1262d000, 0x0c19a670, 0x08c66512, 0x81118124, 0x24144240, 0x04a98819, 0x22619038, 0x891a1629, + 0x1a22250b, 0x036c43b4, 0x51d94642, 0x2305611c, 0x372e1a16, 0x06620669, 0x13b00d49, 0x2686e408, + 0x2ddb8480, 0x82160de0, 0x322ec9a8, 0x49124324, 0xc2326504, 0x384902a3, 0x014b1224, 0x04492c81, + 0x36885438, 0x8c9ba425, 0x63966442, 0x0042dc26, 0x12040301, 0x1aa608e2, 0x98091243, 0x084c9689, + 0xc38670da, 0x9440e418, 0x41123969, 0xd1148d9c, 0x12260404, 0x80209864, 0x9c1290d1, 0x36829202, + 0x4a18020e, 0x1a146459, 0x104ea200, 0x28c83680, 0x514268c9, 0x22815838, 0x90009588, 0x0c479282, + 0xb24944a0, 0x20230210, 0xc032929a, 0x3070dab8, 0x0851a048, 0x83006a08, 0xa4894492, 0x090b4901, + 0xa4240ee3, 0x34640910, 0x669c920d, 0x924069d3, 0x34668120, 0x2960a224, 0x8a8280a0, 0xb6492032, + 0x2161006e, 0x913628c3, 0x3805c312, 0x1089c630, 0xa30424dc, 0x06620936, 0x441c4962, 0x1885241c, + 0x93295aa2, 0x01894832, 0x0b804921, 0x80601ac1, 0x08122244, 0xd0b22d13, 0xa0200827, 0x8e0b0964, + 0xc1c8650c, 0x06321895, 0x2454248d, 0xa3b64924, 0x3672e088, 0x2c1b2390, 0x0cb1511b, 0x48504422, + 0x8dc13202, 0xd4c0901b, 0x312a1b21, 0x6513a770, 0x92404814, 0x4591c838, 0x02a3408d, 0x18100a92, + 0x186019b9, 0x4808122e, 0xc1068c89, 0x3469a294, 0x41202166, 0x63062602, 0xa804dbc0, 0x30481681, + 0xe3966018, 0x8085a292, 0x9161228a, 0x0a890411, 0x036ac334, 0x4e0ca629, 0x0ac44081, 0x88012238, + 0x05840085, 0x0a484dcb, 0xa8640821, 0x08024510, 0x19980509, 0x87216020, 0x2d230691, 0x5406265b, + 0x0086c248, 0x4cc84024, 0x193561ca, 0x240962b0, 0x69e3c200, 0x5a40021c, 0x13814c36, 0x2453108e, + 0x4c28659a, 0x22921003, 0x6918c809, 0x9b966451, 0x26061384, 0x44a23225, 0x11a285d1, 0x386c0038, + 0x28213540, 0xc2922108, 0x14690948, 0x29a2088d, 0x4142619b, 0x461222c6, 0x90221942, 0x094766e1, + 0x26418a08, 0x2e58960c, 0x03a73119, 0xc3016232, 0x445a4828, 0x83880461, 0x244a0c12, 0x88133082, + 0x246a5444, 0x03603964, 0x0ae24bfd, 0x674716b8, 0x9ef17d1e, 0x39e92896, 0x9c187a82, 0x16a9483c, + 0x86f6e07d, 0xae2bb46a, 0xf5465e98, 0x1e8217be, 0x77c40eeb, 0xe296856f, 0xbdddaf2d, 0xaf6f9518, + 0xdb70e7a2, 0xcb4424c1, 0x88651530, 0xbad10f64, 0x6b2c85f4, 0xa3d74597, 0x19bb3c58, 0xb9501f09, + 0xd35db9da, 0x8a628612, 0xf81e0b44, 0xb49bea5f, 0xc1a52072, 0xf9a19f48, 0x6081b415, 0x51c9bcfe, + 0x10879a3f, 0x75adfd99, 0x6d89396f, 0xb487ffea, 0xb9ef801a, 0x986d4719, 0xf0e7df16, 0xfbb13811, + 0xe7644277, 0xa2705165, 0x3755eef3, 0x99475d87, 0x78cb4c4a, 0x1e4516ab, 0x977faac5, 0x0ab64740, + 0x35194600, 0x44ccf267, 0xfbe0bd0a, 0x1641e7d4, 0x7bf943c5, 0x8eca0289, 0x04b2dd4f, 0xc12d6ac0, + 0x3f9ee061, 0x99739641, 0x7e0231c6, 0x42730c20, 0x37834a02, 0x94db5a56, 0x549d72c4, 0xccf51e4e, + 0xaefa45fe, 0xd3a01b7a, 0x36dda155, 0xe150d801, 0x20762cec, 0x97175e90, 0x3a1940f3, 0xaf1818d9, + 0x21c2d1ec, 0x41814d1b, 0x024cb245, 0x44f63977, 0xd74c7b34, 0x81050af9, 0x12160508, 0x9434dc34, + 0x65c7b310, 0xb1bf5e02, 0x32884a38, 0xb9c9af69, 0x621d4a24, 0x9f0d6d85, 0xad3a149c, 0x43a90c37, + 0x8eac8e51, 0x7a97b7e3, 0x9b250f00, 0xc73ec9ec, 0x4aa511d0, 0xdeb8b884, 0xc9d1774f, 0x574784e3, + 0xff747168, 0x8221518c, 0x7f244122, 0x9c5233f5, 0xa342667d, 0x6f15731b, 0x9f48584f, 0xe73af6d2, + 0x2d69a9c9, 0xe6d5181c, 0x5c7cdb0b, 0x945c42aa, 0xf8eb85ac, 0xa1707d39, 0x2c507bff, 0x9739973a, + 0x08728ffc, 0x043827b9, 0x04a26f63, 0xb891e952, 0x8bb0b60e, 0xb385e4bf, 0xd92c9b56, 0x6f8e83e8, + 0xdf4524a9, 0x6f983475, 0xaa645c51, 0xcaaa012f, 0x29d73f1e, 0x86462607, 0x66238abf, 0x512f1f78, + 0x579f5f6b, 0xf515c56a, 0x4997bd85, 0xa7eb7d0c, 0x09cc93b5, 0x3875e449, 0x3ffa9d45, 0x1fc20d24, + 0xd83df3bd, 0x554363eb, 0x36384968, 0x51b4eeb6, 0xf4594708, 0xa32e4173, 0x9d30802e, 0x0d475b43, + 0x0fbc0002, 0xd3fcb2ac, 0xb2564eb0, 0x448e84a1, 0xff5a1044, 0x23e05fa1, 0x0940b560, 0x19a6fac2, + 0x2b850781, 0x735f0b46, 0xf6869557, 0x4eb3594f, 0xc2f277f4, 0x71bc6362, 0xed1b5f39, 0x7853ab08, + 0xc5205d29, 0x8fa33728, 0x173960b9, 0x5d3bd6b9, 0xa3123155, 0x6387a4c4, 0x63669054, 0x81162c98, + 0x7c627859, 0x9971be66, 0x2d87fa01, 0xcda7997b, 0xbd32a669, 0x558177a7, 0xa40d3a56, 0x599a43d4, + 0x247c4bf2, 0xcb3b05ef, 0x90f69317, 0xcd49e1c3, 0xd0b33657, 0xc2516898, 0x4872db36, 0x8dc12552, + 0xc1cd1918, 0xf18b71b8, 0xdd75615e, 0xe74e1d02, 0x59a70112, 0x0e675c65, 0x3ce9a63a, 0x263f1662, + 0xe34b7ec4, 0x81b15f6c, 0x78150c6e, 0xb2398603, 0x4b359929, 0x2e027fae, 0x75c0123d, 0xf00ad895, + 0x3cd5c6ff, 0xb7ea913f, 0x2524598e, 0xc059a14a, 0x8675010f, 0x643fcfa6, 0x41da8a16, 0x4a449c39, + 0xf83b1872, 0xad691a95, 0xcc496d2f, 0x39c66e85, 0xc18c6849, 0x55a87a93, 0xb4adef69, 0xeb523759, + 0xbd759393, 0x39657266, 0xc2602d5f, 0xff15def3, 0x944dd782, 0x98db2e1b, 0xa1fc32ff, 0xb20d3147, + 0x597bd8e2, 0xbdd34a1c, 0x71f109dc, 0x30c1a84f, 0x933b6625, 0x78e0a87e, 0xe69bfeb8, 0x880e11bc, + 0xeb802880, 0xece8e4a6, 0xf8d15ed8, 0x4eaf94c5, 0xae6f2cd5, 0x22dc2d99, 0x0aaca9fc, 0x9729ac15, + 0x6792c7aa, 0x1b0d6861, 0x2c3bea50, 0xe37fc9fd, 0xb72d2f35, 0x71f306e7, 0xc14c75bd, 0x846e40ca, + 0x3c5ecec8, 0x93a78213, 0x3503a068, 0xe557ba28, 0x58769d03, 0x404d2e44, 0x543ee72c, 0x06d73f49, + 0xf817d8a0, 0xce902ec8, 0xb2e02c82, 0x8961c205, 0x4e46477e, 0xa8d362a1, 0xedd543b5, 0x5e6e3e3a, + 0x1223f1a3, 0x9f4aef62, 0x620424a9, 0xa1cff3b9, 0x2179f6cd, 0xe2576f43, 0x7ddf3c04, 0x0bf4c303, + 0x4fcab9e7, 0x5ddf5068, 0x7f84d49c, 0x3562b69e, 0xb9bb142f, 0xe9ddbd41, 0x0ecd9888, 0x1274ad3f, + 0x6f5212b5, 0xef3263b3, 0x1d0d3e27, 0xaed295ea, 0xb001a479, 0x46e974b8, 0xeeab5d4d, 0xfaf551ee, + 0x311f8ad7, 0xcf204776, 0xe521035e, 0xc8dd332e, 0x799033d5, 0x4c41d4bf, 0x9cd01048, 0x8a718253, + 0x34adfdab, 0xc903f4a5, 0x879129ac, 0xeb1b05d1, 0xe64015e5, 0x4da0e263, 0x1adafe04, 0x8c6327aa, + 0x8eae637e, 0x2b6381d7, 0x4c7fd789, 0x84f7e664, 0x92ce49ee, 0xc8d3446a, 0x82efcf39, 0x4fc6e4eb, + 0x716e67de, 0xb828932b, 0x7284423b, 0xae750905, 0x0836cabe, 0x1603ca99, 0x3bd7c32c, 0x793af848, + 0x454d6186, 0xd8605012, 0x8c2c5a0c, 0x5919aed4, 0x6934674c, 0x3fc2f330, 0x6cc1acb7, 0xbcd5c4a3, + 0x97c18f30, 0xe706ccc3, 0x19391a57, 0x01318c15, 0xd43005c3, 0x2f474395, 0xc0133d62, 0xa6dfbf19, + 0x95a0b401, 0xba9314d1, 0x7a8baf6a, 0x48d1e504, 0xdbeaf12f, 0x47e160d2, 0x4a7f6db4, 0x8598c2c9, + 0x1a26bc48, 0x9d534d14, 0x6097d0e6, 0x326e5ce1, 0x4b4d6a1b, 0xc819dd5d, 0xa3ae0602, 0xf9bd9328, + 0x24bff80c, 0x5ee94332, 0x1e57779e, 0x09a82af7, 0xe168a242, 0xda810e2d, 0x5d8b8d18, 0xf0f815f0, + 0xff0872dd, 0x5e55bd1e, 0x2f8a07bf, 0x824aeedb, 0x2df3e3f6, 0xb7ab5442, 0x59afdf86, 0x7083b466, + 0x040b6425, 0xc2df2924, 0xefa38568, 0x10826caa, 0x8215e630, 0xc995006d, 0x39a10d8c, 0xfc519807, + 0xb72d708a, 0x783bece7, 0xbb7bea32, 0x6bafdf8c, 0x8ebe01b1, 0x3904dd65, 0x984c9bff, 0x182430be, + 0x4e8769cd, 0xd0d79d95, 0x585398da, 0xf2daf7c9, 0x1dbd1db6, 0x75cfdbaf, 0xa9047673, 0x76d35592, + 0x08b3976c, 0x9ffe9c9e, 0x6d4ce67c, 0x2eced30b, 0x1c3cc39e, 0xfd04ef3e, 0x1cd08f15, 0xa3d08bcb, + 0x1aa2ff00, 0x440d9ab8, 0x00df0d23, 0xc5dd0481, 0x3cc6bad8, 0x532f33c9, 0x5823e489, 0xed5ed1c6, + 0xd4ca0d9c, 0x8fbba119, 0x2e487ddc, 0x9e0cac71, 0x7fc9aed3, 0xe5733e8d, 0x7dd3b22a, 0x8a848ad0, + 0x80bc3aca, 0x555d2d3b, 0xb0ac0940, 0x052dc1f8, 0xb206298c, 0x84aee424, 0xc63a4a14, 0xa4694b28, + 0xd7ed1820, 0x7c762f61, 0x18f7cb23, 0xc7a23bdc, 0x8c4d6c51, 0x6eb3e50b, 0xf3d729d8, 0x5996dd77, + 0x7140054b, 0x140f46ad, 0x5f31c2ac, 0x2439bb34, 0x6b70e26b, 0x3a841b31, 0xb2a6ee25, 0xf7cf672d, + 0x5fa7d039, 0xc8a5faad, 0xd437085c, 0x0c26ffc4, 0x5923ea57, 0x8b3c235c, 0x4feb2f04, 0xb3de8e33, + 0xf57c404c, 0x835e8bf5, 0x2f6efb08, 0x25ba6096, 0xd3ab434c, 0x5da8c7c4, 0x314b6514, 0x9f91c85d, + 0xccd06dd9, 0x5c191048, 0x1aff0916, 0xffb63c01, 0x6d8d4204, 0xabbcf65b, 0x3b1d0dc7, 0xfd5b9fda, + 0x711add54, 0x9a75acea, 0x04a44c75, 0x4ef657f7, 0x6fe3923c, 0x41c0ac70, 0xa02fb297, 0x5ec40380, + 0x002022c3, 0xdb5af233, 0x43932650, 0xb686b0d7, 0x5b255865, 0xa617e3d8, 0x2508492f, 0x4170e5e8, + 0xf8a31f87, 0xd268b645, 0xa75d21f8, 0x0761cd6c, 0x8558b93a, 0xb3688e98, 0xe5c878e3, 0xce624611, + 0x57b4f8fa, 0xd16de94d, 0x3c4fef94, 0xdfebede2, 0x3507204e, 0x6d039441, 0xd0036294, 0xfe94817f, + 0xd73d3618, 0x2a77d537, 0xc947a97c, 0x8d385737, 0xb97297de, 0x59070d2d, 0x51017cfc, 0xb13aace4, + 0xeb508669, 0xb3807d9a, 0x6a6e89b6, 0x9caa16a7, 0x20613013, 0x41967541, 0xd57d07ec, 0x6ea79f15, + 0x86d85c32, 0x89eba5e9, 0x3d7ab102, 0x0cf93887, 0x8a08ec69, 0xc898acd2, 0x0d444d8a, 0x29e14193, + 0xc7d1c700, 0x87329f6a, 0xef534310, 0xfb1fe9ca, 0x65dc33bf, 0xfa072418, 0xae4e7d03, 0xff67fbf3, + 0x8eba4ede, 0xa311daaa, 0xb11008a0, 0x4fb0d4df, 0xcf670f84, 0x39181a64, 0xda650353, 0x6e446b72, + 0x5389fb62, 0xa803c68f, 0xc3e2a7b5, 0xadca5371, 0x31d5a16a, 0x431af45c, 0x9f26f2f1, 0x9a427670, + 0x9f6f5c19, 0xc6e54f17, 0xe2c3410b, 0x776051fc, 0xc28289c2, 0x1e87cb74, 0x714f9ec2, 0xbb30b10d, + 0xcda6e099, 0x5adc8e3c, 0x6229909d, 0x5b20bfda, 0xc559df3c, 0x4b29db85, 0x1db6e921, 0x645ee6eb, + 0x88660511, 0x705d40bc, 0x56051931, 0xc28a68d5, 0xdd27d6c2, 0x0f6d865a, 0x5196d47b, 0xdbf2dd1f, + 0x4b532152, 0x0b63cd0a, 0x6e442b18, 0xf892dae8, 0x76df608f, 0x24e18784, 0xb1434655, 0xfbd40f59, + 0x3bccc9c6, 0x286ce980, 0xb6e71dbe, 0xe0d53f71, 0x340981c3, 0x3446f9d6, 0xd3872da4, 0x523f84ce, + 0x61968878, 0xe609d386, 0x900dfda7, 0x8008a53e, 0xd3685d8f, 0xd0effff5, 0x16b2f869, 0x91ea4b97, + 0xa90ee37e, 0x3d040f9f, 0x86877843, 0xdfa9f1c6, 0xbf9f9525, 0xcf39d88e, 0x34fb0f92, 0xef6758ec, + 0x88f75f3f, 0x78cc77aa, 0xcbd6b047, 0xd4b614dd, 0x8a465738, 0xc504ca4b, 0x30b4a639, 0x1eea1630, + 0x00e62ace, 0x29dddf73, 0x89e0793d, 0x6fca5e10, 0xa7bdb7c4, 0xef701b4d, 0xcc240742, 0xb776c733, + 0x1351b8cf, 0xc92c1705, 0xd6ed9105, 0x51565a45, 0x737ecc0b, 0x11019a66, 0x6476bba5, 0x7c888117, + 0x94efe83f, 0xa331e5f6, 0x6404934a, 0xdc2f4bc8, 0x104e922a, 0xdfda32d0, 0x0f399fa4, 0xd38681b4, + 0x4973cc81, 0xf7c7c7f3, 0x4febf0e5, 0x975cbe6b, 0x622d2457, 0xfa4e5cb5, 0x666900b1, 0xe28817ae, + 0xb17966ae, 0xecb90a44, 0x4571ddef, 0xab6f0c96, 0x57ac307c, 0x4be12bc0, 0x9d13c364, 0x67d4fdbb, + 0x305bd0df, 0xd5b3d8d2, 0xed73d1bd, 0x21dc9a83, 0xcddc04a9, 0xccee56d3, 0x72d80f68, 0x715f9d6c, + 0xb1a58322, 0x02d27a97, 0xfbbc4f20, 0x21352b5e, 0xe95f5aa4, 0xa7407a4d, 0xb150dc56, 0xbae995b0, + 0x11d32f4e, 0xfac468cb, 0xcd514ac4, 0x21e0842d, 0xcbdaa4d6, 0x4d8fd43b, 0xd16ccef5, 0xfe1d5503, + 0x59431404, 0x73c31a99, 0x561d6d15, 0x9c405846, 0xb2f94f0f, 0x7cc03c6e, 0xe12ccf28, 0x1b286166, + 0xe7e2844d, 0x4250e8c0, 0x12c56f7e, 0xb965d6c7, 0x3b8cc885, 0x8a17a1cd, 0x24279007, 0xb950eb2b, + 0x343c1d08, 0x5b5f73d7, 0x1594b149, 0x1fc35cbc, 0x3f353793, 0x0b514167, 0xa622d731, 0x57a8ef7f, + 0x1eba125a, 0x0d6db2f9, 0xe138cde9, 0x57f49546, 0x7c8998d1, 0xa7aef903, 0xa41762a7, 0x0a963d13, + 0xfc212914, 0x93626932, 0x728889c1, 0x48b252ec, 0xfa4d5f50, 0x78cd982c, 0xfec1209a, 0xe09f28b2, + 0xecaba3d9, 0x8a95b1dc, 0xe7e6f5a9, 0x7e489833, 0xb4df3327, 0xb7f00593, 0xba8e1b25, 0x070036fd, + 0xe0e303b4, 0x5f781042, 0x7bbcdb5e, 0x3a322265, 0x46306470, 0x4add49c6, 0xd34291e0, 0xfb4004ad, + 0xdbe02aa3, 0x5e911821, 0x12bb8448, 0xd560a5cf, 0xbb15a9f3, 0x4cbf4498, 0xed6f29b8, 0x32f41e73, + 0xa8988b5c, 0x7264ae33, 0xb3862712, 0x4835e9be, 0x80ebe9d7, 0xc2bfa04c, 0x62fd6ae8, 0x3301e2ca, + 0x763fe004, 0xb6ee1330, 0x35599e9f, 0x2ad82d30, 0x905b4eed, 0x403912f7, 0xf91cbbed, 0xc7c01aaa, + 0x396efd6b, 0x402438d9, 0x36eacc3d, 0xe2bd5d28, 0x8329d07a, 0x6ef2f6d4, 0x48f8c15c, 0x303af1da, + 0x3a9f23e3, 0x104ec5b4, 0x088ea42e, 0xefd76952, 0xdb5992a0, 0x541e3cf8, 0x5eec19b0, 0x697de6ac, + 0xf2d6c752, 0x1aa56e96, 0xaa844601, 0x4fe3c7eb, 0x59d5c213, 0x19d88f7f, 0x0ff53ce1, 0x4c811eb3, + 0x3f511769, 0x54606dd9, 0x61b7e5f3, 0xbdc94c4e, 0x3b0e0f86, 0x7c0df944, 0xa9e28b6a, 0xa293afb8, + 0x898509a6, 0xa1bf57c9, 0xa317a7bd, 0x9b4a6689, 0xb48a2f52, 0x9e0f93c9, 0x9a31e88b, 0x1f469453, + 0x8cb4e0d6, 0xf59fe4bb, 0xce20df9d, 0xa71e67c2, 0x2b29c3aa, 0x9cd28cc2, 0x787deff8, 0xa04fdd08, + 0x48aaa846, 0x3afc3ff0, 0x6ccfd4a8, 0x17d491c8, 0xb0ad68de, 0x32705a39, 0x31e22341, 0x286f1194, + 0xd9615ba8, 0x00a9b087, 0xb33c2ff7, 0x987464dd, 0x22102a61, 0xfeefb16e, 0x12df0ef1, 0x78a719dc, + 0x1379a9e1, 0x7c27bfe9, 0x7f75c0ca, 0xc780f4e4, 0xbe158ff3, 0xd471808f, 0x438b77c4, 0x14b4646b, + 0x96599fa0, 0xb3a518b6, 0xd44b5a60, 0x7678db1d, 0xe70d300b, 0x1981eab1, 0x56575eda, 0xf57e55dc, +]); + +pub const VENDOR_MLDSA_KEY_1_PUBLIC: ImageMldsaPubKey = ImageMldsaPubKey([ + 0x269e8df7, 0x7aba50b4, 0x9007232b, 0x73e1bca6, 0x70f68d4f, 0xb436b149, 0x16fe3d2d, 0x8f27f0e8, + 0xfce83581, 0x89ec288d, 0xd19e37f1, 0x3900682e, 0xb7cbbcf6, 0x9a7e2518, 0x37805f35, 0xae002ed5, + 0x3191b7f3, 0x3bd7b0e7, 0x9736328f, 0x7887391e, 0x0e3bf042, 0xdeee7e91, 0x370cb74f, 0x9769c21a, + 0xa612bd57, 0xe5422736, 0x3fcce779, 0xd0dce5a0, 0x4e0ec58d, 0x791f57d2, 0x629ae147, 0xc6472490, + 0x00fb7455, 0x6bf404f7, 0x9bd537f9, 0xe24a9b5b, 0x89678cf2, 0x69f9da6f, 0x430175b2, 0x081d16d5, + 0x71869292, 0xf8d4d533, 0x4adef988, 0x7e798760, 0x3063e46b, 0x98b3fe05, 0xe0cf9e47, 0x4f78a812, + 0xe9448b9d, 0xf563bd52, 0x52addaa8, 0xe201a87c, 0x79fc0dc6, 0x6ada3a38, 0xa8a709df, 0x431d351e, + 0xf0450fdc, 0xd80e0ffc, 0xaca9e38b, 0xfd7cc8aa, 0xd0a26497, 0x5b1ecb9b, 0xea9ccc1b, 0xf6ef2bfc, + 0xb31adf56, 0xc1e062cc, 0xc4f50cad, 0x867afcca, 0xc94c7859, 0x971460e7, 0x7ffbdcad, 0xdd5c7768, + 0x63a99d79, 0xfef1a17c, 0xc862ffd4, 0x0e4618df, 0x2437d1b5, 0x8a1210bc, 0x01e7431d, 0x16c10546, + 0x10cdadc6, 0xe8429099, 0x10339aff, 0x119b6740, 0x4bf3260b, 0xd33f50e7, 0x33485939, 0xe4af4909, + 0x249ca204, 0xe9f07faf, 0x9f511381, 0xa2483353, 0x6ca2b61c, 0xfc238cfd, 0x3b2ce26d, 0x65d9a13d, + 0x8672aacd, 0xae0a0cf3, 0xf8c204db, 0xda0ab573, 0xcf209214, 0x1cca8ee1, 0xd2c5bc6e, 0x2388d3b3, + 0x84e081fd, 0x1e05a60c, 0x2dce455e, 0xc30a3f7a, 0x261d9e4d, 0x64397fbd, 0x429d238c, 0xdc5e08da, + 0x3942c54b, 0x87bddea6, 0x5fe5bcfb, 0xdcdbabf5, 0xa0da6316, 0xe03e64ff, 0xb90810eb, 0x57c1e369, + 0x23a2f52c, 0x1507e319, 0xe87b6b98, 0xc818eaca, 0xbfd11a02, 0x43309ab4, 0xa3239f63, 0x687dd37a, + 0xf7af3520, 0x2cd8aff5, 0x40f0c5be, 0x6cf0ecb8, 0x3c50947a, 0x98cc7c69, 0x8fc9a5ad, 0xef80b98d, + 0x3e8a8663, 0x7c183b62, 0xdc5d417d, 0x914372e8, 0x48964c21, 0xc57e16cf, 0x59cde911, 0x7f750484, + 0xa683877a, 0xa4cb99dc, 0x45223ff1, 0x82d9fe23, 0xc693b90f, 0xe3c860c3, 0x7f133ba8, 0x9d6d0bc3, + 0xc61ca40c, 0x8d38a15f, 0x6602c6f8, 0x6e68a418, 0x6ce8b011, 0xbc7ff68f, 0x28dd4656, 0xf76e7160, + 0x42c9ef38, 0x11ab134b, 0xe5b2378a, 0x6cf5bacd, 0x08fe8aea, 0x988100d3, 0x8c984926, 0xfc43da9a, + 0x8e656591, 0x8499970c, 0x5498354e, 0xbab3ffaf, 0x2fd985df, 0x4ed9a18f, 0xb74babde, 0x4aa730e7, + 0xc4559cbf, 0xe966495f, 0x45ffb8c1, 0x20039246, 0xc28a0371, 0x5a4975b5, 0xcbbf4770, 0x738293a5, + 0x371b980c, 0xdae5a2b7, 0xf696a2df, 0x018da10e, 0x20c59b82, 0xc953ecd7, 0x1bfe0665, 0xd6e36ed0, + 0x40611d25, 0x96baa66a, 0xd63f9048, 0x7c02cc78, 0x3a34d1a6, 0xd37a03c0, 0xa9669ee6, 0xaec236ce, + 0xc8d3a277, 0x65d764db, 0x86aa4b57, 0xc99d122e, 0x3f9a4c7f, 0x87ea35e8, 0xf13dc78b, 0xf7fefc4d, + 0xc5708d56, 0x5e56a97d, 0xe222a7fb, 0x3107dd1a, 0x949309d0, 0x99a66c70, 0xf6feb74d, 0xc015322b, + 0x4864b948, 0x66751f31, 0xf5290273, 0x6520cfe6, 0xebf1b1ef, 0x8ff857cc, 0x4fab7676, 0x8b268983, + 0xc01da944, 0x8ca94ce4, 0xf0da1bb2, 0xcad4c8cf, 0x90eef0c5, 0x9a98edc1, 0x3d0a19f8, 0x6eb1b26f, + 0x34adc285, 0x43aecdd9, 0x3a66729d, 0x39dbc12e, 0x0dc1cb6a, 0x1e9a47fa, 0xa8ebb7dd, 0x3f780014, + 0x1da3f94d, 0x57bca525, 0xf3b9f5f4, 0x4ba731f5, 0xabd725db, 0x2ff49140, 0x624068f9, 0xd0964434, + 0xa6831859, 0xfd7d50bf, 0x8be4f7f2, 0x1ec1810e, 0x6e089baa, 0x2e393f3c, 0x94a888eb, 0x67aec405, + 0xd5330d47, 0x0f0e0696, 0xcd3a36c0, 0xd266fedb, 0x6cfe6472, 0x7d74918d, 0x4411f51c, 0x4deaa98c, + 0x5e749da7, 0x0bb096ec, 0x12a4b27c, 0x87017c69, 0x4d8f6066, 0x7894cbf7, 0x2b646d29, 0xf43c02b7, + 0x573e92a4, 0x839408b1, 0x9511b635, 0x8be4f237, 0x3cf447e4, 0x6a181e77, 0x2a176ad8, 0x4371928f, + 0xac2c0b65, 0x1bbe1e1d, 0x99692197, 0x568e5bea, 0x61f42a44, 0x016bb400, 0x136411a2, 0xf587dd99, + 0x0dad4313, 0x598ed8b7, 0x80bcd8e8, 0x6ebadd14, 0x2d438fb7, 0x40323de4, 0x681b7d88, 0x4c8b169c, + 0xe673ca13, 0x3f75a06d, 0x8bca016d, 0x8147763e, 0xec9e5d71, 0x62599071, 0x94634e79, 0xed41b8cd, + 0x51ad9ae8, 0x13a7f44d, 0xe55de2ad, 0x25729d36, 0x4e905d82, 0xfe3ca46b, 0xb7d49c70, 0x2072a578, + 0xe1799ddd, 0x26fe8855, 0x4c0d373e, 0x32b0fd39, 0x3d149b10, 0xd6583f84, 0xdea304ab, 0x08c14aaf, + 0xe6964cb1, 0xc0b2896d, 0x124e8f48, 0x4ff31ea2, 0x0adfabbb, 0x3b387701, 0xc7061085, 0xa62fc56b, + 0x53861c5a, 0x809efe5c, 0xd220c5f3, 0x0bebe480, 0x50ed7245, 0x0f58a00a, 0x93dafa94, 0x080bf5b0, + 0xa0a9a89d, 0x88e230fd, 0x1b865f7d, 0xcfd51df2, 0x003bb471, 0xef2705a7, 0x38b459f6, 0x57e77f09, + 0x3afca830, 0x33c0fe67, 0x56e83a0b, 0x05dd714d, 0x4597b9dd, 0x9bd68198, 0x7d031040, 0x1a451fa3, + 0x6b9f4fce, 0xe34e7d42, 0x99420237, 0xf344546c, 0xfbb103e1, 0xd138c2e8, 0x74198441, 0xccff4569, + 0x8f490c3f, 0xecffc0d7, 0x23fd6096, 0x38d68b40, 0x673db57d, 0x27d25604, 0x8e0cf8a3, 0xbde312a6, + 0x73e04bcd, 0x490e5675, 0x2fadd7b8, 0x34c14e0a, 0x7cd4e782, 0x3861a428, 0x2a9bfc0d, 0x9158cde7, + 0xf72faa75, 0xf026f0b2, 0x9a16e688, 0x2534a9e8, 0x9f91f85a, 0x3feacb0a, 0x66fce285, 0xb24c005c, + 0x279a3764, 0x9c0e2e78, 0xb8d500d2, 0x438bed47, 0x8af75942, 0x5eeb0cfa, 0xe23881b4, 0xad155670, + 0x81a4e4a3, 0xe27749e9, 0xebdc3685, 0x6b0ea41a, 0x43b067ad, 0x58fd4c49, 0x58d9a9ac, 0xf1e0ef81, + 0xb77a6751, 0xeb1f1976, 0x3ce9e8ff, 0x139e51d2, 0x2ec05b1f, 0x6d87fec2, 0xeac68b40, 0xc994f951, + 0x6bfe458d, 0xa1e7e474, 0xf76e7c37, 0x01d408dc, 0xb2440437, 0x0a1692b3, 0x239d51e8, 0x313b48a9, + 0x16eaf9ed, 0xf169547a, 0xc91e129c, 0x6171fe40, 0xe25b7a2e, 0xa59f74a2, 0xafcb7f66, 0x62a01360, + 0x8339e232, 0xeae1a3b2, 0x3f073e8d, 0x3273213c, 0x3b6951de, 0x3dcae727, 0x65e22530, 0x69a0f4b7, + 0xde475aea, 0x3fa68d34, 0x2bb88dd7, 0xcf46cb98, 0x3c6dd329, 0x3c60b4eb, 0x81a8ea44, 0x8e0e4a80, + 0xf1879696, 0xd422f84c, 0x39a5a193, 0x7ca3e020, 0xc7f31988, 0x0355fefc, 0xa1c04bdd, 0x8cfd5f29, + 0xe74dca05, 0xb6ff5284, 0x3f48af00, 0xaa530a3d, 0xfed2fab2, 0x4b35e484, 0x7afdd665, 0xcdebb6f9, + 0x45efec13, 0x859d331e, 0xc608b970, 0xeb633597, 0x44c3c26e, 0x9a568a0d, 0xaba71918, 0x02e10f20, + 0x4d4fb2dd, 0xa7401f07, 0x5b551090, 0x12006de6, 0x0d44047f, 0x43b4e3c1, 0xa39d0dbd, 0xd4270e02, + 0x29e09590, 0x234a1d58, 0x682ddd00, 0x47c3e898, 0xcd180ff6, 0x41251bf8, 0xe9a89709, 0x851796db, + 0x52a7e2ed, 0x5d94df2d, 0xb0282744, 0xd00d0ecd, 0x9fba8081, 0x225eb91f, 0x80f66548, 0x915b2ca0, + 0x46f35723, 0x90805f29, 0x364a6603, 0xeed8567f, 0x0fbefbfa, 0x47e679e3, 0x683ef48e, 0xb96ac167, + 0x833264f5, 0x4b1abd51, 0x2ba590db, 0xb8287b19, 0xea9b23e4, 0x58eeab92, 0xd2342cb2, 0x37f1edc1, + 0x2d68a1aa, 0x6f485d66, 0x8ef4e317, 0x248f587a, 0x4de5d1a8, 0x71bdb32c, 0x76322f27, 0xac184d79, + 0xc92968f7, 0xb3913f4a, 0x3759ea28, 0x23261bc8, 0x067a18b7, 0x6690fb36, 0xb6ee367b, 0x42dbffb8, + 0x3a6ddddd, 0xdb7c4453, 0x6c64c0bd, 0x2c6777f8, 0x261c5b27, 0x87433e9e, 0x51c07e9f, 0x4e705df8, + 0x033d2fa7, 0x68bc8112, 0xdb53fc16, 0x03a07bb9, 0xaac31838, 0xf2f68ed9, 0xaeb0be02, 0xe3e2ceb3, + 0x0d2151d2, 0x7b936751, 0xd77e33a6, 0x5e4b1118, 0x1c42fd08, 0x90df3162, 0x069bdacf, 0x6a5c6bee, + 0x98585c05, 0xbd4848c5, 0x7ef13eb3, 0x8f0b07cc, 0x96b13cd8, 0xf1b0f3ec, 0xd6a10833, 0x51f29825, + 0x81870631, 0x68cf7e36, 0x775beabf, 0x162626bc, 0x1471682f, 0xd05b94ac, 0xa320c84c, 0x708e92de, + 0xdf83e5b5, 0x71cbc72e, 0x3b40451b, 0x24c38789, 0xbdd151d6, 0xfd90d366, 0xa5f189c7, 0x592b98aa, + 0x17da52a6, 0x35449ef1, 0xd3d0dc21, 0x18415c6c, 0xa57bb036, 0x3f20c044, 0x84263084, 0xe2dc4151, + 0x21f9187d, 0x41eafbf2, 0x58e9eb85, 0xf34bf785, 0xf40f61c4, 0x74bb4250, 0xfbde9cc6, 0x244cf564, + 0x0114e3f5, 0x5be304c7, 0x6eb6c553, 0x8506d71d, 0x1090a943, 0x2504f406, 0xba1849e8, 0x3b7f5078, + 0x58f64fe4, 0x21c6df4e, 0x468f012f, 0x28112010, 0xff036d9a, 0xe3486e08, 0xe637d14b, 0xbd8efc71, + 0xb31e945b, 0x11ed4143, 0x5e674aa9, 0x730be9ac, 0xe9474691, 0x99abde87, 0x9aa5e920, 0x4d8aee97, + 0x40ebdf73, 0xb298c6f5, 0x6c3aed71, 0xd1196e7e, 0xc99af8ea, 0xfb220a4f, 0x3016f1f4, 0x4bcc3502, + 0x1aa4f8af, 0x79ebe6f3, 0xee8514da, 0x1cac5cb4, 0x3dfa4f4e, 0x5ca2f290, 0x273fbb1b, 0xd6bf3600, + 0x99ce425e, 0x936306c5, 0x92519add, 0x467460df, 0x48ed0bb4, 0x421a94bf, 0xd165e8ac, 0x6e727152, + 0x85cd139e, 0x01ee823a, 0x5ba35985, 0x4bac6f60, 0x33bcba6d, 0x2f2238be, 0x12d15e88, 0x271b99f8, + 0x594ead7d, 0xccea9a68, 0x1826af29, 0xf48ccdaf, 0x8ce423e8, 0x83d76f32, 0x59d57201, 0x82221243, +]); + +pub const VENDOR_MLDSA_KEY_1_PRIVATE: ImageMldsaPrivKey = ImageMldsaPrivKey([ + 0x269e8df7, 0x7aba50b4, 0x9007232b, 0x73e1bca6, 0x70f68d4f, 0xb436b149, 0x16fe3d2d, 0x8f27f0e8, + 0xfa8862b8, 0x40f4e19d, 0x7f348990, 0xb1a6e2c2, 0xf4eed150, 0x599ba9b8, 0xfe694524, 0x6e0f210c, + 0x550a089a, 0x908e85fe, 0xe2fa6b3f, 0xf5a7a85b, 0xb0cac1b9, 0xbdde9243, 0xd4e9d13e, 0x829b7301, + 0x080924a8, 0x0d9ba6d0, 0xeb2b53ec, 0xbe8efd64, 0x4736cd19, 0x51d4875f, 0x34ba4165, 0x78243a67, + 0x41268e53, 0x8488e234, 0x22041609, 0xcb1232cb, 0x126a5c26, 0x08103732, 0x1b319213, 0x9388cab0, + 0x6d903466, 0x838625a4, 0x160014a8, 0x4584a011, 0x01476e98, 0x16061b98, 0x80134430, 0x11050ac0, + 0xb804c3a2, 0x881a4772, 0x40b40402, 0x37529a88, 0x4484c44c, 0xe0324a22, 0x858d0407, 0x1024200d, + 0x8012920b, 0x4728cc02, 0x8103a610, 0x42048a08, 0xc211d328, 0x4ca1c611, 0x08b68000, 0x92912180, + 0x08ccb669, 0x98b4851a, 0xa2681925, 0x32911429, 0x1b422804, 0x10029a80, 0x00cc1880, 0x08985062, + 0x486c0014, 0x40920024, 0x02a07114, 0x91101834, 0x2a218570, 0x8ac82d0c, 0x83882311, 0x05013980, + 0x50b48c54, 0x12908408, 0x2c932440, 0x23a64480, 0x864c4aa4, 0x6089026a, 0x11452a00, 0x98411496, + 0x2c614288, 0x92984949, 0x442d41a4, 0x49a09871, 0x24a30058, 0xb0685204, 0x8460a410, 0x48864424, + 0x92301920, 0x695ac085, 0x54805008, 0x357281b2, 0x09124392, 0x22110013, 0x245194a2, 0x6158400c, + 0x991089e4, 0x9860c200, 0x72021610, 0xa3248c04, 0x020a0a45, 0x2a930211, 0x19266ac0, 0x98848c24, + 0x51214051, 0x002086cb, 0x12041105, 0x1123236e, 0x59a6655c, 0x08442302, 0x70cc8251, 0x2427649c, + 0x06690c35, 0x6502116e, 0x232672d8, 0x120c0217, 0x49c13488, 0xd4984950, 0x302d0429, 0x681b976d, + 0xd2c028d9, 0x1890c128, 0x8ccb8849, 0x83002c04, 0x122a1a14, 0x30211584, 0x48120882, 0x9261caa2, + 0x8124130a, 0x52422da3, 0x02880cb3, 0x10c2a245, 0x9c308420, 0xa70421c5, 0x451a4961, 0x8010641a, + 0x226c9216, 0x4a114846, 0xc2845124, 0xb70c0034, 0x6a4c220a, 0xc0402291, 0x4042e032, 0x0c53b810, + 0x40b48189, 0x3832d1a0, 0x108c306a, 0x58984da2, 0xb00c82a8, 0x61a22270, 0x01194c22, 0x156993c6, + 0x01a39669, 0x99b4104a, 0x420cd480, 0x911b3044, 0x53a20de4, 0xa40451a4, 0x8d0ab985, 0x02256914, + 0xa90dc906, 0x7183b468, 0x603852cc, 0x04050180, 0x4c04a56d, 0x9a289104, 0xc250c1c6, 0x4813178d, + 0x14025294, 0x344d1c07, 0x0d53a88c, 0xd0928161, 0x2085e426, 0x61434048, 0x00360590, 0x98615bb0, + 0x8c923884, 0xca1044d4, 0x96882144, 0x29883605, 0x9c940cca, 0x9288dbc2, 0x8c413090, 0x2032620c, + 0x4332c890, 0x8850940d, 0x04219261, 0x14110a25, 0x409c406c, 0x1837040a, 0x292a13c1, 0x65183948, + 0x24488284, 0x36645214, 0x61023365, 0x22238cd2, 0x046a8232, 0x0a212524, 0x20066c1b, 0xa230e2a0, + 0x8de38288, 0x2480605c, 0x88642024, 0x61808804, 0x0886400b, 0x407013b0, 0x0dc81866, 0x8a160499, + 0x86646432, 0x26984431, 0x8c946918, 0x492d1436, 0x26111924, 0x10296d5c, 0xc4880436, 0x451c3489, + 0xdcc689e0, 0xc60403c7, 0x6dc8b409, 0xa3b6609a, 0xc28024c2, 0x09e3300a, 0x8a988c00, 0x01700136, + 0x82580668, 0x21940c20, 0xb3109cb8, 0x10a1348d, 0x404069e2, 0x8409e036, 0x80511046, 0x032680a0, + 0xa28564b0, 0x24184769, 0x1c352a40, 0x184a0a47, 0x8d919628, 0xe2060ad2, 0x42282444, 0x8859c86c, + 0x89102e24, 0xc8310987, 0x28932060, 0x80208e89, 0xa60d4214, 0x0604148a, 0xe1866ddc, 0xc0011c97, + 0x209c102e, 0x24034518, 0xb42c1a96, 0x2422024d, 0x4ab82009, 0xb24963a4, 0x2c54b450, 0x82a404c1, + 0x22304004, 0x2159c241, 0x18873149, 0x448d9494, 0x6c1b2252, 0xa3a04c4c, 0x268c12a8, 0x0c1b0840, + 0x43440492, 0x286c0346, 0x82411430, 0x8c3232e1, 0xb6702299, 0x89824245, 0x4412811c, 0x01109288, + 0x8493c891, 0xa0482dcc, 0x30401a35, 0x50a00862, 0x09323159, 0x32500c06, 0x6400354d, 0x2112269c, + 0xa46104b4, 0x9002086a, 0xa0328291, 0xc8401931, 0x0e402432, 0xcc424c8a, 0x2400cba0, 0x68512491, + 0x59a67160, 0x822c2493, 0x0ddc204c, 0x0ba06921, 0x292a9b94, 0x908b8409, 0xc386455a, 0x46644882, + 0x51e1a445, 0x58c4089a, 0xb0080b29, 0x0089a089, 0x94064043, 0x14855b10, 0x29d18690, 0xc928529b, + 0xc0681ba6, 0x0863a240, 0xa4162993, 0xa62d1206, 0x81a20852, 0x99120e41, 0xa009e018, 0x61d0b061, + 0x1a368680, 0x24014936, 0x02a22888, 0x08262c10, 0x2260a326, 0x80932888, 0x20902c22, 0x24600414, + 0x4183c085, 0x5482209c, 0x086d1c83, 0x91811001, 0x5a366018, 0x9790dc16, 0x29d33031, 0x1847454b, + 0x8225e332, 0x2ccb3804, 0x08c54510, 0x02450025, 0x0920a328, 0x1b452500, 0x014c2418, 0x080c2265, + 0x51384612, 0x8090c036, 0x8e509885, 0x21a04c12, 0xc4096146, 0x62a21812, 0x0c311098, 0x444050c6, + 0x6903296d, 0x22c86920, 0xb1096180, 0x6880c621, 0x04c92d1b, 0xa70921a4, 0x4523132d, 0x59382c08, + 0x8671d812, 0x714cc88c, 0x14212641, 0xa4911396, 0x7012b581, 0xa3264298, 0x32689b12, 0x919a368d, + 0x62b82192, 0x008624a0, 0x8842b60c, 0x0c300a18, 0xb4450a01, 0x2a632211, 0xa4062518, 0x2001dc12, + 0x8a1a8889, 0x99240501, 0x324ee3c0, 0x89589444, 0x82484019, 0x3284c986, 0x71ca2690, 0x41324a94, + 0xb400e1b4, 0x80a4c06c, 0x02264c5c, 0x22028246, 0x80e1b44d, 0x59c48141, 0x8830c138, 0x70081791, + 0xc612ae0b, 0xb51a1d22, 0x640751f8, 0xf9525ee4, 0x69e86615, 0xe1a705c8, 0x9272010d, 0x4296f12e, + 0xf0f910ab, 0x255272ba, 0x00aedc7e, 0xce02a0d1, 0x6ed3e27f, 0xed9bc0e9, 0x212057f1, 0x77660d97, + 0x0b35d82c, 0x39875173, 0xae5b688a, 0xf9965da4, 0xfb108722, 0xf270627b, 0xace5bf4a, 0xfd649844, + 0xaa1fe1c4, 0xc33667dd, 0x2b7510a2, 0x8542d095, 0x50825e30, 0xaacc72e2, 0x97e916d3, 0xe6261c79, + 0x21cd19ed, 0xcc19f7c0, 0x2e0c00b4, 0x1697f640, 0x9ccab09c, 0x4fd43be6, 0x6844e028, 0x002f1db3, + 0xeae74a26, 0x78cee3c4, 0x2964149a, 0x81115052, 0x055fcad2, 0x3e9cd01c, 0x1f049edc, 0x4fe5b277, + 0x29b2eb67, 0xdb62cef1, 0x880a1372, 0x2a048776, 0x63981a6e, 0x65356732, 0x6345f799, 0xf4234d69, + 0x009ca1b1, 0x700454f4, 0x2f6acd6c, 0xfc461e03, 0xd4e44c51, 0x03471d4b, 0x6705fbae, 0x5d4d14c7, + 0x691f105f, 0x09ea02ba, 0xe173fa35, 0x4f2396d9, 0x1408ceed, 0xc48949fe, 0x9ad5d1c2, 0xc3bc8105, + 0x8f4de3fa, 0x195f3909, 0x885ba6f9, 0x9be8a20a, 0x91e8c891, 0x2681ffc5, 0xd748c84b, 0xdb29ef3d, + 0x535c74ee, 0x9c0a44a9, 0x1a302ac0, 0x14adf27b, 0x6f3e83c4, 0xed9fa325, 0xa3ea5f66, 0x255a01ab, + 0x7b6d4d41, 0x2b42d33a, 0x6da5aaa7, 0x23b8c21c, 0x106e62f6, 0x4163c372, 0x65287cc4, 0xf59f105e, + 0x1c8bb9b2, 0x008eb61c, 0x44b7b254, 0xc4bde2e4, 0x537c39ef, 0x4912b0fe, 0xccaf21be, 0xb128291c, + 0x4c20de6d, 0xb458d648, 0xf5b53504, 0x3889cab1, 0x8d4365fd, 0x68968788, 0x839504a7, 0x8ddbb65e, + 0x74a68fc3, 0x31eba2d1, 0x4f5d2dc5, 0x4eb0236b, 0xd8e1ee00, 0x490fb31b, 0xc6c4379a, 0x66d865a7, + 0x655f4c6a, 0xf09304cd, 0x101a156c, 0xeb9b0231, 0xfb24d143, 0x57629a0a, 0xb0c30ab6, 0xb54274fb, + 0xc03d818e, 0x7ae789d4, 0x156974fc, 0xdcbc657b, 0x54339012, 0x322a8a4f, 0xdd47ae85, 0x8f6a1bda, + 0x145eec07, 0xe5bf58f1, 0x92869b38, 0x2d5df4b4, 0xc90a784a, 0x76ef14eb, 0x92f50830, 0x9689f442, + 0x55425d97, 0x3d5651cc, 0x3d4d1b7a, 0x11070b61, 0xba61429b, 0x725281e3, 0x1629554b, 0xb650f242, + 0x79ad3d08, 0x8e6b9bf9, 0x2d8c7c76, 0x3f05b206, 0x7e732163, 0x3e43d2fc, 0xb26f4268, 0x28609361, + 0xfa201b8a, 0xbf42691a, 0xef8751b0, 0xa2ae8705, 0x6417e136, 0x2f602020, 0x66a42c28, 0x5e4710e8, + 0x1af3822f, 0xce1c6c14, 0x34efc7ae, 0xc0eec05d, 0x8cba6ca6, 0x943624b6, 0x0d06ec26, 0x65c767c5, + 0x72c950ba, 0xc386df4a, 0x6f973653, 0x35044245, 0xfb484510, 0x772941b8, 0xa8213632, 0x59a634b1, + 0x0d816788, 0xd05970e9, 0x769fd7b5, 0x5f25a453, 0x5b0a130e, 0x2753f540, 0xaf4bec80, 0xb7465239, + 0x02ca06bf, 0x8c5bd29d, 0x1eb4c67d, 0x7d64e33f, 0xdfe04ffe, 0xa08a5fcb, 0x40e4434f, 0xcf75f231, + 0x221cefc0, 0xc36cb6d3, 0xd0ea2be9, 0xaac0e9a1, 0x50833d21, 0xcb0cf2d1, 0xf1ff1a9c, 0x0781dd8a, + 0x76b40b56, 0x134b2840, 0xec7ecaee, 0x0cc7f1e8, 0xd3ba8edc, 0x983ba589, 0x6b1aa4b9, 0x3dc3ef50, + 0x04dfbdd5, 0xf87949f8, 0x9822c1ef, 0xff58cfea, 0x59338078, 0x6c496687, 0x9e9188cd, 0xa0e62946, + 0xdc766feb, 0x6e937d53, 0x143464bb, 0x2279c052, 0x80e72cc7, 0x1e461338, 0x64c4f70b, 0xaae9151e, + 0x248df566, 0xf14c9255, 0x36ddb73b, 0xe5333a1e, 0xb8862cb5, 0x1bc32733, 0x8806be2e, 0x91438582, + 0x8b52fec3, 0xb72ae8ee, 0xc760c818, 0xa4dd7e49, 0x68c02692, 0xff376251, 0xa29af0cb, 0xb63ef0ef, + 0x15a8b420, 0x70b81c9d, 0x6996469a, 0x52d738f7, 0x95d60679, 0x600ad5d6, 0xcd4d8f6d, 0xd980168b, + 0x2b7913fd, 0x92a19ed8, 0x91e20cb6, 0xe0470998, 0x61c806ad, 0x2cb4ee4a, 0x7b7ba4ae, 0x0d6f18eb, + 0x2c2a5279, 0x3ea28e15, 0x2fc726a9, 0x161a7bfe, 0xc588cc15, 0xa57f459d, 0x100911a5, 0x52b4d252, + 0xdd48cc91, 0x9899500d, 0x50f1ddd8, 0x4cfaf759, 0x4cb3c17c, 0x3083507e, 0x18881025, 0x5faf45f4, + 0x0f8532dc, 0xc7cb4dfc, 0x5a453f55, 0xd9170056, 0x3e7ba2cf, 0xd0a7f6a1, 0x60827d52, 0x0da8fd6c, + 0x66d0f7ec, 0x092e20aa, 0x44d33fff, 0xc7ca19ac, 0x4a060a68, 0x2b5479e1, 0x018c4e68, 0x724cef06, + 0x519bac9e, 0x737bae95, 0xf8816dff, 0x26c379cd, 0xcfd60ab4, 0x413de7bd, 0x94bd4d0d, 0x855226a1, + 0x75744ef1, 0x939f505f, 0x05e7beee, 0xee74237f, 0x8201ea98, 0xed8d57e3, 0x878a5d47, 0xaedafeef, + 0xba854333, 0x1ef5d85a, 0xf986c474, 0x2582b433, 0xa96aec58, 0x2078c899, 0xf4135e05, 0xb1837f34, + 0x52ed63d1, 0xb0f5cff6, 0x6af64860, 0x4145490d, 0x88ecfa2b, 0x34112084, 0x660734ed, 0x3d11ff6d, + 0x5a7bc1ea, 0xc4d95bee, 0xc4876dba, 0xd7899855, 0x257d1ad8, 0x30003d3b, 0xec592fe1, 0xf3ff23c1, + 0x3ac6326e, 0x413936c5, 0xe7c7ffe0, 0xec3a11e1, 0xc38fbcb5, 0x0f198825, 0xd1bf3d50, 0x0e07706b, + 0x00b0ba06, 0xb0534a40, 0xb5f74f28, 0x34d99a0c, 0xd992a873, 0x796460a0, 0xd24aa8bc, 0xf4c741f4, + 0x41ec8338, 0xb5f6aae0, 0x4e7b02e3, 0x608002a2, 0xa13265aa, 0xda26eac9, 0x0258f1d0, 0xfe218d91, + 0x2a6a0ccb, 0x65b54414, 0x40b1003a, 0x4d2c832d, 0xb4f70f26, 0x84776095, 0x18a13a95, 0x6122dadb, + 0x0f7991da, 0x88ef6759, 0x8d181a52, 0x04c40c61, 0x0e4e534b, 0xc7c8b23e, 0x23b06705, 0x052b9149, + 0xb789ab0b, 0x526f22b8, 0x1547bdc2, 0x959a298f, 0x0523b7a1, 0xbebc341b, 0xe3539293, 0x76abf3e7, + 0x9dc25384, 0x635163d2, 0xf128f16b, 0xa797c121, 0x8974de93, 0x4d600c72, 0xc0f87e6a, 0xa2d1d43a, + 0x9ca5d09e, 0xaea2145d, 0xe49cc0bc, 0x4a1ea5cf, 0x9f2cbbfe, 0xf558af8c, 0x882d1d9d, 0x9b7d9ca4, + 0xc2881033, 0x0e3c2dd8, 0xbf3f824c, 0x6be302e1, 0x008db935, 0x54ef06e4, 0xbba30df4, 0x905d627b, + 0xa977be2a, 0x39b6402a, 0xac281c84, 0x6ce8d78a, 0x25cfcbc0, 0xc0937971, 0x12281306, 0x00c30566, + 0x5b3fea5d, 0x2d94d0f2, 0xc60daa5b, 0x8cea7e05, 0x25f38bca, 0xd3a058b7, 0x286ab55b, 0x465222b9, + 0xe1f6aa9e, 0x24f7b314, 0x76c163d7, 0xe9c98a8f, 0xede3ad22, 0x34b8dc25, 0xdc0fe020, 0x76362263, + 0x748f35e4, 0xdb45f9c8, 0xb6267791, 0x8b8aaada, 0x537059b5, 0xe3ed1488, 0xb9b50869, 0xc0e4b43c, + 0xb69ffa4d, 0xf541703a, 0xe27d90fa, 0x166e1106, 0xc4ef7a55, 0xf30a300d, 0x2b451408, 0x6e7ac2c6, + 0xec0c03c8, 0xfa21968a, 0xdd819299, 0x508084f5, 0x6889b09b, 0xfc96f47f, 0xbaad9de2, 0xb4f787c6, + 0x71e725fc, 0x669393b5, 0x08c96dcc, 0x6251255d, 0xca5c8bb5, 0x227eb4c9, 0xfdd3a8a5, 0x2fb38c99, + 0x283c534b, 0xe87b3b0a, 0x70f7dbc4, 0x13e2719f, 0x4e9b8c2f, 0xaa451b43, 0xd6719115, 0x881cb619, + 0x377f273b, 0x3140d1d6, 0x198ba618, 0x5fe349da, 0x76cc7024, 0x5b2a517f, 0xc19cf9e1, 0x3a12f0e5, + 0x2a27ef32, 0x1f732c1d, 0xee360263, 0xa7a0c9a0, 0xdda3e291, 0xb6a97489, 0x3e2c8f90, 0xb8cfd16c, + 0x46da27b3, 0x9703a9ae, 0x92ea676a, 0x647a07ba, 0x805435ba, 0x6abdedaf, 0xca797035, 0x24406348, + 0x14581130, 0xf2776850, 0x62b1b1dc, 0x691d75ef, 0x804040ca, 0x0c2bc8de, 0x74a829b4, 0xfe55f26c, + 0xf35a1aa2, 0x5356f0ad, 0x6387ae83, 0xd32f3375, 0xb265a299, 0xcd557285, 0xce3a1526, 0x7bb737bc, + 0x16b0e27a, 0x09eb403d, 0x90ccf09a, 0x4407cc1b, 0x7b90d172, 0x8a9e19a3, 0x7741dbbd, 0x25cbb763, + 0x800bfaed, 0x4641a537, 0x7d7c4ac3, 0x10fbb6e0, 0xaa2bdfb2, 0x2c17a5e6, 0x77cb938a, 0xd9d0e07d, + 0x9f125302, 0x3285fec1, 0x655eba71, 0x1593c918, 0xbdda715f, 0x43201244, 0x1bb95399, 0xc2997e81, + 0xf564c224, 0xb3eecac6, 0x646f1dc8, 0x7dda778b, 0x1cc0bfc7, 0xf3176577, 0xd0f42ad2, 0xe5921b63, + 0xef2c335e, 0xa13d31d1, 0xc17ee638, 0x91599137, 0xcd23856f, 0x6e569405, 0x7cc0de77, 0x7f233e70, + 0x29eb7172, 0x51aa9104, 0x37edb985, 0x1d1c176c, 0xfb68c51c, 0x0f3a9c16, 0xd94c0ada, 0x63094959, + 0xd17a290d, 0x0efb2ac1, 0x541c6692, 0xda9dbf15, 0x88f009a0, 0x5b47b440, 0x46ae4239, 0x9ad7c2c8, + 0x01311afa, 0x6823240d, 0x47e5b5b5, 0xb6d38c43, 0xdc88092f, 0x9dc9c999, 0x4e84284c, 0xc9b18d56, + 0x69f37deb, 0x9775b6f2, 0x5a4852ed, 0xdbf21f1a, 0x5ebda774, 0xfad76f85, 0x4280c264, 0xd92adaa8, + 0x8665efcc, 0x5467337d, 0xc786338b, 0x521c0c83, 0xd5f0da58, 0x5dd0157f, 0x520eab0f, 0x79f33224, + 0xa34dc094, 0xd58cabd8, 0xf44f6631, 0x888ce19b, 0xa8b8e96d, 0x24377eee, 0x504bc979, 0xe5c4c9ba, + 0xefd0bcef, 0x745fa328, 0xe53dbf5a, 0x451f97f2, 0x56d66528, 0xf652d256, 0x22917f51, 0xb1f56068, + 0x47285d8b, 0x278384a6, 0x3ff6ec35, 0xe0503bf2, 0xede9d536, 0xb946dad3, 0x73e9e404, 0x796f4c5d, + 0x25084762, 0xc80a08c2, 0xed5f1276, 0x12dfa63d, 0x0ec925ed, 0x696dff9f, 0x23e30e95, 0x7d834063, + 0x76a06406, 0x7c263a71, 0x3e441f60, 0xeb93d99a, 0x902a946d, 0x94e4068d, 0x508fa1ab, 0xc595c80f, + 0xf9132977, 0x33494fab, 0x3123e06a, 0xf4a90d1c, 0x4e2e17a6, 0x26ae68e6, 0x280a5bc2, 0xa641b4c3, + 0x93886e78, 0x3f373dfc, 0x871f386e, 0xdd14815d, 0xe5792ef0, 0x8d256aec, 0x2df7d95f, 0xdbb6b689, + 0xf51074da, 0x20244c43, 0x31ea7959, 0x3a2e2549, 0xfff8f54d, 0x48cef4a6, 0xf1b039a9, 0x7f670499, + 0x565fc4fa, 0x4a07c8aa, 0x3801516c, 0x1bc346b5, 0xc045b6ec, 0xc2455862, 0x1fa99298, 0xd91313d1, + 0xf6940660, 0x8b51aea7, 0xf639701a, 0x87d154ce, 0xe43b321a, 0x3c4f93fd, 0xd7bc740d, 0x211f32b2, + 0x910e7a68, 0xefd7a7dc, 0x105b6ac3, 0xe959309e, 0xa85d0837, 0x59aecfd2, 0x33ce8c25, 0xcf1fdf32, + 0xe65dcbc2, 0x868becc1, 0x1094251e, 0x5120f7fb, 0x7e8ff046, 0x105ebca4, 0x0cd7b0ce, 0x70a1af93, + 0xf3b7da72, 0x51c77daa, 0xb8aa15e9, 0xfaabbdc9, 0x7ce6d67d, 0xb818bc0b, 0xde45f9ea, 0xce04a526, + 0xd05a4e60, 0x71965def, 0x777abd3c, 0xdc21ff19, 0x358fe316, 0x47db5f62, 0xb47a7462, 0x42aedb05, + 0x7777cfc0, 0x258974d8, 0x366ef87f, 0x2b014015, 0xd21bfc3c, 0x41a778c9, 0x24fa6d63, 0xaafcc288, + 0x97038139, 0x46ee7de8, 0xe294227f, 0x9c12cd89, 0x9ee775bf, 0x10db2257, 0x5f9302af, 0x27f31697, + 0x6111c0cf, 0x141ee6dd, 0x22658241, 0x24fbfd4f, 0x11d6ce28, 0x10285f13, 0x2896b443, 0x852ab04d, + 0xc4856c3a, 0x362bbec7, 0x49c25ee1, 0x6990cf39, 0x61a3c85b, 0x98207cdd, 0xbc027307, 0x0f80f6c0, + 0xf7410772, 0x4fee263c, 0x0bab0e97, 0x7a7cad54, 0x82b94496, 0x8d3c1d0c, 0xab45b83e, 0x642487b8, + 0xe1027734, 0x4fb9f81d, 0x0bb748e6, 0xa46a749f, 0xd7fe6250, 0x2801a758, 0x3d089e6e, 0xe82888b6, + 0xec66405d, 0xb28a0a70, 0x878062ec, 0x02766752, 0x8fc182e3, 0x9aabcffe, 0x5b0c0734, 0xded8110c, + 0x1fe632f6, 0xd68aabc1, 0xdc8f6542, 0xedef8757, 0x1227cdae, 0x31cc37a2, 0x1758b71f, 0x9da2eaf8, + 0xe30e5c09, 0xac97c8a2, 0x80eaaba3, 0x86f81900, 0xd3578a77, 0xd60c3d81, 0x7e9af895, 0x00703403, + 0x9771143d, 0xf7dee957, 0x0a973f6d, 0xebe88690, 0x1f049238, 0x2c086b1e, 0x3c93b42f, 0x2e7aec15, + 0x49e73060, 0x094c147e, 0x73999fb5, 0x928195c1, 0xcf4649e4, 0xdbf861de, 0x3d67405f, 0x7c80b528, + 0x7165e82f, 0xb9700458, 0x87970919, 0x5bb493c0, 0x443fd292, 0x8e73a7a2, 0x19891e10, 0xfb0afd40, + 0x85cbae77, 0x7ce68099, 0xebe21a69, 0xb910fa20, 0x70b2ed62, 0x96007d2a, 0x35192dfc, 0x660d1372, + 0x08e13960, 0x91f71fb7, 0x5736d571, 0xa22177c1, 0x9e37f19e, 0x55ca9e18, 0x72d91fb7, 0x506fcae8, + 0xca9b6baa, 0x6bb6241b, 0x0d61cad5, 0x12beb533, 0x29e72209, 0x859cd3fb, 0x5ce26915, 0xce87a861, + 0x8e326ef4, 0x8d4cbae3, 0x6d696056, 0x4f53a4b4, 0x3443375d, 0xa853ef27, 0x3df97b9e, 0x2b40980c, +]); + +pub const VENDOR_MLDSA_KEY_2_PUBLIC: ImageMldsaPubKey = ImageMldsaPubKey([ + 0x07c83c99, 0xdc33f5d9, 0x6e0ecc2f, 0x84af5046, 0x6c03db81, 0x296c5f6e, 0x5c6c880d, 0x75764ada, + 0xa342b4a7, 0x10873e1e, 0x623b91f8, 0x63e130ae, 0xfa6afaa4, 0xb6e10e79, 0xa894c04b, 0x5b830f54, + 0x6e90b4b0, 0xd906727b, 0xe2556487, 0x571042d2, 0xa3ab6f5e, 0x0823d2d1, 0xc6f508a5, 0x546c1f0b, + 0xb52d5af0, 0x10b607fb, 0x24683dc6, 0xfd72006f, 0x583751db, 0x07a3050f, 0x107905f0, 0x1491b1af, + 0x01edc645, 0x3c76205e, 0x7ae33aae, 0xc7dfb3d3, 0xcb11d9a8, 0xcdb40f6d, 0x3c2fa4bc, 0x3585a211, + 0x8cbcee84, 0x07f7b04d, 0x93be263a, 0x93c67ab3, 0xc50131a4, 0x95808ee3, 0xae413692, 0x895f1e23, + 0x4d086c0b, 0xa0c70d4e, 0xf8d6a98c, 0xc8594755, 0xaeda7243, 0x4af3a7b8, 0x4f602e78, 0xb49db365, + 0xe81fef63, 0xb617d6e6, 0x92cb2a57, 0x170b5462, 0xf2748fa6, 0x65e2610f, 0x1b13eeab, 0x9b140955, + 0xd1b22c0c, 0xb494f85c, 0x1ddc3806, 0x694899d3, 0x4675494c, 0xf022233e, 0xf12fffb6, 0x4c15e927, + 0xfba1b9bc, 0xa7d8ea42, 0xff6a4c8a, 0xc67257e0, 0x3c2be8db, 0x9af95974, 0xb9540d69, 0x1576aa2a, + 0x53fab7fd, 0xd05226e6, 0x8ed640b1, 0xe22d142b, 0x396e4351, 0x27509b36, 0x11f38bab, 0x8a7e894a, + 0x142501d2, 0x4377348b, 0x2065aa1e, 0x71020016, 0x5a8cf2cb, 0xd3ca7945, 0x62579051, 0x3c8e3739, + 0x6718f26b, 0x8422e75c, 0xfb7c7c08, 0xfd42c3fb, 0x75cccfbc, 0x08346b17, 0x9973d63d, 0xdb71e209, + 0x07d51bbc, 0x74d2af89, 0x9916b8ec, 0xfdbba63c, 0x8f0baab3, 0xd268fd2f, 0x4651c8e3, 0x1853d56c, + 0xb2da7a1c, 0x1853406d, 0x9083a417, 0x2188e628, 0xd8fa0f9c, 0x691b7039, 0x347b205d, 0x582e7ecc, + 0xba5b85dc, 0xdc758531, 0xa6ea8e06, 0xd94298a7, 0xb3fc738b, 0x586a639f, 0x3c55bf0b, 0x29943634, + 0x734356d4, 0x3c09e30f, 0x6d30d1a5, 0x8114f475, 0x54169efc, 0xce6ac496, 0xf691bcdb, 0x738c17cb, + 0x4c597c3c, 0x435a3496, 0x2655207b, 0xfcab86cf, 0xaf2657d3, 0x876d6512, 0xe0cdc7f8, 0x50730281, + 0xa50542d0, 0x5e68aa5a, 0x3a12a5f9, 0x687ea850, 0x44d99244, 0xc548a11f, 0xd0e3e746, 0x3b10c333, + 0xf7c6ad1e, 0x90239694, 0x4f079565, 0xc40cb2c0, 0x2222fa1e, 0xd41a93c7, 0x62385f59, 0x815f1ee0, + 0x27bd9075, 0x002e3693, 0x76b828b0, 0x84522853, 0x763378cd, 0x9835d9eb, 0x60d4bbb4, 0x49263676, + 0xb2d70385, 0xbb086a8c, 0xa8ff46c1, 0xd3c254a9, 0xef9e4b32, 0x85706406, 0x502cdbf4, 0xa1e7afb7, + 0x4855441c, 0x8525e291, 0x51bccdc7, 0x291b33b8, 0x0ef08169, 0xb9787e66, 0x961e11e2, 0xd343519e, + 0xa9008942, 0xe182c54f, 0x283aba9b, 0x5f96c03d, 0x2cf80e73, 0xa37c354b, 0xfe5eae25, 0x76fc7d52, + 0x47570e5a, 0x8204c2bc, 0x52ef6927, 0xfee4cb01, 0xc715bf31, 0x22015955, 0x854e3a2d, 0xa6eb3115, + 0xd93f4040, 0x38aaffc5, 0x2b6864c2, 0x8122ef23, 0xebce48a3, 0x3d781fe5, 0x1d02320b, 0x88a55239, + 0xc29a4d31, 0x544012e6, 0x416f9a9f, 0xe8a19925, 0xb5b9d9b7, 0xb19002e3, 0xb47014b6, 0x4351216f, + 0x2d83dc39, 0x4bb27c82, 0x251f3714, 0x98fc68f8, 0x4e5d084c, 0x6310c7ba, 0x70451f9b, 0xac51e071, + 0xad61187c, 0x80df8444, 0x4eb3e552, 0x82bcfa26, 0x756d8dfb, 0x08c5d737, 0x328199be, 0x3ffd33e8, + 0xcdcd65e0, 0x6e10aa8c, 0x548ecc82, 0xdc03ccc4, 0x003a59b6, 0x1b060ec2, 0x4d101965, 0x2af1e033, + 0x42ed5022, 0xbbc8bffe, 0xf8b64f79, 0xe30ca87e, 0x1e983561, 0x6ee36285, 0x2dbf21ee, 0x41b1dd1f, + 0x6b0b0d1d, 0xc5a20921, 0xc5c23361, 0x059aa65a, 0x97ddee36, 0xcee71039, 0x2a1301e4, 0x6a2309bd, + 0x0fa45c99, 0xd4f71b08, 0x23d6e258, 0x3e6b214e, 0x829bdd0d, 0x1d72d73b, 0x9ba0e86e, 0xe7f87eb2, + 0x41e87590, 0x8a8eeb39, 0x9ba98860, 0xb0563236, 0xc62d217a, 0x2131e078, 0xdfd324d4, 0xef3de685, + 0x3402f976, 0x98b33b77, 0x57cfa1d3, 0xe6e02c00, 0x74cc8bf1, 0xbde8887c, 0x835093f0, 0x2fcbea05, + 0x4b49817a, 0xb2049ea4, 0x06139c19, 0x8ec9ffc7, 0x9757e7d3, 0xcfc1ac8d, 0x202d054f, 0xaf296f53, + 0x457a8ba2, 0x9765a855, 0xc5bedc88, 0x3145f4ec, 0xf9c54d41, 0x43a5a9d2, 0x5ecb1dd0, 0x3306eda5, + 0x44ca1571, 0x1d930f92, 0xb9a15510, 0x7ce2080c, 0xca9013c7, 0x9d128f82, 0xc5cbefb1, 0xa1bcbb66, + 0x9551b03f, 0x876afefd, 0xaabf86fb, 0x9bf9e449, 0x689b95da, 0x4b7080c3, 0x9d81852e, 0x8b472915, + 0xbed30dce, 0x67e061bb, 0xaa926446, 0xb8c5d982, 0xe4be808a, 0x53a556e8, 0xc8d148c1, 0xd590965a, + 0x35033c0c, 0x29a34821, 0x06bac80d, 0x5e6e54e8, 0x4ef43b51, 0x8902966d, 0x783cf817, 0xdd4ff344, + 0x3094509b, 0xa6f2a6a9, 0x18e3b8d7, 0x78dd43bf, 0xac6e2f4f, 0x13b73976, 0xaea35976, 0x0e1a01de, + 0xd6496329, 0x44efff17, 0x63955a68, 0xa930be45, 0xd5bc6c6b, 0x05164772, 0xb6615b60, 0x717f0970, + 0x9fac9a5b, 0x9c43ab8e, 0x98bcf5f7, 0xf9beacf2, 0x1cc85030, 0xf089dbc9, 0x376de1d6, 0x3d542381, + 0xbb44abc3, 0x0798778f, 0x2369e57d, 0x8648f9e7, 0x1b2f5d3e, 0x54dc0454, 0xe8278f4c, 0xd3c6b14b, + 0x9a57ee57, 0x4c31414d, 0x07f7cb81, 0x6be02a43, 0x8eb4f66a, 0xd3415ed6, 0x6ddf65dd, 0x8fa57974, + 0xf15f516c, 0xb84c3561, 0xdfa9f65a, 0x3b28a135, 0xded84f3b, 0x87dc9d78, 0xc7d9d88a, 0x34c85f50, + 0xecdec48b, 0xc9751ade, 0x2a75ff1e, 0x11a01fc5, 0xc795825c, 0xf3d44262, 0x1ac7ba61, 0xa410f3d0, + 0x3f0909c9, 0x66ea26e4, 0x65e1b3c1, 0xa5a8ab43, 0xf74868bc, 0xeb5818a0, 0x7c4aebc4, 0x5f3d6a51, + 0xfed0b778, 0x2306575c, 0x698916dd, 0xa0a886b6, 0x1f9773ec, 0xcf2d638a, 0xe311e724, 0x402a4f71, + 0xc4d65151, 0xc2aaca41, 0x90466529, 0x48acf35d, 0x6d6e8a4f, 0x07a4af2f, 0x75b7c335, 0x5e653e28, + 0x0a9f08c5, 0xa0303b7d, 0x610c0934, 0x64640614, 0x23b78b99, 0x41e0328f, 0xb90b7393, 0x51086273, + 0x6e58f1b0, 0xfae31fc8, 0x753c4a46, 0x6661472e, 0x71c15ee9, 0xab592f08, 0x4e8051fb, 0xa250eadc, + 0x3779f92b, 0x29d5998f, 0x19a8be11, 0x922feb0c, 0xe848f87a, 0x4b456950, 0x90e50640, 0x3d583a4c, + 0xb8e13ff4, 0xa3ce79a3, 0xbf3062f7, 0xf8dd0b43, 0x4e025260, 0xc0c9294a, 0x7385a6b7, 0x31c63aa6, + 0x73cc66c3, 0xbf525646, 0x7b40151a, 0xdcbab0f5, 0xdb607a7a, 0xa335db6b, 0xf60a95d5, 0xef8608e9, + 0x4a4a89d3, 0x12e221a8, 0x527a922c, 0xdf596f81, 0xacbda3f2, 0x92d4881c, 0x9ef51c38, 0xea6bf0fc, + 0x7b805b28, 0x90f126f0, 0xc6a0e5a2, 0x3c0de948, 0x021d455a, 0x29cd1fb8, 0xae5b65a9, 0xdeca1834, + 0x18394dc7, 0x8b26d7ab, 0x4d084017, 0xa91b097a, 0xdab043e4, 0x73da33c4, 0xa4b2b473, 0x3d5db2b0, + 0x78b2601a, 0xd057e29f, 0x89ec2abe, 0xed72417d, 0xf919eb5c, 0x9d79f235, 0x3e99e875, 0xc8461e70, + 0x4dc7af0a, 0xa6c27bbe, 0xe11ea07d, 0xc8b18eb5, 0x4f7c51cf, 0x014b3504, 0x27b196d1, 0x1c2fb08b, + 0x80153f7c, 0xa8413134, 0xdb0c703c, 0xacac7994, 0x12bd9b9a, 0x7d0df264, 0x6116a62f, 0x4937007e, + 0x33f30ec7, 0x0a364ae5, 0x6a0bf329, 0xb5c34c03, 0xcd44759c, 0x3188a70c, 0xce710f68, 0x9b26bfae, + 0xea2559f8, 0x30a009af, 0x869a60ce, 0xedc6f6a0, 0x603334b4, 0x0f514e42, 0xd94c193c, 0xe80a789b, + 0x84ab1d8c, 0xc120c2c5, 0xc19c20bb, 0xc3c1abfa, 0x671dfebb, 0x01944ca6, 0x3e068203, 0x6442c3d4, + 0xcc1e2e86, 0x7d3e01e7, 0xf06f77c8, 0x1f01f847, 0xca2fa3dc, 0x4d0a2979, 0xeea17d5e, 0x71c4332d, + 0xf2ff51f3, 0x780751af, 0x14b58f54, 0xb65c18d5, 0xbad2f30e, 0x4d58ff6a, 0x9f0f9e09, 0xe3241375, + 0x97e8d691, 0xb95f409e, 0x3ff6f344, 0xfc8b5f22, 0x19b936be, 0x70698921, 0x957ee707, 0xd92ff8e5, + 0x0ec85563, 0x4d3a4002, 0xbd5584e5, 0x8ec3855f, 0x4ae664e0, 0x5eb129a7, 0xc464bc87, 0x831a59a5, + 0xba3e60a2, 0xc9530753, 0x4f38f4cc, 0xcf56f3c5, 0xde62fdbe, 0xe6350081, 0x6348989d, 0x5fa1f603, + 0x3b1bff62, 0x106dc966, 0x58658cb1, 0xeba78ab5, 0x8a33ad01, 0xf34efcda, 0xfcdd8253, 0x8d02b720, + 0xa5bc211d, 0x90edcb91, 0xc9960959, 0x779221e5, 0xc545ec8f, 0x83cf2a86, 0xf955f7b7, 0xa003bb01, + 0x7aef9d77, 0x31528423, 0xb5bb1657, 0x8352fd88, 0x2ae5f46b, 0xc970eb8d, 0x158eb114, 0xf3288b72, + 0x091ef04f, 0x5d72829f, 0xd7c80056, 0x484fab0e, 0x6ca63ee8, 0xceaff55b, 0xf2f8d0e3, 0xacd240c5, + 0x176f9fd6, 0x383ea584, 0x49d65815, 0x3125d989, 0x320fab5d, 0x3ad62092, 0x47c8ff7e, 0x862d8b37, + 0x377f1927, 0x3156943e, 0x86fbaa79, 0x90399328, 0xf426e613, 0xf214b36a, 0xde93f64a, 0xe01947ed, + 0x9d7de613, 0x9d763456, 0xc7684378, 0x0db54db5, 0x466218d7, 0xf2a8b97c, 0x107ae4ff, 0x29f06bd1, + 0xac5a18b8, 0x67013353, 0x11b4ce13, 0x1edee77c, 0x64653649, 0x75e72943, 0x49171f52, 0x2a57bbc3, + 0x942cc8c0, 0xfc53cac3, 0xa2668f20, 0x8ae807fa, 0x6be0d238, 0xebef9583, 0x28db3df9, 0xb7c47d35, + 0xa1a323aa, 0x09138c84, 0x15f56353, 0xe421d405, 0xc6e3239e, 0x960ebf8b, 0x27b97fc2, 0x15d2d2a6, + 0xf930fde9, 0x42411fd0, 0xd448d1d4, 0x7128f482, 0x24b3f60d, 0x413336c0, 0xc423cd73, 0x8dbe6a2b, +]); +pub const VENDOR_MLDSA_KEY_2_PRIVATE: ImageMldsaPrivKey = ImageMldsaPrivKey([ + 0x07c83c99, 0xdc33f5d9, 0x6e0ecc2f, 0x84af5046, 0x6c03db81, 0x296c5f6e, 0x5c6c880d, 0x75764ada, + 0x4a3334a8, 0x726134b0, 0x74a15681, 0x94a42dc7, 0x0d745dbb, 0x93dd300d, 0x600551b5, 0x8fb992a0, + 0x9666a1af, 0x017fc451, 0x7a8f592f, 0xb9837df5, 0xe8ccacb3, 0x4540f3a9, 0xec8080d4, 0xb138a8f6, + 0x549886f2, 0x1daf3cbb, 0x7205d797, 0x5a0958e2, 0xe4f8eca3, 0x1f095c39, 0x0054d33a, 0xa8fc5faf, + 0x4bb2448b, 0xc40440c8, 0x0d812222, 0x0a210a11, 0x37709b32, 0x60dcb248, 0xc0104220, 0x89919a46, + 0x09489480, 0x81208cdc, 0xb44d8282, 0x30239821, 0x5b08325b, 0xc490c8b0, 0x8140c044, 0xd0281052, + 0xb22c9908, 0x81834861, 0xda366640, 0xb6056236, 0x71924081, 0x13b48520, 0xb44dd2b2, 0x809a0892, + 0x0c130d08, 0xb3811234, 0x62013264, 0x238050d3, 0x90841081, 0x64814065, 0xc98260a2, 0x8005da96, + 0x25e4a60d, 0x1216045a, 0x28009438, 0x4e194480, 0x21922c54, 0xa2250492, 0x20849028, 0x0988441a, + 0x316488a2, 0x00c88840, 0xa11029a1, 0x364cc884, 0x44cc2832, 0x9882618a, 0x400c50b0, 0x04a19689, + 0x04874c09, 0x120cdc10, 0x8459c091, 0x24262e09, 0xc711d490, 0x3154b684, 0xc2a48c43, 0xa4705010, + 0x2d5a8869, 0x8aa601c9, 0x028a4c38, 0x5222194c, 0x14c32061, 0x020e88b4, 0x8cc34611, 0x422665e4, + 0x2405dc32, 0x21d9966c, 0x64163089, 0xa0001843, 0x9211184c, 0xa0c651c9, 0x44044396, 0x00092592, + 0x121264a4, 0x24492001, 0x31099370, 0xa31666e4, 0x90702028, 0x8c501824, 0x02456a82, 0x382ad120, + 0x2ea4002d, 0x24400cdb, 0x022a49b6, 0x31810830, 0x00470c08, 0x872d8832, 0x5018a228, 0x094668a0, + 0x0231c4b4, 0x2402b951, 0x531291d9, 0xb40cdb38, 0x218a9605, 0x1aa08401, 0x21611a87, 0x710b1900, + 0xe0b40dcc, 0xa624d908, 0x2d440842, 0xa3144504, 0x14522218, 0x02231150, 0xd4824d13, 0x304dc140, + 0x81649409, 0x9a9840db, 0x2826a018, 0x8611a011, 0x63b2019a, 0x926cd346, 0x06238948, 0x231612c3, + 0x14728804, 0x2e10342e, 0xd944309b, 0x328d2427, 0x30433400, 0x1a324920, 0x439113b7, 0x04a1904d, + 0x09348190, 0xa81050b2, 0x4c4a248a, 0x9b268884, 0x88801381, 0x611a9449, 0x1b958d03, 0x21228ab4, + 0x2504b90d, 0x49822da3, 0xa269d108, 0x82243289, 0xc234291b, 0x31415a22, 0x44591091, 0xe2180024, + 0x845184a2, 0x21d41481, 0xc1346620, 0xb86022b0, 0x884a248d, 0xc1b81123, 0x80218ab0, 0x21e48651, + 0x02c92590, 0x08244806, 0x10204224, 0x5ac68814, 0x044a1821, 0x8e094750, 0x01b68401, 0x37880039, + 0x44624400, 0x99b27112, 0x120c9092, 0x25214920, 0x11367124, 0x3402e412, 0x0e1aa268, 0x1c079108, + 0x047012a4, 0x6099a485, 0x0c334681, 0x96499c42, 0x68403052, 0x09428c5b, 0x2602e004, 0x2e232785, + 0x103468d2, 0x902c5106, 0x12089391, 0x0ab80dd9, 0xc6011c14, 0x05210181, 0x08950d62, 0x06018316, + 0x8d61b20c, 0x5920481a, 0x38419ab8, 0x85449451, 0xc2c48889, 0x0831c012, 0x09912666, 0x52100924, + 0x452181a6, 0x48449411, 0x23002603, 0xb0601098, 0x4c824880, 0xc0a64183, 0x004c9a84, 0x81d24804, + 0xd18825d8, 0x18089118, 0x82e0c201, 0x5222645b, 0xa289cb28, 0x88cac864, 0xe114500c, 0x42861841, + 0x8821278e, 0x909470d8, 0xa22ddbc6, 0x2c88464d, 0xa4166063, 0x28600325, 0x6d9a0609, 0x13484943, + 0x80901409, 0x621b9665, 0xe0c8310c, 0x05404842, 0x001a3792, 0x14454cc0, 0x4032a328, 0x4e1c0904, + 0x5b220c03, 0x076c1a40, 0x0c08b34d, 0x9080110b, 0x9228d342, 0x49e4988d, 0x08c64164, 0x36801b16, + 0x4e249608, 0x14b10c93, 0x109088c6, 0x7011b844, 0xc010401c, 0xc6851112, 0x7262a621, 0x93484604, + 0x2962e146, 0x11112482, 0x24410822, 0x2960e002, 0x26d48491, 0x12042241, 0xa049e380, 0x8d58a629, + 0x10c7654b, 0xa26d1237, 0x10183340, 0x4c988980, 0x12880985, 0x4c011032, 0x5b146d58, 0xa08d8b06, + 0x42444810, 0x41a86d0b, 0x35891029, 0x8921c66d, 0x84c62921, 0x288e94c6, 0x44da004c, 0xa1b428a4, + 0xc4291937, 0x4220b82c, 0x823011c0, 0x0804c4a6, 0x4c002702, 0x1a876d5b, 0x84851c07, 0x06d01241, + 0x9c4484dc, 0x388d04a2, 0x05890661, 0xa300710c, 0x15311a19, 0x868a3230, 0x10060612, 0x91401893, + 0x20440204, 0x21267159, 0x404462b2, 0x91cbc025, 0xc8a24108, 0x26329b06, 0x6c81b865, 0x1002501a, + 0x11821815, 0x61584464, 0xcc926cc8, 0x144cd912, 0x518c260a, 0x531892da, 0x3246c186, 0x44d4b869, + 0x18035181, 0x36844808, 0x0013b288, 0x24a74c82, 0xc4054c12, 0x45a08461, 0x4848910a, 0x036a4832, + 0x6a9c4406, 0x4c906514, 0xc1404006, 0x4d942040, 0x108849dc, 0x228c8a20, 0x7061a425, 0xa216109a, + 0x26642089, 0x21134800, 0x14976402, 0xa3512225, 0x8d04c231, 0x8ba24dc2, 0xa46c4a30, 0x2d020551, + 0x134350d3, 0x128c23a6, 0x61811482, 0x0aa44149, 0xa8514344, 0x45591281, 0x94180619, 0x09119a06, + 0x651a130a, 0xc1320a1a, 0x972d0841, 0x309c366e, 0x40a66553, 0x264211b7, 0x6dca1060, 0x09c17023, + 0x88004800, 0x42021164, 0xe1b8485a, 0x840da410, 0x04c01052, 0x11274d12, 0x1030e340, 0x608b8260, + 0x1a174c50, 0x0665da12, 0x0d1c478d, 0xd4302e1a, 0xc4899418, 0x2e0b9428, 0x0b080a01, 0x982d49b8, + 0x4111a848, 0xd9b43003, 0x02610b27, 0x21c0002e, 0x890202e1, 0x344a50c8, 0x40d99450, 0x13084ddc, + 0x82901494, 0x69a3c664, 0x5b100611, 0xc02d1ca3, 0x099b3626, 0x8a345222, 0x42121124, 0x2ce39645, + 0x1848aa6f, 0xc51522a5, 0x855bd910, 0xed29a31f, 0xa54a35f5, 0x4db1ea53, 0x6b833e96, 0x6cf3317f, + 0xb27ebf05, 0xf07ea92e, 0xfa08fa4f, 0x6ab024bb, 0x1ae3cc38, 0x9538432b, 0x5794dac3, 0xa66ddb8e, + 0x7f637789, 0x75c7d114, 0x903dc4c3, 0x1c69add6, 0x2011624b, 0xb4b939d1, 0x57fa8b0e, 0x128a0bea, + 0x065f58ec, 0xbc9533bf, 0xd2ee18a3, 0x8ae6bd53, 0x4cee9e92, 0x4c1bdfb3, 0x030b14ca, 0xf0f9619f, + 0x06e13e51, 0x4ae5bcc1, 0xf5966181, 0x8c2c6e06, 0x1cf3b730, 0xb200cea6, 0xe9343435, 0x6848db78, + 0xb1483b38, 0xaefc1f60, 0xb7e0744c, 0xd5629c80, 0x2e12f3c8, 0xb66c33b5, 0xd3442580, 0x346dcecc, + 0x35c8a935, 0x3b5069a0, 0x34d040de, 0x1a84a682, 0x0303fb15, 0x6ad9ce58, 0x38d547fb, 0x2300b290, + 0x69f2e206, 0x8a56d258, 0x847f20ce, 0xa137c29d, 0x4e007b5a, 0xc5af7c9c, 0x5f069381, 0x4a8fac21, + 0xe066244a, 0xbb7747a9, 0x5e0be728, 0x9d3c666e, 0xc5e82cda, 0x6ceea613, 0x897895be, 0x458494dd, + 0x6c8f07d3, 0x63e46385, 0xb9125f82, 0x66b0d552, 0x8d7de2b2, 0xb71b3c51, 0x96f5d8fa, 0xf6cc2ac3, + 0x5bb05678, 0xafcdcb72, 0xcdae1866, 0xf63a6f26, 0x2fb21618, 0x54cf1857, 0x66af58f2, 0x9b3d4e52, + 0xe3132124, 0x21ca1a27, 0xdda816cb, 0x55b00a32, 0x13efcba3, 0xe06cc0b9, 0x7c9a784c, 0x5b223afa, + 0x4319900d, 0x6dbe18bf, 0xc30da952, 0xe8339399, 0x8a42c065, 0xda90702e, 0x137d9108, 0xf407f41e, + 0xa6a189b2, 0x51ef442a, 0x2e124abc, 0xd64c9be0, 0x5cd76f16, 0xd4072196, 0xd78a8c10, 0x24c0f83c, + 0x4a06af6f, 0x3fcbc196, 0x214fd45e, 0xca8b6191, 0x8d9b1fc6, 0xa5df161c, 0x50a0ff6a, 0x74d5f336, + 0xe1e784d5, 0xbe6053da, 0x41f695a4, 0xc6a0556d, 0x60233746, 0x5017194b, 0xb22ba1e7, 0xd39efd3a, + 0x6fa4320e, 0x30db2fc7, 0x46f69eee, 0xf730f67b, 0x94a66056, 0x1cdf4a4e, 0x1b68d873, 0x641925be, + 0xbac8cb02, 0x31f8da52, 0xb7d64d5c, 0x456bd81a, 0xf54b028c, 0x8d9fc1e3, 0x91ad8d57, 0x3159cb0b, + 0xd0d8dcc9, 0x208fd09d, 0x82e0c8aa, 0x4e4c93b6, 0xc2bd4d0f, 0xb0cc3381, 0x0938bcb7, 0xe35dbaaf, + 0x1d0668c4, 0x7bdbf29f, 0x81c46de3, 0x5c563804, 0xb8e1f6c5, 0xb03ca0f9, 0x6ccbf6f9, 0x11b6b175, + 0xcd11ca71, 0x75b05c5d, 0x536259a8, 0xfece8491, 0xb9401397, 0x834f27a6, 0x29216a92, 0xe4f9bec2, + 0xb075ebb3, 0xe6e3d33f, 0x1c7d2c5d, 0xb4c65412, 0xd7c85743, 0x7a05e794, 0x59fa1d9c, 0xe3378fcf, + 0x067d2577, 0x5b2cd670, 0x6980f25b, 0xdab1e514, 0x8dd7c978, 0x2db2df84, 0xa2f21b96, 0x4e316ef7, + 0x108be98e, 0x5ce927de, 0xce966b18, 0x4bc5e035, 0x4667517a, 0xc634dd0c, 0xf321f9cf, 0xe319b24e, + 0x9086ae2b, 0x7066e0e0, 0xe0adc482, 0x82458267, 0x66569fb2, 0x52947a7a, 0x89b7d6ee, 0xf8a1574a, + 0x27b09766, 0x8a0f73dd, 0x775a4936, 0x1d129a2b, 0x25c735ca, 0x752d4556, 0x344b0271, 0x110b4aa1, + 0x9e93441c, 0x1429eb43, 0xb61ee5cf, 0x7d2d80a2, 0xabe3c4cf, 0xb89a1e6e, 0x5adced54, 0x6cbc9b5e, + 0x2f823cf6, 0x9948ac6a, 0xdc5e3a3a, 0xf1643943, 0x0e3580db, 0xae4ca5a8, 0x10d966cd, 0xc52a779e, + 0xf2d22641, 0x3abca734, 0xe0fc28ea, 0x78931a6b, 0xab8f43e9, 0xcdf42bd6, 0x2d66e234, 0x2410bf81, + 0x6694c536, 0xda96e414, 0x379f8335, 0x497ecfad, 0x9d7d7c4e, 0x3ff861c9, 0x27ae006c, 0xe80c44b4, + 0xa3af465c, 0x8735a13e, 0x7f229bdb, 0x203060d0, 0x466c602c, 0x234f67b9, 0x52648793, 0x3e75fb48, + 0xdac64551, 0xaae4318b, 0xacf0f7ac, 0xc67afaf8, 0xae4d18a6, 0x15fbb1fe, 0x3163dbed, 0x7385850b, + 0x18150e8f, 0x1cca21c9, 0x2f14b9ec, 0x1bfae1c4, 0x79fd99df, 0x49c37494, 0x3cee27b9, 0x79974709, + 0x9ed1cee5, 0x5ecfc27a, 0x6840b565, 0x4ebf0c28, 0x444a93ac, 0x64bd2ca1, 0x82fbf849, 0x35dc7a6f, + 0x9b883838, 0x9f4059b1, 0x273396fe, 0x6f6cd3b7, 0xae154411, 0xa4bc878b, 0x24440c85, 0x0422c781, + 0x1e104384, 0x6e515c58, 0x47721fc9, 0xd7b220f2, 0x0c7b65fe, 0xc0c82b4a, 0x7a894728, 0xed9f5265, + 0xee30b0db, 0x607b84fe, 0xb9ef583f, 0xd47b603e, 0x24c40ad2, 0x2eedbb0d, 0x2677ace7, 0x17ab02f5, + 0xfdbe6cb5, 0xa5778de1, 0xf1f19036, 0x3817acf6, 0xc1e35f53, 0x7941a72a, 0x1ab88f5e, 0x2958f78d, + 0x4f9ff6ea, 0xc6c5daa3, 0x9561d9f8, 0x3323dce4, 0xf29156ef, 0x3e8f0475, 0x91e6eea3, 0x1114618e, + 0x43dce6ad, 0xc503f007, 0xe3dcb6c4, 0x7f75e7ad, 0x3b29ced0, 0x76db3863, 0xbc925d37, 0xf5419cbf, + 0xee84b497, 0x3f4c04b2, 0xdad07eef, 0x610b45d0, 0x89f2952e, 0x9fc66879, 0x98dd5c01, 0xa1ed4773, + 0x7e4ee1b2, 0x100b3d78, 0x6ecf4b1e, 0xbee09960, 0x0a2f8c83, 0xb164336b, 0x3233b5d7, 0x718ae361, + 0x14d5d174, 0x6fce6611, 0xaa696fc6, 0x0e21b79f, 0x98c6329c, 0xd883c194, 0x96e8cbbc, 0x466a23ce, + 0xaaea7dde, 0x95f7ddc9, 0xfe74a79b, 0x2267fd89, 0xe6f62872, 0x58d7eec7, 0x356f6a28, 0xccbc1a04, + 0x1ebe4000, 0xaa4c157d, 0x594caafd, 0x9d275924, 0xa2285d69, 0x910972b3, 0x1de5e745, 0xcc739ac9, + 0x206b73bd, 0x723a709b, 0x4af8ad91, 0x54181a6f, 0x1d7ea584, 0x07fe9b1e, 0xea42965e, 0x31fcc96f, + 0x37024715, 0xaf2ee1df, 0x321baece, 0xadf02d01, 0xc50a7476, 0xb1c3d059, 0xd27ea029, 0x7baa2177, + 0x0ceff828, 0x7e3a5ed5, 0x91ec941b, 0x9a11f4ed, 0xea75907f, 0xb45af647, 0x2588500f, 0xe1eb5d63, + 0x748f04f6, 0x63fc724b, 0x0190ed10, 0x3c3b634e, 0x4517881a, 0x7d6e0ac8, 0x88ee8db0, 0x5873f7bc, + 0x646f3e03, 0xf6a91867, 0x0a82c9e8, 0x88aba83b, 0xaf27cc7d, 0xb67ac282, 0x810fba97, 0xda710f79, + 0xa364e645, 0xe526d5f4, 0x6808ef7f, 0x4f3fc4c4, 0x2116c103, 0xbfaf564b, 0xae1495e2, 0x99ddf5fc, + 0xa3ff56fb, 0x54d2690a, 0x81ba15c3, 0xafe66511, 0x93a04b6c, 0xafd1640e, 0xf31832e3, 0x47492f56, + 0x20e08354, 0x67b2ab49, 0xe7777662, 0xbcbcb03b, 0x39d9d2af, 0x7ab9c482, 0x9e293e96, 0xe51f50ca, + 0x31f91e39, 0x309cbc7e, 0x8c78d8c7, 0x3732c739, 0x2a8606ab, 0x7a33574e, 0xf2146c2b, 0x497565ac, + 0x620f8709, 0x4c40db47, 0x8fbff110, 0x245dab83, 0xaea342e6, 0xc9404978, 0x884645dc, 0x2e73e3bd, + 0x5c1ad278, 0xdae3cbc3, 0x80c49bc1, 0x5f6f0acd, 0x52b524e2, 0x7c3f15dc, 0xb2e1c2f1, 0x3a1bddfb, + 0x36fd177b, 0xd25c255e, 0x8797d13e, 0x1e9c8314, 0x5e9e19b4, 0xf71284b6, 0xa673f517, 0xbdc9300a, + 0x75870fdf, 0x6fd6ade6, 0x05f8f0c6, 0xfaccab68, 0x1e66c6c8, 0xedd97d8e, 0x0cd3776f, 0xecaffcf0, + 0x16ad731e, 0xf466d545, 0x3f12e197, 0xc567caf5, 0x4b437dc1, 0x8c83b97a, 0x9e8864ec, 0x1ceb3a42, + 0xaaea3b82, 0xabed0058, 0x2f6cfbe9, 0xf58bc8dc, 0xa7fdec1f, 0xc798f8e1, 0x5b56ee9e, 0xaf1f8c48, + 0x727d3758, 0xc0da9db1, 0x8cc65463, 0x5ee3c417, 0xfb8e552c, 0x117b1eb0, 0xc3586e37, 0x9046662a, + 0x6f06351d, 0xb2d95948, 0x14653155, 0xa0f15268, 0x5d234f6d, 0x68cdaf27, 0x55f33222, 0x9776d563, + 0x89e539e8, 0x1e6d3c01, 0x33408ab5, 0x66ae024f, 0x926bd80e, 0xd7fccc67, 0x19f23e28, 0x5900a645, + 0x5c6dc8a0, 0x40333b66, 0x12629445, 0x4cf9a7ee, 0x86b200c1, 0xc29cf5e5, 0xa73edebe, 0x911fffd2, + 0x9edef161, 0x70944744, 0xdb000ace, 0x0c3c2a4d, 0xccb8c63e, 0x4c8ba41e, 0xe72a2921, 0x6aa22167, + 0x3d1999c5, 0x3271f525, 0x2bf66e88, 0x23618f3a, 0xd7397be8, 0x9f6a7e76, 0x045936c8, 0x239dfbb7, + 0xede73a05, 0xe03dcee6, 0xc3c26183, 0x7105bbe4, 0x2a525c32, 0x37d27aad, 0xa1cec018, 0x760fd57c, + 0xebfe4578, 0x141872d0, 0x70f5cf9c, 0x5ec6d918, 0xfa86178f, 0xc9cd175e, 0x773d44ec, 0x08adad16, + 0xc8f8f752, 0x32497d81, 0x7158d5bd, 0xe634e4d4, 0xa3d80564, 0xb079c6b9, 0xafb1ed32, 0x5c3fcb2b, + 0x750d4a36, 0xfb7a8a80, 0x501f6902, 0x6f0a53be, 0xb9ecfbdd, 0xd9016756, 0x257e47b0, 0x2bd5e0b6, + 0x38258e7b, 0x1747bcd4, 0xfda7650c, 0x94384419, 0xfd67dd56, 0x54e17ea3, 0xc89d375a, 0x25c3e110, + 0xb7990183, 0x2f28c5d6, 0xbf2fc23f, 0x9d48a5dc, 0xcf995fca, 0xa26fdfa4, 0x458385cb, 0xc0be5747, + 0xfdb9fbde, 0xc0065588, 0x8d26d901, 0xed3a180c, 0x475fc26f, 0x4719fc45, 0xc415104b, 0xb17fa12f, + 0x62ee2cca, 0xce872915, 0xc6dd7adc, 0x0cd33138, 0xf19875c0, 0x800661e4, 0x4c03b059, 0xfd6e9cae, + 0xb2c1ab3c, 0xc98f7a28, 0xe7706d34, 0xc812aa34, 0x356342c6, 0xc93d0e79, 0xc9df1c3b, 0x34c56e08, + 0x478a62b7, 0x9b519197, 0xd9d52ee8, 0xa5fc3cfe, 0xc21a9052, 0x03c86617, 0x89a194e1, 0x3571eb52, + 0x20318122, 0xcb482ff7, 0x2eb054ab, 0x0ffbbd71, 0x16a6a9f0, 0x76adb997, 0xd4311631, 0xdd16e53c, + 0xd38768cf, 0x1e377d7d, 0xa3c3119f, 0x71df2e38, 0x9f2e92ea, 0x738b73f8, 0xd3e711ec, 0x16e36af0, + 0xc7d04da3, 0x19a2feb6, 0x6e64969a, 0xa8eb57e7, 0xe9a14167, 0x5be590b1, 0xfceaff28, 0xa076b7fb, + 0x20914d47, 0x3af33bc3, 0xb12e34ee, 0xd2d8a515, 0xdda9b0bd, 0x80b50fe6, 0x65080ec2, 0xf49f1fcd, + 0x999cf5ed, 0xa3c152d7, 0x473058e4, 0xe279426c, 0xb7dbc091, 0xc7d23bf9, 0xbbfb5675, 0x86a2c67c, + 0x9be65904, 0x41faf802, 0x7bb4d1e8, 0x06b66e05, 0xe062f362, 0x20325e89, 0x7279b996, 0xb15fb7b6, + 0x67ee6deb, 0xded75d6c, 0x20ccbdfc, 0xee9bef58, 0xaf6f2c1d, 0x99a26857, 0xdcb7d508, 0xaf982de2, + 0x4bb8012c, 0x531bb0b1, 0x2b6f22a9, 0xc566dffd, 0x5e190370, 0x68b37c04, 0x389c6522, 0x0b9c6814, + 0xe451207a, 0xb598e89a, 0xa8166acc, 0x604f51e3, 0x6d5330e5, 0x15df2571, 0xfed0fcc0, 0xcf1f5db6, + 0xb5e329de, 0xc91cc891, 0xd5bf3b75, 0x438d24f9, 0xecdb101e, 0x0c494837, 0x22ea90fd, 0x629c6ca4, + 0x71d72c7f, 0x992680ac, 0xd95a9ed1, 0x691af434, 0x6c5ea1ad, 0x167c0fdd, 0x177c7b44, 0xfc4fae16, + 0xb8ae8259, 0xfbe3cf1c, 0x532565b4, 0x994323f4, 0xd3e963f2, 0x39b4b228, 0xb9e939ad, 0x407015dd, + 0xf2460771, 0x67134f77, 0xc9454b2b, 0x2e0be32d, 0xfff80389, 0x8eb688ff, 0x7f8f2017, 0x8dfaeb1f, + 0xbac55d88, 0x8b4a47f8, 0x8b79eade, 0x0aa8d8e8, 0x4c591d75, 0xc9698a4c, 0x4a31b6cb, 0x90aa6b60, + 0xcf01e8ff, 0xbd214321, 0xf5717938, 0xa1a6fb58, 0x05c008b5, 0x7df76b96, 0xfb1380b5, 0x407adbd3, + 0x40f00e18, 0xfb5c8a75, 0xae957b71, 0x331edc99, 0x5afd917b, 0x0a160906, 0x9ba37131, 0xf607d6c6, + 0xa51e6900, 0xf853b943, 0x9f8d89a6, 0x84d71970, 0xd9fde6ae, 0x94460d5f, 0x2b0c7166, 0x998cb036, + 0xa2b1e57a, 0x59eb1550, 0x0718936e, 0x6ec15c3f, 0x5dc69abf, 0xe5f7dce8, 0x78810b27, 0x691ba904, + 0xe6d64200, 0x0d17ba04, 0x71a70a7d, 0x7162f3c3, 0xdb5236d1, 0x579990cc, 0x1e160658, 0xec10229f, + 0xaafef2c4, 0xa69ba2ae, 0x88fb53f7, 0x25fc6bc9, 0xe076568d, 0x50d64d57, 0x4da0d9b5, 0x6a68f61b, + 0x274092de, 0xcea9fe02, 0xc81db654, 0x5e59488a, 0x25d8c255, 0x9b6e3adb, 0x0086276c, 0xa5eec937, + 0xedaa837a, 0x89a5c86f, 0x943249d8, 0xd3292564, 0x80653bf5, 0x6f919d24, 0x0e7856dd, 0xe0a29451, + 0xa49e3aa9, 0x807257c7, 0x4ade887f, 0x0c10092b, 0x78a58a37, 0xc335a976, 0xb67c1be2, 0x95956db1, + 0xdb643fc0, 0x25fe4523, 0x49e566fd, 0x35154f92, 0x6f6a8310, 0x5329636e, 0xf941f73d, 0x2cdbcc9e, + 0x7a5160d5, 0x318e561c, 0x61f2d775, 0x3eb4a80b, 0x2e7ce89a, 0xc696ed76, 0x78f741bf, 0x6ca26996, + 0x9640df93, 0x600bfdf0, 0x76c61986, 0x410e6679, 0x04ef985a, 0xf59b4bd6, 0x1e8e4487, 0x9cb3a5d2, + 0x4c6848ee, 0xd45640b4, 0xfc9fc145, 0x2fc6d65d, 0x8f74aa32, 0xc0978c0e, 0xc837e9fc, 0x40290723, + 0x1fbdc9b7, 0x494d1e4e, 0x358b8ecd, 0xf7ebe1cc, 0x8af0a069, 0xb83a1082, 0xc8902a46, 0x2e17b8b1, +]); + +pub const VENDOR_MLDSA_KEY_3_PUBLIC: ImageMldsaPubKey = ImageMldsaPubKey([ + 0xfceb4375, 0x1153eb18, 0xfd2daed7, 0x2ade5f69, 0xb0505b3b, 0xe60eda94, 0x0e3b0c70, 0x277cb2f8, + 0x19a84967, 0x927883af, 0xaa992ba0, 0x94f8b139, 0x45389b64, 0x25bd2b22, 0xc98c8759, 0xc2b4c216, + 0xa3f61eed, 0xa44df1bb, 0x8b2770cd, 0x60a61bc9, 0x90d742d2, 0xef6965ae, 0xe856dd93, 0x1244096a, + 0x6d16bd8a, 0xb6e1c81b, 0x996caaa4, 0x00979339, 0xc7aa39ed, 0x5154aaf7, 0x02163144, 0xfeba8609, + 0x393a131e, 0x56276476, 0x18dab3a7, 0x6fb775c0, 0xf253ac8e, 0xfb26c372, 0x191c6429, 0xcd2ef667, + 0x95e45a9e, 0xf7389383, 0x9c95067e, 0x7a7cb329, 0xa7a22deb, 0x63651279, 0x057a38eb, 0x83a5dd93, + 0x54503486, 0x619ea360, 0xc75ec86c, 0x15698af8, 0xb1ae28e9, 0xe2acbd15, 0x5bb38edd, 0x5eb1df77, + 0xe7be4691, 0x2b6dcd22, 0x76494cdd, 0xba6b9d6a, 0x5a95e874, 0x8026183f, 0xe39dc602, 0x647cf332, + 0x0e9092c1, 0xd8554daf, 0xcd80f180, 0x50df41d8, 0x5562073d, 0x00e6344e, 0x8f56d202, 0x0a5fa18a, + 0xd6c4c0fa, 0x1156ada3, 0x037ca837, 0xafce53f0, 0x04ce1ae5, 0x5e43353b, 0x2711ed9a, 0x8162e125, + 0x2eccbcd0, 0xb3c7debb, 0x7c53347c, 0x815a8ef7, 0x2e701e86, 0x668bad23, 0x20ea6a40, 0x8ba2ec7b, + 0xe33e3a04, 0x9bd09128, 0x95a26c3f, 0x61f83c44, 0xd52a747a, 0xee4b6f11, 0xd3ad170c, 0xe46631dd, + 0x8d0b9000, 0x950e1850, 0x522f7e4f, 0x81f2c69c, 0x4b4a364f, 0x1afcf4b5, 0xe2cb277a, 0x8cafc0ec, + 0xd9ebeeb1, 0xd239aa8f, 0x7ad94e67, 0x1897a157, 0x0ef4664b, 0xe3d3da3c, 0x850efa2b, 0x365a89ab, + 0x9ae735cf, 0xcdca2c5e, 0x5308140c, 0x203e1984, 0xba2acd5a, 0x275ee923, 0xe06d2709, 0x7d57de06, + 0x8da31487, 0x4fa04754, 0x0a016283, 0x22b5973d, 0x55083c79, 0x6ed19b27, 0x9b0a312f, 0x49f54460, + 0xe03bde9e, 0x3c9ff046, 0x42ef3b0d, 0xc48c96d6, 0x0765049a, 0xeb972e8d, 0xcf9efb18, 0x4daab18d, + 0xeaf5a673, 0x09f3b0c2, 0xe30dc2ca, 0x19df7d4f, 0xaed52aea, 0x6023cd92, 0x905ea540, 0xe2213cd1, + 0x71d52047, 0xafdf7ef7, 0x66b87433, 0xb40304bd, 0x4f69c350, 0x0000e7e8, 0xad73cfef, 0xcd0de58d, + 0x07874732, 0x4e1cab00, 0x8c69f9f7, 0xa9eb87e6, 0x4316c260, 0x3db44199, 0x47428b69, 0xfda9a081, + 0x9cded9bc, 0x5c8cd026, 0x3a2f08b3, 0x6fd9f77c, 0x6edf96f5, 0x9dadef6a, 0xc4498cba, 0xb367a49c, + 0xbfd2c9e7, 0xabf5cff8, 0x7c33bddc, 0x5959440a, 0x3f18198d, 0x84ac2ffd, 0x744cb3d3, 0x3169796a, + 0x377ba2f4, 0x1380af6e, 0x30b6b8ed, 0xfe4c2c66, 0x88e12181, 0xf93ac11e, 0x89e4c237, 0x497e8610, + 0xa76e60a7, 0x175376eb, 0x27d546bd, 0xafe2969b, 0xd78831e3, 0x367e07e6, 0xea73601a, 0x8c9e4a5f, + 0xd62e1ea1, 0x38cf3ce7, 0xa0abb05c, 0x14fc1c8e, 0x19e98b1d, 0x78b8251f, 0xaf177e88, 0xf5729566, + 0xdd8e9f5f, 0xaf677777, 0xacb22d90, 0x7f574c0a, 0x3806fa99, 0x464b4ce5, 0x03675fea, 0x0c1219e4, + 0x0a92a4b1, 0xd3d9017f, 0x0cfb686f, 0xbd8cd9c5, 0x94c91887, 0x791fb77f, 0x0c476582, 0xe193f539, + 0x78701ee9, 0x9fee31e6, 0x85482553, 0x82e616b6, 0xd0371aff, 0x256a99c7, 0x5e86711c, 0xfde4c05b, + 0x089a2695, 0x63cd6ba2, 0xcfdaa680, 0x08a8028d, 0x829ba2a1, 0x090b119a, 0x39e283ae, 0x68532d26, + 0xb239a1b7, 0x94f6d39b, 0x3cfe2383, 0x0bd567e0, 0x5d898b7a, 0x4d433496, 0x653e3cdd, 0xa7427df1, + 0x9167b661, 0x235f16ab, 0x865b25e6, 0x18cdaba2, 0x0355d6d7, 0x721d7864, 0x4d393d06, 0x2045b5fa, + 0x8479d515, 0xfdcd440a, 0x2b774cc9, 0x29181e4c, 0xb9d00889, 0xfa1384de, 0x532e3c09, 0xc185f156, + 0x0964279b, 0x1ae7da65, 0x2407d8a7, 0xb8a70a4a, 0x0b589a0b, 0xc458f0c8, 0xa880effa, 0xe2e0c4ab, + 0xa3dd8ca3, 0x5e7ee23b, 0x851f781d, 0xec10bfda, 0x582b8438, 0x537643d2, 0x039db953, 0x3f99a2ca, + 0xd627d0a5, 0x7572bfde, 0xae4727a7, 0xc2fbdb20, 0x381baf72, 0x1184baca, 0xab08620a, 0xb92b7ba2, + 0x7f3247ff, 0x578d9bf0, 0xcbb84518, 0xeeeba7b6, 0x932f07ea, 0xf2614c9a, 0xf4f88d8e, 0x03564a8c, + 0x33f65219, 0x76a5d605, 0xd5bbc871, 0xc3df8c37, 0x61d469b5, 0x823b8da6, 0xfdc18c1b, 0x763c4ae8, + 0x7271f17c, 0x29a97ee9, 0x439a2df8, 0x6da9fdce, 0x3ac2b8dc, 0x04975b7b, 0x7f62356e, 0x3846b4af, + 0xdadbc330, 0xc6d64c59, 0x8c1b768d, 0xf5b4e816, 0x634ca004, 0xbce3de2d, 0xd07a5d18, 0x2eeabd82, + 0x37445e16, 0xb8f2fee4, 0x55d3c524, 0x7a5be01b, 0x01834b48, 0xc4b5db09, 0x8341a906, 0xab8630fb, + 0xb18f33e9, 0xe9ae2cf1, 0x3d1fb31a, 0x03f24084, 0xfd595187, 0x71d831ad, 0x32bd33a6, 0xf955038b, + 0x862119ad, 0x243b2fe4, 0x082924a2, 0xbc95a82d, 0x68d04a7d, 0x79fa1cb4, 0x2c5c73e7, 0x09d64cc2, + 0x74f9aebc, 0x782d2ed9, 0xdce7048a, 0x5efaf676, 0x913a0524, 0xbfb1313b, 0x0ed0e55e, 0x2d941c42, + 0x63f4ab9a, 0xca9fd0f5, 0xc03d8c37, 0xa5b742f0, 0xadc73d55, 0x00c31d85, 0xf0fbc254, 0x7717a177, + 0x76c309bb, 0x27b86de6, 0xa93e502f, 0x5ab316c3, 0xe8b9bafa, 0x7f2c168e, 0x6409bb4a, 0x3a319466, + 0xd7c74f52, 0x12d6f58c, 0xb0c07954, 0xaa8bf337, 0xbab78bd3, 0xb723bc30, 0xf6769e2a, 0x0988d61f, + 0x19481432, 0xe652b8c7, 0xb70df987, 0x39103274, 0x1b0a15e9, 0xf8f3fcd1, 0xa65b3ec2, 0x452cf6ff, + 0x7ee45d3b, 0x08335d97, 0x5968894d, 0x38aa52b4, 0x5bc24fd2, 0xf30e4d34, 0xb56c3918, 0xb12aa907, + 0x272c7031, 0x8ce2762f, 0x43b9f286, 0xb39b815e, 0x6b6ba654, 0x527508a9, 0x0a30c49f, 0xe9bc7d21, + 0x5d825468, 0x43a5295e, 0xa8721f3b, 0x73a822d9, 0x46b3c470, 0xa2cc7e04, 0x8243428c, 0x82e80728, + 0xf8145388, 0xddfcf329, 0x8f833b9d, 0x5d1b1cc8, 0xaf67cc6c, 0x7304cba0, 0x4b9b106d, 0x54f6602e, + 0x02e5a692, 0xf98ab789, 0xc65143cc, 0xb2090226, 0xa8cc0fb7, 0xd35cf5f7, 0xe840a731, 0xd1e7248d, + 0xe9fc209c, 0xc86182d9, 0x0151a072, 0xc61360dd, 0x2c517c66, 0x7a38d359, 0x81f940ec, 0x1eb76514, + 0xcfc2b0d6, 0xc3f505ba, 0x546830a6, 0x3a1511b0, 0x962edb2e, 0xd1319a73, 0x4d0044b3, 0x84fb5beb, + 0x2252f57e, 0xcc462c89, 0x230523a0, 0x0d4e3fae, 0xfb8a2963, 0x352b2a03, 0x817aa4d0, 0xa13c10d6, + 0x055e1f0b, 0xb652b7cc, 0x76cb5955, 0xd5f0afe6, 0xea2ae11e, 0x348c0eb0, 0xaf3638f0, 0xdad014a3, + 0xea63a174, 0x19a1dbf4, 0xcec39900, 0x51cf4d9d, 0x582d6842, 0x479610b2, 0x7fca52b4, 0xc409da72, + 0xaab7611c, 0xcf01c246, 0x1f38da2b, 0x9bcb0ddb, 0xe07fec4f, 0xff3baf53, 0x0457faf2, 0x10dbb73b, + 0x8331e0e8, 0xa4165e82, 0xf99c0c6f, 0xde4e2b1b, 0xf11aaa72, 0xfae00e4e, 0x8cb67a51, 0xe8c080d2, + 0xbabeac89, 0x337c1c68, 0x4df593af, 0xd777498e, 0x3b19438c, 0xe338774e, 0x0016d7cb, 0x25910c4c, + 0x8b0c66c0, 0xaeebf324, 0xcbe64bde, 0xcb871804, 0x7cc6b311, 0xe661a250, 0x1027856f, 0xe430d84c, + 0x63446166, 0x684119ca, 0x880c2de0, 0xeab3f0d3, 0xeceddeac, 0x0deec157, 0x4de7f723, 0x60282ba6, + 0xe3d55954, 0x12208717, 0x232ba6f7, 0x9de9a090, 0x1b69d141, 0x24c14913, 0x88a9e9fb, 0x8c90919d, + 0x6ca74c72, 0x99198852, 0x200e197f, 0xb0db60a6, 0xc26a9b61, 0xdc50af7e, 0x77c250df, 0xe59b65b2, + 0xd90cd8bf, 0x320366ed, 0xc1c3b5ed, 0x0d209a81, 0x69ddf69a, 0x735704d4, 0x56cb98ed, 0xe39b32c5, + 0xac7959e8, 0x4f601f83, 0xc582a7e8, 0x8edfcb68, 0x793b2b93, 0x3134ec93, 0xf13e1030, 0x795c95d1, + 0xf958f673, 0x2eff8092, 0x150022f8, 0x3af86f1a, 0x2ee410fd, 0xd69ff635, 0x181dba1f, 0x68edca94, + 0x8f0b627a, 0xad94268d, 0x2225d7da, 0x9ea27b98, 0x7a138b27, 0xa998e806, 0xede17a7f, 0x89979eec, + 0xa67f006e, 0xbb17410b, 0x9c9a8cfa, 0x6b411ed7, 0x2a060a39, 0xd7375043, 0xba1bbbad, 0x1c677e61, + 0x474fa89f, 0x9038fabe, 0x302dd3d8, 0x1658cf9d, 0x75f37450, 0xc9a92802, 0xcd5da6ba, 0xd431d0c2, + 0x4ece6eab, 0x1b017e9e, 0xf21231db, 0x3e1c4107, 0xe8ae64f5, 0x4563a9fb, 0xda5a50d0, 0xaf60c667, + 0x22bdab0a, 0xc7ef8513, 0x872c7ea1, 0x83b323d4, 0xab2f1dd5, 0x4684d4ff, 0x55dba611, 0x352af222, + 0x23326a4c, 0x7a7d87a0, 0x1d6c8105, 0x492d43a9, 0x8adb8630, 0x9707480c, 0xee33a7c1, 0x67ffd19d, + 0x9de6ca16, 0xca0e9e56, 0x33cf7fc6, 0x72cefe76, 0x49b05e3f, 0x93072b63, 0x5b7df0cb, 0xa6b3663c, + 0xe71a0cca, 0x1ad0684c, 0x2eb19d9b, 0xaed7344d, 0x1cdf762e, 0x3b1b5c68, 0x3ffd1301, 0x4bfb61ab, + 0x10eda6a7, 0xdfa42ed5, 0x0d12e0e1, 0xe5020abd, 0x0242bf64, 0x321077e4, 0x65632e92, 0xfb6a7cb0, + 0xac2d93ad, 0x7ec595a9, 0x26cb689e, 0x772e5864, 0xf21207de, 0x50de9b46, 0x8a2bc178, 0x0bb9d913, + 0x1c048a11, 0xabf6b278, 0xd25091cd, 0xe2672f2f, 0xbd7feaba, 0xe5500769, 0xadbb21e1, 0x475c28ca, + 0x3700cddd, 0xd99372f0, 0x323ad3bb, 0xa9c017e2, 0x3b329468, 0xa601748d, 0x15d919f8, 0x633b8773, + 0x5ecfae12, 0x1d45852a, 0x989458a3, 0x42ad267b, 0xbf72060d, 0x85309842, 0x73a2611d, 0x3c4487c4, + 0x5d6a367a, 0x60af3515, 0x71d96903, 0xfe4e497d, 0x3958dfde, 0x9ea35aa6, 0x4fdf86e7, 0x335af720, +]); +pub const VENDOR_MLDSA_KEY_3_PRIVATE: ImageMldsaPrivKey = ImageMldsaPrivKey([ + 0xfceb4375, 0x1153eb18, 0xfd2daed7, 0x2ade5f69, 0xb0505b3b, 0xe60eda94, 0x0e3b0c70, 0x277cb2f8, + 0xf2f5f2b5, 0x3525003d, 0x873067cd, 0xc97bef69, 0xa5f6d16b, 0xd38b0869, 0xef53659c, 0xcaa0d461, + 0xb3549f5d, 0x1eddb554, 0x8f218ac8, 0x018f9f31, 0x970a87e6, 0x9ed47014, 0xeb80cab7, 0xdfc7b26a, + 0xe600b581, 0x5c81fd6c, 0x9c2ae2b4, 0x0e36b26e, 0xf20b4136, 0x6b1e7966, 0xf00dc23d, 0x6ffb2b18, + 0xc9b42c51, 0x988c8828, 0x51088160, 0x09192c01, 0x27842034, 0x66d23880, 0x5b824883, 0x30225006, + 0x81010709, 0xcb840d08, 0x190404b1, 0x11d43208, 0x14157041, 0x82681a90, 0x011b0381, 0x12152e23, + 0x41249136, 0x09539021, 0x21432160, 0x30264c18, 0x6e20c54c, 0xe43470dc, 0x868da004, 0x2e5a8244, + 0x202664a0, 0x48714b04, 0x20d08071, 0x548600c1, 0xb06c60c6, 0x05944870, 0xdac22924, 0x8671dbc8, + 0x29421804, 0x22b68502, 0x31490881, 0x31a33066, 0x54220000, 0xb95180a0, 0x31cba840, 0x1aa88152, + 0x90282230, 0x8692000c, 0x59828988, 0x06251890, 0x80212188, 0x99304458, 0xa2441bc7, 0x915b9064, + 0xdbb00519, 0x182a9118, 0x84c3386d, 0x98389153, 0x44658214, 0x51004312, 0x80a88510, 0x884d0a26, + 0x32e1b46d, 0xc33429d2, 0xa63064c2, 0x60210311, 0x092672a2, 0x18480106, 0x71820420, 0x241661c2, + 0x04824a16, 0x8ec1c289, 0x03890d0c, 0x406e9436, 0x41d82264, 0x1428700c, 0x84688148, 0x6c80106c, + 0x98022d98, 0x28844448, 0x8150068c, 0x5920860b, 0x950c9804, 0x4e644460, 0x01137100, 0x864119c4, + 0x05818645, 0x4c1285db, 0x4848c386, 0x4d00b981, 0xe438664b, 0x168808a2, 0x69599404, 0xc8980ca1, + 0x4020da88, 0x2d919664, 0x4232489b, 0xb04c0225, 0x2d54a844, 0x13012049, 0x04894192, 0x71c40808, + 0x1a83851b, 0x25850cb4, 0x68598824, 0x424466db, 0xb20493c0, 0x440a1872, 0x13229111, 0x936c5206, + 0x6020a429, 0x03b184cb, 0xb40c5332, 0x6e92468d, 0x203884a4, 0xb8259898, 0x84832422, 0x82148c1a, + 0xc521dc90, 0x7059220e, 0x11a06104, 0x15308128, 0x09a10866, 0x41420d41, 0x2082a4a4, 0x2c040205, + 0x0836694c, 0xb488c3a0, 0x401c4050, 0xa0045111, 0xb6019446, 0x02998849, 0xd8247021, 0x07701249, + 0x0e52144d, 0x03430c1a, 0x47460027, 0x4a43a685, 0x12851120, 0x0386c424, 0x4ae4006d, 0x50947122, + 0x88104382, 0x30e3c870, 0x641472a0, 0x2691c400, 0x4ed43231, 0x50b2809a, 0x342d1944, 0x02c80201, + 0x12c40dd0, 0x200c8c12, 0x654b1400, 0x98423114, 0x066ada10, 0x600ac964, 0x843660d2, 0x2032c4b0, + 0x28143409, 0xa0348981, 0xa88c0234, 0x69090541, 0x02a4654c, 0x2091e180, 0x8d931224, 0x19437204, + 0xb8459222, 0x24daa848, 0x0a4021a0, 0xa46d0445, 0x2509320e, 0x9cb4248b, 0x168d09b9, 0x49a3b04c, + 0x42047203, 0x236580c6, 0x4c00084d, 0xc81671e3, 0x00401b87, 0x69990872, 0xd8142810, 0xa6010009, + 0x021c9449, 0x14c03121, 0x4231c236, 0x2a444250, 0xa4268ca4, 0xb8051c96, 0x0de12611, 0x58344eda, + 0xb62c53c8, 0x91cc3684, 0xa180044c, 0x02490319, 0x8c230304, 0x00a94de1, 0x92681118, 0x2c8ac205, + 0x81c46863, 0x846ce284, 0x48dc2840, 0x92a68101, 0x97889102, 0x6884262d, 0x09409224, 0x22664144, + 0x811b1622, 0xd8362460, 0xc464c184, 0x4c108529, 0x899810db, 0x04408296, 0x00443601, 0xdc88680a, + 0x03714aa8, 0x844c840c, 0xe3226d90, 0x40419932, 0x01a3b40d, 0xd3882024, 0x870062a4, 0x7111b500, + 0xc23682db, 0x388054a8, 0x4c643801, 0x00b12d0b, 0x310d99b2, 0x8094a031, 0x4b960422, 0x486c0ab4, + 0x89123792, 0x9b3450c0, 0x286a18a5, 0x65030100, 0x14b665c0, 0x08494308, 0x25201651, 0x19b59100, + 0x229123b0, 0x61108800, 0xdc025223, 0x81041020, 0x86181728, 0xe100621b, 0x938001c6, 0x6808128a, + 0x22186024, 0x816d03a1, 0x80c0c64d, 0xd2066950, 0x22622032, 0x45cb466e, 0xca405119, 0xa365d4a2, + 0x44901605, 0x9ab6009a, 0x1285c888, 0x2109858d, 0xc11462c0, 0x0622e338, 0x4021c324, 0x12326d19, + 0xb6608008, 0x4448b065, 0x54388d80, 0xb2649036, 0x068b3891, 0x0ca00442, 0x26522140, 0x4d0ab58d, + 0x21108edb, 0x30085c80, 0x3010292d, 0x1cb44418, 0x3969d338, 0x2688b471, 0xc4841164, 0x32054a24, + 0x0442408a, 0x5ac0458a, 0xb4486222, 0x90901620, 0xe1b66d61, 0x46918232, 0x690a864c, 0x99446083, + 0xb2616322, 0x69413686, 0x642612c4, 0x300c4042, 0x81511085, 0x19a01120, 0x4830d9c8, 0x0ca20861, + 0x903850d3, 0x142dc998, 0x011a1982, 0x40968164, 0x2666c9c8, 0x851b3245, 0x102726c0, 0xc4810313, + 0x41601682, 0x02212624, 0x85280ab4, 0x880c246d, 0x1b330d02, 0x47421c06, 0x2c81b801, 0x24328922, + 0x88201c32, 0x054a1651, 0x1c3461dc, 0x006c5838, 0x4ee3a444, 0xa11080c4, 0x32465aa4, 0x65244348, + 0x21989141, 0x4089db42, 0x8a232921, 0x84c28598, 0x388e92a4, 0x25d83670, 0x00280198, 0xb0210429, + 0x31a29249, 0x0c312259, 0x466d1208, 0x40d83801, 0xdbc880a3, 0x9821c048, 0x4ee41024, 0x54a68599, + 0x920ce080, 0x09590870, 0x82888512, 0x4881a090, 0x00582630, 0x1b216458, 0x20091313, 0x04a01624, + 0xc8a845c3, 0x06110b42, 0x80140652, 0x9bb43024, 0xb245d224, 0x4a043182, 0x14186d0b, 0x99408b44, + 0x200ab204, 0x0399910a, 0x252dc4a6, 0x4491a489, 0xe3162ec0, 0xb6291b29, 0x28091431, 0x24296423, + 0x46854bb6, 0x50d1382c, 0xa3448202, 0x914d9342, 0x0e233704, 0x24c9688a, 0x462da382, 0x8d080521, + 0xe094325d, 0xe1abf2f0, 0x69e0c43d, 0xda6e3199, 0xc5039fdd, 0x433b075c, 0x9b100565, 0xdd174cfe, + 0xc156cd53, 0xfbd50b8d, 0x36bcf488, 0xf9bda32a, 0xa2e0968e, 0x6f8b36e7, 0x2913e06d, 0xb9ea7a0f, + 0xcb813f3b, 0x5bb9b097, 0xaefea6ee, 0x3285a5f6, 0x7e08fb9c, 0x128b1ba3, 0xd23cd2d0, 0xaf20a673, + 0xebe58877, 0x76120773, 0x42bfb42e, 0x1591ca2e, 0x6f37c36c, 0x57b40826, 0xe55bc320, 0x4551db62, + 0x3a141e8c, 0xf9d67983, 0x56e111bf, 0xdc0b0076, 0x1be48373, 0x5e8d0318, 0x212b96f9, 0x2915dfd3, + 0x3f5f69a2, 0x2087e133, 0x69270897, 0x11b886b7, 0x5b260628, 0x2d0bc1f9, 0x1bdc0b98, 0xa4d80ab8, + 0x340bf79b, 0xbc968221, 0x139c9b86, 0xf664bfc2, 0x7b40c1be, 0xc86d08b0, 0xe8bcdfcd, 0x38205f7e, + 0x4a3c6e2f, 0x4a0a5104, 0x8b2dca54, 0x072dc766, 0xb7a5ad18, 0x0e79ef88, 0x378bd7e7, 0x5a77b4ee, + 0x188814df, 0xec1cf892, 0x6836b50d, 0xb55273a1, 0xfa21aa6e, 0x705cf832, 0x29bbecc5, 0x60a66769, + 0xe1885a44, 0xcde9ae21, 0x478f43e0, 0xcbe014e5, 0xeb702886, 0x27c433eb, 0x4566cffe, 0x7aa5260a, + 0xae88ed87, 0xd6354859, 0x10edf0a2, 0x25b99353, 0xdfa6d361, 0x1c9c9e6e, 0xf7ab4d44, 0xd90d38a8, + 0x1b0b1b53, 0xe787a8a0, 0x2d749096, 0x0fd8c801, 0x613b2727, 0xa72c4e92, 0x5930511c, 0x8f49f8ba, + 0xc66c9bb3, 0x20ff8cfe, 0xc2e37baa, 0xfe5eabeb, 0x5e30fc4a, 0x7ec2f6a9, 0x2006f97b, 0x865d22b2, + 0xa6264de5, 0xf5ddaf0e, 0x76cb2d31, 0xadb8f647, 0x1eb5c13f, 0xa8424218, 0x2f0cd41f, 0x15195cd0, + 0xd63d3eb0, 0xc996a19a, 0x57fd3989, 0x403b459f, 0xea9e49dc, 0xc7463c7f, 0x1cfa645f, 0xaa7704bf, + 0x8fcdf6a8, 0x3f166d7d, 0xcecc956a, 0x9ccd672d, 0xb80b6c59, 0xf28cc52b, 0x99d3b558, 0x53384453, + 0xa97efb17, 0xb36f4752, 0xc0612fa4, 0xe6f6ae92, 0xc6f13e1c, 0x1cab4134, 0xb4a03902, 0x7c1611a6, + 0x1a45f85a, 0x786023b2, 0x515f64d3, 0x59ac0c09, 0xa62a12e6, 0xa96e89fd, 0x263c7c66, 0x82fa0303, + 0x76903879, 0x878e5b0f, 0x12c2866a, 0x2f7564c6, 0xbcaed65e, 0xd4ce929d, 0x2bcd71f3, 0xad4846fa, + 0xb403ab29, 0x823ee6e2, 0xd869cbba, 0x3cbb0da1, 0x53dab20a, 0xdee3213f, 0x72abc57b, 0x3c47b19a, + 0x6c714ed9, 0xf9f6d774, 0x08b2ebe8, 0x8d5adf8c, 0x7d72b052, 0x773420ea, 0xe0bdea5e, 0x547318ba, + 0x29ab438d, 0xb1eb49f5, 0xbfbf67ee, 0x491e939c, 0x7a35acd2, 0xd05b2a89, 0x202b0ec3, 0xd4bbad2a, + 0xbf52b2a1, 0xc2ea2d22, 0xd4787a8a, 0x6a1e84b0, 0x7fbcee55, 0x10bdd515, 0xe870a524, 0x6e11559a, + 0xfff3a2ce, 0x749afd14, 0x99d40585, 0x44023917, 0xdef9cf1b, 0xcd88ef22, 0x38cc09a4, 0x896b47d7, + 0x6e990183, 0xaed7be68, 0x14017ed8, 0x852849e7, 0x1b3f766c, 0x215eef66, 0x7b0bfb1b, 0x21ff50fe, + 0x0481dd6a, 0x9e027f13, 0x6b0b8e7b, 0x172a3b44, 0xe7de5594, 0x82651456, 0xf68c6caf, 0x36316a7d, + 0xa9c874f6, 0xc4539d9c, 0xebd1a40c, 0xec0f78ef, 0xef18fa43, 0xc2b356fe, 0x0cfe9b64, 0xa115b4f2, + 0x7b774d56, 0x61257cc7, 0xba1c4cb3, 0x9fb8dceb, 0xb11f6ade, 0x91848a46, 0x72f2e575, 0xf1c4834f, + 0x0d82fcad, 0x1f3a02fe, 0xe97514f9, 0xa4b4fed9, 0xf0285d90, 0x5119b52a, 0xd25e4d0a, 0x91c06d96, + 0xcd3d9a18, 0x5362504c, 0x3a61785e, 0x91feafdc, 0x41d4026d, 0x763c79f9, 0xa3ead4c5, 0x76b20f47, + 0xb48c5fdb, 0x65b9aff9, 0x571961b5, 0x3a6ef0a3, 0x0fa18ade, 0xf74e9f49, 0x9017b007, 0x44a2099d, + 0xbef35753, 0x607b5f2b, 0xd51d633d, 0x2a432ef0, 0xb653b130, 0xe2074fa4, 0x43d94f7a, 0x32db246e, + 0x5b51610c, 0x47a16119, 0x6e8fc84a, 0xb4c5bbbc, 0xd58df5ca, 0x5dcb2fcf, 0x249cc84b, 0xf07d2e29, + 0x396d3809, 0xe4caebd6, 0xcc97442f, 0x79f944ca, 0x1e679710, 0xcfe25061, 0x74462928, 0x9ec883b2, + 0x15505394, 0xec3a839d, 0x9024df68, 0x27fd802f, 0xba8326f7, 0xbe37b8d3, 0x451a9f3b, 0xdc31cc8b, + 0x65581dbc, 0xbe7c540d, 0x54e9b7fe, 0xfaa462ac, 0x7ebfca4a, 0x1525cc04, 0x6ecad592, 0xad0dee77, + 0x5ec4c9fe, 0xf76da4fc, 0xf660b893, 0x65b3a1be, 0x2ff5ec55, 0x93381c8c, 0x27d9f025, 0x26239e04, + 0x72448ea3, 0x246f19cb, 0xce7815af, 0x06dc4f35, 0xcac65cae, 0x5f5b5adf, 0x39bff140, 0x32c1c51c, + 0xbbea5c12, 0x8a0c1bca, 0x51326752, 0x179c2cfd, 0xdb37f097, 0xbab80a7b, 0xf9e468ba, 0x7af1f31e, + 0xaa80204f, 0xe9a765aa, 0x34e5f0d9, 0xa29ef263, 0x740da94f, 0x31184550, 0x22c24df1, 0x74671460, + 0x22f3eeea, 0x17e9a785, 0xf88c06dd, 0x655f451b, 0xd2333384, 0xa235cb5d, 0x6e692b10, 0x38749a07, + 0x7ead2458, 0x62eee304, 0x8d5aa530, 0xcebabc60, 0x7af5350d, 0x12d4afaa, 0xd455755b, 0xb1d2a449, + 0x2f3868cd, 0x0c5f083b, 0xa73250fa, 0x70dea22f, 0x3c7e63b4, 0xdc9c9c55, 0xd65df8dd, 0x2b9837b8, + 0x82fcf8fc, 0xa3c28171, 0xbebd4ca4, 0x28ac28b6, 0x3a6d1aea, 0xb4bce9ff, 0xf6022189, 0x522f2d17, + 0x4ac239b1, 0xf018ba02, 0x5516011a, 0xc3cf3066, 0x57dd3ef8, 0xbea22c50, 0x3bcb870a, 0x3e9ca12b, + 0xdb7dd198, 0xff0040e9, 0x420c1677, 0x3533a37a, 0xeb56c7a3, 0xeb532225, 0x927fd6dc, 0x0b12025e, + 0x47cc7039, 0xdba89498, 0x65b2bac9, 0x9087c5b5, 0x19730733, 0x4f099638, 0x93959e29, 0xc44c0d39, + 0xa2af6c7c, 0x731a7b8d, 0x1854499b, 0xf0ee0efb, 0xd66db82d, 0x6b6339a5, 0xccffec8e, 0x33c88b5d, + 0xecb30181, 0x274e56ec, 0x86bb6f69, 0x4aa39576, 0xcaec4149, 0xe42512f2, 0xb7ed4778, 0xda494ce0, + 0x5daef573, 0x1310703f, 0x66a6d964, 0x8ea89e1c, 0x16b4c8b1, 0xdbcfdf7d, 0x82ff9445, 0x69c20ae5, + 0xef865591, 0xd1338406, 0x35532ff3, 0x7ac36912, 0x1b3cc422, 0xd7a0e661, 0xccf8f266, 0xfa2d74be, + 0x424366a6, 0x55bf6f78, 0x68d21b42, 0x07bc867a, 0x99b055a9, 0x29a174da, 0x5678e714, 0xe8229321, + 0xbeffc2a9, 0x612e8af8, 0xc0ff73f2, 0x0e94d504, 0x0f3eabda, 0x81e0ac77, 0x031915d9, 0x214745d7, + 0x21dab24a, 0xa37d2549, 0xbcd8fef9, 0x95603559, 0xa06945a9, 0x1300c021, 0x76f635b1, 0xc99b2413, + 0xd3a0a9ac, 0xfb55eb30, 0xb443378e, 0xc2203cbf, 0x4acebce8, 0xc31aff6a, 0x682475d8, 0x147bbb57, + 0x1c3243b8, 0x4bddc5d7, 0x47608a02, 0x6efd3d8a, 0x1d1e3ba9, 0x20698583, 0x9bd659b1, 0xc1729e43, + 0x4318caec, 0xf2dc3cd5, 0x4a89071d, 0x7ca75907, 0xeac9fb4e, 0xb37eee65, 0xbe2624cf, 0xe9b70814, + 0xc38ddb06, 0xfd13b84b, 0x57ccbb92, 0x4dff401d, 0xc7a4658f, 0x0be9667c, 0x0a5f822a, 0x98a01142, + 0x29721c77, 0x179a6a01, 0xc9223def, 0x961ea1b2, 0x52b4be45, 0x34d13de2, 0xcdd0bf3c, 0x9a0affef, + 0x45e69d86, 0x167bb011, 0x72ffe873, 0x0c9bc486, 0x17ae9f25, 0x46c7f1b1, 0x9afd95b8, 0xfdd6168a, + 0xf711baed, 0x9a02b5b4, 0x19b4cf27, 0x3fdc71dd, 0x560774ce, 0xb903f9de, 0xfa56d8ad, 0x6b811135, + 0x28290960, 0x00f974c5, 0x32364342, 0x2e1a8ec1, 0xc7272567, 0x63c15bcc, 0xde5c4f0d, 0x2a134f7e, + 0x3eb9165b, 0x4d5ef602, 0x6770cd1a, 0x84ffd017, 0x4390035e, 0x998f0382, 0xc74ac192, 0xf42a9422, + 0x50afab4b, 0x8994246d, 0xcfa732c1, 0x4a60c019, 0x0b63b2d1, 0x1a6833a8, 0x3903b196, 0xb4e73c8a, + 0x96c098e3, 0x3fed6698, 0xe7c1ae1e, 0x5f121099, 0x11ab5a83, 0xb10a68d8, 0xe8470928, 0x66953229, + 0x5eae475b, 0xce1a6215, 0xd2eb2572, 0x174cd8c5, 0xc1b37abc, 0x67bf18bb, 0x186d6dc3, 0x06d89456, + 0x738a62d6, 0xbf20f90f, 0xb1e0b6be, 0xd7e3e12b, 0x39317145, 0x8be93c24, 0xaef84a3e, 0x41f3df92, + 0x40490af0, 0x69dd041b, 0x2f0bc1b8, 0x3a43583c, 0xc6726ba0, 0x603ac654, 0x1a3b825d, 0x372da930, + 0xb688289f, 0xb008ba4e, 0xa04dfd82, 0x959ad88d, 0xeef18154, 0x2d050581, 0x81a60e7a, 0x1b04f8f8, + 0xecbc2bca, 0xc67f2ce9, 0x623847e1, 0x8a1b2235, 0x4bb1a652, 0xbe5b0d17, 0x6f93151a, 0x34ab610d, + 0xc6ff00b4, 0x16241d84, 0x6e704597, 0x5f52c3ac, 0x0a77eb46, 0xbf9dd22c, 0xcad79394, 0x68a329d8, + 0x85c71552, 0x3ed3d22f, 0xfd6601e2, 0xc0968ca4, 0x3993c1bc, 0xb40b58bf, 0x0b1a61b1, 0x7521c175, + 0x5005f3b5, 0x80ec6156, 0x1e2bea2c, 0xcb550f61, 0x7b35edf8, 0xae7c0388, 0x8b970c14, 0x7f6bcb23, + 0x2693e008, 0x3ddf6bd4, 0xf5881878, 0x5426dc41, 0x7d62942d, 0xb90ca12a, 0x130203a6, 0xe19a59c7, + 0x3471f664, 0x9928692c, 0x180a25d5, 0xf63b679c, 0x3c3fbf3a, 0x315a89a2, 0xdc1c408d, 0x9fdd51bf, + 0xea43978e, 0xb1f3ff68, 0xf29aa2cb, 0x67063220, 0xf2109dc3, 0xe001e8f8, 0x2a621a87, 0x4d2450ec, + 0x61c241fe, 0xf0db2024, 0xeb528d24, 0xdae2f74f, 0xbb46da6b, 0xe3f3235c, 0x49197960, 0x88f8657a, + 0x22430738, 0xb63105b8, 0xad5e807e, 0xf5714249, 0x8eac01e0, 0x6d3b98ff, 0xe5f44225, 0x324aaf2f, + 0x6b866e2b, 0x05970c14, 0xcbfa93f5, 0x70c420b9, 0x8f316e27, 0xc988d0f7, 0x0fe76eab, 0xa9f6bc1e, + 0xa2ca023a, 0x513fe5e9, 0xdce2d4d3, 0x31946be8, 0x48736b49, 0xbd381e4c, 0x279a6441, 0x47723521, + 0xd6682ff3, 0x91d89738, 0x471a20a5, 0x7bd180a2, 0x7b22f2db, 0x9aaf39b8, 0xc23b1e4c, 0xbfe6cec3, + 0x050d9728, 0xe7a15d6a, 0xf7f7f013, 0x7c646b29, 0xbbe83d7c, 0x8741308a, 0x3d6749af, 0x1c6d1af5, + 0xfe3c2192, 0x57e5befc, 0x0e634f34, 0x62e3687b, 0xcaf6b6fe, 0x88c20547, 0x6c4e79e3, 0x396dbcb6, + 0x456c7bd7, 0x96a7eb16, 0xa8665d3a, 0xf1704b85, 0x2f358053, 0xe21b40c2, 0x5db87596, 0x4cf09f46, + 0x9d5e4a3d, 0x32ac4e72, 0x9bdea41e, 0xa5482f4a, 0x6a560d5b, 0x3f534541, 0x329140ee, 0x4db08497, + 0x13d971b3, 0x38fff9cd, 0x1799a92b, 0xf67fbe43, 0x2c0f4d7e, 0x818cf886, 0xea2457d5, 0x74cb7d41, + 0x38089c48, 0x5810daaa, 0xb904e229, 0x5dc8a98f, 0x5cb8b59a, 0xac7f3f01, 0xc970af08, 0x05fa1fb9, + 0x17a2ba3d, 0x292113c2, 0x60d33128, 0x1785d65a, 0xe5982508, 0xd79c3519, 0x6683091b, 0x1080b5f3, + 0xb8184f9c, 0xc99e794a, 0x09ef141d, 0xe0750711, 0x905de708, 0x23618695, 0x50497a87, 0x0235537d, + 0x98e6249d, 0x24528d33, 0x352109f9, 0xfed23f0a, 0xc973fa3b, 0x058b03a9, 0xc0ac8687, 0x3edc9b4e, + 0xbbe925dc, 0x4a92a992, 0xcb9ba5a8, 0x6a39f252, 0x3ea6060f, 0xdcdb0d71, 0xeff93630, 0xe20be088, + 0xd493c639, 0x3c89b1b0, 0xeb5fd043, 0x6172e0c3, 0xa44032b1, 0x99759caf, 0x8e4e1949, 0x4605519a, + 0xc723d5d3, 0x2f9b4e3c, 0xebbe1e2f, 0x1e972541, 0x6afa862f, 0xabece680, 0xc90c0343, 0x6a8b8d5e, + 0x3549314b, 0xb1f360ef, 0x82afb086, 0x417f7f19, 0xc19877c1, 0x73ff652f, 0xed1886b3, 0xdb5451e4, + 0xa96e8ab1, 0x518a3975, 0x5d218afb, 0x7de35abc, 0xaab78394, 0x3cdd1c5b, 0x24898b48, 0xd2c6ce0e, + 0x4fa851aa, 0xa3db9ed5, 0xa8b54d4d, 0xbf7f317b, 0x991a0195, 0x31413319, 0xc782e091, 0x6f5ea41e, + 0xf2df0283, 0x9f353de9, 0x7defccbf, 0xc45858c3, 0x5ec70941, 0x141cb58d, 0x3353e213, 0x16006992, + 0x538f4b70, 0x0a76db78, 0x74b313e5, 0xa77b640a, 0x27678620, 0x0586ef7d, 0xe5191c45, 0x42a47a15, + 0x60966bb0, 0xf5940b86, 0xccd8b42d, 0xbbde4cd9, 0xf48cd269, 0xe8d940ee, 0x61b9561c, 0xc6ee3241, + 0x47fd80d9, 0x09eb276c, 0xd481b58f, 0xed93d636, 0xee10463c, 0x5e59cab6, 0xac754eb7, 0x8af5d3f2, + 0x736da85d, 0x1f2a512c, 0xffaa037f, 0x5f1a1f91, 0xd548bbab, 0x4d6e0529, 0x44d78579, 0x1c8a3655, + 0x700758e7, 0xbd875495, 0x25d758cd, 0x02c1f2a5, 0xcd6f6b3f, 0x76e8f4e3, 0xacd4ab01, 0x0d3a0cb9, + 0x3557e9c4, 0xd5e38dad, 0x95f91a49, 0xf0e5971e, 0x265cd0c6, 0x27b4152d, 0xd57bff92, 0x5b9e4ce8, + 0x2a30f04e, 0x862d4677, 0x0d5d7174, 0xac5fb33a, 0xd6435b70, 0x1da86cc6, 0x4d8804ae, 0x90cf6d4d, +]); + pub const OWNER_LMS_KEY_PRIVATE: ImageLmsPrivKey = ImageLmsPrivKey { tree_type: IMAGE_LMS_TREE_TYPE, otstype: IMAGE_LMS_OTS_TYPE, @@ -237,6 +1196,246 @@ pub const OWNER_ECC_KEY_PRIVATE: ImageEccPrivKey = [ 0x59fdf849, 0xe39f4256, 0x19342ed2, 0x81d28d3d, 0x45ab3219, 0x5174582c, 0xecb4e9df, 0x9cc2e991, 0xb75f88fd, 0xfa4bc6a4, 0x6b88340f, 0x05dd8890, ]; +pub const OWNER_MLDSA_KEY_PUBLIC: ImageMldsaPubKey = ImageMldsaPubKey([ + 0xa9edf181, 0x8ca2903b, 0xd364ae34, 0xd614de58, 0x18e90b12, 0x8760caee, 0x57c06d4c, 0x1c431b7c, + 0x9a7d0f9e, 0xe9cdecea, 0xe6f4d4f2, 0x3fa5fa0e, 0x2161fa18, 0x98fdc152, 0x3bd34aab, 0x955161d2, + 0x44ea42d1, 0x14b25044, 0xcca768fb, 0xc426f8b2, 0x1b1dc6d7, 0x11d3c93e, 0x260b5dda, 0x01add04f, + 0xd43693d7, 0xd1fee110, 0x74c2b640, 0xb01b1e79, 0x6deca0b6, 0x9a0fc5af, 0xda30d600, 0x88d26c7b, + 0xc4c24cd6, 0x057ee05c, 0x23a4cdea, 0x2f5613a2, 0x004ae612, 0x406fbcd7, 0x5ad5fe27, 0x546191b7, + 0x7bbb6bff, 0xbc33fc3b, 0xc731c42e, 0xaee9844a, 0x53ed4a86, 0x80551327, 0xd1de8942, 0xbc6d8aff, + 0x33977eb9, 0x2ef8210f, 0x9d184cad, 0x1f9f8e52, 0xd653f2b3, 0xf07557ad, 0x1f08397f, 0xd67c1e8a, + 0x05dff2bf, 0x26697a4c, 0xa3f9b3c0, 0x35aae338, 0x4bd86680, 0x2ee3bdba, 0xb14dcc6b, 0xdae76a5b, + 0x5a234e5d, 0xeb9d9ee3, 0x763d8f90, 0xbb18e648, 0x8189d961, 0xa408ec7e, 0xee5ba5fd, 0x6e17938a, + 0xe0d1d617, 0x3dadfc75, 0xee2aa095, 0xa41013db, 0xb0e1c446, 0xf753f6bc, 0x57dfb5c4, 0x5a2a1b8d, + 0x20086118, 0x1dadc069, 0x405b37a3, 0x4861260a, 0xce801a93, 0x9a2664c0, 0x835d2b43, 0x27350d29, + 0x23b61b54, 0xa0ed01ba, 0x3b7655c8, 0xcd11b74c, 0x73fa4887, 0x34d4916a, 0x6c4807dd, 0x85924bc6, + 0x9ddc322d, 0x3abe0386, 0x153c9756, 0xd0cae283, 0x985f56f2, 0xc4975ca8, 0x3d931345, 0x292b12a4, + 0xb11335aa, 0x7b51ce33, 0xcc0d9f40, 0x32a36e01, 0xbcde7139, 0xca8ea361, 0x213310e9, 0xeb06c031, + 0xfff30efb, 0x3c8d9334, 0x0abc11ed, 0xd90174cd, 0xbf9a2892, 0x6c7f056e, 0x7bf52027, 0x02c38dbd, + 0x1fc6b7fe, 0x33e0a82a, 0x983e73f9, 0x16eff198, 0x424cc2e4, 0xda99a2a2, 0x7679eb69, 0x38b2e1b2, + 0xf8b7aa69, 0x099d7496, 0xbdca1bc8, 0x3239c2d3, 0xf1ede587, 0xbd259010, 0xf114abc3, 0x135fb877, + 0x5bdafc64, 0xf57ca311, 0x7d55a1ea, 0x6af2cca3, 0x1a5bf6d9, 0x816dcf83, 0x32133dbf, 0xa1c84b99, + 0xae14fb05, 0xdc56492f, 0x66c0c39e, 0xad83710c, 0xce9e6897, 0x8498fe4e, 0x7496ed64, 0x76a8e2e9, + 0x9eedb0bf, 0x37d564ac, 0xccc44941, 0xac25bafc, 0x2b928e78, 0x0153c082, 0x4a7a1d6f, 0xb68a130c, + 0x08108d48, 0xa1687f50, 0x606d1b20, 0x05e2485c, 0x63ce90b9, 0x802e4cd7, 0xc0858c6e, 0x76c5b634, + 0x2e4fe033, 0x7612c7c2, 0x023db18d, 0x63837a2f, 0x935d7d95, 0x4f945b1b, 0xc0daae44, 0x48223d2b, + 0x6a4dd3fc, 0x841888e1, 0xc70e42ed, 0x5f81ae17, 0x8867f430, 0xeac6f08a, 0x420a8cfb, 0xddeb5083, + 0x7873733d, 0x5f475385, 0x294295e2, 0xfb1f2db8, 0x6494d1e5, 0x7957b759, 0x4d028c27, 0xdd478840, + 0xdc68e7df, 0xdf41900b, 0x7cb582a0, 0xe04372f3, 0x3ba64c11, 0x4482541f, 0x5a047003, 0x36932a8f, + 0xbe8ab863, 0xc46cf851, 0x0e57d9fb, 0xb9c7d232, 0x1b9f3561, 0x4b51c902, 0xfbbc3b62, 0xb9434d66, + 0x75c60db3, 0x0fdd59fd, 0xc7cc5cd5, 0x1f86e668, 0x3b9497ef, 0x6476c761, 0x0bc2587f, 0x8f73ae50, + 0xa04c3f67, 0xcf8176c4, 0xc28bd63e, 0xe5232075, 0xdadf6262, 0xe3e9ba2f, 0x429f0860, 0xd7c855b0, + 0x51041db0, 0xb2ca6fe0, 0x396c284a, 0x11cdfe70, 0x3a980044, 0xd29ede2d, 0x80bbdb55, 0x0a6f8ad1, + 0x7f639ede, 0x72a1a813, 0xd81af86c, 0xbf5395fb, 0x7726acc5, 0x3b6fb30d, 0x322861bf, 0xec76a9c2, + 0xdd207eeb, 0x6f3d1ea7, 0x1a8d3f96, 0x930c7201, 0x371b6fa3, 0x4433c032, 0x8a00ea11, 0xf840c9df, + 0x6f5ba9b5, 0x8c38dd6a, 0x0d845211, 0xa15d3490, 0x8039bd57, 0x3b0e5041, 0x6aa08b83, 0x08d412e5, + 0x5474e803, 0x9c015cbd, 0x26a065fd, 0x0bee7534, 0xca1d9aa6, 0xc252daa6, 0x61619a88, 0x9d8850f7, + 0x439fc928, 0x99ca3ca6, 0x8bc9f696, 0xfa9cd591, 0xd458839c, 0x800c3844, 0xeaf3d1ec, 0xb2091964, + 0x29018964, 0x775b34a2, 0xd06de4b4, 0x6a25681b, 0x073fc9f8, 0x9188605f, 0x2c9c8e75, 0x6caf217f, + 0x49ff9c5a, 0x59f182ca, 0x7d4051ff, 0x6c0c83ab, 0xe5374894, 0x76fa7c70, 0x0078a93a, 0x50e7843a, + 0x3dfd2077, 0x7f7bef16, 0x91375673, 0xbdc22b88, 0x3e580c18, 0xaa43eb88, 0x6fec172f, 0x8d0e9256, + 0xece1bc9b, 0xce493fdd, 0x8969d311, 0x27676663, 0xf51e75f5, 0x00cd58bb, 0x01582bed, 0xdd5d5a24, + 0x6dfdec4f, 0x96d83661, 0x52ff4ad6, 0xc5715662, 0xb462bc46, 0x9bb58efe, 0x87f0c2b2, 0x0acc719b, + 0x61173b74, 0xbed67b3d, 0xd755d372, 0x1e811efb, 0x85779a8f, 0x55fbc12b, 0x1f386d46, 0xa5774522, + 0x14385289, 0xee4cd6fc, 0x652d160d, 0xe0788f01, 0x4141e9ef, 0x8160a67b, 0x4980141a, 0x9a3ecebb, + 0xf30614a7, 0x6dcd5387, 0xfa59906e, 0xfd86cca1, 0x6fe27d63, 0x89ae7cbf, 0x537c695e, 0x85915342, + 0x6dcce6e2, 0x345bd54e, 0x2002a238, 0x0509513d, 0x8cbb738b, 0x56419b12, 0xf58986c5, 0xae2e9152, + 0xa58b9904, 0x8d2c3015, 0x0bb68e79, 0x55ddacf1, 0x392223b6, 0x1262d7f3, 0xa17e595a, 0xb07850fb, + 0x05e0618e, 0x11b4a1d3, 0xb874d706, 0x33593c24, 0x00b06880, 0xda2ea3ba, 0x9ee72613, 0x2f30a0ba, + 0x703a5124, 0x43605551, 0xc9b4036c, 0x886edf8c, 0x330cc0f1, 0x622331d7, 0x50c2f160, 0x13045f4a, + 0x6d256f58, 0xee389395, 0x4e5276b9, 0xe07d3cbe, 0xacca856c, 0xf401596e, 0x80ead6c5, 0x24276a01, + 0x8f21b769, 0x6aec714a, 0xd9c82a5f, 0xe1f3d888, 0x39629df0, 0xf5285a0d, 0x6ac3ffd5, 0x9e172d30, + 0x3a224dd6, 0x11581a25, 0xcb029443, 0x71bfe4b4, 0xc43cb7e2, 0x46b4faaa, 0xeee795ff, 0xb3aad498, + 0x29964d98, 0xcdf245a9, 0x04de106f, 0x1042f8f1, 0x417ac1e1, 0x4396fd42, 0xd09ad4f3, 0xdae8eec8, + 0xde14cf86, 0x9c076dae, 0x2991ef52, 0xd38e041c, 0xe8c6b5ca, 0xf0ec147a, 0xd14e40b6, 0x3c3b6c88, + 0x68a02855, 0x80165424, 0xd3b18ce7, 0x13dc003b, 0x77764082, 0x90304a85, 0xe34674c5, 0x33ae75d9, + 0x63bf9638, 0x0f24e8fe, 0x80ce8f7e, 0x9b98a3f9, 0x28206561, 0x7e08dc2b, 0x904cadb0, 0x45a25183, + 0x1ff478dc, 0x83c34ec9, 0xfdb2bcd6, 0x2f2146fb, 0x9139bd89, 0x309bf6e5, 0x5b0fcb30, 0x2826fbbb, + 0x9e079a3e, 0xe5a1e804, 0x5f22236a, 0xef64b60f, 0xa0782191, 0x5c4fc08c, 0x5b1c1565, 0x8d07e923, + 0x12228a9f, 0x110f1a89, 0x778eb329, 0x071eca05, 0xdc5a40f7, 0x48e68677, 0x3affe364, 0x8444431a, + 0xde0de523, 0x2046267a, 0xe9575a36, 0x4ebc7d1b, 0x9c5f4851, 0x716c5f77, 0xb9ab7634, 0x15c7263c, + 0x039509e8, 0x332806ac, 0x03617595, 0x6fd4f350, 0xe856d73e, 0x267715cb, 0x74acc70e, 0x1fd15a90, + 0x51382b6a, 0x7e891b6e, 0x5f4a2522, 0xf96c6ea5, 0x699dcd73, 0xf933f8ff, 0x7f281bad, 0xf5e7b8a8, + 0xf2fd42ad, 0x5eb5b70b, 0xcc0ff682, 0xf104102a, 0x73799523, 0x1a69423b, 0xd01e5cc0, 0xdd68c064, + 0xf29e5036, 0x0376e13c, 0xd3202d76, 0x82167410, 0x9ba53d4e, 0x0d59f401, 0xb4d0162d, 0xfa140b74, + 0x670214d5, 0x3b5e8acb, 0xac1be132, 0x97e52a12, 0x957588dc, 0x9cc12968, 0x0b4d2665, 0x0cd524f1, + 0xb8e46f1d, 0xb41bea5d, 0x991cc28a, 0xa6a3ed19, 0x46fe159c, 0x3eff070e, 0x2740c5d7, 0xe9c38078, + 0x9dc8b6ff, 0xfe141cd9, 0xa4b95b04, 0x3b0f241f, 0xef8d6eaf, 0xe461f23c, 0x69f9200b, 0x4596757e, + 0xb8b11b89, 0x01e0ae5a, 0x38687fd1, 0x99d20225, 0x9a220401, 0xe7055116, 0x64230d61, 0xeb8a55fd, + 0x765f2bb9, 0x5eff9147, 0xa4c86af8, 0x5593e0eb, 0x96b82ca7, 0xc4814f2e, 0xd259e8d3, 0xbb1234ed, + 0xf6f38432, 0x899ba5a4, 0x6ff4225b, 0x9ee7117b, 0x4cad1aa1, 0xcb99a376, 0x3ea69eb9, 0x7c6b971f, + 0x29839dba, 0xc31db6f7, 0x69815b18, 0xb5343677, 0x73f81d85, 0xb277990d, 0x79ee8ad6, 0xbb177961, + 0x6bb475a6, 0x2204b474, 0x8b4aa996, 0x7fe608ea, 0x366aae72, 0x1aa5b878, 0xd529b26a, 0xadab4f38, + 0xf54baa55, 0xb69b0048, 0x55d1a676, 0xd7ab2146, 0x53b4eded, 0x70aab061, 0xa18f2250, 0x45280dc5, + 0x31bc9a28, 0x9b8d3797, 0xe2cb1ded, 0x7c036185, 0x40a096d8, 0x9ea26872, 0xd9afa9d5, 0xe605ec82, + 0x2901edae, 0xd9631cc7, 0x048cdb68, 0x8d3cdf75, 0x0829f08d, 0x593cfb9b, 0xd5bb0bc5, 0xcd320692, + 0xf42353cf, 0x548b8309, 0x84301f99, 0x848c3414, 0xec1b95ef, 0x7633b520, 0x490fb309, 0x4be3337c, + 0x710fba4d, 0x604a628c, 0x86369ca7, 0xf16d4fcc, 0xc0aa76db, 0xcb31420f, 0xed8258bb, 0x1f9475f7, + 0xb40a83e2, 0x81cc090c, 0x0d40bda7, 0x669fc89d, 0xa45a9a13, 0x3c94fc17, 0x2c2a4ad1, 0x073d85fd, + 0xc6770a51, 0xced5344f, 0xdd079bd5, 0x1db63096, 0x4369137d, 0xe3c630b8, 0x8d1dea6c, 0x132db9fa, + 0x17356e05, 0x97b46adf, 0x0f1110d7, 0xd51cc9d9, 0xa6f45ae4, 0x1b80f8a2, 0x48784324, 0xfacfa6de, + 0x872f6713, 0xfd469ddd, 0xce3fed1e, 0x1f563412, 0xbcd00aae, 0x6ebf366a, 0x4127d1d7, 0x67a6ae1b, + 0x0c88b9b2, 0x18067649, 0xb44fede0, 0xbbeed2b4, 0x7dc52499, 0xbd3bbbf4, 0x15b16ea1, 0x7b61ae52, + 0x09c4be4d, 0x421c22d1, 0xda6807cb, 0x91cc1b38, 0xe48b104f, 0x5512727c, 0xa56c9e15, 0xf140dd46, + 0x41df9ac8, 0x652b787c, 0xd5e0d7ca, 0x0cd0273b, 0x4018b74d, 0xdfeaaeb8, 0x27e1cf84, 0x6ccfd694, +]); + +pub const OWNER_MLDSA_KEY_PRIVATE: ImageMldsaPrivKey = ImageMldsaPrivKey([ + 0xa9edf181, 0x8ca2903b, 0xd364ae34, 0xd614de58, 0x18e90b12, 0x8760caee, 0x57c06d4c, 0x1c431b7c, + 0x96e09924, 0x3390088f, 0x4d2050f4, 0xf5b72751, 0x1b02227f, 0x924db512, 0x1e232203, 0x8e4b084e, + 0xe4e40d01, 0xa63ea9d9, 0xfc282aa4, 0xd0029632, 0x07aed24d, 0xdf7f7abc, 0x30dbe1b8, 0x4af84aa4, + 0x0262e156, 0xeef18774, 0xe0a0d2a0, 0xfa132f76, 0x15b720d2, 0x6772af13, 0x89f1e394, 0x22d54bca, + 0x80480581, 0x1601e0a6, 0x2192a881, 0x11a388d1, 0x0292d426, 0x211ba169, 0x0331861a, 0xc7890a01, + 0x8c0ca56d, 0x24466444, 0x40840201, 0x4d102010, 0x18c00c13, 0x430613b6, 0x6480c864, 0x20b86c02, + 0x95290a35, 0x26923484, 0x51408093, 0x38851b15, 0x8adaa06d, 0xe4c02880, 0x02659b22, 0x8ddb3068, + 0x9122625b, 0x30121809, 0x90032052, 0x0c4348d1, 0x208c6294, 0x6d54c884, 0x48465004, 0xa32d0027, + 0x4ccac200, 0x4ac270a2, 0x12690c21, 0x45538468, 0x48062223, 0x16466320, 0x225c1202, 0x4a2225cb, + 0x20258912, 0x10533426, 0x62b44c43, 0x86300887, 0x4cc8a208, 0x24b86188, 0x12690ac8, 0x911a1764, + 0x90b00102, 0x138a0ba6, 0x4122b764, 0x08262a42, 0x842844a6, 0x84111982, 0x80186d00, 0x12062398, + 0x28ca346e, 0xe1a288d1, 0x4441d3c6, 0x9118b809, 0x44924844, 0x220c1047, 0x05091000, 0x5a2821da, + 0x18481b91, 0x41581640, 0xd93001c9, 0xc2000b98, 0x6d8b1022, 0xe2c401d1, 0x9444cc22, 0x49988068, + 0xe138090b, 0x329122a5, 0x29200046, 0x59b80820, 0x112849b4, 0x7189c04d, 0x1cc23023, 0x1221dc16, + 0x31c3a005, 0x0015485b, 0x2406ca00, 0x6ca0a820, 0x50a44ca1, 0x968d5394, 0x81c03671, 0xa2304ad2, + 0x98210091, 0x20134569, 0x90166cdc, 0x3270e290, 0x080a894c, 0x43102892, 0x92504ba6, 0x8c64046c, + 0x4438415c, 0x14711491, 0x8511a144, 0x904405dc, 0x28125904, 0x4220a751, 0xa1a020a3, 0x24219c30, + 0x6080c491, 0x19270d12, 0x42041a33, 0x8a42c620, 0xd2888090, 0xa6901034, 0x00101884, 0x042189da, + 0x424dc4b2, 0x08531020, 0x91949054, 0x38302238, 0x40120210, 0x0b320512, 0xc6451380, 0x8889826d, + 0xa44802dc, 0x84308892, 0x251c3900, 0x19b16993, 0xc2884bb8, 0x001ca568, 0x44400490, 0x32421ac4, + 0x65cb322a, 0x9ac49110, 0x8445c408, 0x894a044a, 0x01c33158, 0x22889884, 0x69a21872, 0xca2826d0, + 0x20291126, 0x50c31011, 0x042101c9, 0x044a6218, 0x8d5b9831, 0x43004ec8, 0x92852281, 0x4c200071, + 0x80a29008, 0xa7400a19, 0x28023869, 0xc34882c2, 0xb4490840, 0x4a644442, 0x4cb8444a, 0x068262c6, + 0x401a1065, 0x0bc320d4, 0x486a00b7, 0x08432865, 0x0a8691a1, 0xa22de4b8, 0x4142c62d, 0x00845019, + 0xb184cca4, 0x09133262, 0x50b28112, 0x25621bb0, 0x4493b681, 0xa4a489c9, 0x12850c47, 0x651b8908, + 0x903491c0, 0x346d6142, 0x0943b025, 0x09914098, 0x24045148, 0x0e0a8421, 0x9ba80ce2, 0x10210829, + 0x64e42230, 0x8b9221d9, 0xc6840017, 0x20021545, 0x11262211, 0x334600c6, 0x4112128e, 0x99a84823, + 0xb20c0c12, 0x0d1b4068, 0x88b28921, 0x276d0384, 0x04049471, 0x91980943, 0xb804c1b6, 0x2c614848, + 0x49200ad3, 0x42451117, 0x1001a405, 0xd9086220, 0x40212384, 0x11024770, 0x200791c8, 0x168a91a8, + 0x48182006, 0x899425e4, 0xc0884226, 0x889a9880, 0x02284802, 0x39325206, 0x8ee24092, 0xc8082ee4, + 0x80218cb6, 0x10128610, 0x48160990, 0x081288a6, 0x0593a220, 0x58282c82, 0x28288908, 0x68214684, + 0x02a0655a, 0x1691d326, 0x8d4bc669, 0x4cb8640c, 0x32845024, 0x31cba085, 0x94948c1c, 0x928cd428, + 0x20230502, 0xc0946d21, 0x29641b88, 0x3022436d, 0x8a4431d2, 0xa044a042, 0x72011341, 0x02372ae0, + 0xb60d1b07, 0x0ee13060, 0x04094a8b, 0x16319bc0, 0x604b862c, 0x8b042219, 0x282899c4, 0x218c1050, + 0x00986511, 0x22900b15, 0x45d42484, 0x9c084043, 0xa6895244, 0x00094240, 0x914805da, 0xc02ca214, + 0x84120469, 0x5c388520, 0x024494a4, 0x70904020, 0x512226a3, 0x408d0b15, 0x2a422262, 0x03898cd2, + 0x4825d8a6, 0x0108478d, 0xa0906c19, 0xc10d8346, 0x6d13386c, 0xa0220259, 0x18666112, 0x6420116a, + 0x1238611b, 0xc00d1381, 0x680c0068, 0x12340c64, 0x329092b0, 0x21c8400a, 0x8014850a, 0x424e2012, + 0x6d9ab86d, 0xd432881a, 0xa8718306, 0x02611009, 0x04252d40, 0xa671e008, 0x6808376c, 0x64106899, + 0x2485e102, 0x641b4064, 0xa0088444, 0x90056342, 0x24c19844, 0x90926190, 0x22210083, 0x21118720, + 0x23b66cd1, 0x28259904, 0x8c00260a, 0x4a2868da, 0x406c4b44, 0x6189b86c, 0xa4088688, 0x342c4c28, + 0x92002232, 0x82a28494, 0x248c1ac8, 0x8062a451, 0x81a088c9, 0x40711405, 0x6e422649, 0x01044920, + 0x30085cc0, 0x2849c810, 0x4b180d9b, 0x84894a34, 0x31d92629, 0x1917011c, 0x007221c7, 0x51244844, + 0x42101114, 0x87516126, 0x06818664, 0x24948d21, 0x06290c08, 0x21432289, 0x218689cb, 0x38015c38, + 0x2dd8466a, 0x8c002018, 0x346553a8, 0x09838071, 0xd01010c8, 0x04081c39, 0x6958b209, 0x64486e18, + 0xb125e410, 0x2c821269, 0x49404822, 0x0082e412, 0x68db3204, 0x01c39053, 0x862c2133, 0x2e5a1490, + 0x1ac22444, 0x10240b26, 0x1008a828, 0x191025c1, 0x20809a82, 0x690c1411, 0x01185202, 0x205044c4, + 0x2cc90064, 0xe3862548, 0xb42d2346, 0x1054b88c, 0xd1025223, 0x3360c294, 0x0510122e, 0xdab849d0, + 0x04910986, 0x8c1c4810, 0x24b37142, 0x12425a92, 0x25242944, 0x54b04110, 0x260ecac0, 0x0d649829, + 0xe8b9c7f9, 0xc23dbc6b, 0x4220609d, 0x1f24e383, 0xe8166c04, 0x1c6acaed, 0x3c793662, 0x5789659c, + 0x2049e56e, 0x28525f79, 0xf5555fc1, 0x0b4e6814, 0x1b6acc83, 0xf0676949, 0x11180962, 0xd9917486, + 0xf8f27850, 0x8cfb76b6, 0xeda5b6b3, 0x3320a838, 0xf881b854, 0x9a8734ac, 0x9961416b, 0x6d599ab6, + 0x200a7153, 0x31a3ae66, 0x949e21f8, 0xfc1baf69, 0x6f842410, 0x6a6a7843, 0x1096b8a7, 0x3d679633, + 0x27816715, 0x022361de, 0x136e3ac3, 0xe9de78e1, 0x759ddb9f, 0x39a47760, 0x31c516a3, 0xebb0d646, + 0x546dee41, 0xd7c63fdb, 0x3ee71e0c, 0x65d95bc0, 0x36485f66, 0x872dacd1, 0x0519a0e9, 0xfc3756c0, + 0x44742f5a, 0xbd08f1af, 0xf8cc5855, 0xc00834e2, 0x867bed1e, 0x20309bd9, 0x9d7799af, 0xd66dc882, + 0x2c513bf3, 0x02c674c2, 0xc63c4fc5, 0x3e1ac8aa, 0xf59f2eab, 0x037058c2, 0x9b009798, 0x1537b864, + 0x9cbb3e73, 0xd960cb98, 0x49a0b1c3, 0x6dc496c2, 0xc259f374, 0xad6d8313, 0x658aafdf, 0xfad50391, + 0x69070ddd, 0xb478112d, 0x219b270c, 0x24d5c164, 0xa790c775, 0x6b06fadb, 0xe99bf637, 0xc78783fe, + 0x6201a263, 0x1aa807fd, 0xc4bcf998, 0x6cb44a4d, 0x73f49f17, 0x8e97e557, 0xa73198b2, 0xdacc791e, + 0x536eab9d, 0x4ace9692, 0x9e0ed687, 0xb53ec019, 0xf2ddd342, 0x338a90ce, 0x2ca620c0, 0xdaa1e1df, + 0xa17eb53d, 0x637a9ef7, 0x8632738d, 0xe9a4be38, 0x7e67a8d1, 0xe53a8876, 0xcdfc829b, 0x02c4b16a, + 0x51782d1a, 0xe5543849, 0x71dcec5d, 0xa4ec3caf, 0x172c6d9e, 0x34f7a8a2, 0x07c6b3c3, 0xcd346c19, + 0x0c585e77, 0x7f8ef441, 0x43f5a58e, 0xdca6b700, 0x30a4ef7d, 0xbee8c7cb, 0xc6dc09d1, 0xffd897e3, + 0x756a95a2, 0xb791dda0, 0x57ea01da, 0xd58e53ba, 0xc37334ad, 0x786addd8, 0x6882c7ad, 0xcb77c4b4, + 0xd497f47b, 0x44305bcd, 0xb85cc8f7, 0x5ecd4efe, 0x76223a43, 0x4474ca8e, 0x1cf467e5, 0xf73dab15, + 0x64fe66f4, 0xfc03b12a, 0xbaafe69a, 0x9f85d30a, 0x30cf54ec, 0x91477b87, 0xf0f86b72, 0xc7ea4b05, + 0xdba9ef2c, 0x0b6de1a6, 0xad135073, 0xc7d6bad3, 0x18ea282e, 0xe5ee87b6, 0x90dd1da2, 0xc209f08e, + 0xaabd400a, 0xe898a156, 0xc41902d5, 0x70f1e261, 0x4affdb75, 0x3d387ecf, 0x269e7e4c, 0x28d6f46e, + 0x4695378c, 0xb15dcb9e, 0xfc8f0e8e, 0xda7baa8e, 0xffe031ad, 0x5f524886, 0x7a9bce75, 0xcc84f37b, + 0xc30b9b00, 0x0a6ab5a4, 0x22ea5fcd, 0x81ff5fbf, 0xeec75195, 0xb3e9a80d, 0xf012a016, 0x3b630fcb, + 0x64c81c97, 0x2d0a94ac, 0x92d16ca1, 0xf43e3b6e, 0xdf411d87, 0xc7eaf235, 0x822d3988, 0xc38e7708, + 0x9a88cecc, 0x0fe8d7a9, 0x09dc4281, 0x74081bbd, 0x2287cd53, 0xf4420b3a, 0x63ac2dd8, 0xccb970cd, + 0x694777ce, 0x93b5d4ea, 0xc1d77e08, 0xd4f3ec57, 0xe3819b61, 0x262495c0, 0xd1ede1b1, 0x6cad8aad, + 0x5af6dbc4, 0xd8e88da1, 0x85105b3e, 0xe6249caa, 0xc4ecb948, 0x9a1f9968, 0xa794346f, 0x554c5f41, + 0x2bead684, 0x3921a44a, 0xd8065e60, 0x0a3a8eca, 0x88b54852, 0x6642a521, 0xe4ab32e3, 0x7672249d, + 0x04cb729c, 0x5dc6d091, 0x433951c2, 0x30e63ce8, 0x0cfdc827, 0x90ea4bb1, 0x22e958d8, 0x03463b16, + 0xc4d531c6, 0x6b84084f, 0xe0dbd384, 0x12191ed3, 0xf663555f, 0x4aa7fde0, 0xafdb367f, 0x54c379a1, + 0xfa6ce9ae, 0xd42da422, 0xe415c0aa, 0xc85bdbad, 0x8629efc4, 0xbd150a35, 0x1d276e43, 0x201b42fa, + 0xb21a7fb1, 0xacc33522, 0x51b22a7a, 0x2dec4eff, 0xa0043754, 0x7f779d8a, 0x8ca10220, 0xda3c472e, + 0xa58c8f3c, 0x96ac701f, 0x58b99778, 0x10285fa8, 0x90861cc0, 0x48cfc58f, 0xfd645307, 0x621297fc, + 0x2ff0584a, 0x68db0197, 0xd97d1704, 0x804e8d4a, 0x02e283fb, 0x27ec1473, 0x72865316, 0xa54c6812, + 0x4806a764, 0x91a75120, 0x6bc17bf0, 0x05810793, 0x0013abb4, 0x4eb1cd77, 0x6a74a433, 0xa7753557, + 0x19d405cc, 0xa7526138, 0x716357c7, 0x03591820, 0x4179a9ca, 0x2567f0db, 0x23839632, 0x34511972, + 0x85a08f21, 0xaf31fda6, 0xbe348234, 0xd3b7a044, 0x6cdb9efa, 0xcb3da517, 0x1b05ee9b, 0xefcf07ca, + 0x4da1cbb1, 0x406508dd, 0x8e2288da, 0x190a8c79, 0x8d4a1146, 0xe3a51f72, 0xb7c4dabd, 0xa432e88c, + 0xd2aad6ca, 0x34c59ba6, 0x1c23f041, 0xd7cc940e, 0xd62a7fba, 0x38157303, 0x17d3cc14, 0xb0cafb46, + 0xcc43536a, 0xd705059e, 0x55ef2e5f, 0x85b495bf, 0x76b8cfc4, 0xb2c0e926, 0x751c50a2, 0x3af6a072, + 0x2bddd143, 0x6f3a8b33, 0x83232fb8, 0x767d34c6, 0x91b36a46, 0xd2c9b1f2, 0x5c727391, 0xdc78b7fc, + 0xcf8a8141, 0xe4ac79cf, 0x49b9c046, 0xe992bf74, 0x62c888e3, 0xed890ef7, 0x4cbbad2c, 0x00c8a3f6, + 0xf7fbd420, 0x70bcfaac, 0x3703db70, 0xe9534913, 0x42922ddc, 0xf435dafa, 0x79e474b8, 0x8f45eca6, + 0xd345b788, 0xd1bb7400, 0x1ba4ef65, 0xec227365, 0xaa61e5c5, 0x885039e9, 0x4d82d065, 0xcfba7fbb, + 0x7e7a70c4, 0x88ec55d5, 0x7f0408c7, 0xc2319441, 0x29559cd1, 0x2b6aa5c3, 0xa1587b2b, 0xe8bdb4c3, + 0x8ca1c0de, 0x2d320459, 0x3d90584e, 0x54524bb3, 0x5022bef2, 0x38d12c32, 0x7f12b4ec, 0xe081434f, + 0x14cc84a2, 0x448e3844, 0x97b3cade, 0x4f05b16f, 0xc1ecccbd, 0xe5d83abd, 0x45789747, 0xee5a0b4f, + 0x03341703, 0x028e4f4c, 0x8df55734, 0x7dca8211, 0x5876ed05, 0x03a32b26, 0xbc158747, 0x0e3f127e, + 0xeb5eaffb, 0x3a084860, 0x3a293513, 0x15ac4a85, 0xad8aafa3, 0xf66177ef, 0x71f4edbe, 0x333871a3, + 0x7cbd5a35, 0x566ccc75, 0x9ceac3d6, 0xc83669b4, 0xf3bcc824, 0x1f3ae324, 0x43b4bc7b, 0x0e89c64b, + 0x64a6d5ae, 0x431dc05f, 0xa3fa240f, 0xb554ad67, 0x79fb1001, 0xc0ebbb03, 0x2e9d8315, 0x8a5d4e41, + 0xb6e14048, 0xf2dddb9b, 0x53e893ac, 0x7bd7d7ce, 0x15f24cd3, 0x387faa8c, 0x0a383d3e, 0x07edc260, + 0x1400221d, 0x5b20954b, 0xff9a5bfa, 0xb4796281, 0x54f864f3, 0x9b44501b, 0xa9f7db70, 0x59a68e41, + 0x032eafd7, 0x6ae3ed54, 0xdab736f9, 0xc89e7293, 0x3a92fabd, 0x3a16232a, 0x50f82e42, 0xa10bee0b, + 0x6fae2e67, 0x80d6833c, 0x304f4952, 0xc5226ca9, 0x1cfc6e6b, 0x6ec7c4f4, 0x777e4e3d, 0xbfd5bafb, + 0x88a75583, 0x6005f437, 0xfd0e4806, 0xb4184a44, 0x3d3bb53a, 0x8586986b, 0xdb1a3460, 0x176036b8, + 0x51804b0f, 0x47aa649f, 0x89c403c6, 0x5eca96b6, 0x83eb71e1, 0x4b9f7092, 0xa69ec4e0, 0xaf1aa1de, + 0xfa91d553, 0xae7a87ae, 0x05aee90e, 0xa5f1d67c, 0x9b5b3a5a, 0x8eb36024, 0xaed5340b, 0x7b849665, + 0x9990b354, 0x0481d276, 0x37719dc4, 0xd6c6b670, 0x489a6191, 0xdf92ebf2, 0x2224e920, 0xf8b600a8, + 0x5908a149, 0x8acdbac1, 0x36122717, 0x5a153f58, 0x79b20e80, 0x5c206841, 0x3c13d457, 0x8326207c, + 0x9b2ccae9, 0x9b3974ef, 0xa13e0448, 0xa08f5e5d, 0x09d9d139, 0xcad491e6, 0x2f61d91e, 0xe732babe, + 0xade3d065, 0x764a37ef, 0xa96632b6, 0x32b025c8, 0xd0b13a16, 0x0ad89f96, 0x645b8557, 0x10b0f790, + 0xe9243d3a, 0xec9b4d3a, 0x75571796, 0xca6b3a50, 0x528ef73e, 0xdd3ebe43, 0x2049810d, 0xab256b64, + 0xe3cdb52d, 0xe6968fca, 0x6bc4b9f8, 0x0e435960, 0x0b162dd3, 0x5c54fc67, 0x8d2b96c7, 0x054ce5da, + 0x9ad99f7f, 0xb37baa12, 0x73ce5bde, 0x98381447, 0xb09792da, 0x892c2a92, 0x719aedca, 0xe203a4df, + 0x8380b847, 0x51a359aa, 0xf38e85b0, 0xe154b115, 0x1fbff8fc, 0x962fb5a0, 0xfdaa97bd, 0xa129620a, + 0x3ae88938, 0x4767bd22, 0x261a5cba, 0x0e8fef67, 0xa8d8ccd7, 0xfa7fd7c1, 0xb39cc047, 0x6bb69a1f, + 0xeb5f6afe, 0x8550dc3f, 0xc1323d50, 0xb0954273, 0xbfec3437, 0xed482668, 0x1b6c4f47, 0x2ce96a82, + 0x6c012381, 0xee4c7745, 0x49257789, 0xf481eb4e, 0x36a48493, 0xb2b90147, 0x9c5ff3cb, 0x6c4782c0, + 0x9e0a0137, 0x9b56445a, 0xdfbb5eec, 0xdf7e8b46, 0xc5bc0237, 0x33983f77, 0x377adb00, 0x9b263594, + 0x5bbfbc58, 0x50d3cac9, 0xfe52f22c, 0x28df0401, 0x55f772aa, 0xafdeb4e6, 0xf7f9c990, 0xdab1df3f, + 0x25c58828, 0x47c572b1, 0x47178007, 0xf26d0ba5, 0xa14498f3, 0xafab85bc, 0xbac276b9, 0x0137fa35, + 0x8a61d4a3, 0x4116049b, 0xe74cbb93, 0x111fceb5, 0xdfd59167, 0x19e99dd3, 0x44dfc252, 0x722b3cde, + 0xf2cd8879, 0xe0008864, 0x0cf9dfb4, 0xa055e582, 0xa35141b7, 0x2b2feff8, 0xc7889c65, 0xcaa20356, + 0xa23bcf57, 0x16f919b3, 0xa98d36b1, 0x1957b858, 0xca5a8b82, 0xbd1256d8, 0x5414753b, 0x877dafc6, + 0x86395346, 0x271913d6, 0x4284ab49, 0x74f00ac3, 0x907e3a19, 0xdc776637, 0x39905d92, 0xdc7e6540, + 0x29fc13ce, 0xf6444416, 0x01db39ad, 0x22c10bf4, 0xa2d95fbc, 0x26aad96d, 0xc83d64c2, 0x68b8d6be, + 0xfa99283e, 0x68f59e81, 0x90002aee, 0xbd364c68, 0xc9aba7d0, 0xba6467d4, 0x0c706523, 0x55f8331a, + 0x39aed764, 0x2469f25b, 0x31e63695, 0xb31f8825, 0x99f6b312, 0x249f0a26, 0xacc53a30, 0xe703773b, + 0x8f422869, 0x2028e3b6, 0x3b01fb82, 0xc640cdac, 0x391e3862, 0x58673342, 0x36aab4ba, 0xe2c6162e, + 0xc775aee7, 0x55f03353, 0x0d788b24, 0x94314ade, 0x97732da1, 0x98633625, 0x7fb5ef7e, 0x9e18a8a9, + 0x9be2ad60, 0x8ce63d60, 0x4f1642eb, 0x4f09b173, 0x02d75da7, 0xadca9607, 0x747cef0f, 0x6af08095, + 0x3a79c9ea, 0x3cf1dd97, 0xef4dde52, 0x4de93246, 0x7cb7f300, 0x4fc84fa3, 0xffb31118, 0xd062c26e, + 0x289f0763, 0x1ada6075, 0x5b4861ab, 0x926479bc, 0x4f7ffde1, 0x61962df3, 0xdbed6bd9, 0x4914b5b9, + 0xf47cee07, 0xefc3314c, 0x6a7a6f67, 0x90dccc5d, 0xb235a956, 0xc9cdd58d, 0x5b72dc1a, 0xbae72880, + 0xba002a6a, 0x1b47ba27, 0x310cda7d, 0xc712f080, 0x5418c6bd, 0xa786e406, 0xe342e51f, 0x7a89dd78, + 0xda3b85c6, 0x130854bc, 0x0c841032, 0xdecf3d38, 0x828280c4, 0xfd793fc5, 0xe42deeb1, 0xc2ca0835, + 0x56c5917e, 0x44dacce4, 0x3470f808, 0xa7069123, 0xefd5dd01, 0x0b891398, 0x16a2d2aa, 0x6fc0b54f, + 0xacaf0721, 0x00f1528d, 0x9d9b94d4, 0x0024ce52, 0x76022521, 0xb5fc9ace, 0xf8a2807f, 0xbaed124c, + 0x3e8f265c, 0x029d32b2, 0x8cd781cf, 0x30dab5c4, 0xe58533e5, 0xe36c473c, 0xe9a4bef9, 0x204dc928, + 0x06c5bb8c, 0x48e66f89, 0x466429ed, 0x8547bd23, 0x6e5429e1, 0x79f892d9, 0x4ae12005, 0xa8bf5d2f, + 0xca081816, 0x5003046d, 0x754f949d, 0xfd3ce99b, 0xe2d5b673, 0xc64dfa92, 0x58e6e616, 0x9d197ff4, + 0xad43a9b2, 0x19b1a2b7, 0x0c6ba056, 0x4ee60270, 0xefc06c28, 0x9ace693c, 0x15e48637, 0xcbf3da6d, + 0x4d3dead8, 0xe2cabbc9, 0x543fc38f, 0x6918599e, 0xb50dc0cf, 0x31623061, 0x9595fe5f, 0x92bcabe3, + 0xb86f2b58, 0x37b3ff6a, 0x0f7d1a97, 0xf8ae3b46, 0x2642c9b0, 0xe88e7c6d, 0xc31d5bf0, 0x3423f888, + 0xa8b94edd, 0x8110815f, 0x01d8bece, 0x22d13954, 0x0b91b4f4, 0x52877919, 0x3341edac, 0x70a08054, + 0x101eae37, 0xb2ee8b41, 0xa0143e10, 0x40945ebd, 0xe4fe71f1, 0xb599ff3c, 0xc923c3cf, 0x889f8708, + 0xa65f1eab, 0xeb4dee86, 0x74ce79f9, 0xc9920734, 0x619de7ef, 0x56c8ced8, 0x459ccd5b, 0x716dec10, + 0x18ef6b23, 0xfd15d916, 0xabd7dd35, 0x524da8d2, 0x4e018f01, 0xe1965985, 0xcad5cf3b, 0x96d9d398, + 0x1678fff8, 0xdf33d2cb, 0xdee41e97, 0xe3afd430, 0x315279d4, 0xd69e68ce, 0x7c08c6fb, 0xe873f1db, + 0xc61bee3b, 0x5b5def66, 0xbbea475b, 0x5d95fdf6, 0x615d22b1, 0x9078ecb8, 0x5b65387a, 0x039b9726, + 0xa5a06912, 0x4d9552b3, 0xde16916f, 0xe3b341bb, 0xef5f1c34, 0x70d5baef, 0x38774f0c, 0x63592edb, + 0xed63bc5d, 0x3284fe16, 0x77b81382, 0xa514d7c5, 0xecc9b4d7, 0xef4caac5, 0x0f2132ec, 0x0f59b2d1, + 0x844953aa, 0x6da7de93, 0x51517608, 0xe4979c9d, 0xae0ada00, 0xa4771757, 0xe04b7f77, 0x25e557e8, + 0x99937648, 0x00639c9f, 0x403ac714, 0x5b1333ba, 0x5f20370b, 0x665c6205, 0x9734759f, 0xedb7b002, +]); + pub const VENDOR_PUBLIC_KEYS: ImageVendorPubKeys = ImageVendorPubKeys { ecc_pub_keys: [ VENDOR_ECC_KEY_0_PUBLIC, @@ -278,11 +1477,18 @@ pub const VENDOR_PUBLIC_KEYS: ImageVendorPubKeys = ImageVendorPubKeys { VENDOR_LMS_KEY_2_PUBLIC, VENDOR_LMS_KEY_3_PUBLIC, ], + mldsa_pub_keys: [ + VENDOR_MLDSA_KEY_0_PUBLIC, + VENDOR_MLDSA_KEY_1_PUBLIC, + VENDOR_MLDSA_KEY_2_PUBLIC, + VENDOR_MLDSA_KEY_3_PUBLIC, + ], }; -pub const OWNER_PUBLIC_KEYS: ImageOwnerPubKeys = ImageOwnerPubKeys { +pub const OWNER_PUBLIC_KEYS: OwnerPubKeyConfig = OwnerPubKeyConfig { ecc_pub_key: OWNER_ECC_KEY_PUBLIC, lms_pub_key: OWNER_LMS_KEY_PUBLIC, + mldsa_pub_key: OWNER_MLDSA_KEY_PUBLIC, }; pub const VENDOR_PRIVATE_KEYS: ImageVendorPrivKeys = ImageVendorPrivKeys { ecc_priv_keys: [ @@ -325,19 +1531,27 @@ pub const VENDOR_PRIVATE_KEYS: ImageVendorPrivKeys = ImageVendorPrivKeys { VENDOR_LMS_KEY_2_PRIVATE, VENDOR_LMS_KEY_3_PRIVATE, ], + mldsa_priv_keys: [ + VENDOR_MLDSA_KEY_0_PRIVATE, + VENDOR_MLDSA_KEY_1_PRIVATE, + VENDOR_MLDSA_KEY_2_PRIVATE, + VENDOR_MLDSA_KEY_3_PRIVATE, + ], }; pub const OWNER_PRIVATE_KEYS: ImageOwnerPrivKeys = ImageOwnerPrivKeys { ecc_priv_key: OWNER_ECC_KEY_PRIVATE, lms_priv_key: OWNER_LMS_KEY_PRIVATE, + mldsa_priv_key: OWNER_MLDSA_KEY_PRIVATE, }; pub const VENDOR_CONFIG_KEY_0: ImageGeneratorVendorConfig = ImageGeneratorVendorConfig { ecc_key_count: VENDOR_ECC_MAX_KEY_COUNT, lms_key_count: VENDOR_LMS_MAX_KEY_COUNT, + mldsa_key_count: VENDOR_MLDSA_MAX_KEY_COUNT, pub_keys: VENDOR_PUBLIC_KEYS, ecc_key_idx: 0, - lms_key_idx: 0, + pqc_key_idx: 0, priv_keys: Some(VENDOR_PRIVATE_KEYS), not_before: [0u8; 15], not_after: [0u8; 15], @@ -346,30 +1560,32 @@ pub const VENDOR_CONFIG_KEY_0: ImageGeneratorVendorConfig = ImageGeneratorVendor pub const VENDOR_CONFIG_KEY_1: ImageGeneratorVendorConfig = ImageGeneratorVendorConfig { ecc_key_idx: 1, - lms_key_idx: 1, + pqc_key_idx: 1, ..VENDOR_CONFIG_KEY_0 }; pub const VENDOR_CONFIG_KEY_2: ImageGeneratorVendorConfig = ImageGeneratorVendorConfig { ecc_key_idx: 2, - lms_key_idx: 2, + pqc_key_idx: 2, ..VENDOR_CONFIG_KEY_0 }; pub const VENDOR_CONFIG_KEY_3: ImageGeneratorVendorConfig = ImageGeneratorVendorConfig { ecc_key_idx: 3, - lms_key_idx: 3, + pqc_key_idx: 3, ..VENDOR_CONFIG_KEY_0 }; pub const OWNER_CONFIG: ImageGeneratorOwnerConfig = ImageGeneratorOwnerConfig { - pub_keys: ImageOwnerPubKeys { + pub_keys: OwnerPubKeyConfig { ecc_pub_key: OWNER_ECC_KEY_PUBLIC, lms_pub_key: OWNER_LMS_KEY_PUBLIC, + mldsa_pub_key: OWNER_MLDSA_KEY_PUBLIC, }, priv_keys: Some(ImageOwnerPrivKeys { ecc_priv_key: OWNER_ECC_KEY_PRIVATE, lms_priv_key: OWNER_LMS_KEY_PRIVATE, + mldsa_priv_key: OWNER_MLDSA_KEY_PRIVATE, }), not_before: [0u8; 15], not_after: [0u8; 15], diff --git a/image/gen/Cargo.toml b/image/gen/Cargo.toml index 16a3aea9cd..eb251f5abc 100644 --- a/image/gen/Cargo.toml +++ b/image/gen/Cargo.toml @@ -15,3 +15,5 @@ caliptra-image-types = { workspace = true, features = ["std"] } caliptra-lms-types.workspace = true memoffset.workspace = true zerocopy.workspace = true +fips204.workspace = true +rand.workspace = true diff --git a/image/gen/src/generator.rs b/image/gen/src/generator.rs index f854bc8748..69115e4aaf 100644 --- a/image/gen/src/generator.rs +++ b/image/gen/src/generator.rs @@ -13,7 +13,11 @@ Abstract: --*/ use anyhow::bail; use caliptra_image_types::*; +use fips204::ml_dsa_87::{PrivateKey, SIG_LEN}; +use fips204::traits::{SerDes, Signer}; use memoffset::offset_of; +use rand::rngs::StdRng; +use rand::SeedableRng; use zerocopy::AsBytes; use crate::*; @@ -76,28 +80,49 @@ impl ImageGenerator { } let ecc_key_idx = config.vendor_config.ecc_key_idx; - let lms_key_idx = config.vendor_config.lms_key_idx; + let pqc_key_idx = config.vendor_config.pqc_key_idx; // Create Header let toc_digest = self.toc_digest(&fmc_toc, &runtime_toc)?; - let header = self.gen_header(config, ecc_key_idx, lms_key_idx, toc_digest)?; + let header = self.gen_header(config, ecc_key_idx, pqc_key_idx, toc_digest)?; // Create Preamble - let header_digest_vendor = self.header_digest_vendor(&header)?; - let header_digest_owner = self.header_digest_owner(&header)?; + let vendor_header_digest_384 = self.vendor_header_digest_384(&header)?; + let mut vendor_header_digest_holder = ImageDigestHolder { + digest_384: &vendor_header_digest_384, + digest_512: None, + }; + + let owner_header_digest_384 = self.owner_header_digest_384(&header)?; + let mut owner_header_digest_holder = ImageDigestHolder { + digest_384: &owner_header_digest_384, + digest_512: None, + }; + + let (vendor_header_digest_512, owner_header_digest_512); + + // Update vendor_digest_holder and owner_digest_holder with SHA512 digests if MLDSA validation is required. + if config.pqc_key_type == FwVerificationPqcKeyType::MLDSA { + vendor_header_digest_512 = self.vendor_header_digest_512(&header)?; + vendor_header_digest_holder.digest_512 = Some(&vendor_header_digest_512); + + owner_header_digest_512 = self.owner_header_digest_512(&header)?; + owner_header_digest_holder.digest_512 = Some(&owner_header_digest_512); + } + let preamble = self.gen_preamble( config, ecc_key_idx, - lms_key_idx, - &header_digest_vendor, - &header_digest_owner, + pqc_key_idx, + &vendor_header_digest_holder, + &owner_header_digest_holder, )?; // Create Manifest let manifest = ImageManifest { marker: MANIFEST_MARKER, size: core::mem::size_of::() as u32, - fw_image_type: config.fw_image_type.into(), + pqc_key_type: config.pqc_key_type.into(), reserved: [0u8; 3], preamble, header, @@ -115,14 +140,60 @@ impl ImageGenerator { Ok(image) } + fn mldsa_sign( + &self, + digest: &ImageDigest512, + priv_key: &ImageMldsaPrivKey, + ) -> anyhow::Result { + pub fn from_hw_format(value: &[u32]) -> [u8; NUM_BYTES] { + let mut result = [0u8; NUM_BYTES]; + for (i, &item) in value.iter().enumerate() { + let bytes = item.to_be_bytes(); + let start = i * 4; + if start + 4 <= NUM_BYTES { + result[start..start + 4].copy_from_slice(&bytes); + } else { + break; // Prevent overflow if the input slice is larger than NUM_BYTES / 4 + } + } + result + } + + let mut rng = StdRng::from_seed([0u8; 32]); + + // Private key is received in hw format. Reverse the DWORD endianess for signing. + let priv_key = { + let key_bytes: [u8; MLDSA87_PRIV_KEY_BYTE_SIZE] = + from_hw_format::(&priv_key.0); + PrivateKey::try_from_bytes(key_bytes).unwrap() + }; + + // Digest is received in hw format. Reverse the DWORD endianess for signing. + let digest: [u8; MLDSA87_MSG_BYTE_SIZE] = from_hw_format::(digest); + + let signature = priv_key.try_sign_with_rng(&mut rng, &digest, &[]).unwrap(); + let signature_extended = { + let mut sig = [0u8; SIG_LEN + 1]; + sig[..SIG_LEN].copy_from_slice(&signature); + sig + }; + + // Return the signature in hw format. + let mut sig: ImageMldsaSignature = ImageMldsaSignature::default(); + for (i, chunk) in signature_extended.chunks(4).enumerate() { + sig.0[i] = u32::from_be_bytes(chunk.try_into().unwrap()); + } + Ok(sig) + } + /// Create preamble pub fn gen_preamble( &self, config: &ImageGeneratorConfig, ecc_vendor_key_idx: u32, - lms_vendor_key_idx: u32, - digest_vendor: &ImageDigest, - digest_owner: &ImageDigest, + pqc_vendor_key_idx: u32, + vendor_digest_holder: &ImageDigestHolder, + owner_digest_holder: &ImageDigestHolder, ) -> anyhow::Result where E: ImageGeneratorExecutable, @@ -130,47 +201,68 @@ impl ImageGenerator { let mut vendor_sigs = ImageSignatures::default(); let mut owner_sigs = ImageSignatures::default(); + // Add Vendor Header Signatures. if let Some(priv_keys) = config.vendor_config.priv_keys { let sig = self.crypto.ecdsa384_sign( - digest_vendor, + vendor_digest_holder.digest_384, &priv_keys.ecc_priv_keys[ecc_vendor_key_idx as usize], &config.vendor_config.pub_keys.ecc_pub_keys[ecc_vendor_key_idx as usize], )?; vendor_sigs.ecc_sig = sig; - let lms_sig = self.crypto.lms_sign( - digest_vendor, - &priv_keys.lms_priv_keys[lms_vendor_key_idx as usize], - )?; - vendor_sigs.lms_sig = lms_sig; + if config.pqc_key_type == FwVerificationPqcKeyType::LMS { + let lms_sig = self.crypto.lms_sign( + vendor_digest_holder.digest_384, + &priv_keys.lms_priv_keys[pqc_vendor_key_idx as usize], + )?; + let sig = lms_sig.as_bytes(); + vendor_sigs.pqc_sig.0[..sig.len()].copy_from_slice(sig); + } else { + let mldsa_sig = self.mldsa_sign( + vendor_digest_holder.digest_512.unwrap(), + &priv_keys.mldsa_priv_keys[pqc_vendor_key_idx as usize], + )?; + + let sig = mldsa_sig.as_bytes(); + vendor_sigs.pqc_sig.0[..sig.len()].copy_from_slice(sig); + }; } + // Add Owner Header Signatures. if let Some(owner_config) = &config.owner_config { if let Some(priv_keys) = &owner_config.priv_keys { let sig = self.crypto.ecdsa384_sign( - digest_owner, + owner_digest_holder.digest_384, &priv_keys.ecc_priv_key, &owner_config.pub_keys.ecc_pub_key, )?; owner_sigs.ecc_sig = sig; - let lms_sig = self - .crypto - .lms_sign(digest_owner, &priv_keys.lms_priv_key)?; - owner_sigs.lms_sig = lms_sig; + if config.pqc_key_type == FwVerificationPqcKeyType::LMS { + let lms_sig = self + .crypto + .lms_sign(owner_digest_holder.digest_384, &priv_keys.lms_priv_key)?; + let sig = lms_sig.as_bytes(); + owner_sigs.pqc_sig.0[..sig.len()].copy_from_slice(sig); + } else { + let mldsa_sig = self.mldsa_sign( + owner_digest_holder.digest_512.unwrap(), + &priv_keys.mldsa_priv_key, + )?; + let sig = mldsa_sig.as_bytes(); + owner_sigs.pqc_sig.0[..sig.len()].copy_from_slice(sig); + }; } } let mut vendor_pub_key_info = ImageVendorPubKeyInfo { ecc_key_descriptor: ImageEccKeyDescriptor { version: KEY_DESCRIPTOR_VERSION, - intent: Intent::Vendor.into(), reserved: 0, key_hash_count: config.vendor_config.ecc_key_count as u8, key_hash: ImageEccKeyHashes::default(), }, pqc_key_descriptor: ImagePqcKeyDescriptor { version: KEY_DESCRIPTOR_VERSION, - intent: Intent::Vendor.into(), - key_type: KeyType::LMS.into(), + key_type: FwVerificationPqcKeyType::default() as u8, key_hash_count: config.vendor_config.lms_key_count as u8, key_hash: ImagePqcKeyHashes::default(), }, @@ -182,10 +274,23 @@ impl ImageGenerator { let ecc_pub_key_digest = self.crypto.sha384_digest(ecc_pub_key.as_bytes())?; vendor_pub_key_info.ecc_key_descriptor.key_hash[i as usize] = ecc_pub_key_digest; } - for i in 0..config.vendor_config.lms_key_count { - let lms_pub_key = config.vendor_config.pub_keys.lms_pub_keys[i as usize]; - let lms_pub_key_digest = self.crypto.sha384_digest(lms_pub_key.as_bytes())?; - vendor_pub_key_info.pqc_key_descriptor.key_hash[i as usize] = lms_pub_key_digest; + if config.pqc_key_type == FwVerificationPqcKeyType::LMS { + for i in 0..config.vendor_config.lms_key_count { + vendor_pub_key_info.pqc_key_descriptor.key_hash[i as usize] = + self.crypto.sha384_digest( + config.vendor_config.pub_keys.lms_pub_keys[i as usize].as_bytes(), + )?; + } + vendor_pub_key_info.pqc_key_descriptor.key_type = FwVerificationPqcKeyType::LMS.into(); + } else { + for i in 0..config.vendor_config.mldsa_key_count { + vendor_pub_key_info.pqc_key_descriptor.key_hash[i as usize] = + self.crypto.sha384_digest( + config.vendor_config.pub_keys.mldsa_pub_keys[i as usize].as_bytes(), + )?; + } + vendor_pub_key_info.pqc_key_descriptor.key_type = + FwVerificationPqcKeyType::MLDSA.into(); } let mut preamble = ImagePreamble { @@ -193,43 +298,34 @@ impl ImageGenerator { vendor_ecc_pub_key_idx: ecc_vendor_key_idx, vendor_ecc_active_pub_key: config.vendor_config.pub_keys.ecc_pub_keys [ecc_vendor_key_idx as usize], - vendor_lms_pub_key_idx: lms_vendor_key_idx, - vendor_lms_active_pub_key: config.vendor_config.pub_keys.lms_pub_keys - [lms_vendor_key_idx as usize], + vendor_pqc_pub_key_idx: pqc_vendor_key_idx, vendor_sigs, owner_sigs, ..Default::default() }; - if let Some(owner_config) = &config.owner_config { - let mut owner_pub_key_info = ImageOwnerPubKeyInfo { - ecc_key_descriptor: ImageEccKeyDescriptor { - version: KEY_DESCRIPTOR_VERSION, - intent: Intent::Owner.into(), - reserved: 0, - key_hash_count: 1, - key_hash: ImageEccKeyHashes::default(), - }, - pqc_key_descriptor: ImagePqcKeyDescriptor { - version: KEY_DESCRIPTOR_VERSION, - intent: Intent::Owner.into(), - key_type: KeyType::LMS.into(), - key_hash_count: 1, - key_hash: ImagePqcKeyHashes::default(), - }, - }; - - // Hash the ECC and LMS owner public keys. - let ecc_pub_key = owner_config.pub_keys.ecc_pub_key; - let ecc_pub_key_digest = self.crypto.sha384_digest(ecc_pub_key.as_bytes())?; - owner_pub_key_info.ecc_key_descriptor.key_hash[0_usize] = ecc_pub_key_digest; + // Store the PQC (LMS or MLDSA) vendor public key in the Preamble. + let pqc_pub_key = match config.pqc_key_type { + FwVerificationPqcKeyType::LMS => { + config.vendor_config.pub_keys.lms_pub_keys[pqc_vendor_key_idx as usize].as_bytes() + } + FwVerificationPqcKeyType::MLDSA => config.vendor_config.pub_keys.mldsa_pub_keys + [pqc_vendor_key_idx as usize] + .0 + .as_bytes(), + }; + preamble.vendor_pqc_active_pub_key.0[..pqc_pub_key.len()].copy_from_slice(pqc_pub_key); - let lms_pub_key = owner_config.pub_keys.lms_pub_key; - let lms_pub_key_digest = self.crypto.sha384_digest(lms_pub_key.as_bytes())?; - owner_pub_key_info.pqc_key_descriptor.key_hash[0_usize] = lms_pub_key_digest; + if let Some(owner_config) = &config.owner_config { + // Store the ECC owner public key in the Preamble. + preamble.owner_pub_keys.ecc_pub_key = owner_config.pub_keys.ecc_pub_key; - preamble.owner_pub_key_info = owner_pub_key_info; - preamble.owner_pub_keys = owner_config.pub_keys; + // Store the PQC (LMS or MLDSA) owner public key in the Preamble. + let pqc_pub_key = match config.pqc_key_type { + FwVerificationPqcKeyType::LMS => owner_config.pub_keys.lms_pub_key.as_bytes(), + FwVerificationPqcKeyType::MLDSA => owner_config.pub_keys.mldsa_pub_key.0.as_bytes(), + }; + preamble.owner_pub_keys.pqc_pub_key.0[..pqc_pub_key.len()].copy_from_slice(pqc_pub_key); } Ok(preamble) @@ -241,14 +337,14 @@ impl ImageGenerator { config: &ImageGeneratorConfig, ecc_key_idx: u32, lms_key_idx: u32, - digest: ImageDigest, + digest: ImageDigest384, ) -> anyhow::Result where E: ImageGeneratorExecutable, { let mut header = ImageHeader { vendor_ecc_pub_key_idx: ecc_key_idx, - vendor_lms_pub_key_idx: lms_key_idx, + vendor_pqc_pub_key_idx: lms_key_idx, flags: Self::DEFAULT_FLAGS, toc_len: MAX_TOC_ENTRY_COUNT, toc_digest: digest, @@ -273,26 +369,38 @@ impl ImageGenerator { } /// Calculate header digest for vendor. - /// Vendor digest is calculated upto the `owner_data` field. - pub fn header_digest_vendor(&self, header: &ImageHeader) -> anyhow::Result { + /// Vendor digest is calculated up to the `owner_data` field. + pub fn vendor_header_digest_384(&self, header: &ImageHeader) -> anyhow::Result { let offset = offset_of!(ImageHeader, owner_data); self.crypto .sha384_digest(header.as_bytes().get(..offset).unwrap()) } /// Calculate header digest for owner. - pub fn header_digest_owner(&self, header: &ImageHeader) -> anyhow::Result { + pub fn owner_header_digest_384(&self, header: &ImageHeader) -> anyhow::Result { self.crypto.sha384_digest(header.as_bytes()) } + /// Vendor digest is calculated up to the `owner_data` field. + pub fn vendor_header_digest_512(&self, header: &ImageHeader) -> anyhow::Result { + let offset = offset_of!(ImageHeader, owner_data); + self.crypto + .sha512_digest(header.as_bytes().get(..offset).unwrap()) + } + + /// Calculate header digest for owner. + pub fn owner_header_digest_512(&self, header: &ImageHeader) -> anyhow::Result { + self.crypto.sha512_digest(header.as_bytes()) + } + /// Calculate owner public key descriptor digest. - pub fn owner_pubkey_digest(&self, preamble: &ImagePreamble) -> anyhow::Result { + pub fn owner_pubkey_digest(&self, preamble: &ImagePreamble) -> anyhow::Result { self.crypto - .sha384_digest(preamble.owner_pub_key_info.as_bytes()) + .sha384_digest(preamble.owner_pub_keys.as_bytes()) } /// Calculate vendor public key descriptor digest. - pub fn vendor_pubkey_digest(&self, preamble: &ImagePreamble) -> anyhow::Result { + pub fn vendor_pubkey_digest(&self, preamble: &ImagePreamble) -> anyhow::Result { self.crypto .sha384_digest(preamble.vendor_pub_key_info.as_bytes()) } @@ -332,7 +440,7 @@ impl ImageGenerator { &self, fmc_toc: &ImageTocEntry, rt_toc: &ImageTocEntry, - ) -> anyhow::Result { + ) -> anyhow::Result { let mut toc_content: Vec = Vec::new(); toc_content.extend_from_slice(fmc_toc.as_bytes()); toc_content.extend_from_slice(rt_toc.as_bytes()); diff --git a/image/gen/src/lib.rs b/image/gen/src/lib.rs index d20a443abc..50c567669d 100644 --- a/image/gen/src/lib.rs +++ b/image/gen/src/lib.rs @@ -64,13 +64,16 @@ pub trait ImageGeneratorCrypto { Ok(hasher.finish()) } - /// Calculate SHA-384 digest - fn sha384_digest(&self, data: &[u8]) -> anyhow::Result; + /// Calculate SHA2-384 digest + fn sha384_digest(&self, data: &[u8]) -> anyhow::Result; + + /// Calculate SHA2-512 digest + fn sha512_digest(&self, data: &[u8]) -> anyhow::Result; /// Calculate ECDSA Signature fn ecdsa384_sign( &self, - digest: &ImageDigest, + digest: &ImageDigest384, priv_key: &ImageEccPrivKey, pub_key: &ImageEccPubKey, ) -> anyhow::Result; @@ -78,7 +81,7 @@ pub trait ImageGeneratorCrypto { /// Calculate LMS Signature fn lms_sign( &self, - digest: &ImageDigest, + digest: &ImageDigest384, priv_key: &ImageLmsPrivKey, ) -> anyhow::Result; @@ -87,6 +90,12 @@ pub trait ImageGeneratorCrypto { /// Read ECC-384 Private Key from PEM file fn ecc_priv_key_from_pem(path: &Path) -> anyhow::Result; + + /// Read MLDSA Public Key from file + fn mldsa_pub_key_from_file(path: &Path) -> anyhow::Result; + + /// Read MLDSA Private Key from file + fn mldsa_priv_key_from_file(path: &Path) -> anyhow::Result; } /// Image Generator Vendor Configuration @@ -96,11 +105,13 @@ pub struct ImageGeneratorVendorConfig { pub lms_key_count: u32, + pub mldsa_key_count: u32, + pub pub_keys: ImageVendorPubKeys, pub ecc_key_idx: u32, - pub lms_key_idx: u32, + pub pqc_key_idx: u32, pub priv_keys: Option, @@ -114,7 +125,7 @@ pub struct ImageGeneratorVendorConfig { /// Image Generator Owner Configuration #[derive(Default, Clone)] pub struct ImageGeneratorOwnerConfig { - pub pub_keys: ImageOwnerPubKeys, + pub pub_keys: OwnerPubKeyConfig, pub priv_keys: Option, @@ -131,7 +142,7 @@ pub struct ImageGeneratorConfig where T: ImageGeneratorExecutable, { - pub fw_image_type: FwImageType, + pub pqc_key_type: FwVerificationPqcKeyType, pub vendor_config: ImageGeneratorVendorConfig, diff --git a/image/types/src/lib.rs b/image/types/src/lib.rs index c645707836..a9f124d5f8 100644 --- a/image/types/src/lib.rs +++ b/image/types/src/lib.rs @@ -26,9 +26,11 @@ use memoffset::{offset_of, span_of}; use zerocopy::{AsBytes, FromBytes}; pub const MANIFEST_MARKER: u32 = 0x4E414D43; -pub const KEY_DESCRIPTOR_VERSION: u8 = 1; +pub const KEY_DESCRIPTOR_VERSION: u16 = 1; pub const VENDOR_ECC_MAX_KEY_COUNT: u32 = 4; pub const VENDOR_LMS_MAX_KEY_COUNT: u32 = 32; +pub const VENDOR_MLDSA_MAX_KEY_COUNT: u32 = 4; +pub const VENDOR_PQC_MAX_KEY_COUNT: u32 = VENDOR_LMS_MAX_KEY_COUNT; pub const MAX_TOC_ENTRY_COUNT: u32 = 2; pub const IMAGE_REVISION_BYTE_SIZE: usize = 20; pub const ECC384_SCALAR_WORD_SIZE: usize = 12; @@ -38,6 +40,7 @@ pub const SHA192_DIGEST_WORD_SIZE: usize = 6; pub const SHA256_DIGEST_WORD_SIZE: usize = 8; pub const SHA384_DIGEST_WORD_SIZE: usize = 12; pub const SHA384_DIGEST_BYTE_SIZE: usize = 48; +pub const SHA512_DIGEST_WORD_SIZE: usize = 16; pub const IMAGE_LMS_OTS_P_PARAM: usize = 51; pub const IMAGE_LMS_KEY_HEIGHT: usize = 15; pub const IMAGE_BYTE_SIZE: usize = 128 * 1024; @@ -46,9 +49,20 @@ pub const IMAGE_LMS_TREE_TYPE: LmsAlgorithmType = LmsAlgorithmType::LmsSha256N24 // LMOTS-SHA192-W4 pub const IMAGE_LMS_OTS_TYPE: LmotsAlgorithmType = LmotsAlgorithmType::LmotsSha256N24W4; pub const IMAGE_MANIFEST_BYTE_SIZE: usize = core::mem::size_of::(); +pub const MLDSA87_PUB_KEY_BYTE_SIZE: usize = 2592; +pub const MLDSA87_PUB_KEY_WORD_SIZE: usize = 648; +pub const MLDSA87_PRIV_KEY_BYTE_SIZE: usize = 4896; +pub const MLDSA87_PRIV_KEY_WORD_SIZE: usize = 1224; +pub const MLDSA87_SIGNATURE_BYTE_SIZE: usize = 4628; +pub const MLDSA87_SIGNATURE_WORD_SIZE: usize = 1157; +pub const MLDSA87_MSG_BYTE_SIZE: usize = 64; + +pub const PQC_PUB_KEY_BYTE_SIZE: usize = MLDSA87_PUB_KEY_BYTE_SIZE; +pub const PQC_SIGNATURE_BYTE_SIZE: usize = MLDSA87_SIGNATURE_BYTE_SIZE; pub type ImageScalar = [u32; ECC384_SCALAR_WORD_SIZE]; -pub type ImageDigest = [u32; SHA384_DIGEST_WORD_SIZE]; +pub type ImageDigest384 = [u32; SHA384_DIGEST_WORD_SIZE]; +pub type ImageDigest512 = [u32; SHA512_DIGEST_WORD_SIZE]; pub type ImageRevision = [u8; IMAGE_REVISION_BYTE_SIZE]; pub type ImageEccPrivKey = ImageScalar; @@ -66,6 +80,58 @@ pub struct ImageEccPubKey { pub type ImageLmsPublicKey = LmsPublicKey; pub type ImageLmsPrivKey = LmsPrivateKey; +#[repr(C)] +#[derive(AsBytes, FromBytes, Debug, Copy, Clone, Eq, PartialEq, Zeroize)] +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] +pub struct ImageMldsaPubKey(pub [u32; MLDSA87_PUB_KEY_WORD_SIZE]); + +impl Default for ImageMldsaPubKey { + fn default() -> Self { + ImageMldsaPubKey([0; MLDSA87_PUB_KEY_WORD_SIZE]) + } +} + +// [TODO][CAP2] Remove this once ZeroCopy crate is updated to 0.8.13 +impl ImageMldsaPubKey { + pub fn ref_from_prefix(bytes: &[u8]) -> Option<&Self> { + if bytes.len() >= size_of::() { + Some(unsafe { &*(bytes.as_ptr() as *const Self) }) + } else { + None + } + } + + pub fn mut_ref_from_prefix(bytes: &mut [u8]) -> Option<&mut Self> { + if bytes.len() >= size_of::() { + Some(unsafe { &mut *(bytes.as_mut_ptr() as *mut Self) }) + } else { + None + } + } +} + +#[repr(C)] +#[derive(AsBytes, FromBytes, Debug, Copy, Clone, Eq, PartialEq, Zeroize)] +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] +pub struct ImageMldsaPrivKey(pub [u32; MLDSA87_PRIV_KEY_WORD_SIZE]); + +impl Default for ImageMldsaPrivKey { + fn default() -> Self { + ImageMldsaPrivKey([0; MLDSA87_PRIV_KEY_WORD_SIZE]) + } +} + +#[repr(C)] +#[derive(AsBytes, FromBytes, Debug, Copy, Clone, Eq, PartialEq, Zeroize)] +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] +pub struct ImagePqcPubKey(pub [u8; PQC_PUB_KEY_BYTE_SIZE]); + +impl Default for ImagePqcPubKey { + fn default() -> Self { + ImagePqcPubKey([0; PQC_PUB_KEY_BYTE_SIZE]) + } +} + #[repr(C)] #[derive(AsBytes, FromBytes, Default, Debug, Copy, Clone, Eq, PartialEq, Zeroize)] #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] @@ -81,47 +147,81 @@ pub type ImageLmsSignature = LmsSignature; pub type ImageLmOTSSignature = LmotsSignature; -pub enum Intent { - Vendor = 1, - Owner = 2, -} +#[repr(C)] +#[derive(AsBytes, FromBytes, Debug, Copy, Clone, Eq, PartialEq, Zeroize)] +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] +pub struct ImageMldsaSignature(pub [u32; MLDSA87_SIGNATURE_WORD_SIZE]); -impl From for u8 { - fn from(val: Intent) -> Self { - val as u8 +impl Default for ImageMldsaSignature { + fn default() -> Self { + ImageMldsaSignature([0; MLDSA87_SIGNATURE_WORD_SIZE]) } } -pub enum KeyType { - ECC = 1, - LMS = 2, - MLDSA = 3, +// [TODO][CAP2] Remove this once ZeroCopy crate is updated to 0.8.13 +impl ImageMldsaSignature { + pub fn ref_from_prefix(bytes: &[u8]) -> Option<&Self> { + if bytes.len() >= size_of::() { + Some(unsafe { &*(bytes.as_ptr() as *const Self) }) + } else { + None + } + } + + pub fn mut_ref_from_prefix(bytes: &mut [u8]) -> Option<&mut Self> { + if bytes.len() >= size_of::() { + Some(unsafe { &mut *(bytes.as_mut_ptr() as *mut Self) }) + } else { + None + } + } } -impl From for u8 { - fn from(val: KeyType) -> Self { - val as u8 +#[repr(C)] +#[derive(AsBytes, FromBytes, Debug, Copy, Clone, Eq, PartialEq, Zeroize)] +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] +pub struct ImagePqcSignature(pub [u8; PQC_SIGNATURE_BYTE_SIZE]); + +impl Default for ImagePqcSignature { + fn default() -> Self { + ImagePqcSignature([0; PQC_SIGNATURE_BYTE_SIZE]) } } -#[derive(Copy, Clone)] -pub enum FwImageType { - EccLms = 1, - EccMldsa = 2, +#[derive(Copy, Clone, PartialEq, Eq)] +pub enum FwVerificationPqcKeyType { + LMS = 1, + MLDSA = 2, } -impl From for u8 { - fn from(val: FwImageType) -> Self { +impl From for u8 { + fn from(val: FwVerificationPqcKeyType) -> Self { val as u8 } } -impl Default for FwImageType { +impl Default for FwVerificationPqcKeyType { fn default() -> Self { - Self::EccLms + Self::LMS } } +impl FwVerificationPqcKeyType { + pub fn from_u8(value: u8) -> Option { + match value { + 1 => Some(FwVerificationPqcKeyType::LMS), + 2 => Some(FwVerificationPqcKeyType::MLDSA), + _ => None, + } + } +} + +#[derive(Debug)] +pub struct ImageDigestHolder<'a> { + pub digest_384: &'a ImageDigest384, + pub digest_512: Option<&'a ImageDigest512>, +} + /// Caliptra Image Bundle #[cfg(feature = "std")] #[derive(Debug, Default)] @@ -183,8 +283,8 @@ pub struct ImageManifest { /// Size of `Manifest` structure pub size: u32, - /// Firmware image type (ECC + LMS keys or ECC + MLDSA keys) - pub fw_image_type: u8, + /// PQC key type for image verification (LMS or MLDSA keys) + pub pqc_key_type: u8, pub reserved: [u8; 3], @@ -206,7 +306,7 @@ impl Default for ImageManifest { Self { marker: Default::default(), size: size_of::() as u32, - fw_image_type: 0, + pqc_key_type: 0, reserved: [0u8; 3], preamble: ImagePreamble::default(), header: ImageHeader::default(), @@ -223,10 +323,10 @@ impl ImageManifest { span.start as u32 + offset..span.end as u32 + offset } - /// Returns the `Range` containing the owner public key descriptors - pub fn owner_pub_key_descriptors_range() -> Range { + /// Returns the `Range` containing the owner public key + pub fn owner_pub_key_range() -> Range { let offset = offset_of!(ImageManifest, preamble) as u32; - let span = span_of!(ImagePreamble, owner_pub_key_info); + let span = span_of!(ImagePreamble, owner_pub_keys); span.start as u32 + offset..span.end as u32 + offset } @@ -250,6 +350,7 @@ pub struct ImageVendorPubKeys { pub ecc_pub_keys: [ImageEccPubKey; VENDOR_ECC_MAX_KEY_COUNT as usize], #[zeroize(skip)] pub lms_pub_keys: [ImageLmsPublicKey; VENDOR_LMS_MAX_KEY_COUNT as usize], + pub mldsa_pub_keys: [ImageMldsaPubKey; VENDOR_MLDSA_MAX_KEY_COUNT as usize], } #[repr(C)] @@ -263,19 +364,20 @@ pub struct ImageVendorPubKeyInfo { #[repr(C)] #[derive(AsBytes, FromBytes, Default, Debug, Clone, Copy, Zeroize)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] -pub struct ImageOwnerPubKeyInfo { - pub ecc_key_descriptor: ImageEccKeyDescriptor, - - pub pqc_key_descriptor: ImagePqcKeyDescriptor, +pub struct ImageVendorPrivKeys { + pub ecc_priv_keys: [ImageEccPrivKey; VENDOR_ECC_MAX_KEY_COUNT as usize], + #[zeroize(skip)] + pub lms_priv_keys: [ImageLmsPrivKey; VENDOR_LMS_MAX_KEY_COUNT as usize], + pub mldsa_priv_keys: [ImageMldsaPrivKey; VENDOR_MLDSA_MAX_KEY_COUNT as usize], } #[repr(C)] #[derive(AsBytes, FromBytes, Default, Debug, Clone, Copy, Zeroize)] -pub struct ImageVendorPrivKeys { - pub ecc_priv_keys: [ImageEccPrivKey; VENDOR_ECC_MAX_KEY_COUNT as usize], +pub struct OwnerPubKeyConfig { + pub ecc_pub_key: ImageEccPubKey, #[zeroize(skip)] - pub lms_priv_keys: [ImageLmsPrivKey; VENDOR_LMS_MAX_KEY_COUNT as usize], + pub lms_pub_key: ImageLmsPublicKey, + pub mldsa_pub_key: ImageMldsaPubKey, } #[repr(C)] @@ -283,8 +385,7 @@ pub struct ImageVendorPrivKeys { #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] pub struct ImageOwnerPubKeys { pub ecc_pub_key: ImageEccPubKey, - #[zeroize(skip)] - pub lms_pub_key: ImageLmsPublicKey, + pub pqc_pub_key: ImagePqcPubKey, } #[repr(C)] @@ -293,6 +394,7 @@ pub struct ImageOwnerPrivKeys { pub ecc_priv_key: ImageEccPrivKey, #[zeroize(skip)] pub lms_priv_key: ImageLmsPrivKey, + pub mldsa_priv_key: ImageMldsaPrivKey, } #[repr(C)] @@ -300,8 +402,7 @@ pub struct ImageOwnerPrivKeys { #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] pub struct ImageSignatures { pub ecc_sig: ImageEccSignature, - #[zeroize(skip)] - pub lms_sig: ImageLmsSignature, + pub pqc_sig: ImagePqcSignature, } /// Caliptra Image ECC Key Descriptor @@ -309,8 +410,7 @@ pub struct ImageSignatures { #[derive(AsBytes, Clone, Copy, FromBytes, Default, Debug, Zeroize)] #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] pub struct ImageEccKeyDescriptor { - pub version: u8, - pub intent: u8, + pub version: u16, pub reserved: u8, pub key_hash_count: u8, pub key_hash: ImageEccKeyHashes, @@ -321,16 +421,14 @@ pub struct ImageEccKeyDescriptor { #[derive(AsBytes, Clone, Copy, FromBytes, Default, Debug, Zeroize)] #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] pub struct ImagePqcKeyDescriptor { - pub version: u8, - pub intent: u8, + pub version: u16, pub key_type: u8, pub key_hash_count: u8, pub key_hash: ImagePqcKeyHashes, } -pub type ImageEccKeyHashes = [ImageDigest; VENDOR_ECC_MAX_KEY_COUNT as usize]; -pub type ImageLmsKeyHashes = [ImageDigest; VENDOR_LMS_MAX_KEY_COUNT as usize]; -pub type ImagePqcKeyHashes = [ImageDigest; VENDOR_LMS_MAX_KEY_COUNT as usize]; +pub type ImageEccKeyHashes = [ImageDigest384; VENDOR_ECC_MAX_KEY_COUNT as usize]; +pub type ImagePqcKeyHashes = [ImageDigest384; VENDOR_PQC_MAX_KEY_COUNT as usize]; /// Caliptra Image Bundle Preamble #[repr(C)] @@ -346,20 +444,16 @@ pub struct ImagePreamble { /// Vendor Active Public Key pub vendor_ecc_active_pub_key: ImageEccPubKey, - /// Vendor LMS Public Key Index - pub vendor_lms_pub_key_idx: u32, + /// Vendor PQC Public Key Index + pub vendor_pqc_pub_key_idx: u32, - /// Vendor Active LMS Public Key - #[zeroize(skip)] - pub vendor_lms_active_pub_key: ImageLmsPublicKey, + /// Vendor Active PQC (LMS or MLDSA) Public Key + pub vendor_pqc_active_pub_key: ImagePqcPubKey, /// Vendor Signatures pub vendor_sigs: ImageSignatures, - /// Owner Public Key Descriptor (no Key Hashes) - pub owner_pub_key_info: ImageOwnerPubKeyInfo, - - /// Owner Public Key + /// Owner Public Keys pub owner_pub_keys: ImageOwnerPubKeys, /// Owner Signatures @@ -408,8 +502,8 @@ pub struct ImageHeader { /// Vendor ECC Public Key Index pub vendor_ecc_pub_key_idx: u32, - /// Vendor LMS Public Key Index - pub vendor_lms_pub_key_idx: u32, + /// Vendor PQC Public Key Index + pub vendor_pqc_pub_key_idx: u32, /// Flags /// Bit 0: Interpret the pl0_pauser field. If not set, all PAUSERs are PL1. @@ -423,7 +517,7 @@ pub struct ImageHeader { pub pl0_pauser: u32, /// TOC Digest - pub toc_digest: ImageDigest, + pub toc_digest: ImageDigest384, /// Vendor Data pub vendor_data: VendorSignedData, @@ -498,7 +592,7 @@ pub struct ImageTocEntry { pub size: u32, /// Digest - pub digest: ImageDigest, + pub digest: ImageDigest384, } impl ImageTocEntry { diff --git a/image/verify/fuzz/src/fuzz_target_common.rs b/image/verify/fuzz/src/fuzz_target_common.rs index 5a39d1b07c..012330d4da 100644 --- a/image/verify/fuzz/src/fuzz_target_common.rs +++ b/image/verify/fuzz/src/fuzz_target_common.rs @@ -21,43 +21,43 @@ const IMAGE_BUNDLE_SIZE: u32 = 131072; * - Ensures bundle is being fuzzed well (by offsets). */ struct TestEnv { - digest: ImageDigest, - fmc_digest: ImageDigest, + digest: ImageDigest384, + fmc_digest: ImageDigest384, verify_result: bool, verify_lms_result: bool, - vendor_pub_key_digest: ImageDigest, + vendor_pub_key_digest: ImageDigest384, vendor_ecc_pub_key_revocation: VendorPubKeyRevocation, vendor_lms_pub_key_revocation: u32, - owner_pub_key_digest: ImageDigest, + owner_pub_key_digest: ImageDigest384, lifecycle: Lifecycle, } impl Default for TestEnv { fn default() -> Self { TestEnv { - digest: ImageDigest::default(), - fmc_digest: ImageDigest::default(), + digest: ImageDigest384::default(), + fmc_digest: ImageDigest384::default(), // PATCHED verify_result: true, // PATCHED verify_lms_result: true, - vendor_pub_key_digest: ImageDigest::default(), + vendor_pub_key_digest: ImageDigest384::default(), vendor_ecc_pub_key_revocation: VendorPubKeyRevocation::default(), vendor_lms_pub_key_revocation: 0, - owner_pub_key_digest: ImageDigest::default(), + owner_pub_key_digest: ImageDigest384::default(), lifecycle: Lifecycle::Unprovisioned, } } } impl ImageVerificationEnv for TestEnv { - fn sha384_digest(&mut self, _offset: u32, _len: u32) -> CaliptraResult { + fn sha384_digest(&mut self, _offset: u32, _len: u32) -> CaliptraResult { Ok(self.digest) } fn ecc384_verify( &mut self, - _digest: &ImageDigest, + _digest: &ImageDigest384, _pub_key: &ImageEccPubKey, sig: &ImageEccSignature, ) -> CaliptraResult> { @@ -70,7 +70,7 @@ impl ImageVerificationEnv for TestEnv { fn lms_verify( &mut self, - _digest: &ImageDigest, + _digest: &ImageDigest384, pub_key: &ImageLmsPublicKey, _sig: &ImageLmsSignature, ) -> CaliptraResult> { @@ -81,7 +81,7 @@ impl ImageVerificationEnv for TestEnv { } } - fn vendor_pub_key_digest(&self) -> ImageDigest { + fn vendor_pub_key_digest(&self) -> ImageDigest384 { self.vendor_pub_key_digest } @@ -93,7 +93,7 @@ impl ImageVerificationEnv for TestEnv { self.vendor_lms_pub_key_revocation } - fn owner_pub_key_digest_fuses(&self) -> ImageDigest { + fn owner_pub_key_digest_fuses(&self) -> ImageDigest384 { self.owner_pub_key_digest } @@ -109,15 +109,15 @@ impl ImageVerificationEnv for TestEnv { 0 } - fn vendor_lms_pub_key_idx_dv(&self) -> u32 { + fn vendor_pqc_pub_key_idx_dv(&self) -> u32 { 0 } - fn owner_pub_key_digest_dv(&self) -> ImageDigest { + fn owner_pub_key_digest_dv(&self) -> ImageDigest384 { self.owner_pub_key_digest } - fn get_fmc_digest_dv(&self) -> ImageDigest { + fn get_fmc_digest_dv(&self) -> ImageDigest384 { self.fmc_digest } diff --git a/image/verify/src/lib.rs b/image/verify/src/lib.rs index a013cc9cc1..15d470a568 100644 --- a/image/verify/src/lib.rs +++ b/image/verify/src/lib.rs @@ -44,7 +44,7 @@ pub struct ImageVerificationExeInfo { pub entry_point: u32, /// Digest of the image - pub digest: ImageDigest, + pub digest: ImageDigest384, } /// Information To Be Logged For The Verified Image @@ -56,11 +56,11 @@ pub struct ImageVerificationLogInfo { /// Vendor ECC Public Key Revocation Fuse pub fuse_vendor_ecc_pub_key_revocation: VendorPubKeyRevocation, - // LMS Vendor Public Key Index - pub vendor_lms_pub_key_idx: u32, + // PQC (LMS or MLDSA) Vendor Public Key Index + pub vendor_pqc_pub_key_idx: u32, - /// Vendor LMS Public Key Revocation Fuse - pub fuse_vendor_lms_pub_key_revocation: u32, + /// Vendor PQC (LMS or MLDSA) Public Key Revocation Fuse + pub fuse_vendor_pqc_pub_key_revocation: u32, /// Firmware's SVN logging information pub fw_log_info: FirmwareSvnLogInfo, @@ -72,14 +72,14 @@ pub struct ImageVerificationInfo { /// Vendor ECC public key index pub vendor_ecc_pub_key_idx: u32, - /// Vendor LMS public key index - pub vendor_lms_pub_key_idx: u32, + /// Vendor PQC (LMS or MLDSA) public key index + pub vendor_pqc_pub_key_idx: u32, /// PQC Verification Configuration pub pqc_verify_config: RomPqcVerifyConfig, /// Digest of owner public keys that verified the image - pub owner_pub_keys_digest: ImageDigest, + pub owner_pub_keys_digest: ImageDigest384, /// Whether `owner_pub_keys_digest` was in fuses pub owner_pub_keys_digest_in_fuses: bool, @@ -103,12 +103,15 @@ pub struct ImageVerificationInfo { /// Image Verification Environment pub trait ImageVerificationEnv { /// Calculate SHA-384 Digest - fn sha384_digest(&mut self, offset: u32, len: u32) -> CaliptraResult; + fn sha384_digest(&mut self, offset: u32, len: u32) -> CaliptraResult; + + /// Calculate SHA-512 Digest + fn sha512_digest(&mut self, offset: u32, len: u32) -> CaliptraResult; /// Perform ECC-384 Verification fn ecc384_verify( &mut self, - digest: &ImageDigest, + digest: &ImageDigest384, pub_key: &ImageEccPubKey, sig: &ImageEccSignature, ) -> CaliptraResult>; @@ -116,13 +119,20 @@ pub trait ImageVerificationEnv { /// Perform LMS Verification fn lms_verify( &mut self, - digest: &ImageDigest, + digest: &ImageDigest384, pub_key: &ImageLmsPublicKey, sig: &ImageLmsSignature, ) -> CaliptraResult>; + fn mldsa87_verify( + &mut self, + digest: &ImageDigest512, + pub_key: &ImageMldsaPubKey, + sig: &ImageMldsaSignature, + ) -> CaliptraResult; + /// Get Vendor Public Key Digest from fuses - fn vendor_pub_key_info_digest_fuses(&self) -> ImageDigest; + fn vendor_pub_key_info_digest_fuses(&self) -> ImageDigest384; /// Get Vendor ECC Public Key Revocation list fn vendor_ecc_pub_key_revocation(&self) -> VendorPubKeyRevocation; @@ -131,7 +141,7 @@ pub trait ImageVerificationEnv { fn vendor_lms_pub_key_revocation(&self) -> u32; /// Get Owner Public Key Digest from fuses - fn owner_pub_key_digest_fuses(&self) -> ImageDigest; + fn owner_pub_key_digest_fuses(&self) -> ImageDigest384; /// Get Anti-Rollback disable setting fn anti_rollback_disable(&self) -> bool; @@ -142,14 +152,14 @@ pub trait ImageVerificationEnv { // Get the vendor ECC key index saved on cold boot in data vault fn vendor_ecc_pub_key_idx_dv(&self) -> u32; - // Get the vendor LMS key index saved on cold boot in data vault - fn vendor_lms_pub_key_idx_dv(&self) -> u32; + // Get the vendor PQC (LMS or MLDSA) key index saved on cold boot in data vault + fn vendor_pqc_pub_key_idx_dv(&self) -> u32; // Get the owner key digest saved on cold boot in data vault - fn owner_pub_key_digest_dv(&self) -> ImageDigest; + fn owner_pub_key_digest_dv(&self) -> ImageDigest384; // Save the fmc digest in the data vault on cold boot - fn get_fmc_digest_dv(&self) -> ImageDigest; + fn get_fmc_digest_dv(&self) -> ImageDigest384; // Get Runtime fuse SVN fn runtime_fuse_svn(&self) -> u32; diff --git a/image/verify/src/verifier.rs b/image/verify/src/verifier.rs index e0228a326a..a992ef0482 100644 --- a/image/verify/src/verifier.rs +++ b/image/verify/src/verifier.rs @@ -23,27 +23,34 @@ use caliptra_cfi_lib::{ use caliptra_drivers::*; use caliptra_image_types::*; use memoffset::offset_of; +use zerocopy::AsBytes; -const ZERO_DIGEST: &ImageDigest = &[0u32; SHA384_DIGEST_WORD_SIZE]; +const ZERO_DIGEST: &ImageDigest384 = &[0u32; SHA384_DIGEST_WORD_SIZE]; + +/// PQC public key and signature +enum PqcKeyInfo<'a> { + Lms(&'a ImageLmsPublicKey, &'a ImageLmsSignature), + Mldsa(&'a ImageMldsaPubKey, &'a ImageMldsaSignature), +} /// Header Info struct HeaderInfo<'a> { vendor_ecc_pub_key_idx: u32, - vendor_lms_pub_key_idx: u32, + vendor_pqc_pub_key_idx: u32, vendor_ecc_pub_key_revocation: VendorPubKeyRevocation, vendor_ecc_info: (&'a ImageEccPubKey, &'a ImageEccSignature), - vendor_lms_info: (&'a ImageLmsPublicKey, &'a ImageLmsSignature), - vendor_lms_pub_key_revocation: u32, + vendor_pqc_info: PqcKeyInfo<'a>, + vendor_pqc_pub_key_revocation: u32, owner_ecc_info: (&'a ImageEccPubKey, &'a ImageEccSignature), - owner_lms_info: (&'a ImageLmsPublicKey, &'a ImageLmsSignature), - owner_pub_keys_digest: ImageDigest, + owner_pqc_info: PqcKeyInfo<'a>, + owner_pub_keys_digest: ImageDigest384, owner_pub_keys_digest_in_fuses: bool, } /// TOC Info struct TocInfo<'a> { len: u32, - digest: &'a ImageDigest, + digest: &'a ImageDigest384, } /// Image Info @@ -97,9 +104,13 @@ impl ImageVerifier { Err(CaliptraError::IMAGE_VERIFIER_ERR_MANIFEST_SIZE_MISMATCH)?; } + // Check the verification pqc key type. + let pqc_key_type = FwVerificationPqcKeyType::from_u8(manifest.pqc_key_type) + .ok_or(CaliptraError::IMAGE_VERIFIER_ERR_FW_IMAGE_VERIFICATION_KEY_TYPE_INVALID)?; + // Verify the preamble let preamble = &manifest.preamble; - let header_info = self.verify_preamble(preamble, reason); + let header_info = self.verify_preamble(preamble, reason, pqc_key_type); let header_info = okref(&header_info)?; // Verify Header @@ -127,7 +138,7 @@ impl ImageVerifier { let info = ImageVerificationInfo { vendor_ecc_pub_key_idx: header_info.vendor_ecc_pub_key_idx, - vendor_lms_pub_key_idx: header_info.vendor_lms_pub_key_idx, + vendor_pqc_pub_key_idx: header_info.vendor_pqc_pub_key_idx, owner_pub_keys_digest: header_info.owner_pub_keys_digest, owner_pub_keys_digest_in_fuses: header_info.owner_pub_keys_digest_in_fuses, fmc: fmc_info, @@ -137,15 +148,15 @@ impl ImageVerifier { log_info: ImageVerificationLogInfo { vendor_ecc_pub_key_idx: header_info.vendor_ecc_pub_key_idx, fuse_vendor_ecc_pub_key_revocation: header_info.vendor_ecc_pub_key_revocation, - fuse_vendor_lms_pub_key_revocation: header_info.vendor_lms_pub_key_revocation, - vendor_lms_pub_key_idx: header_info.vendor_lms_pub_key_idx, + fuse_vendor_pqc_pub_key_revocation: header_info.vendor_pqc_pub_key_revocation, + vendor_pqc_pub_key_idx: header_info.vendor_pqc_pub_key_idx, fw_log_info: FirmwareSvnLogInfo { manifest_svn: fw_svn, reserved: 0, fuse_svn: self.env.runtime_fuse_svn(), }, }, - pqc_verify_config: manifest.fw_image_type.into(), + pqc_verify_config: manifest.pqc_key_type.into(), }; Ok(info) @@ -188,13 +199,14 @@ impl ImageVerifier { &mut self, preamble: &'a ImagePreamble, reason: ResetReason, + pqc_key_type: FwVerificationPqcKeyType, ) -> CaliptraResult> { // Verify Vendor Public Key Info Digest - self.verify_vendor_pub_key_info_digest(&preamble.vendor_pub_key_info)?; + self.verify_vendor_pub_key_info_digest(&preamble.vendor_pub_key_info, pqc_key_type)?; // Verify Owner Public Key Info Digest let (owner_pub_keys_digest, owner_pub_keys_digest_in_fuses) = - self.verify_owner_pub_key_info_digest(reason)?; + self.verify_owner_pk_digest(reason)?; // Verify ECC Vendor Key Index let (vendor_ecc_pub_key_idx, vendor_ecc_pub_key_revocation) = @@ -206,15 +218,58 @@ impl ImageVerifier { &preamble.vendor_sigs.ecc_sig, ); - // Verify LMS Vendor Key Index - let (vendor_lms_pub_key_idx, vendor_lms_pub_key_revocation) = - self.verify_vendor_lms_pk_idx(preamble, reason)?; + struct PubKeyIndexInfo { + key_idx: u32, + key_revocation: u32, + } - // LMS Vendor Information - let vendor_lms_info = ( - &preamble.vendor_lms_active_pub_key, - &preamble.vendor_sigs.lms_sig, - ); + // Verify PQC Vendor Key Index + let vendor_pqc_info: PqcKeyInfo<'a>; + let vendor_pqc_pub_key_idx_info = match pqc_key_type { + FwVerificationPqcKeyType::LMS => { + // Read the LMS public key and signature from the preamble + let lms_pub_key = ImageLmsPublicKey::ref_from_prefix( + preamble.vendor_pqc_active_pub_key.0.as_bytes(), + ) + .ok_or(CaliptraError::IMAGE_VERIFIER_ERR_LMS_VENDOR_PUB_KEY_INVALID)?; + + let lms_sig = + ImageLmsSignature::ref_from_prefix(preamble.vendor_sigs.pqc_sig.0.as_bytes()) + .ok_or(CaliptraError::IMAGE_VERIFIER_ERR_LMS_VENDOR_SIG_INVALID)?; + + vendor_pqc_info = PqcKeyInfo::Lms(lms_pub_key, lms_sig); + + // Verify the vendor LMS public key index and revocation status + let (vendor_pqc_pub_key_idx, vendor_lms_pub_key_revocation) = + self.verify_vendor_lms_pk_idx(preamble, reason)?; + + // Return the public key index information + PubKeyIndexInfo { + key_idx: vendor_pqc_pub_key_idx, + key_revocation: vendor_lms_pub_key_revocation, + } + } + FwVerificationPqcKeyType::MLDSA => { + let mldsa_pub_key = ImageMldsaPubKey::ref_from_prefix( + preamble.vendor_pqc_active_pub_key.0.as_bytes(), + ) + .ok_or(CaliptraError::IMAGE_VERIFIER_ERR_MLDSA_VENDOR_PUB_KEY_READ_FAILED)?; + + let mldsa_sig = + ImageMldsaSignature::ref_from_prefix(preamble.vendor_sigs.pqc_sig.0.as_bytes()) + .ok_or(CaliptraError::IMAGE_VERIFIER_ERR_MLDSA_VENDOR_SIG_READ_FAILED)?; + + vendor_pqc_info = PqcKeyInfo::Mldsa(mldsa_pub_key, mldsa_sig); + + // [TODO][CAP2] Verify the vendor MLDSA public key index and revocation status + + // Return the public key index information + PubKeyIndexInfo { + key_idx: 0, + key_revocation: 0, + } + } + }; // Owner Information let owner_ecc_info = ( @@ -222,22 +277,44 @@ impl ImageVerifier { &preamble.owner_sigs.ecc_sig, ); - let owner_lms_info = ( - &preamble.owner_pub_keys.lms_pub_key, - &preamble.owner_sigs.lms_sig, - ); + let owner_pqc_info: PqcKeyInfo<'a> = match pqc_key_type { + FwVerificationPqcKeyType::LMS => { + let lms_pub_key = ImageLmsPublicKey::ref_from_prefix( + preamble.owner_pub_keys.pqc_pub_key.0.as_bytes(), + ) + .ok_or(CaliptraError::IMAGE_VERIFIER_ERR_LMS_OWNER_PUB_KEY_INVALID)?; + + let lms_sig = + ImageLmsSignature::ref_from_prefix(preamble.owner_sigs.pqc_sig.0.as_bytes()) + .ok_or(CaliptraError::IMAGE_VERIFIER_ERR_LMS_OWNER_SIG_INVALID)?; + + PqcKeyInfo::Lms(lms_pub_key, lms_sig) + } + FwVerificationPqcKeyType::MLDSA => { + let mldsa_pub_key = ImageMldsaPubKey::ref_from_prefix( + preamble.owner_pub_keys.pqc_pub_key.0.as_bytes(), + ) + .ok_or(CaliptraError::IMAGE_VERIFIER_ERR_MLDSA_OWNER_PUB_KEY_READ_FAILED)?; + + let mldsa_sig = + ImageMldsaSignature::ref_from_prefix(preamble.owner_sigs.pqc_sig.0.as_bytes()) + .ok_or(CaliptraError::IMAGE_VERIFIER_ERR_MLDSA_OWNER_SIG_READ_FAILED)?; + + PqcKeyInfo::Mldsa(mldsa_pub_key, mldsa_sig) + } + }; let info = HeaderInfo { vendor_ecc_pub_key_idx, - vendor_lms_pub_key_idx, + vendor_pqc_pub_key_idx: vendor_pqc_pub_key_idx_info.key_idx, vendor_ecc_info, - vendor_lms_info, - owner_lms_info, + vendor_pqc_info, + owner_pqc_info, owner_pub_keys_digest, owner_pub_keys_digest_in_fuses, owner_ecc_info, vendor_ecc_pub_key_revocation, - vendor_lms_pub_key_revocation, + vendor_pqc_pub_key_revocation: vendor_pqc_pub_key_idx_info.key_revocation, }; Ok(info) @@ -296,7 +373,7 @@ impl ImageVerifier { preamble: &ImagePreamble, reason: ResetReason, ) -> CaliptraResult<(u32, u32)> { - let key_idx = preamble.vendor_lms_pub_key_idx; + let key_idx = preamble.vendor_pqc_pub_key_idx; let revocation = self.env.vendor_lms_pub_key_revocation(); let key_hash_count = preamble .vendor_pub_key_info @@ -319,13 +396,13 @@ impl ImageVerifier { } if cfi_launder(reason) == ResetReason::UpdateReset { - let expected = self.env.vendor_lms_pub_key_idx_dv(); + let expected = self.env.vendor_pqc_pub_key_idx_dv(); if cfi_launder(expected) != key_idx { Err( - CaliptraError::IMAGE_VERIFIER_ERR_UPDATE_RESET_VENDOR_LMS_PUB_KEY_IDX_MISMATCH, + CaliptraError::IMAGE_VERIFIER_ERR_UPDATE_RESET_VENDOR_PQC_PUB_KEY_IDX_MISMATCH, )?; } else { - cfi_assert_eq(self.env.vendor_lms_pub_key_idx_dv(), key_idx); + cfi_assert_eq(self.env.vendor_pqc_pub_key_idx_dv(), key_idx); } } else { cfi_assert_ne(reason, ResetReason::UpdateReset); @@ -338,6 +415,7 @@ impl ImageVerifier { fn verify_vendor_pub_key_info_digest( &mut self, pub_key_info: &ImageVendorPubKeyInfo, + pqc_key_type: FwVerificationPqcKeyType, ) -> Result<(), NonZeroU32> { // We skip vendor public key check in unprovisioned state if cfi_launder(self.env.dev_lifecycle() as u32) == Lifecycle::Unprovisioned as u32 { @@ -367,9 +445,6 @@ impl ImageVerifier { if pub_key_info.ecc_key_descriptor.version != KEY_DESCRIPTOR_VERSION { Err(CaliptraError::IMAGE_VERIFIER_ERR_ECC_KEY_DESCRIPTOR_VERSION_MISMATCH)?; } - if pub_key_info.ecc_key_descriptor.intent != Intent::Vendor as u8 { - Err(CaliptraError::IMAGE_VERIFIER_ERR_ECC_KEY_DESCRIPTOR_INTENT_MISMATCH)?; - } if pub_key_info.ecc_key_descriptor.key_hash_count == 0 { Err(CaliptraError::IMAGE_VERIFIER_ERR_ECC_KEY_DESCRIPTOR_INVALID_HASH_COUNT)?; } @@ -377,21 +452,23 @@ impl ImageVerifier { Err(CaliptraError::IMAGE_VERIFIER_ERR_ECC_KEY_DESCRIPTOR_HASH_COUNT_GT_MAX)?; } - // Validate the LMS key descriptor. + // Validate the PQC key descriptor. if pub_key_info.pqc_key_descriptor.version != KEY_DESCRIPTOR_VERSION { - Err(CaliptraError::IMAGE_VERIFIER_ERR_LMS_KEY_DESCRIPTOR_VERSION_MISMATCH)?; - } - if pub_key_info.pqc_key_descriptor.intent != Intent::Vendor as u8 { - Err(CaliptraError::IMAGE_VERIFIER_ERR_LMS_KEY_DESCRIPTOR_INTENT_MISMATCH)?; + Err(CaliptraError::IMAGE_VERIFIER_ERR_PQC_KEY_DESCRIPTOR_VERSION_MISMATCH)?; } - if pub_key_info.pqc_key_descriptor.key_type != KeyType::LMS as u8 { - Err(CaliptraError::IMAGE_VERIFIER_ERR_LMS_KEY_DESCRIPTOR_TYPE_MISMATCH)?; + if pub_key_info.pqc_key_descriptor.key_type != pqc_key_type as u8 { + Err(CaliptraError::IMAGE_VERIFIER_ERR_PQC_KEY_DESCRIPTOR_TYPE_MISMATCH)?; } if pub_key_info.pqc_key_descriptor.key_hash_count == 0 { - Err(CaliptraError::IMAGE_VERIFIER_ERR_LMS_KEY_DESCRIPTOR_INVALID_HASH_COUNT)?; + Err(CaliptraError::IMAGE_VERIFIER_ERR_PQC_KEY_DESCRIPTOR_INVALID_HASH_COUNT)?; } - if pub_key_info.pqc_key_descriptor.key_hash_count > VENDOR_LMS_MAX_KEY_COUNT as u8 { - Err(CaliptraError::IMAGE_VERIFIER_ERR_LMS_KEY_DESCRIPTOR_HASH_COUNT_GT_MAX)?; + if (pqc_key_type == FwVerificationPqcKeyType::LMS + && pub_key_info.pqc_key_descriptor.key_hash_count > VENDOR_LMS_MAX_KEY_COUNT as u8) + || (pqc_key_type == FwVerificationPqcKeyType::MLDSA + && pub_key_info.pqc_key_descriptor.key_hash_count + > VENDOR_MLDSA_MAX_KEY_COUNT as u8) + { + Err(CaliptraError::IMAGE_VERIFIER_ERR_PQC_KEY_DESCRIPTOR_HASH_COUNT_GT_MAX)?; } let range = ImageManifest::vendor_pub_key_descriptors_range(); @@ -425,11 +502,11 @@ impl ImageVerifier { /// Verify owner public key digest. /// Returns a bool indicating whether the digest was in fuses. - fn verify_owner_pub_key_info_digest( + fn verify_owner_pk_digest( &mut self, reason: ResetReason, - ) -> CaliptraResult<(ImageDigest, bool)> { - let range = ImageManifest::owner_pub_key_descriptors_range(); + ) -> CaliptraResult<(ImageDigest384, bool)> { + let range = ImageManifest::owner_pub_key_range(); #[cfg(feature = "fips-test-hooks")] unsafe { @@ -491,7 +568,7 @@ impl ImageVerifier { }; // Vendor header digest is calculated up to the owner_data field. - let digest_vendor = self + let vendor_digest_384 = self .env .sha384_digest(range.start, vendor_header_len as u32) .map_err(|err| { @@ -499,7 +576,12 @@ impl ImageVerifier { CaliptraError::IMAGE_VERIFIER_ERR_HEADER_DIGEST_FAILURE })?; - let digest_owner = self + let mut vendor_digest_holder = ImageDigestHolder { + digest_384: &vendor_digest_384, + digest_512: None, + }; + + let owner_digest_384 = self .env .sha384_digest(range.start, range.len() as u32) .map_err(|err| { @@ -507,8 +589,41 @@ impl ImageVerifier { CaliptraError::IMAGE_VERIFIER_ERR_HEADER_DIGEST_FAILURE })?; - // Verify vendor signature - self.verify_vendor_sig(&digest_vendor, info.vendor_ecc_info, info.vendor_lms_info)?; + let mut owner_digest_holder = ImageDigestHolder { + digest_384: &owner_digest_384, + digest_512: None, + }; + + let vendor_digest_512: [u32; 16]; + let owner_digest_512: [u32; 16]; + + // Update vendor_digest_holder and owner_digest_holder with SHA512 digests if MLDSA validation i required. + if let PqcKeyInfo::Mldsa(_, _) = info.vendor_pqc_info { + vendor_digest_512 = self + .env + .sha512_digest(range.start, vendor_header_len as u32) + .map_err(|err| { + self.env.set_fw_extended_error(err.into()); + CaliptraError::IMAGE_VERIFIER_ERR_HEADER_DIGEST_FAILURE + })?; + vendor_digest_holder.digest_512 = Some(&vendor_digest_512); + + owner_digest_512 = self + .env + .sha512_digest(range.start, range.len() as u32) + .map_err(|err| { + self.env.set_fw_extended_error(err.into()); + CaliptraError::IMAGE_VERIFIER_ERR_HEADER_DIGEST_FAILURE + })?; + owner_digest_holder.digest_512 = Some(&owner_digest_512); + } + + // Verify vendor signatures. + self.verify_vendor_sig( + &vendor_digest_holder, + info.vendor_ecc_info, + &info.vendor_pqc_info, + )?; // Verify the ECC public key index used to verify header signature is encoded // in the header @@ -518,24 +633,19 @@ impl ImageVerifier { cfi_assert_eq(header.vendor_ecc_pub_key_idx, info.vendor_ecc_pub_key_idx); } - // Verify the LMS public key index used to verify header signature is encoded + // Verify the PQC (LMS or MLDSA) public key index used to verify header signature is encoded // in the header - if cfi_launder(header.vendor_lms_pub_key_idx) != info.vendor_lms_pub_key_idx { - return Err(CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_LMS_PUB_KEY_INDEX_MISMATCH); + if cfi_launder(header.vendor_pqc_pub_key_idx) != info.vendor_pqc_pub_key_idx { + return Err(CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_PQC_PUB_KEY_INDEX_MISMATCH); } else { - cfi_assert_eq(header.vendor_lms_pub_key_idx, info.vendor_lms_pub_key_idx); + cfi_assert_eq(header.vendor_pqc_pub_key_idx, info.vendor_pqc_pub_key_idx); } - // Verify owner ECC signature - let (owner_ecc_pub_key, owner_ecc_sig) = info.owner_ecc_info; - self.verify_owner_ecc_sig(&digest_owner, owner_ecc_pub_key, owner_ecc_sig)?; - - // Verify owner LMS signature - let (owner_lms_pub_key, owner_lms_sig) = info.owner_lms_info; - self.verify_owner_lms_sig( - &digest_owner, - cfi_launder(owner_lms_pub_key), - cfi_launder(owner_lms_sig), + // Verify owner signatures. + self.verify_owner_sig( + &owner_digest_holder, + info.owner_ecc_info, + &info.owner_pqc_info, )?; let verif_info = TocInfo { @@ -549,23 +659,43 @@ impl ImageVerifier { /// Verify Owner Signature // Inlined to reduce ROM size #[inline(always)] - fn verify_owner_ecc_sig( + fn verify_ecc_sig( &mut self, - digest: &ImageDigest, + digest: &ImageDigest384, pub_key: &ImageEccPubKey, sig: &ImageEccSignature, + is_owner: bool, ) -> CaliptraResult<()> { + let (signature_invalid, pub_key_invalid_arg, sig_invalid_arg) = if is_owner { + ( + CaliptraError::IMAGE_VERIFIER_ERR_OWNER_ECC_SIGNATURE_INVALID, + CaliptraError::IMAGE_VERIFIER_ERR_OWNER_ECC_PUB_KEY_INVALID_ARG, + CaliptraError::IMAGE_VERIFIER_ERR_OWNER_ECC_SIGNATURE_INVALID_ARG, + ) + } else { + ( + CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_ECC_SIGNATURE_INVALID, + CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_ECC_PUB_KEY_INVALID_ARG, + CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_ECC_SIGNATURE_INVALID_ARG, + ) + }; + if &pub_key.x == ZERO_DIGEST || &pub_key.y == ZERO_DIGEST { - Err(CaliptraError::IMAGE_VERIFIER_ERR_OWNER_ECC_PUB_KEY_INVALID_ARG)?; + return Err(pub_key_invalid_arg); } if &sig.r == ZERO_DIGEST || &sig.s == ZERO_DIGEST { - Err(CaliptraError::IMAGE_VERIFIER_ERR_OWNER_ECC_SIGNATURE_INVALID_ARG)?; + return Err(sig_invalid_arg); } #[cfg(feature = "fips-test-hooks")] unsafe { + let fips_verify_failure = if is_owner { + caliptra_drivers::FipsTestHook::FW_LOAD_OWNER_ECC_VERIFY_FAILURE + } else { + caliptra_drivers::FipsTestHook::FW_LOAD_VENDOR_ECC_VERIFY_FAILURE + }; caliptra_drivers::FipsTestHook::update_hook_cmd_if_hook_set( - caliptra_drivers::FipsTestHook::FW_LOAD_OWNER_ECC_VERIFY_FAILURE, + fips_verify_failure, caliptra_drivers::FipsTestHook::ECC384_VERIFY_FAILURE, ) }; @@ -575,11 +705,15 @@ impl ImageVerifier { .ecc384_verify(digest, pub_key, sig) .map_err(|err| { self.env.set_fw_extended_error(err.into()); - CaliptraError::IMAGE_VERIFIER_ERR_OWNER_ECC_VERIFY_FAILURE + if is_owner { + CaliptraError::IMAGE_VERIFIER_ERR_OWNER_ECC_VERIFY_FAILURE + } else { + CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_ECC_VERIFY_FAILURE + } })?; if cfi_launder(verify_r) != caliptra_drivers::Array4xN(sig.r) { - Err(CaliptraError::IMAGE_VERIFIER_ERR_OWNER_ECC_SIGNATURE_INVALID)?; + return Err(signature_invalid); } else { caliptra_cfi_lib::cfi_assert_eq_12_words(&verify_r.0, &sig.r); } @@ -590,13 +724,13 @@ impl ImageVerifier { /// Verify Vendor Signature fn verify_vendor_sig( &mut self, - digest: &ImageDigest, + digest_holder: &ImageDigestHolder, ecc_info: (&ImageEccPubKey, &ImageEccSignature), - lms_info: (&ImageLmsPublicKey, &ImageLmsSignature), + pqc_info: &PqcKeyInfo, ) -> CaliptraResult<()> { let (ecc_pub_key, ecc_sig) = ecc_info; if &ecc_pub_key.x == ZERO_DIGEST || &ecc_pub_key.y == ZERO_DIGEST { - Err(CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_PUB_KEY_DIGEST_INVALID_ARG)?; + Err(CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_ECC_PUB_KEY_INVALID_ARG)?; } if &ecc_sig.r == ZERO_DIGEST || &ecc_sig.s == ZERO_DIGEST { Err(CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_ECC_SIGNATURE_INVALID_ARG)?; @@ -612,7 +746,7 @@ impl ImageVerifier { let verify_r = self .env - .ecc384_verify(digest, ecc_pub_key, ecc_sig) + .ecc384_verify(digest_holder.digest_384, ecc_pub_key, ecc_sig) .map_err(|err| { self.env.set_fw_extended_error(err.into()); CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_ECC_VERIFY_FAILURE @@ -624,43 +758,99 @@ impl ImageVerifier { caliptra_cfi_lib::cfi_assert_eq_12_words(&verify_r.0, &ecc_sig.r); } - #[cfg(feature = "fips-test-hooks")] - unsafe { - caliptra_drivers::FipsTestHook::update_hook_cmd_if_hook_set( - caliptra_drivers::FipsTestHook::FW_LOAD_VENDOR_LMS_VERIFY_FAILURE, - caliptra_drivers::FipsTestHook::LMS_VERIFY_FAILURE, - ) - }; + // Verify PQC signature. + match pqc_info { + PqcKeyInfo::Lms(lms_pub_key, lms_sig) => { + self.verify_lms_sig(digest_holder.digest_384, lms_pub_key, lms_sig, false)?; + } + PqcKeyInfo::Mldsa(mldsa_pub_key, mldsa_sig) => { + if let Some(digest_512) = digest_holder.digest_512 { + let result = self + .env + .mldsa87_verify(digest_512, mldsa_pub_key, mldsa_sig) + .map_err(|err| { + self.env.set_fw_extended_error(err.into()); + CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_MLDSA_VERIFY_FAILURE + })?; + + if cfi_launder(result) != Mldsa87Result::Success { + Err(CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_MLDSA_SIGNATURE_INVALID)?; + } + } else { + Err(CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_MLDSA_DIGEST_MISSING)?; + } + } + } - let (lms_pub_key, lms_sig) = lms_info; - let candidate_key = self - .env - .lms_verify(digest, lms_pub_key, lms_sig) - .map_err(|err| { - self.env.set_fw_extended_error(err.into()); - CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_LMS_VERIFY_FAILURE - })?; - let pub_key_digest = HashValue::from(lms_pub_key.digest); - if candidate_key != pub_key_digest { - return Err(CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_LMS_SIGNATURE_INVALID); - } else { - caliptra_cfi_lib::cfi_assert_eq_6_words(&candidate_key.0, &pub_key_digest.0); + Ok(()) + } + + fn verify_owner_sig( + &mut self, + digest_holder: &ImageDigestHolder, + ecc_info: (&ImageEccPubKey, &ImageEccSignature), + pqc_info: &PqcKeyInfo, + ) -> CaliptraResult<()> { + // Verify owner ECC signature + let (ecc_pub_key, ecc_sig) = ecc_info; + self.verify_ecc_sig(digest_holder.digest_384, ecc_pub_key, ecc_sig, true)?; + + // Verify owner PQC signature + match pqc_info { + PqcKeyInfo::Lms(lms_pub_key, lms_sig) => { + self.verify_lms_sig(digest_holder.digest_384, lms_pub_key, lms_sig, true)?; + } + PqcKeyInfo::Mldsa(mldsa_pub_key, mldsa_sig) => { + if let Some(digest_512) = digest_holder.digest_512 { + let result = self + .env + .mldsa87_verify(digest_512, mldsa_pub_key, mldsa_sig) + .map_err(|err| { + self.env.set_fw_extended_error(err.into()); + CaliptraError::IMAGE_VERIFIER_ERR_OWNER_MLDSA_VERIFY_FAILURE + })?; + + if cfi_launder(result) != Mldsa87Result::Success { + Err(CaliptraError::IMAGE_VERIFIER_ERR_OWNER_MLDSA_SIGNATURE_INVALID)?; + } + } else { + Err(CaliptraError::IMAGE_VERIFIER_ERR_OWNER_MLDSA_DIGEST_MISSING)?; + } + } } Ok(()) } /// Verify owner LMS Signature - fn verify_owner_lms_sig( + fn verify_lms_sig( &mut self, - digest: &ImageDigest, + digest: &ImageDigest384, lms_pub_key: &ImageLmsPublicKey, lms_sig: &ImageLmsSignature, + is_owner: bool, ) -> CaliptraResult<()> { + let (verify_failure, signature_invalid) = if is_owner { + ( + CaliptraError::IMAGE_VERIFIER_ERR_OWNER_LMS_VERIFY_FAILURE, + CaliptraError::IMAGE_VERIFIER_ERR_OWNER_LMS_SIGNATURE_INVALID, + ) + } else { + ( + CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_LMS_VERIFY_FAILURE, + CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_LMS_SIGNATURE_INVALID, + ) + }; + #[cfg(feature = "fips-test-hooks")] unsafe { + let fips_verify_failure = if is_owner { + caliptra_drivers::FipsTestHook::FW_LOAD_OWNER_LMS_VERIFY_FAILURE + } else { + caliptra_drivers::FipsTestHook::FW_LOAD_VENDOR_LMS_VERIFY_FAILURE + }; caliptra_drivers::FipsTestHook::update_hook_cmd_if_hook_set( - caliptra_drivers::FipsTestHook::FW_LOAD_OWNER_LMS_VERIFY_FAILURE, + fips_verify_failure, caliptra_drivers::FipsTestHook::LMS_VERIFY_FAILURE, ) }; @@ -670,12 +860,12 @@ impl ImageVerifier { .lms_verify(digest, lms_pub_key, lms_sig) .map_err(|err| { self.env.set_fw_extended_error(err.into()); - CaliptraError::IMAGE_VERIFIER_ERR_OWNER_LMS_VERIFY_FAILURE + verify_failure })?; let pub_key_digest = HashValue::from(lms_pub_key.digest); if candidate_key != pub_key_digest { - return Err(CaliptraError::IMAGE_VERIFIER_ERR_OWNER_LMS_SIGNATURE_INVALID); + return Err(signature_invalid); } else { caliptra_cfi_lib::cfi_assert_eq_6_words(&candidate_key.0, &pub_key_digest.0); } @@ -973,15 +1163,13 @@ mod tests { vendor_pub_key_info: ImageVendorPubKeyInfo { ecc_key_descriptor: ImageEccKeyDescriptor { version: KEY_DESCRIPTOR_VERSION, - intent: Intent::Vendor as u8, key_hash_count: 1, reserved: 0, key_hash: ImageEccKeyHashes::default(), }, pqc_key_descriptor: ImagePqcKeyDescriptor { version: KEY_DESCRIPTOR_VERSION, - intent: Intent::Vendor as u8, - key_type: KeyType::LMS as u8, + key_type: FwVerificationPqcKeyType::LMS as u8, key_hash_count: 1, key_hash: ImagePqcKeyHashes::default(), }, @@ -1005,15 +1193,13 @@ mod tests { vendor_pub_key_info: ImageVendorPubKeyInfo { ecc_key_descriptor: ImageEccKeyDescriptor { version: KEY_DESCRIPTOR_VERSION, - intent: Intent::Vendor as u8, key_hash_count: 4, reserved: 0, key_hash: ImageEccKeyHashes::default(), }, pqc_key_descriptor: ImagePqcKeyDescriptor { version: KEY_DESCRIPTOR_VERSION, - intent: Intent::Vendor as u8, - key_type: KeyType::LMS as u8, + key_type: FwVerificationPqcKeyType::LMS as u8, key_hash_count: 1, key_hash: ImagePqcKeyHashes::default(), }, @@ -1035,7 +1221,7 @@ mod tests { lifecycle: Lifecycle::Production, vendor_pub_key_digest: DUMMY_DATA, owner_pub_key_digest: DUMMY_DATA, - digest: DUMMY_DATA, + digest_384: DUMMY_DATA, ..Default::default() }; @@ -1045,15 +1231,15 @@ mod tests { vendor_pub_key_info: ImageVendorPubKeyInfo { ecc_key_descriptor: ImageEccKeyDescriptor { version: KEY_DESCRIPTOR_VERSION, - intent: Intent::Vendor as u8, + key_hash_count: 1, reserved: 0, key_hash: ImageEccKeyHashes::default(), }, pqc_key_descriptor: ImagePqcKeyDescriptor { version: KEY_DESCRIPTOR_VERSION, - intent: Intent::Vendor as u8, - key_type: KeyType::LMS as u8, + + key_type: FwVerificationPqcKeyType::LMS as u8, key_hash_count: 1, key_hash: ImagePqcKeyHashes::default(), }, @@ -1061,7 +1247,11 @@ mod tests { ..Default::default() }; - let result = verifier.verify_preamble(&preamble, ResetReason::UpdateReset); + let result = verifier.verify_preamble( + &preamble, + ResetReason::UpdateReset, + FwVerificationPqcKeyType::LMS, + ); assert!(result.is_ok()); } @@ -1071,7 +1261,7 @@ mod tests { lifecycle: Lifecycle::Production, vendor_pub_key_digest: DUMMY_DATA, owner_pub_key_digest: DUMMY_DATA, - digest: DUMMY_DATA, + digest_384: DUMMY_DATA, fmc_digest: DUMMY_DATA, ..Default::default() }; @@ -1096,7 +1286,7 @@ mod tests { lifecycle: Lifecycle::Production, vendor_pub_key_digest: DUMMY_DATA, owner_pub_key_digest: DUMMY_DATA, - digest: DUMMY_DATA, + digest_384: DUMMY_DATA, ..Default::default() }; @@ -1122,7 +1312,7 @@ mod tests { lifecycle: Lifecycle::Production, vendor_pub_key_digest: DUMMY_DATA, owner_pub_key_digest: DUMMY_DATA, - digest: DUMMY_DATA, + digest_384: DUMMY_DATA, fmc_digest: DUMMY_DATA, ..Default::default() }; @@ -1132,15 +1322,15 @@ mod tests { vendor_pub_key_info: ImageVendorPubKeyInfo { ecc_key_descriptor: ImageEccKeyDescriptor { version: KEY_DESCRIPTOR_VERSION, - intent: Intent::Vendor as u8, + key_hash_count: 1, reserved: 0, key_hash: ImageEccKeyHashes::default(), }, pqc_key_descriptor: ImagePqcKeyDescriptor { version: KEY_DESCRIPTOR_VERSION, - intent: Intent::Vendor as u8, - key_type: KeyType::LMS as u8, + + key_type: FwVerificationPqcKeyType::LMS as u8, key_hash_count: 1, key_hash: ImagePqcKeyHashes::default(), }, @@ -1148,7 +1338,11 @@ mod tests { ..Default::default() }; - let result = verifier.verify_preamble(&preamble, ResetReason::UpdateReset); + let result = verifier.verify_preamble( + &preamble, + ResetReason::UpdateReset, + FwVerificationPqcKeyType::LMS, + ); assert!(result.is_ok()); } @@ -1188,7 +1382,11 @@ mod tests { ..Default::default() }; let mut verifier = ImageVerifier::new(test_env); - let result = verifier.verify_preamble(&preamble, ResetReason::ColdReset); + let result = verifier.verify_preamble( + &preamble, + ResetReason::ColdReset, + FwVerificationPqcKeyType::LMS, + ); assert!(result.is_err()); assert_eq!( result.err(), @@ -1202,7 +1400,7 @@ mod tests { lifecycle: Lifecycle::Production, vendor_pub_key_digest: DUMMY_DATA, owner_pub_key_digest: DUMMY_DATA, - digest: DUMMY_DATA, + digest_384: DUMMY_DATA, ..Default::default() }; let mut verifier = ImageVerifier::new(test_env); @@ -1210,15 +1408,15 @@ mod tests { vendor_pub_key_info: ImageVendorPubKeyInfo { ecc_key_descriptor: ImageEccKeyDescriptor { version: KEY_DESCRIPTOR_VERSION, - intent: Intent::Vendor as u8, + key_hash_count: 1, reserved: 0, key_hash: ImageEccKeyHashes::default(), }, pqc_key_descriptor: ImagePqcKeyDescriptor { version: KEY_DESCRIPTOR_VERSION, - intent: Intent::Vendor as u8, - key_type: KeyType::LMS as u8, + + key_type: FwVerificationPqcKeyType::LMS as u8, key_hash_count: 1, key_hash: ImagePqcKeyHashes::default(), }, @@ -1226,7 +1424,11 @@ mod tests { ..Default::default() }; - let result = verifier.verify_preamble(&preamble, ResetReason::ColdReset); + let result = verifier.verify_preamble( + &preamble, + ResetReason::ColdReset, + FwVerificationPqcKeyType::LMS, + ); assert!(result.is_ok()); } @@ -1243,22 +1445,26 @@ mod tests { vendor_pub_key_info: ImageVendorPubKeyInfo { ecc_key_descriptor: ImageEccKeyDescriptor { version: KEY_DESCRIPTOR_VERSION, - intent: Intent::Vendor as u8, + key_hash_count: 1, reserved: 0, key_hash: ImageEccKeyHashes::default(), }, pqc_key_descriptor: ImagePqcKeyDescriptor { version: KEY_DESCRIPTOR_VERSION, - intent: Intent::Vendor as u8, - key_type: KeyType::LMS as u8, + + key_type: FwVerificationPqcKeyType::LMS as u8, key_hash_count: 1, key_hash: ImagePqcKeyHashes::default(), }, }, ..Default::default() }; - let result = verifier.verify_preamble(&preamble, ResetReason::ColdReset); + let result = verifier.verify_preamble( + &preamble, + ResetReason::ColdReset, + FwVerificationPqcKeyType::LMS, + ); assert_eq!( result.err(), Some(CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_PUB_KEY_DIGEST_MISMATCH) @@ -1278,20 +1484,20 @@ mod tests { let binding_vendor_lms_sig = vendor_lms_sig(); let header_info: HeaderInfo = HeaderInfo { vendor_ecc_pub_key_idx: 0, - vendor_lms_pub_key_idx: 0, + vendor_pqc_pub_key_idx: 0, vendor_ecc_info: (&ImageEccPubKey::default(), &ImageEccSignature::default()), - vendor_lms_info: (&binding_vendor_lms_pubkey, &binding_vendor_lms_sig), + vendor_pqc_info: PqcKeyInfo::Lms(&binding_vendor_lms_pubkey, &binding_vendor_lms_sig), owner_ecc_info: (&ecc_pubkey, &ecc_sig), - owner_lms_info: (&owner_lms_pubkey, &owner_lms_sig), - owner_pub_keys_digest: ImageDigest::default(), + owner_pqc_info: PqcKeyInfo::Lms(&owner_lms_pubkey, &owner_lms_sig), + owner_pub_keys_digest: ImageDigest384::default(), owner_pub_keys_digest_in_fuses: false, vendor_ecc_pub_key_revocation: Default::default(), - vendor_lms_pub_key_revocation: Default::default(), + vendor_pqc_pub_key_revocation: Default::default(), }; let result = verifier.verify_header(&header, &header_info); assert_eq!( result.err(), - Some(CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_PUB_KEY_DIGEST_INVALID_ARG) + Some(CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_ECC_PUB_KEY_INVALID_ARG) ); } @@ -1308,15 +1514,15 @@ mod tests { let binding_vendor_lms_sig = vendor_lms_sig(); let header_info: HeaderInfo = HeaderInfo { vendor_ecc_pub_key_idx: 0, - vendor_lms_pub_key_idx: 0, + vendor_pqc_pub_key_idx: 0, vendor_ecc_info: (&VENDOR_ECC_PUBKEY, &ImageEccSignature::default()), - vendor_lms_info: (&binding_vendor_lms_pubkey, &binding_vendor_lms_sig), + vendor_pqc_info: PqcKeyInfo::Lms(&binding_vendor_lms_pubkey, &binding_vendor_lms_sig), owner_ecc_info: (&owner_ecc_pubkey, &owner_ecc_sig), - owner_lms_info: (&owner_lms_pubkey, &owner_lms_sig), - owner_pub_keys_digest: ImageDigest::default(), + owner_pqc_info: PqcKeyInfo::Lms(&owner_lms_pubkey, &owner_lms_sig), + owner_pub_keys_digest: ImageDigest384::default(), owner_pub_keys_digest_in_fuses: false, vendor_ecc_pub_key_revocation: Default::default(), - vendor_lms_pub_key_revocation: Default::default(), + vendor_pqc_pub_key_revocation: Default::default(), }; let result = verifier.verify_header(&header, &header_info); assert_eq!( @@ -1344,15 +1550,15 @@ mod tests { let binding_vendor_lms_sig = vendor_lms_sig(); let header_info: HeaderInfo = HeaderInfo { vendor_ecc_pub_key_idx: 0, - vendor_lms_pub_key_idx: 0, + vendor_pqc_pub_key_idx: 0, vendor_ecc_info: (&VENDOR_ECC_PUBKEY, &VENDOR_ECC_SIG), - vendor_lms_info: (&binding_vendor_lms_pubkey, &binding_vendor_lms_sig), + vendor_pqc_info: PqcKeyInfo::Lms(&binding_vendor_lms_pubkey, &binding_vendor_lms_sig), owner_ecc_info: (&owner_ecc_pubkey, &owner_ecc_sig), - owner_lms_info: (&owner_lms_pubkey, &owner_lms_sig), - owner_pub_keys_digest: ImageDigest::default(), + owner_pqc_info: PqcKeyInfo::Lms(&owner_lms_pubkey, &owner_lms_sig), + owner_pub_keys_digest: ImageDigest384::default(), owner_pub_keys_digest_in_fuses: false, vendor_ecc_pub_key_revocation: Default::default(), - vendor_lms_pub_key_revocation: Default::default(), + vendor_pqc_pub_key_revocation: Default::default(), }; let result = verifier.verify_header(&header, &header_info); assert_eq!( @@ -1380,15 +1586,15 @@ mod tests { let binding_vendor_lms_sig = vendor_lms_sig(); let header_info: HeaderInfo = HeaderInfo { vendor_ecc_pub_key_idx: 0, - vendor_lms_pub_key_idx: 0, + vendor_pqc_pub_key_idx: 0, vendor_ecc_pub_key_revocation: Default::default(), vendor_ecc_info: (&VENDOR_ECC_PUBKEY, &VENDOR_ECC_SIG), - vendor_lms_info: (&binding_vendor_lms_pubkey, &binding_vendor_lms_sig), + vendor_pqc_info: PqcKeyInfo::Lms(&binding_vendor_lms_pubkey, &binding_vendor_lms_sig), owner_ecc_info: (&owner_ecc_pubkey, &owner_ecc_sig), - owner_lms_info: (&owner_lms_pubkey, &owner_lms_sig), - owner_pub_keys_digest: ImageDigest::default(), + owner_pqc_info: PqcKeyInfo::Lms(&owner_lms_pubkey, &owner_lms_sig), + owner_pub_keys_digest: ImageDigest384::default(), owner_pub_keys_digest_in_fuses: false, - vendor_lms_pub_key_revocation: Default::default(), + vendor_pqc_pub_key_revocation: Default::default(), }; let result = verifier.verify_header(&header, &header_info); assert_eq!( @@ -1401,7 +1607,7 @@ mod tests { fn test_header_incorrect_pubkey_index() { let test_env = TestEnv { verify_result: true, - verify_lms_result: true, + verify_pqc_result: true, ..Default::default() }; let mut verifier = ImageVerifier::new(test_env); @@ -1414,15 +1620,15 @@ mod tests { let binding_vendor_lms_sig = vendor_lms_sig(); let header_info: HeaderInfo = HeaderInfo { vendor_ecc_pub_key_idx: 1, - vendor_lms_pub_key_idx: 0, + vendor_pqc_pub_key_idx: 0, vendor_ecc_info: (&VENDOR_ECC_PUBKEY, &VENDOR_ECC_SIG), - vendor_lms_info: (&binding_vendor_lms_pubkey, &binding_vendor_lms_sig), + vendor_pqc_info: PqcKeyInfo::Lms(&binding_vendor_lms_pubkey, &binding_vendor_lms_sig), owner_ecc_info: (&owner_ecc_pubkey, &owner_ecc_sig), - owner_lms_info: (&owner_lms_pubkey, &owner_lms_sig), - owner_pub_keys_digest: ImageDigest::default(), + owner_pqc_info: PqcKeyInfo::Lms(&owner_lms_pubkey, &owner_lms_sig), + owner_pub_keys_digest: ImageDigest384::default(), owner_pub_keys_digest_in_fuses: false, vendor_ecc_pub_key_revocation: Default::default(), - vendor_lms_pub_key_revocation: Default::default(), + vendor_pqc_pub_key_revocation: Default::default(), }; let result = verifier.verify_header(&header, &header_info); assert_eq!( @@ -1435,7 +1641,7 @@ mod tests { fn test_header_incorrect_lms_pubkey_index() { let test_env = TestEnv { verify_result: true, - verify_lms_result: true, + verify_pqc_result: true, ..Default::default() }; let mut verifier = ImageVerifier::new(test_env); @@ -1448,20 +1654,20 @@ mod tests { let binding_vendor_lms_sig = vendor_lms_sig(); let header_info: HeaderInfo = HeaderInfo { vendor_ecc_pub_key_idx: 0, - vendor_lms_pub_key_idx: 1, + vendor_pqc_pub_key_idx: 1, vendor_ecc_info: (&VENDOR_ECC_PUBKEY, &VENDOR_ECC_SIG), - vendor_lms_info: (&binding_vendor_lms_pubkey, &binding_vendor_lms_sig), + vendor_pqc_info: PqcKeyInfo::Lms(&binding_vendor_lms_pubkey, &binding_vendor_lms_sig), owner_ecc_info: (&owner_ecc_pubkey, &owner_ecc_sig), - owner_lms_info: (&owner_lms_pubkey, &owner_lms_sig), - owner_pub_keys_digest: ImageDigest::default(), + owner_pqc_info: PqcKeyInfo::Lms(&owner_lms_pubkey, &owner_lms_sig), + owner_pub_keys_digest: ImageDigest384::default(), owner_pub_keys_digest_in_fuses: false, vendor_ecc_pub_key_revocation: Default::default(), - vendor_lms_pub_key_revocation: Default::default(), + vendor_pqc_pub_key_revocation: Default::default(), }; let result = verifier.verify_header(&header, &header_info); assert_eq!( result.err(), - Some(CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_LMS_PUB_KEY_INDEX_MISMATCH) + Some(CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_PQC_PUB_KEY_INDEX_MISMATCH) ); } @@ -1469,7 +1675,7 @@ mod tests { fn test_header_owner_pubkey_invalid_arg() { let test_env = TestEnv { verify_result: true, - verify_lms_result: true, + verify_pqc_result: true, ..Default::default() }; let mut verifier = ImageVerifier::new(test_env); @@ -1482,15 +1688,15 @@ mod tests { let binding_vendor_lms_sig = vendor_lms_sig(); let header_info: HeaderInfo = HeaderInfo { vendor_ecc_pub_key_idx: 0, - vendor_lms_pub_key_idx: 0, + vendor_pqc_pub_key_idx: 0, vendor_ecc_info: (&VENDOR_ECC_PUBKEY, &VENDOR_ECC_SIG), - vendor_lms_info: (&binding_vendor_lms_pubkey, &binding_vendor_lms_sig), + vendor_pqc_info: PqcKeyInfo::Lms(&binding_vendor_lms_pubkey, &binding_vendor_lms_sig), owner_ecc_info: (&owner_ecc_pubkey, &owner_ecc_sig), - owner_lms_info: (&owner_lms_pubkey, &owner_lms_sig), - owner_pub_keys_digest: ImageDigest::default(), + owner_pqc_info: PqcKeyInfo::Lms(&owner_lms_pubkey, &owner_lms_sig), + owner_pub_keys_digest: ImageDigest384::default(), owner_pub_keys_digest_in_fuses: false, vendor_ecc_pub_key_revocation: Default::default(), - vendor_lms_pub_key_revocation: Default::default(), + vendor_pqc_pub_key_revocation: Default::default(), }; let result = verifier.verify_header(&header, &header_info); assert_eq!( @@ -1503,7 +1709,7 @@ mod tests { fn test_header_owner_signature_invalid_arg() { let test_env = TestEnv { verify_result: true, - verify_lms_result: true, + verify_pqc_result: true, ..Default::default() }; let mut verifier = ImageVerifier::new(test_env); @@ -1515,15 +1721,15 @@ mod tests { let binding_vendor_lms_sig = vendor_lms_sig(); let header_info: HeaderInfo = HeaderInfo { vendor_ecc_pub_key_idx: 0, - vendor_lms_pub_key_idx: 0, + vendor_pqc_pub_key_idx: 0, vendor_ecc_info: (&VENDOR_ECC_PUBKEY, &VENDOR_ECC_SIG), - vendor_lms_info: (&binding_vendor_lms_pubkey, &binding_vendor_lms_sig), + vendor_pqc_info: PqcKeyInfo::Lms(&binding_vendor_lms_pubkey, &binding_vendor_lms_sig), owner_ecc_info: (&OWNER_ECC_PUBKEY, &owner_ecc_sig), - owner_lms_info: (&owner_lms_pubkey, &owner_lms_sig), - owner_pub_keys_digest: ImageDigest::default(), + owner_pqc_info: PqcKeyInfo::Lms(&owner_lms_pubkey, &owner_lms_sig), + owner_pub_keys_digest: ImageDigest384::default(), owner_pub_keys_digest_in_fuses: false, vendor_ecc_pub_key_revocation: Default::default(), - vendor_lms_pub_key_revocation: Default::default(), + vendor_pqc_pub_key_revocation: Default::default(), }; let result = verifier.verify_header(&header, &header_info); assert_eq!( @@ -1536,7 +1742,7 @@ mod tests { fn test_header_success() { let test_env = TestEnv { verify_result: true, - verify_lms_result: true, + verify_pqc_result: true, ..Default::default() }; let mut verifier = ImageVerifier::new(test_env); @@ -1551,15 +1757,15 @@ mod tests { let binding_vendor_lms_sig = vendor_lms_sig(); let header_info: HeaderInfo = HeaderInfo { vendor_ecc_pub_key_idx: 0, - vendor_lms_pub_key_idx: 0, + vendor_pqc_pub_key_idx: 0, vendor_ecc_info: (&VENDOR_ECC_PUBKEY, &VENDOR_ECC_SIG), - vendor_lms_info: (&binding_vendor_lms_pubkey, &binding_vendor_lms_sig), + vendor_pqc_info: PqcKeyInfo::Lms(&binding_vendor_lms_pubkey, &binding_vendor_lms_sig), owner_ecc_info: (&OWNER_ECC_PUBKEY, &OWNER_ECC_SIG), - owner_lms_info: (&owner_lms_pubkey, &owner_lms_sig), - owner_pub_keys_digest: ImageDigest::default(), + owner_pqc_info: PqcKeyInfo::Lms(&owner_lms_pubkey, &owner_lms_sig), + owner_pub_keys_digest: ImageDigest384::default(), owner_pub_keys_digest_in_fuses: false, vendor_ecc_pub_key_revocation: Default::default(), - vendor_lms_pub_key_revocation: Default::default(), + vendor_pqc_pub_key_revocation: Default::default(), }; let toc_info = verifier.verify_header(&header, &header_info).unwrap(); assert_eq!(toc_info.len, 100); @@ -1573,7 +1779,7 @@ mod tests { let mut verifier = ImageVerifier::new(test_env); let toc_info = TocInfo { len: MAX_TOC_ENTRY_COUNT / 2, - digest: &ImageDigest::default(), + digest: &ImageDigest384::default(), }; let result = verifier.verify_toc(&manifest, &toc_info, manifest.size); assert_eq!( @@ -1605,7 +1811,7 @@ mod tests { let mut verifier = ImageVerifier::new(test_env); let toc_info = TocInfo { len: MAX_TOC_ENTRY_COUNT, - digest: &ImageDigest::default(), + digest: &ImageDigest384::default(), }; // Case 0: @@ -1735,7 +1941,7 @@ mod tests { let mut verifier = ImageVerifier::new(test_env); let toc_info = TocInfo { len: MAX_TOC_ENTRY_COUNT, - digest: &ImageDigest::default(), + digest: &ImageDigest384::default(), }; // FMC size == 0 @@ -1780,7 +1986,7 @@ mod tests { let mut verifier = ImageVerifier::new(test_env); let toc_info = TocInfo { len: MAX_TOC_ENTRY_COUNT, - digest: &ImageDigest::default(), + digest: &ImageDigest384::default(), }; // [-FMC--] @@ -1807,7 +2013,7 @@ mod tests { let mut verifier = ImageVerifier::new(test_env); let toc_info = TocInfo { len: MAX_TOC_ENTRY_COUNT, - digest: &ImageDigest::default(), + digest: &ImageDigest384::default(), }; // [-FMC--] @@ -1834,7 +2040,7 @@ mod tests { let mut verifier = ImageVerifier::new(test_env); let toc_info = TocInfo { len: MAX_TOC_ENTRY_COUNT, - digest: &ImageDigest::default(), + digest: &ImageDigest384::default(), }; manifest.fmc.offset = 0; @@ -2004,41 +2210,47 @@ mod tests { } struct TestEnv { - digest: ImageDigest, - fmc_digest: ImageDigest, + digest_384: ImageDigest384, + digest_512: ImageDigest512, + fmc_digest: ImageDigest384, verify_result: bool, - verify_lms_result: bool, - vendor_pub_key_digest: ImageDigest, + verify_pqc_result: bool, + vendor_pub_key_digest: ImageDigest384, vendor_ecc_pub_key_revocation: VendorPubKeyRevocation, vendor_lms_pub_key_revocation: u32, - owner_pub_key_digest: ImageDigest, + owner_pub_key_digest: ImageDigest384, lifecycle: Lifecycle, } impl Default for TestEnv { fn default() -> Self { TestEnv { - digest: ImageDigest::default(), - fmc_digest: ImageDigest::default(), + digest_384: ImageDigest384::default(), + digest_512: ImageDigest512::default(), + fmc_digest: ImageDigest384::default(), verify_result: false, - verify_lms_result: false, - vendor_pub_key_digest: ImageDigest::default(), + verify_pqc_result: false, + vendor_pub_key_digest: ImageDigest384::default(), vendor_ecc_pub_key_revocation: VendorPubKeyRevocation::default(), vendor_lms_pub_key_revocation: 0, - owner_pub_key_digest: ImageDigest::default(), + owner_pub_key_digest: ImageDigest384::default(), lifecycle: Lifecycle::Unprovisioned, } } } impl ImageVerificationEnv for TestEnv { - fn sha384_digest(&mut self, _offset: u32, _len: u32) -> CaliptraResult { - Ok(self.digest) + fn sha384_digest(&mut self, _offset: u32, _len: u32) -> CaliptraResult { + Ok(self.digest_384) + } + + fn sha512_digest(&mut self, _offset: u32, _len: u32) -> CaliptraResult { + Ok(self.digest_512) } fn ecc384_verify( &mut self, - _digest: &ImageDigest, + _digest: &ImageDigest384, _pub_key: &ImageEccPubKey, sig: &ImageEccSignature, ) -> CaliptraResult> { @@ -2051,18 +2263,31 @@ mod tests { fn lms_verify( &mut self, - _digest: &ImageDigest, + _digest: &ImageDigest384, pub_key: &ImageLmsPublicKey, _sig: &ImageLmsSignature, ) -> CaliptraResult> { - if self.verify_lms_result { + if self.verify_pqc_result { Ok(HashValue::from(pub_key.digest)) } else { Ok(HashValue::from(&[0xDEADBEEF; 6])) } } - fn vendor_pub_key_info_digest_fuses(&self) -> ImageDigest { + fn mldsa87_verify( + &mut self, + _digest: &ImageDigest512, + _pub_key: &ImageMldsaPubKey, + _sig: &ImageMldsaSignature, + ) -> CaliptraResult { + if self.verify_pqc_result { + Ok(Mldsa87Result::Success) + } else { + Ok(Mldsa87Result::SigVerifyFailed) + } + } + + fn vendor_pub_key_info_digest_fuses(&self) -> ImageDigest384 { self.vendor_pub_key_digest } @@ -2074,7 +2299,7 @@ mod tests { self.vendor_lms_pub_key_revocation } - fn owner_pub_key_digest_fuses(&self) -> ImageDigest { + fn owner_pub_key_digest_fuses(&self) -> ImageDigest384 { self.owner_pub_key_digest } @@ -2090,15 +2315,15 @@ mod tests { 0 } - fn vendor_lms_pub_key_idx_dv(&self) -> u32 { + fn vendor_pqc_pub_key_idx_dv(&self) -> u32 { 0 } - fn owner_pub_key_digest_dv(&self) -> ImageDigest { + fn owner_pub_key_digest_dv(&self) -> ImageDigest384 { self.owner_pub_key_digest } - fn get_fmc_digest_dv(&self) -> ImageDigest { + fn get_fmc_digest_dv(&self) -> ImageDigest384 { self.fmc_digest } diff --git a/lms-types/src/lib.rs b/lms-types/src/lib.rs index d5d1423a3e..8bf00f8c37 100644 --- a/lms-types/src/lib.rs +++ b/lms-types/src/lib.rs @@ -97,6 +97,26 @@ unsafe impl FromBytes for LmsPublicKey { fn only_derive_is_allowed_to_implement_this_trait() {} } +impl LmsPublicKey { + pub fn ref_from_prefix(bytes: &[u8]) -> Option<&Self> { + if bytes.len() >= size_of::() { + Some(unsafe { &*(bytes.as_ptr() as *const Self) }) + } else { + None + } + } +} + +impl LmsPublicKey { + pub fn mut_ref_from_prefix(bytes: &mut [u8]) -> Option<&mut Self> { + if bytes.len() >= size_of::() { + Some(unsafe { &mut *(bytes.as_mut_ptr() as *mut Self) }) + } else { + None + } + } +} + #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[derive(Copy, Clone, Debug, PartialEq, Eq, Zeroize)] #[repr(C)] @@ -171,6 +191,27 @@ unsafe impl AsBytes for LmsSigna unsafe impl FromBytes for LmsSignature { fn only_derive_is_allowed_to_implement_this_trait() {} } +impl LmsSignature { + pub fn ref_from_prefix(bytes: &[u8]) -> Option<&Self> { + if bytes.len() >= size_of::() { + Some(unsafe { &*(bytes.as_ptr() as *const Self) }) + } else { + None + } + } +} + +impl LmsSignature { + pub fn mut_ref_from_prefix(bytes: &mut [u8]) -> Option<&mut Self> { + { + if bytes.len() >= size_of::() { + Some(unsafe { &mut *(bytes.as_mut_ptr() as *mut Self) }) + } else { + None + } + } + } +} #[derive(Debug, Copy, Clone, Eq, PartialEq)] #[repr(C)] diff --git a/rom/dev/Makefile b/rom/dev/Makefile index c46f568124..9294ddfca3 100644 --- a/rom/dev/Makefile +++ b/rom/dev/Makefile @@ -68,10 +68,10 @@ build-fw-image: gen-certs build-test-fmc build-test-rt --manifest-path ../../image/app/Cargo.toml \ -- \ create \ - --image-type 1 \ + --pqc-key-type 1 \ --key-config $(TARGET_DIR)/keys.toml \ --ecc-pk-idx 1 \ - --lms-pk-idx 3 \ + --pqc-pk-idx 3 \ --fmc $(TARGET_DIR)/caliptra-rom-test-fmc \ --fmc-version 0 \ --fmc-svn 0 \ diff --git a/rom/dev/README.md b/rom/dev/README.md index cac3579868..7e5b85de1a 100644 --- a/rom/dev/README.md +++ b/rom/dev/README.md @@ -114,8 +114,6 @@ It is the unsigned portion of the manifest. Preamble contains the signing public | Active LMS or MLDSA Key | 2592 | LMS public key (48 bytes + 2544 unused bytes) used to verify the Firmware Manifest Header Signature.
**tree_type:** LMS Algorithm Type (4 bytes, big endian) Must equal 12.
**otstype:** LM-OTS Algorithm Type (4 bytes, big endian) Must equal 7.
**id:** (16 bytes)
**digest:** (24 bytes)

**OR**

MLDSA-87 public key used to verify the Firmware Manifest Header Signature.
(2592 bytes)| | Manufacturer ECC Signature | 96 | Manufacturer ECC P-384 signature of the Firmware Manifest header hashed using SHA2-384.
**R-Coordinate:** Random Point (48 bytes)
**S-Coordinate:** Proof (48 bytes) | | Manufacturer LMS or MLDSA Signature | 4628 | Manufacturer LMS signature (1620 bytes + 3008 unused bytes) of the Firmware Manifest header hashed using SHA2-384.
**q:** Leaf of the Merkle tree where the OTS public key appears (4 bytes)
**ots:** Lmots Signature (1252 bytes)
**tree_type:** Lms Algorithm Type (4 bytes)
**tree_path:** Path through the tree from the leaf associated with the LM-OTS signature to the root. (360 bytes)

**OR**

Vendor MLDSA-87 signature of the Firmware Manifest header hashed using SHA2-512 (4627 bytes + 1 Reserved byte)| -| Owner ECC Key Descriptor | 52 | Public Key Descriptor for ECC key | -| Owner LMS or MLDSA Key Descriptor | 52 | Public Key Descriptor for LMS or MLDSA key | | Owner ECC Public Key | 96 | ECC P-384 public key used to verify the Firmware Manifest Header Signature.
**X-Coordinate:** Public Key X-Coordinate (48 bytes)
**Y-Coordinate:** Public Key Y-Coordinate (48 bytes)| | Owner LMS or MLDSA Public Key | 2592 | LMS public key (48 bytes + 2544 unused bytes) used to verify the Firmware Manifest Header Signature.
**tree_type:** LMS Algorithm Type (4 bytes)
**otstype:** LMS Ots Algorithm Type (4 bytes)
**id:** (16 bytes)
**digest:** (24 bytes)

**OR**

MLDSA-87 public key used to verify the Firmware Manifest Header Signature.
(2592 bytes)| | Owner ECC Signature | 96 | Manufacturer ECC P-384 signature of the Firmware Manifest header hashed using SHA2-384.
**R-Coordinate:** Random Point (48 bytes)
**S-Coordinate:** Proof (48 bytes) | diff --git a/rom/dev/doc/test-coverage/test-coverage.md b/rom/dev/doc/test-coverage/test-coverage.md index 9477b13a3f..8733faf9fe 100644 --- a/rom/dev/doc/test-coverage/test-coverage.md +++ b/rom/dev/doc/test-coverage/test-coverage.md @@ -100,7 +100,7 @@ Tests update reset flow by providing a non-fw load Mailbox command | **test_upd Tests update reset flow by providing non-compliant fw image | **test_update_reset_verify_image_failure** | IMAGE_VERIFIER_ERR_MANIFEST_MARKER_MISMATCH Check if boot statuses are correctly reported | **test_update_reset_boot_status** | N/A Tests update reset flow by providing a different vendor ECC public key index in the image | **test_update_reset_vendor_ecc_pub_key_idx_dv_mismatch** |IMAGE_VERIFIER_ERR_UPDATE_RESET_VENDOR_ECC_PUB_KEY_IDX_MISMATCH -Tests update reset flow by providing a different vendor LMS public key index in the image | **test_update_reset_vendor_lms_pub_key_idx_dv_mismatch** | IMAGE_VERIFIER_ERR_UPDATE_RESET_VENDOR_LMS_PUB_KEY_IDX_MISMATCH +Tests update reset flow by providing a different vendor LMS public key index in the image | **test_update_reset_vendor_lms_pub_key_idx_dv_mismatch** | IMAGE_VERIFIER_ERR_UPDATE_RESET_VENDOR_PQC_PUB_KEY_IDX_MISMATCH Check value in WarmResetEntry4::RomUpdateResetStatus datavault register | **test_check_rom_update_reset_status_reg** | N/A Ensure that hitless update flow can update an entire 128k bundle with completely different ICCM contents than original boot | **test_update_reset_max_fw_image** | N/A

diff --git a/rom/dev/src/crypto.rs b/rom/dev/src/crypto.rs index 2a48ad0428..666197c936 100644 --- a/rom/dev/src/crypto.rs +++ b/rom/dev/src/crypto.rs @@ -313,7 +313,7 @@ impl Crypto { // Generate the public key. let pub_key = env - .mldsa + .mldsa87 .key_pair(&KeyReadArgs::new(key_pair_seed), &mut env.trng)?; Ok(MlDsaKeyPair { diff --git a/rom/dev/src/flow/cold_reset/fmc_alias.rs b/rom/dev/src/flow/cold_reset/fmc_alias.rs index aa130dc04d..f93fc3c0ce 100644 --- a/rom/dev/src/flow/cold_reset/fmc_alias.rs +++ b/rom/dev/src/flow/cold_reset/fmc_alias.rs @@ -208,7 +208,7 @@ impl FmcAliasLayer { env.soc_ifc.debug_locked() as u8, env.soc_ifc.fuse_bank().anti_rollback_disable() as u8, env.data_vault.ecc_vendor_pk_index() as u8, - env.data_vault.lms_vendor_pk_index() as u8, + env.data_vault.pqc_vendor_pk_index() as u8, fw_proc_info.pqc_verify_config, fw_proc_info.owner_pub_keys_digest_in_fuses as u8, ])?; diff --git a/rom/dev/src/flow/cold_reset/fw_processor.rs b/rom/dev/src/flow/cold_reset/fw_processor.rs index dc290b86a4..ff11224e38 100644 --- a/rom/dev/src/flow/cold_reset/fw_processor.rs +++ b/rom/dev/src/flow/cold_reset/fw_processor.rs @@ -111,6 +111,7 @@ impl FirmwareProcessor { sha2_512_384: &mut env.sha2_512_384, soc_ifc: &mut env.soc_ifc, ecc384: &mut env.ecc384, + mldsa87: &mut env.mldsa87, data_vault: &mut env.data_vault, pcr_bank: &mut env.pcr_bank, image: txn.raw_mailbox_contents(), @@ -382,6 +383,7 @@ impl FirmwareProcessor { soc_ifc: venv.soc_ifc, data_vault: venv.data_vault, ecc384: venv.ecc384, + mldsa87: venv.mldsa87, image: venv.image, }; @@ -395,8 +397,10 @@ impl FirmwareProcessor { let info = verifier.verify(manifest, img_bundle_sz, ResetReason::ColdReset)?; cprintln!( - "[fwproc] Img verified w/ Vendor ECC Key Idx {}, with SVN {} and effective fuse SVN {}", + "[fwproc] Img verified w/ Vendor ECC Key Idx {}, PQC Key Type: {}, PQC Key Idx {}, with SVN {} and effective fuse SVN {}", info.vendor_ecc_pub_key_idx, + manifest.pqc_key_type, + info.vendor_pqc_pub_key_idx, info.fw_svn, info.effective_fuse_svn, ); @@ -476,18 +480,18 @@ impl FirmwareProcessor { log_info.fw_log_info.fuse_svn.as_bytes(), )?; - // Log VendorLmsPubKeyIndex + // Log VendorPqcPubKeyIndex log_fuse_data( log, - FuseLogEntryId::VendorLmsPubKeyIndex, - log_info.vendor_lms_pub_key_idx.as_bytes(), + FuseLogEntryId::VendorPqcPubKeyIndex, + log_info.vendor_pqc_pub_key_idx.as_bytes(), )?; - // Log VendorLmsPubKeyRevocation + // Log VendorPqcPubKeyRevocation log_fuse_data( log, - FuseLogEntryId::VendorLmsPubKeyRevocation, - log_info.fuse_vendor_lms_pub_key_revocation.as_bytes(), + FuseLogEntryId::VendorPqcPubKeyRevocation, + log_info.fuse_vendor_pqc_pub_key_revocation.as_bytes(), )?; Ok(()) @@ -565,8 +569,8 @@ impl FirmwareProcessor { // If LMS is not enabled, write the max value to the data vault // to indicate the index is invalid. data_vault.write_cold_reset_entry4( - ColdResetEntry4::LmsVendorPubKeyIndex, - info.vendor_lms_pub_key_idx, + ColdResetEntry4::PqcVendorPubKeyIndex, + info.vendor_pqc_pub_key_idx, ); data_vault.write_warm_reset_entry48(WarmResetEntry48::RtTci, &info.runtime.digest.into()); diff --git a/rom/dev/src/flow/fake.rs b/rom/dev/src/flow/fake.rs index 6ca822fd9d..e712fd4be2 100644 --- a/rom/dev/src/flow/fake.rs +++ b/rom/dev/src/flow/fake.rs @@ -243,12 +243,13 @@ pub(crate) struct FakeRomImageVerificationEnv<'a, 'b> { pub(crate) soc_ifc: &'a mut SocIfc, pub(crate) data_vault: &'a mut DataVault, pub(crate) ecc384: &'a mut Ecc384, + pub(crate) mldsa87: &'a mut Mldsa87, pub image: &'b [u8], } impl<'a, 'b> ImageVerificationEnv for &mut FakeRomImageVerificationEnv<'a, 'b> { - /// Calculate Digest using SHA-384 Accelerator - fn sha384_digest(&mut self, offset: u32, len: u32) -> CaliptraResult { + /// Calculate 384 digest using SHA2 Engine + fn sha384_digest(&mut self, offset: u32, len: u32) -> CaliptraResult { let err = CaliptraError::IMAGE_VERIFIER_ERR_DIGEST_OUT_OF_BOUNDS; let data = self .image @@ -259,10 +260,22 @@ impl<'a, 'b> ImageVerificationEnv for &mut FakeRomImageVerificationEnv<'a, 'b> { Ok(self.sha2_512_384.sha384_digest(data)?.0) } + /// Calculate 512 digest using SHA2 Engine + fn sha512_digest(&mut self, offset: u32, len: u32) -> CaliptraResult { + let err = CaliptraError::IMAGE_VERIFIER_ERR_DIGEST_OUT_OF_BOUNDS; + let data = self + .image + .get(offset as usize..) + .ok_or(err)? + .get(..len as usize) + .ok_or(err)?; + Ok(self.sha2_512_384.sha512_digest(data)?.0) + } + /// ECC-384 Verification routine fn ecc384_verify( &mut self, - digest: &ImageDigest, + digest: &ImageDigest384, pub_key: &ImageEccPubKey, sig: &ImageEccSignature, ) -> CaliptraResult> { @@ -288,7 +301,7 @@ impl<'a, 'b> ImageVerificationEnv for &mut FakeRomImageVerificationEnv<'a, 'b> { fn lms_verify( &mut self, - digest: &ImageDigest, + digest: &ImageDigest384, pub_key: &ImageLmsPublicKey, sig: &ImageLmsSignature, ) -> CaliptraResult> { @@ -304,8 +317,26 @@ impl<'a, 'b> ImageVerificationEnv for &mut FakeRomImageVerificationEnv<'a, 'b> { } } + fn mldsa87_verify( + &mut self, + digest: &ImageDigest512, + pub_key: &ImageMldsaPubKey, + sig: &ImageMldsaSignature, + ) -> CaliptraResult { + if self.soc_ifc.verify_in_fake_mode() { + let pub_key = Mldsa87PubKey::from(pub_key.0); + let sig = Mldsa87Signature::from(sig.0); + let msg: Mldsa87Msg = Mldsa87Msg::from(digest); + + self.mldsa87.verify(&pub_key, &msg, &sig) + } else { + // Mock verify, just always return success + Ok(Mldsa87Result::Success) + } + } + /// Retrieve Vendor Public Key Digest - fn vendor_pub_key_info_digest_fuses(&self) -> ImageDigest { + fn vendor_pub_key_info_digest_fuses(&self) -> ImageDigest384 { self.soc_ifc.fuse_bank().vendor_pub_key_info_hash().into() } @@ -320,7 +351,7 @@ impl<'a, 'b> ImageVerificationEnv for &mut FakeRomImageVerificationEnv<'a, 'b> { } /// Retrieve Owner Public Key Digest from fuses - fn owner_pub_key_digest_fuses(&self) -> ImageDigest { + fn owner_pub_key_digest_fuses(&self) -> ImageDigest384 { self.soc_ifc.fuse_bank().owner_pub_key_hash().into() } @@ -340,17 +371,17 @@ impl<'a, 'b> ImageVerificationEnv for &mut FakeRomImageVerificationEnv<'a, 'b> { } /// Get the vendor LMS key index saved in data vault on cold boot - fn vendor_lms_pub_key_idx_dv(&self) -> u32 { - self.data_vault.lms_vendor_pk_index() + fn vendor_pqc_pub_key_idx_dv(&self) -> u32 { + self.data_vault.pqc_vendor_pk_index() } /// Get the owner public key digest saved in the dv on cold boot - fn owner_pub_key_digest_dv(&self) -> ImageDigest { + fn owner_pub_key_digest_dv(&self) -> ImageDigest384 { self.data_vault.owner_pk_hash().into() } // Get the fmc digest from the data vault on cold boot - fn get_fmc_digest_dv(&self) -> ImageDigest { + fn get_fmc_digest_dv(&self) -> ImageDigest384 { self.data_vault.fmc_tci().into() } diff --git a/rom/dev/src/flow/update_reset.rs b/rom/dev/src/flow/update_reset.rs index 9f154650fb..b7f8be199b 100644 --- a/rom/dev/src/flow/update_reset.rs +++ b/rom/dev/src/flow/update_reset.rs @@ -70,6 +70,7 @@ impl UpdateResetFlow { sha2_512_384: &mut env.sha2_512_384, soc_ifc: &mut env.soc_ifc, ecc384: &mut env.ecc384, + mldsa87: &mut env.mldsa87, data_vault: &mut env.data_vault, pcr_bank: &mut env.pcr_bank, image: recv_txn.raw_mailbox_contents(), @@ -151,6 +152,7 @@ impl UpdateResetFlow { soc_ifc: env.soc_ifc, data_vault: env.data_vault, ecc384: env.ecc384, + mldsa87: env.mldsa87, image: env.image, }; diff --git a/rom/dev/src/lock.rs b/rom/dev/src/lock.rs index 58f4cd7214..3934e18779 100644 --- a/rom/dev/src/lock.rs +++ b/rom/dev/src/lock.rs @@ -77,7 +77,7 @@ fn lock_cold_reset_reg(env: &mut RomEnv) { // Lock the Lms Vendor Public Key Index in data vault until next cold reset env.data_vault - .lock_cold_reset_entry4(ColdResetEntry4::LmsVendorPubKeyIndex); + .lock_cold_reset_entry4(ColdResetEntry4::PqcVendorPubKeyIndex); // Lock Cold Reset Status register in data vault until next cold reset env.data_vault diff --git a/rom/dev/src/pcr.rs b/rom/dev/src/pcr.rs index 47b2cf81f5..6e680be95a 100644 --- a/rom/dev/src/pcr.rs +++ b/rom/dev/src/pcr.rs @@ -85,7 +85,7 @@ pub(crate) fn extend_pcrs( env.data_vault.ecc_vendor_pk_index() as u8, env.data_vault.fmc_svn() as u8, info.effective_fuse_svn as u8, - env.data_vault.lms_vendor_pk_index() as u8, + env.data_vault.pqc_vendor_pk_index() as u8, info.pqc_verify_config as u8, info.owner_pub_keys_digest_in_fuses as u8, ]; diff --git a/rom/dev/src/rom_env.rs b/rom/dev/src/rom_env.rs index 9ab6e40d52..f2c7bfb74b 100644 --- a/rom/dev/src/rom_env.rs +++ b/rom/dev/src/rom_env.rs @@ -78,7 +78,7 @@ pub struct RomEnv { pub persistent_data: PersistentDataAccessor, /// Mldsa87 Engine - pub mldsa: Mldsa87, + pub mldsa87: Mldsa87, } impl RomEnv { @@ -107,7 +107,7 @@ impl RomEnv { fht_data_store: FhtDataStore::default(), trng, persistent_data: PersistentDataAccessor::new(), - mldsa: Mldsa87::new(MldsaReg::new()), + mldsa87: Mldsa87::new(MldsaReg::new()), }) } } diff --git a/rom/dev/tests/rom_integration_tests/test_fmcalias_derivation.rs b/rom/dev/tests/rom_integration_tests/test_fmcalias_derivation.rs index 72a3079fca..9c1799f44f 100644 --- a/rom/dev/tests/rom_integration_tests/test_fmcalias_derivation.rs +++ b/rom/dev/tests/rom_integration_tests/test_fmcalias_derivation.rs @@ -22,7 +22,7 @@ use caliptra_hw_model::{BootParams, Fuses, HwModel, InitParams, ModelError, Secu use caliptra_image_crypto::OsslCrypto as Crypto; use caliptra_image_fake_keys::{OWNER_CONFIG, VENDOR_CONFIG_KEY_1}; use caliptra_image_gen::ImageGenerator; -use caliptra_image_types::{FwImageType, IMAGE_BYTE_SIZE}; +use caliptra_image_types::{FwVerificationPqcKeyType, IMAGE_BYTE_SIZE}; use caliptra_test::swap_word_bytes; use openssl::hash::{Hasher, MessageDigest}; use zerocopy::{AsBytes, FromBytes}; @@ -202,7 +202,7 @@ fn test_pcr_log() { VENDOR_CONFIG_KEY_1.ecc_key_idx as u8, FMC_SVN as u8, 0_u8, - VENDOR_CONFIG_KEY_1.lms_key_idx as u8, + VENDOR_CONFIG_KEY_1.pqc_key_idx as u8, RomPqcVerifyConfig::EcdsaAndLms as u8, true as u8, ], @@ -304,7 +304,7 @@ fn test_pcr_log_no_owner_key_digest_fuse() { VENDOR_CONFIG_KEY_1.ecc_key_idx as u8, 0_u8, 0_u8, - VENDOR_CONFIG_KEY_1.lms_key_idx as u8, + VENDOR_CONFIG_KEY_1.pqc_key_idx as u8, RomPqcVerifyConfig::EcdsaAndLms as u8, false as u8, ], @@ -399,7 +399,7 @@ fn test_pcr_log_fmc_fuse_svn() { VENDOR_CONFIG_KEY_1.ecc_key_idx as u8, FMC_SVN as u8, FMC_FUSE_SVN as u8, - VENDOR_CONFIG_KEY_1.lms_key_idx as u8, + VENDOR_CONFIG_KEY_1.pqc_key_idx as u8, RomPqcVerifyConfig::EcdsaAndLms as u8, true as u8, ], @@ -610,7 +610,7 @@ fn test_fuse_log() { fmc_version: 0, app_svn: FMC_SVN, app_version: 0, - fw_image_type: FwImageType::EccLms, + pqc_key_type: FwVerificationPqcKeyType::LMS, }; let image_bundle = caliptra_builder::build_and_sign_image(&TEST_FMC_WITH_UART, &APP_WITH_UART, image_options) @@ -703,15 +703,15 @@ fn test_fuse_log() { assert_eq!(fuse_log_entry.entry_id, FuseLogEntryId::FuseRtSvn as u32); assert_eq!(fuse_log_entry.log_data[0], FMC_SVN); - // Validate the VendorLmsPubKeyIndex + // Validate the VendorPqcPubKeyIndex fuse_log_entry_offset += core::mem::size_of::(); let fuse_log_entry = FuseLogEntry::read_from_prefix(fuse_entry_arr[fuse_log_entry_offset..].as_bytes()).unwrap(); assert_eq!( fuse_log_entry.entry_id, - FuseLogEntryId::VendorLmsPubKeyIndex as u32 + FuseLogEntryId::VendorPqcPubKeyIndex as u32 ); - assert_eq!(fuse_log_entry.log_data[0], VENDOR_CONFIG_KEY_1.lms_key_idx); + assert_eq!(fuse_log_entry.log_data[0], VENDOR_CONFIG_KEY_1.pqc_key_idx); // Validate that the ID is VendorPubKeyRevocation fuse_log_entry_offset += core::mem::size_of::(); @@ -719,7 +719,7 @@ fn test_fuse_log() { FuseLogEntry::read_from_prefix(fuse_entry_arr[fuse_log_entry_offset..].as_bytes()).unwrap(); assert_eq!( fuse_log_entry.entry_id, - FuseLogEntryId::VendorLmsPubKeyRevocation as u32 + FuseLogEntryId::VendorPqcPubKeyRevocation as u32 ); assert_eq!(fuse_log_entry.log_data[0], 0,); } diff --git a/rom/dev/tests/rom_integration_tests/test_image_validation.rs b/rom/dev/tests/rom_integration_tests/test_image_validation.rs index 89618df6e8..96fa6dec31 100644 --- a/rom/dev/tests/rom_integration_tests/test_image_validation.rs +++ b/rom/dev/tests/rom_integration_tests/test_image_validation.rs @@ -9,13 +9,15 @@ use caliptra_builder::{ }, ImageOptions, }; -use caliptra_common::memory_layout::{ICCM_ORG, ICCM_SIZE}; -use caliptra_common::RomBootStatus::*; -use caliptra_drivers::MfgFlags; -use caliptra_drivers::{Array4x12, IdevidCertAttr}; +use caliptra_common::{ + memory_layout::{ICCM_ORG, ICCM_SIZE}, + RomBootStatus::*, +}; +use caliptra_drivers::{Array4x12, IdevidCertAttr, MfgFlags}; use caliptra_error::CaliptraError; use caliptra_hw_model::{ - BootParams, DeviceLifecycle, Fuses, HwModel, InitParams, ModelError, SecurityState, U4, + BootParams, DefaultHwModel, DeviceLifecycle, Fuses, HwModel, InitParams, ModelError, + SecurityState, U4, }; use caliptra_image_crypto::OsslCrypto as Crypto; use caliptra_image_elf::ElfExecutable; @@ -24,16 +26,18 @@ use caliptra_image_fake_keys::{ }; use caliptra_image_gen::{ImageGenerator, ImageGeneratorConfig, ImageGeneratorVendorConfig}; use caliptra_image_types::{ - FwImageType, ImageBundle, ImageManifest, VENDOR_ECC_MAX_KEY_COUNT, VENDOR_LMS_MAX_KEY_COUNT, + FwVerificationPqcKeyType, ImageBundle, ImageDigestHolder, ImageLmsPublicKey, ImageLmsSignature, + ImageManifest, ImageMldsaPubKey, ImageMldsaSignature, MLDSA87_SIGNATURE_WORD_SIZE, + VENDOR_ECC_MAX_KEY_COUNT, VENDOR_LMS_MAX_KEY_COUNT, VENDOR_MLDSA_MAX_KEY_COUNT, +}; +use openssl::{ + asn1::{Asn1Integer, Asn1Time}, + bn::BigNum, + hash::MessageDigest, + pkey::{PKey, Private}, + rsa::Rsa, + x509::{X509Req, X509}, }; -use openssl::asn1::Asn1Integer; -use openssl::asn1::Asn1Time; -use openssl::bn::BigNum; -use openssl::hash::MessageDigest; -use openssl::pkey::{PKey, Private}; -use openssl::rsa::Rsa; -use openssl::x509::X509Req; -use openssl::x509::X509; use std::str; use zerocopy::AsBytes; @@ -250,17 +254,17 @@ fn test_preamble_vendor_lms_pubkey_revocation() { for idx in 0..VENDOR_LMS_MAX_KEY_COUNT { let vendor_config = ImageGeneratorVendorConfig { ecc_key_idx: 3, - lms_key_idx: idx, + pqc_key_idx: idx, ..VENDOR_CONFIG_KEY_0 }; let mut image_options = ImageOptions::default(); - let key_idx = vendor_config.lms_key_idx; + let key_idx = vendor_config.pqc_key_idx; image_options.vendor_config = vendor_config; let fuses = caliptra_hw_model::Fuses { lms_verify: true, - fuse_lms_revocation: 1u32 << image_options.vendor_config.lms_key_idx, + fuse_lms_revocation: 1u32 << image_options.vendor_config.pqc_key_idx, ..Default::default() }; @@ -325,7 +329,7 @@ fn test_preamble_vendor_lms_pubkey_out_of_bounds() { }; let (mut hw, mut image_bundle) = helpers::build_hw_model_and_image_bundle(fuses, ImageOptions::default()); - image_bundle.manifest.preamble.vendor_lms_pub_key_idx = VENDOR_LMS_MAX_KEY_COUNT; + image_bundle.manifest.preamble.vendor_pqc_pub_key_idx = VENDOR_LMS_MAX_KEY_COUNT; assert_eq!( ModelError::MailboxCmdFailed( @@ -352,7 +356,7 @@ fn test_header_verify_vendor_sig_zero_ecc_pubkey() { assert_eq!( ModelError::MailboxCmdFailed( - CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_PUB_KEY_DIGEST_INVALID_ARG.into() + CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_ECC_PUB_KEY_INVALID_ARG.into() ), hw.upload_firmware(&image_bundle.to_bytes().unwrap()) .unwrap_err() @@ -378,7 +382,7 @@ fn test_header_verify_vendor_sig_zero_ecc_pubkey() { assert_eq!( ModelError::MailboxCmdFailed( - CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_PUB_KEY_DIGEST_INVALID_ARG.into() + CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_ECC_PUB_KEY_INVALID_ARG.into() ), hw.upload_firmware(&image_bundle.to_bytes().unwrap()) .unwrap_err() @@ -513,13 +517,18 @@ fn test_header_verify_vendor_lms_sig_mismatch() { helpers::build_hw_model_and_image_bundle(fuses, ImageOptions::default()); // Modify the vendor public key. - let lms_pub_key_backup = image_bundle.manifest.preamble.vendor_lms_active_pub_key; + let lms_pub_key_backup = image_bundle.manifest.preamble.vendor_pqc_active_pub_key; - image_bundle - .manifest - .preamble - .vendor_lms_active_pub_key - .digest = [Default::default(); 6]; + let lms_pub_key = ImageLmsPublicKey::mut_ref_from_prefix( + image_bundle + .manifest + .preamble + .vendor_pqc_active_pub_key + .0 + .as_bytes_mut(), + ) + .unwrap(); + lms_pub_key.digest = [Default::default(); 6]; assert_eq!( ModelError::MailboxCmdFailed( CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_LMS_SIGNATURE_INVALID.into() @@ -537,9 +546,18 @@ fn test_header_verify_vendor_lms_sig_mismatch() { helpers::build_hw_model_and_image_bundle(fuses, ImageOptions::default()); // Modify the vendor signature. - image_bundle.manifest.preamble.vendor_lms_active_pub_key = lms_pub_key_backup; - image_bundle.manifest.preamble.vendor_sigs.lms_sig.tree_path[0] = [Default::default(); 6]; - + image_bundle.manifest.preamble.vendor_pqc_active_pub_key = lms_pub_key_backup; + let lms_sig = ImageLmsSignature::mut_ref_from_prefix( + image_bundle + .manifest + .preamble + .vendor_sigs + .pqc_sig + .0 + .as_bytes_mut(), + ) + .unwrap(); + lms_sig.tree_path[0] = [Default::default(); 6]; assert_eq!( ModelError::MailboxCmdFailed( CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_LMS_SIGNATURE_INVALID.into() @@ -564,14 +582,19 @@ fn test_header_verify_owner_lms_sig_mismatch() { helpers::build_hw_model_and_image_bundle(fuses, ImageOptions::default()); // Modify the owner public key. - let lms_pub_key_backup = image_bundle.manifest.preamble.owner_pub_keys.lms_pub_key; + let lms_pub_key_backup = image_bundle.manifest.preamble.owner_pub_keys.pqc_pub_key; - image_bundle - .manifest - .preamble - .owner_pub_keys - .lms_pub_key - .digest = [Default::default(); 6]; + let lms_pub_key = ImageLmsPublicKey::mut_ref_from_prefix( + image_bundle + .manifest + .preamble + .owner_pub_keys + .pqc_pub_key + .0 + .as_bytes_mut(), + ) + .unwrap(); + lms_pub_key.digest = [Default::default(); 6]; assert_eq!( ModelError::MailboxCmdFailed( CaliptraError::IMAGE_VERIFIER_ERR_OWNER_LMS_SIGNATURE_INVALID.into() @@ -589,9 +612,18 @@ fn test_header_verify_owner_lms_sig_mismatch() { helpers::build_hw_model_and_image_bundle(fuses, ImageOptions::default()); // Modify the owner signature. - image_bundle.manifest.preamble.owner_pub_keys.lms_pub_key = lms_pub_key_backup; - image_bundle.manifest.preamble.owner_sigs.lms_sig.tree_path[0] = [Default::default(); 6]; - + image_bundle.manifest.preamble.owner_pub_keys.pqc_pub_key = lms_pub_key_backup; + let lms_sig = ImageLmsSignature::mut_ref_from_prefix( + image_bundle + .manifest + .preamble + .owner_sigs + .pqc_sig + .0 + .as_bytes_mut(), + ) + .unwrap(); + lms_sig.tree_path[0] = [Default::default(); 6]; assert_eq!( ModelError::MailboxCmdFailed( CaliptraError::IMAGE_VERIFIER_ERR_OWNER_LMS_SIGNATURE_INVALID.into() @@ -638,13 +670,13 @@ fn test_header_verify_vendor_lms_pub_key_in_preamble_and_header() { helpers::build_hw_model_and_image_bundle(fuses, ImageOptions::default()); // Change vendor pubkey index. - image_bundle.manifest.header.vendor_lms_pub_key_idx = - image_bundle.manifest.preamble.vendor_lms_pub_key_idx + 1; + image_bundle.manifest.header.vendor_pqc_pub_key_idx = + image_bundle.manifest.preamble.vendor_pqc_pub_key_idx + 1; update_header(&mut image_bundle); assert_eq!( ModelError::MailboxCmdFailed( - CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_LMS_PUB_KEY_INDEX_MISMATCH.into() + CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_PQC_PUB_KEY_INDEX_MISMATCH.into() ), hw.upload_firmware(&image_bundle.to_bytes().unwrap()) .unwrap_err() @@ -1798,24 +1830,33 @@ fn update_header(image_bundle: &mut ImageBundle) { runtime: ElfExecutable::default(), vendor_config: opts.vendor_config, owner_config: opts.owner_config, - fw_image_type: FwImageType::EccLms, + pqc_key_type: FwVerificationPqcKeyType::LMS, }; let gen = ImageGenerator::new(Crypto::default()); - let header_digest_vendor = gen - .header_digest_vendor(&image_bundle.manifest.header) + let vendor_header_digest_384 = gen + .vendor_header_digest_384(&image_bundle.manifest.header) .unwrap(); - let header_digest_owner = gen - .header_digest_owner(&image_bundle.manifest.header) + let vendor_header_digest_holder = ImageDigestHolder { + digest_384: &vendor_header_digest_384, + digest_512: None, + }; + + let owner_header_digest_384 = gen + .owner_header_digest_384(&image_bundle.manifest.header) .unwrap(); + let owner_header_digest_holder = ImageDigestHolder { + digest_384: &owner_header_digest_384, + digest_512: None, + }; image_bundle.manifest.preamble = gen .gen_preamble( &config, image_bundle.manifest.preamble.vendor_ecc_pub_key_idx, - image_bundle.manifest.preamble.vendor_lms_pub_key_idx, - &header_digest_vendor, - &header_digest_owner, + image_bundle.manifest.preamble.vendor_pqc_pub_key_idx, + &vendor_header_digest_holder, + &owner_header_digest_holder, ) .unwrap(); } @@ -2118,3 +2159,328 @@ fn test_max_fw_image() { assert_eq!(iccm_cmp.len(), 1); assert_eq!(iccm_cmp[0], 0); } + +#[test] +fn test_mldsa_verification() { + let rom = caliptra_builder::build_firmware_rom(firmware::rom_from_env()).unwrap(); + let mut hw = caliptra_hw_model::new( + InitParams { + rom: &rom, + ..Default::default() + }, + BootParams::default(), + ) + .unwrap(); + + let image_options = ImageOptions { + pqc_key_type: FwVerificationPqcKeyType::MLDSA, + ..Default::default() + }; + + let image_bundle = caliptra_builder::build_and_sign_image( + &TEST_FMC_INTERACTIVE, + &TEST_RT_WITH_UART, + image_options, + ) + .unwrap(); + + hw.upload_firmware(&image_bundle.to_bytes().unwrap()) + .unwrap(); + + hw.step_until_boot_status(u32::from(ColdResetComplete), true); +} + +fn hw_and_mldsa_image_bundle() -> (DefaultHwModel, ImageBundle) { + let rom = caliptra_builder::build_firmware_rom(firmware::rom_from_env()).unwrap(); + let hw = caliptra_hw_model::new( + InitParams { + rom: &rom, + ..Default::default() + }, + BootParams::default(), + ) + .unwrap(); + + let image_options = ImageOptions { + pqc_key_type: FwVerificationPqcKeyType::MLDSA, + ..Default::default() + }; + + let image_bundle = caliptra_builder::build_and_sign_image( + &TEST_FMC_INTERACTIVE, + &TEST_RT_WITH_UART, + image_options, + ) + .unwrap(); + + (hw, image_bundle) +} + +#[test] +fn test_header_verify_vendor_mldsa_sig_zero() { + let (mut hw, mut image_bundle) = hw_and_mldsa_image_bundle(); + + // Modify the vendor public key. + let mldsa_pub_key_backup = image_bundle.manifest.preamble.vendor_pqc_active_pub_key; + + let mldsa_pub_key = ImageMldsaPubKey::mut_ref_from_prefix( + image_bundle + .manifest + .preamble + .vendor_pqc_active_pub_key + .0 + .as_bytes_mut(), + ) + .unwrap(); + + *mldsa_pub_key = Default::default(); + assert_eq!( + hw.upload_firmware(&image_bundle.to_bytes().unwrap()) + .unwrap_err(), + ModelError::MailboxCmdFailed( + CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_MLDSA_SIGNATURE_INVALID.into() + ) + ); + drop(hw); + + let (mut hw, mut image_bundle) = hw_and_mldsa_image_bundle(); + + // Modify the vendor signature. + image_bundle.manifest.preamble.vendor_pqc_active_pub_key = mldsa_pub_key_backup; + let mldsa_sig = ImageMldsaSignature::mut_ref_from_prefix( + image_bundle + .manifest + .preamble + .vendor_sigs + .pqc_sig + .0 + .as_bytes_mut(), + ) + .unwrap(); + *mldsa_sig = Default::default(); + assert_eq!( + hw.upload_firmware(&image_bundle.to_bytes().unwrap()) + .unwrap_err(), + ModelError::MailboxCmdFailed( + CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_MLDSA_SIGNATURE_INVALID.into() + ) + ); + + assert_eq!( + hw.soc_ifc().cptra_boot_status().read(), + u32::from(FwProcessorManifestLoadComplete) + ); +} + +#[test] +fn test_header_verify_vendor_mldsa_sig_mismatch() { + let (mut hw, mut image_bundle) = hw_and_mldsa_image_bundle(); + + // Modify the vendor public key. + let mldsa_pub_key_backup = image_bundle.manifest.preamble.vendor_pqc_active_pub_key; + + let mldsa_pub_key = ImageMldsaPubKey::mut_ref_from_prefix( + image_bundle + .manifest + .preamble + .vendor_pqc_active_pub_key + .0 + .as_bytes_mut(), + ) + .unwrap(); + + *mldsa_pub_key = Default::default(); + assert_eq!( + hw.upload_firmware(&image_bundle.to_bytes().unwrap()) + .unwrap_err(), + ModelError::MailboxCmdFailed( + CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_MLDSA_SIGNATURE_INVALID.into() + ) + ); + drop(hw); + + let (mut hw, mut image_bundle) = hw_and_mldsa_image_bundle(); + + // Modify the vendor signature. + image_bundle.manifest.preamble.vendor_pqc_active_pub_key = mldsa_pub_key_backup; + let mldsa_sig = ImageMldsaSignature::mut_ref_from_prefix( + image_bundle + .manifest + .preamble + .vendor_sigs + .pqc_sig + .0 + .as_bytes_mut(), + ) + .unwrap(); + + let mut signature = [0u32; MLDSA87_SIGNATURE_WORD_SIZE]; + signature[0..4].copy_from_slice(&[0xDE, 0xAD, 0xBE, 0xEF]); + *mldsa_sig = ImageMldsaSignature(signature); + + assert_eq!( + hw.upload_firmware(&image_bundle.to_bytes().unwrap()) + .unwrap_err(), + ModelError::MailboxCmdFailed( + CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_MLDSA_SIGNATURE_INVALID.into() + ) + ); + + assert_eq!( + hw.soc_ifc().cptra_boot_status().read(), + u32::from(FwProcessorManifestLoadComplete) + ); +} + +#[test] +fn test_header_verify_owner_mldsa_sig_zero() { + let (mut hw, mut image_bundle) = hw_and_mldsa_image_bundle(); + + // Modify the owner public key. + let mldsa_pub_key_backup = image_bundle.manifest.preamble.owner_pub_keys.pqc_pub_key; + + let mldsa_pub_key = ImageMldsaPubKey::mut_ref_from_prefix( + image_bundle + .manifest + .preamble + .owner_pub_keys + .pqc_pub_key + .0 + .as_bytes_mut(), + ) + .unwrap(); + + *mldsa_pub_key = Default::default(); + assert_eq!( + hw.upload_firmware(&image_bundle.to_bytes().unwrap()) + .unwrap_err(), + ModelError::MailboxCmdFailed( + CaliptraError::IMAGE_VERIFIER_ERR_OWNER_MLDSA_SIGNATURE_INVALID.into() + ) + ); + drop(hw); + + let (mut hw, mut image_bundle) = hw_and_mldsa_image_bundle(); + + // Modify the owner signature. + image_bundle.manifest.preamble.owner_pub_keys.pqc_pub_key = mldsa_pub_key_backup; + let mldsa_sig = ImageMldsaSignature::mut_ref_from_prefix( + image_bundle + .manifest + .preamble + .owner_sigs + .pqc_sig + .0 + .as_bytes_mut(), + ) + .unwrap(); + *mldsa_sig = Default::default(); + assert_eq!( + hw.upload_firmware(&image_bundle.to_bytes().unwrap()) + .unwrap_err(), + ModelError::MailboxCmdFailed( + CaliptraError::IMAGE_VERIFIER_ERR_OWNER_MLDSA_SIGNATURE_INVALID.into() + ) + ); + + assert_eq!( + hw.soc_ifc().cptra_boot_status().read(), + u32::from(FwProcessorManifestLoadComplete) + ); +} + +#[test] +fn test_header_verify_owner_mldsa_sig_mismatch() { + let (mut hw, mut image_bundle) = hw_and_mldsa_image_bundle(); + + // Modify the owner public key. + let mldsa_pub_key_backup = image_bundle.manifest.preamble.owner_pub_keys.pqc_pub_key; + + let mldsa_pub_key = ImageMldsaPubKey::mut_ref_from_prefix( + image_bundle + .manifest + .preamble + .owner_pub_keys + .pqc_pub_key + .0 + .as_bytes_mut(), + ) + .unwrap(); + + *mldsa_pub_key = Default::default(); + assert_eq!( + hw.upload_firmware(&image_bundle.to_bytes().unwrap()) + .unwrap_err(), + ModelError::MailboxCmdFailed( + CaliptraError::IMAGE_VERIFIER_ERR_OWNER_MLDSA_SIGNATURE_INVALID.into() + ) + ); + drop(hw); + + let (mut hw, mut image_bundle) = hw_and_mldsa_image_bundle(); + + // Modify the owner signature. + image_bundle.manifest.preamble.owner_pub_keys.pqc_pub_key = mldsa_pub_key_backup; + let mldsa_sig = ImageMldsaSignature::mut_ref_from_prefix( + image_bundle + .manifest + .preamble + .owner_sigs + .pqc_sig + .0 + .as_bytes_mut(), + ) + .unwrap(); + + let mut signature = [0u32; MLDSA87_SIGNATURE_WORD_SIZE]; + signature[0..4].copy_from_slice(&[0xDE, 0xAD, 0xBE, 0xEF]); + *mldsa_sig = ImageMldsaSignature(signature); + + assert_eq!( + hw.upload_firmware(&image_bundle.to_bytes().unwrap()) + .unwrap_err(), + ModelError::MailboxCmdFailed( + CaliptraError::IMAGE_VERIFIER_ERR_OWNER_MLDSA_SIGNATURE_INVALID.into() + ) + ); + + assert_eq!( + hw.soc_ifc().cptra_boot_status().read(), + u32::from(FwProcessorManifestLoadComplete) + ); +} + +#[test] +fn test_header_verify_vendor_mldsa_pub_key_in_preamble_and_header() { + let (mut hw, mut image_bundle) = hw_and_mldsa_image_bundle(); + + // Change vendor pubkey index. + image_bundle.manifest.header.vendor_pqc_pub_key_idx = + image_bundle.manifest.preamble.vendor_pqc_pub_key_idx + 1; + update_header(&mut image_bundle); + + assert_eq!( + hw.upload_firmware(&image_bundle.to_bytes().unwrap()) + .unwrap_err(), + ModelError::MailboxCmdFailed( + CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_MLDSA_SIGNATURE_INVALID.into() + ) + ); +} + +// TODO: Uncomment this test when functionality is implemented. +// #[test] +#[allow(dead_code)] +fn test_preamble_vendor_mldsa_pubkey_out_of_bounds() { + let (mut hw, mut image_bundle) = hw_and_mldsa_image_bundle(); + + image_bundle.manifest.preamble.vendor_pqc_pub_key_idx = VENDOR_MLDSA_MAX_KEY_COUNT; + + assert_eq!( + hw.upload_firmware(&image_bundle.to_bytes().unwrap()) + .unwrap_err(), + ModelError::MailboxCmdFailed( + CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_LMS_PUB_KEY_INDEX_OUT_OF_BOUNDS.into() + ) + ); +} diff --git a/rom/dev/tests/rom_integration_tests/test_update_reset.rs b/rom/dev/tests/rom_integration_tests/test_update_reset.rs index e22e5c12f4..769cab5f3f 100644 --- a/rom/dev/tests/rom_integration_tests/test_update_reset.rs +++ b/rom/dev/tests/rom_integration_tests/test_update_reset.rs @@ -345,7 +345,7 @@ fn test_update_reset_vendor_ecc_pub_key_idx_dv_mismatch() { fn test_update_reset_vendor_lms_pub_key_idx_dv_mismatch() { let rom = caliptra_builder::build_firmware_rom(firmware::rom_from_env()).unwrap(); let vendor_config_cold_boot = ImageGeneratorVendorConfig { - lms_key_idx: 3, + pqc_key_idx: 3, ..VENDOR_CONFIG_KEY_0 }; let image_options = ImageOptions { @@ -361,7 +361,7 @@ fn test_update_reset_vendor_lms_pub_key_idx_dv_mismatch() { // Generate firmware with a different vendor LMS key index. let vendor_config_update_reset = ImageGeneratorVendorConfig { - lms_key_idx: 2, + pqc_key_idx: 2, ..VENDOR_CONFIG_KEY_0 }; let image_options = ImageOptions { @@ -396,7 +396,7 @@ fn test_update_reset_vendor_lms_pub_key_idx_dv_mismatch() { assert_eq!( hw.upload_firmware(&image_bundle2.to_bytes().unwrap()), Err(caliptra_hw_model::ModelError::MailboxCmdFailed( - CaliptraError::IMAGE_VERIFIER_ERR_UPDATE_RESET_VENDOR_LMS_PUB_KEY_IDX_MISMATCH.into() + CaliptraError::IMAGE_VERIFIER_ERR_UPDATE_RESET_VENDOR_PQC_PUB_KEY_IDX_MISMATCH.into() )) ); @@ -407,7 +407,7 @@ fn test_update_reset_vendor_lms_pub_key_idx_dv_mismatch() { assert_eq!( hw.soc_ifc().cptra_fw_error_non_fatal().read(), - u32::from(CaliptraError::IMAGE_VERIFIER_ERR_UPDATE_RESET_VENDOR_LMS_PUB_KEY_IDX_MISMATCH) + u32::from(CaliptraError::IMAGE_VERIFIER_ERR_UPDATE_RESET_VENDOR_PQC_PUB_KEY_IDX_MISMATCH) ); } diff --git a/rom/dev/tests/rom_integration_tests/test_warm_reset.rs b/rom/dev/tests/rom_integration_tests/test_warm_reset.rs index ecce2a6260..4bb3bd715b 100644 --- a/rom/dev/tests/rom_integration_tests/test_warm_reset.rs +++ b/rom/dev/tests/rom_integration_tests/test_warm_reset.rs @@ -31,7 +31,7 @@ fn test_warm_reset_success() { ) .unwrap(); - let (vendor_pk_desc_hash, owner_pk_desc_hash) = image_pk_desc_hash(&image.manifest); + let (vendor_pk_desc_hash, owner_pk_hash) = image_pk_desc_hash(&image.manifest); let mut hw = caliptra_hw_model::new( InitParams { @@ -42,7 +42,7 @@ fn test_warm_reset_success() { BootParams { fuses: Fuses { key_manifest_pk_hash: vendor_pk_desc_hash, - owner_pk_hash: owner_pk_desc_hash, + owner_pk_hash, fmc_key_manifest_svn: 0b1111111, runtime_svn: [0x7F, 0, 0, 0], // Equals 7 ..Default::default() @@ -61,7 +61,7 @@ fn test_warm_reset_success() { // Perform warm reset hw.warm_reset_flow(&Fuses { key_manifest_pk_hash: vendor_pk_desc_hash, - owner_pk_hash: owner_pk_desc_hash, + owner_pk_hash, fmc_key_manifest_svn: 0b1111111, runtime_svn: [0x7F, 0, 0, 0], // Equals 7 ..Default::default() diff --git a/rom/dev/tools/keys.toml b/rom/dev/tools/keys.toml index a2c7942644..b69dbe6274 100644 --- a/rom/dev/tools/keys.toml +++ b/rom/dev/tools/keys.toml @@ -41,6 +41,10 @@ lms_pub_keys = [ "vnd-lms-pub-key-2.pem", "vnd-lms-pub-key-3.pem", ] + +# [TODO][CAP2] Add MLDSA key files. +mldsa_pub_keys = [] + ecc_priv_keys = [ "vnd-priv-key-0.pem", "vnd-priv-key-1.pem", @@ -82,8 +86,13 @@ lms_priv_keys = [ "vnd-lms-priv-key-3.pem", ] +mldsa_priv_keys = [] + [owner] ecc_pub_key = "own-pub-key.pem" ecc_priv_key = "own-priv-key.pem" lms_pub_key = "own-lms-pub-key.pem" lms_priv_key = "own-lms-priv-key.pem" +mldsa_pub_key = "" +mldsa_priv_key = "" + diff --git a/rom/dev/tools/test-fmc/src/main.rs b/rom/dev/tools/test-fmc/src/main.rs index da6a6ca3cf..a478d030dc 100644 --- a/rom/dev/tools/test-fmc/src/main.rs +++ b/rom/dev/tools/test-fmc/src/main.rs @@ -322,8 +322,8 @@ fn read_datavault_coldresetentry4(mbox: &caliptra_registers::mbox::RegisterBlock send_to_mailbox(mbox, (EccVendorPubKeyIndex as u32).as_bytes(), false); send_to_mailbox(mbox, data_vault.ecc_vendor_pk_index().as_bytes(), false); - send_to_mailbox(mbox, (LmsVendorPubKeyIndex as u32).as_bytes(), false); - send_to_mailbox(mbox, data_vault.lms_vendor_pk_index().as_bytes(), false); + send_to_mailbox(mbox, (PqcVendorPubKeyIndex as u32).as_bytes(), false); + send_to_mailbox(mbox, data_vault.pqc_vendor_pk_index().as_bytes(), false); mbox.dlen() .write(|_| (core::mem::size_of::() * 10).try_into().unwrap()); diff --git a/runtime/src/authorize_and_stash.rs b/runtime/src/authorize_and_stash.rs index f3e48521c4..3105c5e063 100644 --- a/runtime/src/authorize_and_stash.rs +++ b/runtime/src/authorize_and_stash.rs @@ -31,7 +31,7 @@ use caliptra_drivers::{ PersistentData, RomPqcVerifyConfig, Sha256, Sha2_512_384, SocIfc, }; use caliptra_image_types::{ - ImageDigest, ImageEccPubKey, ImageEccSignature, ImageLmsPublicKey, ImageLmsSignature, + ImageDigest384, ImageEccPubKey, ImageEccSignature, ImageLmsPublicKey, ImageLmsSignature, ImagePreamble, SHA192_DIGEST_WORD_SIZE, SHA384_DIGEST_BYTE_SIZE, }; use crypto::{AlgLen, Crypto}; diff --git a/runtime/src/drivers.rs b/runtime/src/drivers.rs index 293fa74488..ad77325ab1 100644 --- a/runtime/src/drivers.rs +++ b/runtime/src/drivers.rs @@ -27,22 +27,29 @@ use arrayvec::ArrayVec; use caliptra_cfi_derive_git::{cfi_impl_fn, cfi_mod_fn}; use caliptra_cfi_lib_git::{cfi_assert, cfi_assert_eq, cfi_assert_eq_12_words, cfi_launder}; use caliptra_common::mailbox_api::AddSubjectAltNameReq; -use caliptra_drivers::KeyId; use caliptra_drivers::{ - cprint, cprintln, pcr_log::RT_FW_JOURNEY_PCR, Array4x12, CaliptraError, CaliptraResult, - DataVault, Ecc384, KeyVault, Lms, PersistentDataAccessor, Pic, ResetReason, Sha1, SocIfc, -}; -use caliptra_drivers::{ - hand_off::DataStore, Ecc384PubKey, Hmac, PcrBank, PcrId, Sha256, Sha256Alg, Sha2_512_384, - Sha2_512_384Acc, Trng, + cprint, cprintln, hand_off::DataStore, pcr_log::RT_FW_JOURNEY_PCR, Array4x12, CaliptraError, + CaliptraResult, DataVault, Ecc384, Ecc384PubKey, Hmac, KeyId, KeyVault, Lms, Mldsa87, PcrBank, + PcrId, PersistentDataAccessor, Pic, ResetReason, Sha1, Sha256, Sha256Alg, Sha2_512_384, + Sha2_512_384Acc, SocIfc, Trng, }; use caliptra_image_types::ImageManifest; -use caliptra_registers::el2_pic_ctrl::El2PicCtrl; -use caliptra_registers::mbox::enums::MboxStatusE; use caliptra_registers::{ - csrng::CsrngReg, dv::DvReg, ecc::EccReg, entropy_src::EntropySrcReg, hmac::HmacReg, kv::KvReg, - mbox::MboxCsr, pv::PvReg, sha256::Sha256Reg, sha512::Sha512Reg, sha512_acc::Sha512AccCsr, - soc_ifc::SocIfcReg, soc_ifc_trng::SocIfcTrngReg, + csrng::CsrngReg, + dv::DvReg, + ecc::EccReg, + el2_pic_ctrl::El2PicCtrl, + entropy_src::EntropySrcReg, + hmac::HmacReg, + kv::KvReg, + mbox::{enums::MboxStatusE, MboxCsr}, + mldsa::MldsaReg, + pv::PvReg, + sha256::Sha256Reg, + sha512::Sha512Reg, + sha512_acc::Sha512AccCsr, + soc_ifc::SocIfcReg, + soc_ifc_trng::SocIfcTrngReg, }; use caliptra_x509::{NotAfter, NotBefore}; use dpe::context::{Context, ContextState, ContextType}; @@ -90,6 +97,9 @@ pub struct Drivers { /// Ecc384 Engine pub ecc384: Ecc384, + /// Mldsa87 Engine + pub mldsa87: Mldsa87, + pub persistent_data: PersistentDataAccessor, pub lms: Lms, @@ -135,6 +145,7 @@ impl Drivers { sha2_512_384_acc: Sha2_512_384Acc::new(Sha512AccCsr::new()), hmac: Hmac::new(HmacReg::new()), ecc384: Ecc384::new(EccReg::new()), + mldsa87: Mldsa87::new(MldsaReg::new()), sha1: Sha1::default(), lms: Lms::default(), trng, diff --git a/runtime/src/fips.rs b/runtime/src/fips.rs index 5768c17e25..148e2609e7 100644 --- a/runtime/src/fips.rs +++ b/runtime/src/fips.rs @@ -116,6 +116,7 @@ pub mod fips_self_test_cmd { sha2_512_384: &mut env.sha2_512_384, soc_ifc: &mut env.soc_ifc, ecc384: &mut env.ecc384, + mldsa87: &mut env.mldsa87, data_vault: &mut env.data_vault, pcr_bank: &mut env.pcr_bank, image: env.mbox.raw_mailbox_contents(), diff --git a/runtime/src/set_auth_manifest.rs b/runtime/src/set_auth_manifest.rs index 9c2d84a582..eeca2f9de0 100644 --- a/runtime/src/set_auth_manifest.rs +++ b/runtime/src/set_auth_manifest.rs @@ -32,7 +32,7 @@ use caliptra_drivers::{ PersistentData, RomPqcVerifyConfig, Sha256, Sha2_512_384, SocIfc, }; use caliptra_image_types::{ - ImageDigest, ImageEccPubKey, ImageEccSignature, ImageLmsPublicKey, ImageLmsSignature, + ImageDigest384, ImageEccPubKey, ImageEccSignature, ImageLmsPublicKey, ImageLmsSignature, ImagePreamble, SHA192_DIGEST_WORD_SIZE, SHA384_DIGEST_BYTE_SIZE, }; use crypto::{AlgLen, Crypto}; @@ -52,7 +52,7 @@ impl SetAuthManifestCmd { manifest: &[u8], offset: u32, len: u32, - ) -> CaliptraResult { + ) -> CaliptraResult { let err = CaliptraError::IMAGE_VERIFIER_ERR_DIGEST_OUT_OF_BOUNDS; let data = manifest .get(offset as usize..) @@ -64,7 +64,7 @@ impl SetAuthManifestCmd { fn ecc384_verify( ecc384: &mut Ecc384, - digest: &ImageDigest, + digest: &ImageDigest384, pub_key: &ImageEccPubKey, sig: &ImageEccSignature, ) -> CaliptraResult> { @@ -85,7 +85,7 @@ impl SetAuthManifestCmd { fn lms_verify( sha256: &mut Sha256, - digest: &ImageDigest, + digest: &ImageDigest384, pub_key: &ImageLmsPublicKey, sig: &ImageLmsSignature, ) -> CaliptraResult> { @@ -134,7 +134,9 @@ impl SetAuthManifestCmd { } // Verify vendor LMS signature. - let vendor_fw_lms_key = &fw_preamble.vendor_lms_active_pub_key; + let vendor_fw_lms_key = + ImageLmsPublicKey::ref_from_prefix(fw_preamble.vendor_pqc_active_pub_key.0.as_bytes()) + .ok_or(CaliptraError::RUNTIME_AUTH_MANIFEST_LMS_VENDOR_PUB_KEY_INVALID)?; let candidate_key = Self::lms_verify( sha256, @@ -192,7 +194,9 @@ impl SetAuthManifestCmd { } // Verify owner LMS signature. - let owner_fw_lms_key = &fw_preamble.owner_pub_keys.lms_pub_key; + let owner_fw_lms_key = + ImageLmsPublicKey::ref_from_prefix(fw_preamble.owner_pub_keys.pqc_pub_key.0.as_bytes()) + .ok_or(CaliptraError::RUNTIME_AUTH_MANIFEST_LMS_OWNER_PUB_KEY_INVALID)?; let candidate_key = Self::lms_verify( sha256, @@ -213,7 +217,7 @@ impl SetAuthManifestCmd { fn verify_vendor_image_metadata_col( auth_manifest_preamble: &AuthManifestPreamble, - image_metadata_col_digest: &ImageDigest, + image_metadata_col_digest: &ImageDigest384, sha2: &mut Sha2_512_384, ecc384: &mut Ecc384, sha256: &mut Sha256, @@ -274,7 +278,7 @@ impl SetAuthManifestCmd { fn verify_owner_image_metadata_col( auth_manifest_preamble: &AuthManifestPreamble, - image_metadata_col_digest: &ImageDigest, + image_metadata_col_digest: &ImageDigest384, sha2: &mut Sha2_512_384, ecc384: &mut Ecc384, sha256: &mut Sha256, diff --git a/runtime/tests/runtime_integration_tests/test_pauser_privilege_levels.rs b/runtime/tests/runtime_integration_tests/test_pauser_privilege_levels.rs index b7293d6d9a..07c0772e83 100644 --- a/runtime/tests/runtime_integration_tests/test_pauser_privilege_levels.rs +++ b/runtime/tests/runtime_integration_tests/test_pauser_privilege_levels.rs @@ -15,7 +15,7 @@ use caliptra_hw_model::{BootParams, Fuses, HwModel, InitParams, SecurityState}; use caliptra_image_crypto::OsslCrypto as Crypto; use caliptra_image_elf::ElfExecutable; use caliptra_image_gen::{ImageGenerator, ImageGeneratorConfig}; -use caliptra_image_types::FwImageType; +use caliptra_image_types::{FwVerificationPqcKeyType, ImageDigestHolder}; use caliptra_runtime::{ RtBootStatus, PL0_DPE_ACTIVE_CONTEXT_THRESHOLD, PL1_DPE_ACTIVE_CONTEXT_THRESHOLD, }; @@ -541,14 +541,24 @@ fn test_pl0_unset_in_header() { let opts = ImageOptions::default(); let ecc_index = opts.vendor_config.ecc_key_idx; - let lms_index = opts.vendor_config.lms_key_idx; + let lms_index = opts.vendor_config.pqc_key_idx; let gen = ImageGenerator::new(Crypto::default()); - let header_digest_vendor = gen - .header_digest_vendor(&image_bundle.manifest.header) + let vendor_header_digest_384 = gen + .vendor_header_digest_384(&image_bundle.manifest.header) .unwrap(); - let header_digest_owner = gen - .header_digest_owner(&image_bundle.manifest.header) + let vendor_header_digest_holder = ImageDigestHolder { + digest_384: &vendor_header_digest_384, + digest_512: None, + }; + + let owner_header_digest_384 = gen + .owner_header_digest_384(&image_bundle.manifest.header) .unwrap(); + let owner_header_digest_holder = ImageDigestHolder { + digest_384: &owner_header_digest_384, + digest_512: None, + }; + let fmc_elf = build_firmware_elf(&FMC_WITH_UART).unwrap(); let app_elf = build_firmware_elf(&APP_WITH_UART).unwrap(); let preamble = gen @@ -570,12 +580,12 @@ fn test_pl0_unset_in_header() { .unwrap(), vendor_config: opts.vendor_config, owner_config: opts.owner_config, - fw_image_type: FwImageType::EccLms, + pqc_key_type: FwVerificationPqcKeyType::LMS, }, ecc_index, lms_index, - &header_digest_vendor, - &header_digest_owner, + &vendor_header_digest_holder, + &owner_header_digest_holder, ) .unwrap(); image_bundle.manifest.preamble = preamble; diff --git a/runtime/tests/runtime_integration_tests/test_warm_reset.rs b/runtime/tests/runtime_integration_tests/test_warm_reset.rs index 3652c2e643..5f99c5a813 100644 --- a/runtime/tests/runtime_integration_tests/test_warm_reset.rs +++ b/runtime/tests/runtime_integration_tests/test_warm_reset.rs @@ -28,7 +28,7 @@ fn test_rt_journey_pcr_validation() { ) .unwrap(); - let (vendor_pk_desc_hash, owner_pk_desc_hash) = image_pk_desc_hash(&image.manifest); + let (vendor_pk_desc_hash, owner_pk_hash) = image_pk_desc_hash(&image.manifest); let mut model = caliptra_hw_model::new( InitParams { @@ -39,7 +39,7 @@ fn test_rt_journey_pcr_validation() { BootParams { fuses: Fuses { key_manifest_pk_hash: vendor_pk_desc_hash, - owner_pk_hash: owner_pk_desc_hash, + owner_pk_hash, fmc_key_manifest_svn: 0b1111111, ..Default::default() }, @@ -60,7 +60,7 @@ fn test_rt_journey_pcr_validation() { // Perform warm reset model.warm_reset_flow(&Fuses { key_manifest_pk_hash: vendor_pk_desc_hash, - owner_pk_hash: owner_pk_desc_hash, + owner_pk_hash, fmc_key_manifest_svn: 0b1111111, ..Default::default() }); @@ -91,7 +91,7 @@ fn test_mbox_busy_during_warm_reset() { ) .unwrap(); - let (vendor_pk_desc_hash, owner_pk_desc_hash) = image_pk_desc_hash(&image.manifest); + let (vendor_pk_desc_hash, owner_pk_hash) = image_pk_desc_hash(&image.manifest); let mut model = caliptra_hw_model::new( InitParams { @@ -102,7 +102,7 @@ fn test_mbox_busy_during_warm_reset() { BootParams { fuses: Fuses { key_manifest_pk_hash: vendor_pk_desc_hash, - owner_pk_hash: owner_pk_desc_hash, + owner_pk_hash, fmc_key_manifest_svn: 0b1111111, ..Default::default() }, @@ -123,7 +123,7 @@ fn test_mbox_busy_during_warm_reset() { // Perform warm reset model.warm_reset_flow(&Fuses { key_manifest_pk_hash: vendor_pk_desc_hash, - owner_pk_hash: owner_pk_desc_hash, + owner_pk_hash, fmc_key_manifest_svn: 0b1111111, ..Default::default() }); diff --git a/sw-emulator/lib/periph/src/ml_dsa87.rs b/sw-emulator/lib/periph/src/ml_dsa87.rs index a6627d86a9..41133a0af2 100644 --- a/sw-emulator/lib/periph/src/ml_dsa87.rs +++ b/sw-emulator/lib/periph/src/ml_dsa87.rs @@ -20,6 +20,7 @@ use caliptra_emu_types::{RvData, RvSize}; use fips204::ml_dsa_87::{try_keygen_with_rng, PrivateKey, PublicKey, PK_LEN, SIG_LEN, SK_LEN}; use fips204::traits::{SerDes, Signer, Verifier}; use rand::rngs::StdRng; +use rand::Rng; use rand::SeedableRng; use tock_registers::interfaces::{ReadWriteable, Readable, Writeable}; use tock_registers::register_bitfields; @@ -355,7 +356,7 @@ impl Mldsa87 { self.verify_res .copy_from_slice(&self.signature[..ML_DSA87_VERIFICATION_SIZE / 4]); } else { - self.verify_res.fill(0); + self.verify_res = rand::thread_rng().gen::<[u32; 16]>(); } } @@ -713,7 +714,11 @@ mod tests { assert_eq!(result, &test_signature[..ML_DSA87_VERIFICATION_SIZE]); // Bad signature - let mut signature = [0; SIG_LEN + 1]; + let mut rng = rand::thread_rng(); + let mut signature = [0u8; SIG_LEN + 1]; + + rng.fill(&mut signature[..64]); + signature.to_big_endian(); for i in (0..signature.len()).step_by(4) { @@ -747,7 +752,7 @@ mod tests { } let result = bytes_from_words_be(&ml_dsa87.verify_res); - assert_eq!(&result, &[0; 64]); + assert_ne!(result, &test_signature[..ML_DSA87_VERIFICATION_SIZE]); } #[test] diff --git a/test/src/lib.rs b/test/src/lib.rs index 5d3186a374..ebcd55fa3b 100644 --- a/test/src/lib.rs +++ b/test/src/lib.rs @@ -37,15 +37,14 @@ pub fn bytes_to_be_words_48(buf: &[u8; 48]) -> [u32; 12] { result } -// Returns the vendor and owner public key descriptor hashes from the image. +// Returns the vendor public key descriptor and owner public key hashes from the image. pub fn image_pk_desc_hash(manifest: &ImageManifest) -> ([u32; 12], [u32; 12]) { let vendor_pk_desc_hash = bytes_to_be_words_48(&sha384(manifest.preamble.vendor_pub_key_info.as_bytes())); - let owner_pk_desc_hash = - bytes_to_be_words_48(&sha384(manifest.preamble.owner_pub_key_info.as_bytes())); + let owner_pk_hash = bytes_to_be_words_48(&sha384(manifest.preamble.owner_pub_keys.as_bytes())); - (vendor_pk_desc_hash, owner_pk_desc_hash) + (vendor_pk_desc_hash, owner_pk_hash) } // Run a test which boots ROM -> FMC -> test_bin. If test_bin_name is None, diff --git a/test/tests/caliptra_integration_tests/fake_collateral_boot_test.rs b/test/tests/caliptra_integration_tests/fake_collateral_boot_test.rs index e6a4f32ef2..9215367530 100755 --- a/test/tests/caliptra_integration_tests/fake_collateral_boot_test.rs +++ b/test/tests/caliptra_integration_tests/fake_collateral_boot_test.rs @@ -59,7 +59,7 @@ fn fake_boot_test() { ) .unwrap(); - let (vendor_pk_desc_hash, owner_pk_desc_hash) = image_pk_desc_hash(&image.manifest); + let (vendor_pk_desc_hash, owner_pk_hash) = image_pk_desc_hash(&image.manifest); let mut hw = caliptra_hw_model::new( InitParams { @@ -69,7 +69,7 @@ fn fake_boot_test() { BootParams { fuses: Fuses { key_manifest_pk_hash: vendor_pk_desc_hash, - owner_pk_hash: owner_pk_desc_hash, + owner_pk_hash, fmc_key_manifest_svn: 0b1111111, runtime_svn: [0x7F, 0, 0, 0], // Equals 7 ..Default::default() diff --git a/test/tests/caliptra_integration_tests/jtag_test.rs b/test/tests/caliptra_integration_tests/jtag_test.rs index 34739103fc..b64bdeb0d8 100644 --- a/test/tests/caliptra_integration_tests/jtag_test.rs +++ b/test/tests/caliptra_integration_tests/jtag_test.rs @@ -88,11 +88,11 @@ fn gdb_test() { ) .unwrap(); - let (vendor_pk_desc_hash, owner_pk_desc_hash) = image_pk_desc_hash(&image.manifest); + let (vendor_pk_desc_hash, owner_pk_hash) = image_pk_desc_hash(&image.manifest); let fuses = Fuses { key_manifest_pk_hash: vendor_pk_desc_hash, - owner_pk_hash: owner_pk_desc_hash, + owner_pk_hash, fmc_key_manifest_svn: 0b1111111, lms_verify: true, ..Default::default() diff --git a/test/tests/caliptra_integration_tests/smoke_test.rs b/test/tests/caliptra_integration_tests/smoke_test.rs index b8422efd5f..252c3192b0 100644 --- a/test/tests/caliptra_integration_tests/smoke_test.rs +++ b/test/tests/caliptra_integration_tests/smoke_test.rs @@ -154,13 +154,13 @@ fn smoke_test() { ) .unwrap(); let vendor_pk_desc_hash = sha384(image.manifest.preamble.vendor_pub_key_info.as_bytes()); - let owner_pk_desc_hash = sha384(image.manifest.preamble.owner_pub_key_info.as_bytes()); + let owner_pk_hash = sha384(image.manifest.preamble.owner_pub_keys.as_bytes()); let vendor_pk_desc_hash_words = bytes_to_be_words_48(&vendor_pk_desc_hash); - let owner_pk_desc_hash_words = bytes_to_be_words_48(&owner_pk_desc_hash); + let owner_pk_hash_words = bytes_to_be_words_48(&owner_pk_hash); let fuses = Fuses { key_manifest_pk_hash: vendor_pk_desc_hash_words, - owner_pk_hash: owner_pk_desc_hash_words, + owner_pk_hash: owner_pk_hash_words, fmc_key_manifest_svn: 0b1111111, runtime_svn: [0x7F, 0, 0, 0], // Equals 7 lms_verify: true, @@ -265,11 +265,11 @@ fn smoke_test() { hasher.update(&[security_state.debug_locked() as u8]); hasher.update(&[fuses.anti_rollback_disable as u8]); hasher.update(/*ecc_vendor_pk_index=*/ &[0u8]); // No keys are revoked - hasher.update(&[image.manifest.header.vendor_lms_pub_key_idx as u8]); - hasher.update(&[image.manifest.fw_image_type]); + hasher.update(&[image.manifest.header.vendor_pqc_pub_key_idx as u8]); + hasher.update(&[image.manifest.pqc_key_type]); hasher.update(&[true as u8]); hasher.update(vendor_pk_desc_hash.as_bytes()); - hasher.update(&owner_pk_desc_hash); + hasher.update(&owner_pk_hash); let device_info_hash = hasher.finish(); let dice_tcb_info = DiceTcbInfo::find_multiple_in_cert(fmc_alias_cert_der).unwrap(); @@ -313,14 +313,14 @@ fn smoke_test() { security_state, fuse_anti_rollback_disable: false, vendor_pub_key_hash: vendor_pk_desc_hash_words, - owner_pub_key_hash: owner_pk_desc_hash_words, + owner_pub_key_hash: owner_pk_hash_words, owner_pub_key_hash_from_fuses: true, ecc_vendor_pub_key_index: image.manifest.preamble.vendor_ecc_pub_key_idx, fmc_digest: image.manifest.fmc.digest, fmc_svn: image.manifest.fmc.svn, // This is from the SVN in the fuses (7 bits set) fmc_fuse_svn: 7, - lms_vendor_pub_key_index: image.manifest.header.vendor_lms_pub_key_idx, + lms_vendor_pub_key_index: image.manifest.header.vendor_pqc_pub_key_idx, rom_verify_config: 1, // RomVerifyConfig::EcdsaAndLms }), &expected_ldevid_key, diff --git a/test/tests/caliptra_integration_tests/warm_reset.rs b/test/tests/caliptra_integration_tests/warm_reset.rs index 49699f4b15..a5135005d8 100644 --- a/test/tests/caliptra_integration_tests/warm_reset.rs +++ b/test/tests/caliptra_integration_tests/warm_reset.rs @@ -28,7 +28,7 @@ fn warm_reset_basic() { ) .unwrap(); - let (vendor_pk_desc_hash, owner_pk_desc_hash) = image_pk_desc_hash(&image.manifest); + let (vendor_pk_desc_hash, owner_pk_hash) = image_pk_desc_hash(&image.manifest); let mut hw = caliptra_hw_model::new( InitParams { @@ -39,7 +39,7 @@ fn warm_reset_basic() { BootParams { fuses: Fuses { key_manifest_pk_hash: vendor_pk_desc_hash, - owner_pk_hash: owner_pk_desc_hash, + owner_pk_hash, fmc_key_manifest_svn: 0b1111111, runtime_svn: [0x7F, 0, 0, 0], // Equals 7 ..Default::default() @@ -58,7 +58,7 @@ fn warm_reset_basic() { // Perform warm reset hw.warm_reset_flow(&Fuses { key_manifest_pk_hash: vendor_pk_desc_hash, - owner_pk_hash: owner_pk_desc_hash, + owner_pk_hash, fmc_key_manifest_svn: 0b1111111, runtime_svn: [0x7F, 0, 0, 0], // Equals 7 ..Default::default() @@ -88,7 +88,7 @@ fn warm_reset_during_fw_load() { ) .unwrap(); - let (vendor_pk_desc_hash, owner_pk_desc_hash) = image_pk_desc_hash(&image.manifest); + let (vendor_pk_desc_hash, owner_pk_hash) = image_pk_desc_hash(&image.manifest); let mut hw = caliptra_hw_model::new( InitParams { @@ -99,7 +99,7 @@ fn warm_reset_during_fw_load() { BootParams { fuses: Fuses { key_manifest_pk_hash: vendor_pk_desc_hash, - owner_pk_hash: owner_pk_desc_hash, + owner_pk_hash, fmc_key_manifest_svn: 0b1111111, runtime_svn: [0x7F, 0, 0, 0], // Equals 7 ..Default::default() @@ -129,7 +129,7 @@ fn warm_reset_during_fw_load() { // Perform warm reset while ROM is executing the firmware load hw.warm_reset_flow(&Fuses { key_manifest_pk_hash: vendor_pk_desc_hash, - owner_pk_hash: owner_pk_desc_hash, + owner_pk_hash, fmc_key_manifest_svn: 0b1111111, runtime_svn: [0x7F, 0, 0, 0], // Equals 7 ..Default::default() diff --git a/test/tests/fips_test_suite/fw_load.rs b/test/tests/fips_test_suite/fw_load.rs index efd441995d..2efafb0061 100755 --- a/test/tests/fips_test_suite/fw_load.rs +++ b/test/tests/fips_test_suite/fw_load.rs @@ -15,9 +15,9 @@ use caliptra_hw_model::{ use caliptra_image_crypto::OsslCrypto as Crypto; use caliptra_image_fake_keys::{VENDOR_CONFIG_KEY_0, VENDOR_CONFIG_KEY_1}; use caliptra_image_gen::{ImageGenerator, ImageGeneratorConfig, ImageGeneratorVendorConfig}; -use caliptra_image_types::SHA384_DIGEST_WORD_SIZE; use caliptra_image_types::{ - FwImageType, ImageBundle, VENDOR_ECC_MAX_KEY_COUNT, VENDOR_LMS_MAX_KEY_COUNT, + FwVerificationPqcKeyType, ImageBundle, ImageDigestHolder, ImageLmsPublicKey, + SHA384_DIGEST_WORD_SIZE, VENDOR_ECC_MAX_KEY_COUNT, VENDOR_LMS_MAX_KEY_COUNT, }; use caliptra_test::image_pk_desc_hash; @@ -48,7 +48,7 @@ fn update_manifest(image_bundle: &mut ImageBundle, hdr_digest: HdrDigest, toc_di runtime: caliptra_image_elf::ElfExecutable::default(), vendor_config: opts.vendor_config, owner_config: opts.owner_config, - fw_image_type: FwImageType::EccLms, + pqc_key_type: FwVerificationPqcKeyType::LMS, }; let gen = ImageGenerator::new(Crypto::default()); @@ -61,21 +61,30 @@ fn update_manifest(image_bundle: &mut ImageBundle, hdr_digest: HdrDigest, toc_di } if hdr_digest == HdrDigest::Update { - let header_digest_vendor = gen - .header_digest_vendor(&image_bundle.manifest.header) + let vendor_header_digest_384 = gen + .vendor_header_digest_384(&image_bundle.manifest.header) .unwrap(); - let header_digest_owner = gen - .header_digest_owner(&image_bundle.manifest.header) + let vendor_header_digest_holder = ImageDigestHolder { + digest_384: &vendor_header_digest_384, + digest_512: None, + }; + + let owner_header_digest_384 = gen + .owner_header_digest_384(&image_bundle.manifest.header) .unwrap(); + let owner_header_digest_holder = ImageDigestHolder { + digest_384: &owner_header_digest_384, + digest_512: None, + }; // Update preamble image_bundle.manifest.preamble = gen .gen_preamble( &config, image_bundle.manifest.preamble.vendor_ecc_pub_key_idx, - image_bundle.manifest.preamble.vendor_lms_pub_key_idx, - &header_digest_vendor, - &header_digest_owner, + image_bundle.manifest.preamble.vendor_pqc_pub_key_idx, + &vendor_header_digest_holder, + &owner_header_digest_holder, ) .unwrap(); } @@ -628,7 +637,7 @@ fn fw_load_error_owner_ecc_signature_invalid_arg() { } #[test] -fn fw_load_error_vendor_pub_key_digest_invalid_arg() { +fn fw_load_error_vendor_pub_key_invalid_arg() { // Generate image let mut fw_image = build_fw_image(ImageOptions::default()); // Set ecc_pub_key.x to zero. @@ -642,7 +651,7 @@ fn fw_load_error_vendor_pub_key_digest_invalid_arg() { fw_load_error_flow( Some(fw_image), None, - CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_PUB_KEY_DIGEST_INVALID_ARG.into(), + CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_ECC_PUB_KEY_INVALID_ARG.into(), ); } @@ -665,13 +674,13 @@ fn fw_load_error_update_reset_owner_digest_failure() { // Generate image let mut update_image = build_fw_image(ImageOptions::default()); - // Set ecc pub key hash to some corrupted, non-zero value + // Set ecc_pub_key.y to some corrupted, non-zero value update_image .manifest .preamble - .owner_pub_key_info - .ecc_key_descriptor - .key_hash[0] + .owner_pub_keys + .ecc_pub_key + .y .fill(0x1234abcd); update_fw_error_flow( @@ -931,8 +940,8 @@ fn fw_load_error_vendor_lms_pub_key_index_mismatch() { // Generate image let mut fw_image = build_fw_image(ImageOptions::default()); // Change vendor pubkey index. - fw_image.manifest.header.vendor_lms_pub_key_idx = - fw_image.manifest.preamble.vendor_lms_pub_key_idx + 1; + fw_image.manifest.header.vendor_pqc_pub_key_idx = + fw_image.manifest.preamble.vendor_pqc_pub_key_idx + 1; update_manifest(&mut fw_image, HdrDigest::Update, TocDigest::Update); // Turn LMS verify on @@ -944,7 +953,7 @@ fn fw_load_error_vendor_lms_pub_key_index_mismatch() { fw_load_error_flow( Some(fw_image), Some(fuses), - CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_LMS_PUB_KEY_INDEX_MISMATCH.into(), + CaliptraError::IMAGE_VERIFIER_ERR_VENDOR_PQC_PUB_KEY_INDEX_MISMATCH.into(), ); } @@ -970,7 +979,7 @@ fn fw_load_error_vendor_lms_pub_key_index_out_of_bounds() { // Generate image let mut fw_image = build_fw_image(ImageOptions::default()); // Set LMS pub key index to MAX + 1 - fw_image.manifest.preamble.vendor_lms_pub_key_idx = VENDOR_LMS_MAX_KEY_COUNT; + fw_image.manifest.preamble.vendor_pqc_pub_key_idx = VENDOR_LMS_MAX_KEY_COUNT; // Turn LMS verify on let fuses = caliptra_hw_model::Fuses { @@ -989,8 +998,20 @@ fn fw_load_error_vendor_lms_pub_key_index_out_of_bounds() { fn fw_load_error_vendor_lms_signature_invalid() { // Generate image let mut fw_image = build_fw_image(ImageOptions::default()); + + // Get a mutable reference to the LMS public key. + let lms_pub_key = ImageLmsPublicKey::mut_ref_from_prefix( + fw_image + .manifest + .preamble + .vendor_pqc_active_pub_key + .0 + .as_bytes_mut(), + ) + .unwrap(); + // Modify the vendor public key. - fw_image.manifest.preamble.vendor_lms_active_pub_key.digest = [Default::default(); 6]; + lms_pub_key.digest = [Default::default(); 6]; // Turn LMS verify on let fuses = caliptra_hw_model::Fuses { @@ -1041,8 +1062,21 @@ fn fw_load_error_owner_lms_verify_failure() { fn fw_load_error_owner_lms_signature_invalid() { // Generate image let mut fw_image = build_fw_image(ImageOptions::default()); + + // Get a mutable reference to the LMS public key. + let lms_pub_key = ImageLmsPublicKey::mut_ref_from_prefix( + fw_image + .manifest + .preamble + .owner_pub_keys + .pqc_pub_key + .0 + .as_bytes_mut(), + ) + .unwrap(); + // Modify the owner public key - fw_image.manifest.preamble.owner_pub_keys.lms_pub_key.digest = [Default::default(); 6]; + lms_pub_key.digest = [Default::default(); 6]; // Turn LMS verify on let fuses = caliptra_hw_model::Fuses { @@ -1060,7 +1094,7 @@ fn fw_load_error_owner_lms_signature_invalid() { #[test] fn fw_load_error_vendor_lms_pub_key_revoked() { let vendor_config = ImageGeneratorVendorConfig { - lms_key_idx: 5, + pqc_key_idx: 5, ..VENDOR_CONFIG_KEY_0 }; let image_options = ImageOptions { @@ -1071,7 +1105,7 @@ fn fw_load_error_vendor_lms_pub_key_revoked() { // Set fuses let fuses = caliptra_hw_model::Fuses { lms_verify: true, - fuse_lms_revocation: 1u32 << image_options.vendor_config.lms_key_idx, + fuse_lms_revocation: 1u32 << image_options.vendor_config.pqc_key_idx, ..Default::default() }; @@ -1116,9 +1150,9 @@ fn fw_load_error_runtime_size_zero() { } #[test] -fn fw_load_error_update_reset_vendor_lms_pub_key_idx_mismatch() { +fn fw_load_error_update_reset_vendor_pqc_pub_key_idx_mismatch() { let vendor_config_update_reset = ImageGeneratorVendorConfig { - lms_key_idx: 2, + pqc_key_idx: 2, ..VENDOR_CONFIG_KEY_0 }; let image_options_update_reset = ImageOptions { @@ -1138,7 +1172,7 @@ fn fw_load_error_update_reset_vendor_lms_pub_key_idx_mismatch() { None, Some(fuses), Some(update_image), - CaliptraError::IMAGE_VERIFIER_ERR_UPDATE_RESET_VENDOR_LMS_PUB_KEY_IDX_MISMATCH.into(), + CaliptraError::IMAGE_VERIFIER_ERR_UPDATE_RESET_VENDOR_PQC_PUB_KEY_IDX_MISMATCH.into(), ); } @@ -1195,12 +1229,12 @@ fn fw_load_bad_pub_key_flow(fw_image: ImageBundle, exp_error_code: u32) { // Generate pub key hashes and set fuses // Use a fresh image (will NOT be loaded) let pk_hash_src_image = build_fw_image(ImageOptions::default()); - let (vendor_pk_desc_hash, owner_pk_desc_hash) = image_pk_desc_hash(&pk_hash_src_image.manifest); + let (vendor_pk_desc_hash, owner_pk_hash) = image_pk_desc_hash(&pk_hash_src_image.manifest); let fuses = Fuses { life_cycle: DeviceLifecycle::Production, key_manifest_pk_hash: vendor_pk_desc_hash, - owner_pk_hash: owner_pk_desc_hash, + owner_pk_hash, lms_verify: true, ..Default::default() }; @@ -1249,13 +1283,8 @@ fn fw_load_bad_owner_ecc_pub_key() { // Generate image let mut fw_image = build_fw_image(ImageOptions::default()); - // Modify the pub key hash - fw_image - .manifest - .preamble - .owner_pub_key_info - .ecc_key_descriptor - .key_hash[0][0] ^= 0x1; + // Modify the pub key + fw_image.manifest.preamble.owner_pub_keys.ecc_pub_key.x[0] ^= 0x1; fw_load_bad_pub_key_flow( fw_image, @@ -1287,13 +1316,18 @@ fn fw_load_bad_owner_lms_pub_key() { // Generate image let mut fw_image = build_fw_image(ImageOptions::default()); - // Modify the pub key hash - fw_image - .manifest - .preamble - .owner_pub_key_info - .pqc_key_descriptor - .key_hash[0][0] ^= 0x1; + // Modify the pub key + let lms_pub_key = ImageLmsPublicKey::mut_ref_from_prefix( + fw_image + .manifest + .preamble + .owner_pub_keys + .pqc_pub_key + .0 + .as_bytes_mut(), + ) + .unwrap(); + lms_pub_key.digest[0] = 0xDEADBEEF.into(); fw_load_bad_pub_key_flow( fw_image,