diff --git a/FROZEN_IMAGES.sha384sum b/FROZEN_IMAGES.sha384sum index 778b1b47ce..8bda8fe0b6 100644 --- a/FROZEN_IMAGES.sha384sum +++ b/FROZEN_IMAGES.sha384sum @@ -1,3 +1,3 @@ # WARNING: Do not update this file without the approval of the Caliptra TAC -133bf3969893178e041b61001d75bfb504be3b3676cac608a40877f1e4b46b4855f86c1859cfc3e22745327102fba4b0 caliptra-rom-no-log.bin -44f5bbbc4b71d7f0926f85b7d81ef7e17f721557b38379b650497eb8dd19d0a74ab5a1e2177c7e99653a878d2daed3b3 caliptra-rom-with-log.bin +9fe3c2a8031c31e7a9ce56e5b8b430414d74db9d04161512b90fb60d5df120cc3998c8881eea10b7c4e1c1bea4326b27 caliptra-rom-no-log.bin +f1a8736ab386897c62a173032910ed03566043b01305ceaab7d25614b86e86ef97dd90bf9cdf7aaa7eb470f9e155133b caliptra-rom-with-log.bin diff --git a/drivers/src/ecc384.rs b/drivers/src/ecc384.rs index 48bc925ee1..d41f61e54b 100644 --- a/drivers/src/ecc384.rs +++ b/drivers/src/ecc384.rs @@ -228,6 +228,58 @@ impl Ecc384 { trng: &mut Trng, priv_key: Ecc384PrivKeyOut, ) -> CaliptraResult { + self.key_pair_base(seed, nonce, trng, priv_key, None) + } + + /// Generate ECC-384 Key Pair for FIPS KAT testing + /// ONLY to be used for KAT testing + /// + /// # Arguments + /// + /// * `trng` - TRNG driver instance + /// * `priv_key` - Generate ECC-384 Private key + /// * `pct_sig` - Ecc 384 signature to return signature generated during the pairwise consistency test + /// + /// # Returns + /// + /// * `Ecc384PubKey` - Generated ECC-384 Public Key + #[cfg_attr(not(feature = "no-cfi"), cfi_impl_fn)] + pub fn key_pair_for_fips_kat( + &mut self, + trng: &mut Trng, + priv_key: Ecc384PrivKeyOut, + pct_sig: &mut Ecc384Signature, + ) -> CaliptraResult { + let seed = Array4x12::new([0u32; 12]); + let nonce = Array4x12::new([0u32; 12]); + self.key_pair_base( + &Ecc384Seed::from(&seed), + &nonce, + trng, + priv_key, + Some(pct_sig), + ) + } + + /// Private base function to generate ECC-384 Key Pair + /// pct_sig should only be provided in the KAT use case + #[cfg_attr(not(feature = "no-cfi"), cfi_impl_fn)] + #[inline(never)] + fn key_pair_base( + &mut self, + seed: &Ecc384Seed, + nonce: &Array4x12, + trng: &mut Trng, + priv_key: Ecc384PrivKeyOut, + pct_sig: Option<&mut Ecc384Signature>, + ) -> CaliptraResult { + #[cfg(feature = "fips-test-hooks")] + unsafe { + crate::FipsTestHook::error_if_hook_set( + crate::FipsTestHook::ECC384_KEY_PAIR_GENERATE_FAILURE, + )? + } + let ecc = self.ecc.regs_mut(); let mut priv_key = priv_key; @@ -299,7 +351,13 @@ impl Ecc384 { }; match self.sign(&priv_key.into(), &pub_key, &digest, trng) { - Ok(mut sig) => sig.zeroize(), + Ok(mut sig) => { + // Return the signature from this test if requested (only used for KAT) + if let Some(output_sig) = pct_sig { + *output_sig = sig; + } + sig.zeroize(); + } Err(_) => { // Remap error to a pairwise consistency check failure return Err(CaliptraError::DRIVER_ECC384_KEYGEN_PAIRWISE_CONSISTENCY_FAILURE); @@ -308,6 +366,14 @@ impl Ecc384 { self.zeroize_internal(); + #[cfg(feature = "fips-test-hooks")] + let pub_key = unsafe { + crate::FipsTestHook::corrupt_data_if_hook_set( + crate::FipsTestHook::ECC384_CORRUPT_KEY_PAIR, + &pub_key, + ) + }; + Ok(pub_key) } @@ -431,12 +497,12 @@ impl Ecc384 { caliptra_cfi_lib::cfi_assert_eq_12_words(&r.0, &sig.r.0); #[cfg(feature = "fips-test-hooks")] - let sig_result = unsafe { + let sig_result = Ok(unsafe { crate::FipsTestHook::corrupt_data_if_hook_set( crate::FipsTestHook::ECC384_CORRUPT_SIGNATURE, - &sig_result, + sig, ) - }; + }); sig_result } diff --git a/drivers/src/fips_test_hooks.rs b/drivers/src/fips_test_hooks.rs index 0a02241027..5a2e0718dc 100755 --- a/drivers/src/fips_test_hooks.rs +++ b/drivers/src/fips_test_hooks.rs @@ -11,6 +11,7 @@ impl FipsTestHook { pub const COMPLETE: u8 = 0x1; // Set by external test pub const CONTINUE: u8 = 0x10; + pub const HALT_SELF_TESTS: u8 = 0x21; pub const SHA1_CORRUPT_DIGEST: u8 = 0x22; pub const SHA256_CORRUPT_DIGEST: u8 = 0x23; @@ -22,6 +23,7 @@ impl FipsTestHook { pub const ECC384_PAIRWISE_CONSISTENCY_ERROR: u8 = 0x29; pub const HALT_FW_LOAD: u8 = 0x2A; pub const HALT_SHUTDOWN_RT: u8 = 0x2B; + pub const ECC384_CORRUPT_KEY_PAIR: u8 = 0x2C; pub const SHA1_DIGEST_FAILURE: u8 = 0x40; pub const SHA256_DIGEST_FAILURE: u8 = 0x41; @@ -32,6 +34,7 @@ impl FipsTestHook { pub const ECC384_VERIFY_FAILURE: u8 = 0x46; pub const HMAC384_FAILURE: u8 = 0x47; pub const LMS_VERIFY_FAILURE: u8 = 0x48; + pub const ECC384_KEY_PAIR_GENERATE_FAILURE: u8 = 0x49; // FW Load Errors pub const FW_LOAD_VENDOR_PUB_KEY_DIGEST_FAILURE: u8 = 0x50; diff --git a/error/src/lib.rs b/error/src/lib.rs index eb106accf1..750a1611ba 100644 --- a/error/src/lib.rs +++ b/error/src/lib.rs @@ -587,11 +587,13 @@ impl CaliptraError { pub const KAT_HMAC384_FAILURE: CaliptraError = CaliptraError::new_const(0x90030001); pub const KAT_HMAC384_TAG_MISMATCH: CaliptraError = CaliptraError::new_const(0x90030002); - pub const KAT_ECC384_SIGNATURE_GENERATE_FAILURE: CaliptraError = - CaliptraError::new_const(0x90040001); - pub const KAT_ECC384_SIGNATURE_VERIFY_FAILURE: CaliptraError = - CaliptraError::new_const(0x90040002); + // 0x90040001 was KAT_ECC384_SIGNATURE_GENERATE_FAILURE + // 0x90040002 was KAT_ECC384_SIGNATURE_VERIFY_FAILURE pub const KAT_ECC384_SIGNATURE_MISMATCH: CaliptraError = CaliptraError::new_const(0x90040003); + pub const KAT_ECC384_KEY_PAIR_GENERATE_FAILURE: CaliptraError = + CaliptraError::new_const(0x90040004); + pub const KAT_ECC384_KEY_PAIR_VERIFY_FAILURE: CaliptraError = + CaliptraError::new_const(0x90040005); pub const KAT_SHA2_512_384_ACC_DIGEST_START_OP_FAILURE: CaliptraError = CaliptraError::new_const(0x90050001); diff --git a/kat/src/ecc384_kat.rs b/kat/src/ecc384_kat.rs index c8513ee7df..4a82acff9d 100644 --- a/kat/src/ecc384_kat.rs +++ b/kat/src/ecc384_kat.rs @@ -13,34 +13,34 @@ Abstract: --*/ use caliptra_drivers::{ - Array4x12, Array4xN, CaliptraError, CaliptraResult, Ecc384, Ecc384PrivKeyIn, Ecc384PubKey, + Array4x12, Array4xN, CaliptraError, CaliptraResult, Ecc384, Ecc384PrivKeyOut, Ecc384PubKey, Ecc384Signature, Trng, }; -const PRIV_KEY: Array4x12 = Array4x12::new([ - 0xc908585a, 0x486c3b3d, 0x8bbe50eb, 0x7d2eb8a0, 0x3aa04e3d, 0x8bde2c31, 0xa8a2a1e3, 0x349dc21c, - 0xbbe6c90a, 0xe2f74912, 0x8884b622, 0xbb72b4c5, +const KEY_GEN_PRIV_KEY: Array4x12 = Array4x12::new([ + 0xfeeef554, 0x4a765649, 0x90128ad1, 0x89e873f2, 0x1f0dfd5a, 0xd7e2fa86, 0x1127ee6e, 0x394ca784, + 0x871c1aec, 0x032c7a8b, 0x10b93e0e, 0xab8946d6, ]); -const PUB_KEY: Ecc384PubKey = Ecc384PubKey { +const KEY_GEN_PUB_KEY: Ecc384PubKey = Ecc384PubKey { x: Array4xN([ - 0x98233ca, 0x567a3f14, 0xbe784904, 0xc6921d43, 0x3b4f853a, 0x523742e4, 0xbc98767e, - 0x23ca3da6, 0x656bec46, 0xa7b1119e, 0x63d266ca, 0x6254977f, + 0xd7dd94e0, 0xbffc4cad, 0xe9902b7f, 0xdb154260, 0xd5ec5dfd, 0x57950e83, 0x59015a30, + 0x2c8bf7bb, 0xa7e5f6df, 0xfc168516, 0x2bdd35f9, 0xf5c1b0ff, ]), y: Array4xN([ - 0x75d0b401, 0xc8bac39a, 0xc5fb0f2b, 0x3b95372c, 0x41d9de40, 0x55fddb06, 0xf7484974, - 0x8d0aed85, 0x9b6550ca, 0x750c3cd1, 0x1851e050, 0xbb7d20b2, + 0xbb9c3a2f, 0x061e8d70, 0x14278dd5, 0x1e66a918, 0xa6b6f9f1, 0xc1937312, 0xd4e7a921, + 0xb18ef0f4, 0x1fdd401d, 0x9e771850, 0x9f8731e9, 0xeec9c31d, ]), }; const SIGNATURE: Ecc384Signature = Ecc384Signature { r: Array4xN([ - 0x36f85014, 0x6f400443, 0x848cae03, 0x57591032, 0xe6a395de, 0x66e7261a, 0x38049fb, - 0xee15db19, 0x5dbd9786, 0x9439292a, 0x4f5792e4, 0x3a1231b7, + 0x93799D55, 0x12263628, 0x34F60F7B, 0x945290B7, 0xCCE6E996, 0x01FB7EBD, 0x026C2E3C, + 0x445D3CD9, 0xB65068DA, 0xC0A848BE, 0x9F0560AA, 0x758FDA27, ]), s: Array4xN([ - 0xeeea4294, 0x82fd8fa9, 0xd4d5f960, 0xa09edfa6, 0xc765efe5, 0xff4c17a5, 0x12e694fa, - 0xcc45d3f6, 0xfc3d3b5c, 0x62739c1f, 0xb9fcae3, 0x26f54b43, + 0xE548E535, 0xA1CC600E, 0x133B5591, 0xAEBAAD78, 0x054006D7, 0x52D0E1DF, 0x94FBFA95, + 0xD78F0B3F, 0x8E81B911, 0x9C2BE008, 0xBF6D6F4E, 0x4185F87D, ]), }; @@ -51,7 +51,7 @@ impl Ecc384Kat { /// This function executes the Known Answer Tests (aka KAT) for ECC384. /// /// Test vector source: - /// Generated using MbedTLS library. + /// Zeroed inputs, outputs verified against python cryptography lib built on OpenSSL /// /// # Arguments /// @@ -61,24 +61,35 @@ impl Ecc384Kat { /// /// * `CaliptraResult` - Result denoting the KAT outcome. pub fn execute(&self, ecc: &mut Ecc384, trng: &mut Trng) -> CaliptraResult<()> { - self.kat_signature_generate_and_verify(ecc, trng) + self.kat_key_pair_gen_sign_and_verify(ecc, trng) } - fn kat_signature_generate_and_verify( + fn kat_key_pair_gen_sign_and_verify( &self, ecc: &mut Ecc384, trng: &mut Trng, ) -> CaliptraResult<()> { - let digest = Array4x12::new([0u32; 12]); - // The driver validates every signature that it generates, so don't need - // to explicitly verify here. - let signature = ecc - .sign(&Ecc384PrivKeyIn::from(&PRIV_KEY), &PUB_KEY, &digest, trng) - .map_err(|_| CaliptraError::KAT_ECC384_SIGNATURE_GENERATE_FAILURE)?; - - if signature != SIGNATURE { - Err(CaliptraError::KAT_ECC384_SIGNATURE_VERIFY_FAILURE)?; + let mut priv_key = Array4x12::new([0u32; 12]); + let mut pct_sig = Ecc384Signature { + r: Array4x12::new([0u32; 12]), + s: Array4x12::new([0u32; 12]), + }; + + let pub_key = ecc + .key_pair_for_fips_kat(trng, Ecc384PrivKeyOut::from(&mut priv_key), &mut pct_sig) + .map_err(|_| CaliptraError::KAT_ECC384_KEY_PAIR_GENERATE_FAILURE)?; + + // NOTE: Signature verify step is performed in ECC driver sign function + if priv_key != KEY_GEN_PRIV_KEY { + Err(CaliptraError::KAT_ECC384_KEY_PAIR_VERIFY_FAILURE)?; + } + if pub_key != KEY_GEN_PUB_KEY { + Err(CaliptraError::KAT_ECC384_KEY_PAIR_VERIFY_FAILURE)?; } + if pct_sig != SIGNATURE { + Err(CaliptraError::KAT_ECC384_SIGNATURE_MISMATCH)?; + } + Ok(()) } } diff --git a/test/tests/fips_test_suite/self_tests.rs b/test/tests/fips_test_suite/self_tests.rs index af065aed42..1168527ec2 100755 --- a/test/tests/fips_test_suite/self_tests.rs +++ b/test/tests/fips_test_suite/self_tests.rs @@ -394,38 +394,68 @@ pub fn kat_sha2_512_384acc_digest_mismatch_rt() { #[test] #[cfg(not(feature = "test_env_immutable_rom"))] pub fn kat_ecc384_signature_generate_failure_rom() { - // Should be KAT_ECC384_SIGNATURE_VERIFY_FAILURE but ROM is using the wrong code self_test_failure_flow_rom( FipsTestHook::ECC384_SIGNATURE_GENERATE_FAILURE, - u32::from(CaliptraError::KAT_ECC384_SIGNATURE_GENERATE_FAILURE), + u32::from(CaliptraError::KAT_ECC384_KEY_PAIR_GENERATE_FAILURE), ); } #[test] pub fn kat_ecc384_signature_generate_failure_rt() { - // Should be KAT_ECC384_SIGNATURE_VERIFY_FAILURE but ROM is using the wrong code self_test_failure_flow_rt( FipsTestHook::ECC384_SIGNATURE_GENERATE_FAILURE, - u32::from(CaliptraError::KAT_ECC384_SIGNATURE_GENERATE_FAILURE), + u32::from(CaliptraError::KAT_ECC384_KEY_PAIR_GENERATE_FAILURE), ); } #[test] #[cfg(not(feature = "test_env_immutable_rom"))] pub fn kat_ecc384_signature_verify_failure_rom() { - // Should be KAT_ECC384_SIGNATURE_VERIFY_FAILURE but ROM is using the wrong code self_test_failure_flow_rom( FipsTestHook::ECC384_CORRUPT_SIGNATURE, - u32::from(CaliptraError::KAT_ECC384_SIGNATURE_GENERATE_FAILURE), + u32::from(CaliptraError::KAT_ECC384_SIGNATURE_MISMATCH), ); } #[test] pub fn kat_ecc384_signature_verify_failure_rt() { - // Should be KAT_ECC384_SIGNATURE_VERIFY_FAILURE but ROM is using the wrong code self_test_failure_flow_rt( FipsTestHook::ECC384_CORRUPT_SIGNATURE, - u32::from(CaliptraError::KAT_ECC384_SIGNATURE_GENERATE_FAILURE), + u32::from(CaliptraError::KAT_ECC384_SIGNATURE_MISMATCH), + ); +} + +#[test] +#[cfg(not(feature = "test_env_immutable_rom"))] +pub fn kat_ecc384_deterministic_key_gen_generate_failure_rom() { + self_test_failure_flow_rom( + FipsTestHook::ECC384_KEY_PAIR_GENERATE_FAILURE, + u32::from(CaliptraError::KAT_ECC384_KEY_PAIR_GENERATE_FAILURE), + ); +} + +#[test] +pub fn kat_ecc384_deterministic_key_gen_generate_failure_rt() { + self_test_failure_flow_rt( + FipsTestHook::ECC384_KEY_PAIR_GENERATE_FAILURE, + u32::from(CaliptraError::KAT_ECC384_KEY_PAIR_GENERATE_FAILURE), + ); +} + +#[test] +#[cfg(not(feature = "test_env_immutable_rom"))] +pub fn kat_ecc384_deterministic_key_gen_verify_failure_rom() { + self_test_failure_flow_rom( + FipsTestHook::ECC384_CORRUPT_KEY_PAIR, + u32::from(CaliptraError::KAT_ECC384_KEY_PAIR_VERIFY_FAILURE), + ); +} + +#[test] +pub fn kat_ecc384_deterministic_key_gen_verify_failure_rt() { + self_test_failure_flow_rt( + FipsTestHook::ECC384_CORRUPT_KEY_PAIR, + u32::from(CaliptraError::KAT_ECC384_KEY_PAIR_VERIFY_FAILURE), ); }