From e25afa52276af9e39f14df1cf7936e0f19126261 Mon Sep 17 00:00:00 2001 From: Roland Mikhel Date: Tue, 14 Mar 2023 14:08:43 +0100 Subject: [PATCH] sim: Replace hash with SHA384 when P384 is used Currently all the hashing functionality is done with SHA256 but if we would like to use ECDSA-P384 that requires SHA384 as the hashing algorithm. However, MCUboot is using SHA256 for image hashing and public key hashing. This commit modifies the hashing operations to use SHA384 thus SHA256 can be omitted which is beneficial from a code size standpoint. Signed-off-by: Roland Mikhel Change-Id: I364eefe334e4fe6668b8a3b97991b5dbb0c80104 --- sim/mcuboot-sys/build.rs | 1 + sim/src/tlv.rs | 45 ++++++++++++++++++++++++++-------------- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/sim/mcuboot-sys/build.rs b/sim/mcuboot-sys/build.rs index 23dfe66b98..23aa3d0fc6 100644 --- a/sim/mcuboot-sys/build.rs +++ b/sim/mcuboot-sys/build.rs @@ -218,6 +218,7 @@ fn main() { conf.file("../../ext/mbedtls/library/sha256.c"); } + conf.conf.include("../../ext/mbedtls/include"); conf.file("csupport/keys.c"); conf.file("../../ext/mbedtls/library/asn1parse.c"); conf.file("../../ext/mbedtls/library/bignum.c"); diff --git a/sim/src/tlv.rs b/sim/src/tlv.rs index 9a7e14f99d..086af63827 100644 --- a/sim/src/tlv.rs +++ b/sim/src/tlv.rs @@ -51,6 +51,7 @@ use typenum::{U16, U32}; pub enum TlvKinds { KEYHASH = 0x01, SHA256 = 0x10, + SHA384 = 0x11, RSA2048 = 0x20, ECDSASIG = 0x22, RSA3072 = 0x23, @@ -167,8 +168,13 @@ impl TlvGen { #[allow(dead_code)] pub fn new_ecdsa() -> TlvGen { + let hash_kind = if cfg!(feature = "use-p384-curve") { + TlvKinds::SHA384 + } else { + TlvKinds::SHA256 + }; TlvGen { - kinds: vec![TlvKinds::SHA256, TlvKinds::ECDSASIG], + kinds: vec![hash_kind, TlvKinds::ECDSASIG], ..Default::default() } } @@ -370,6 +376,8 @@ impl ManifestGen for TlvGen { // Estimate the size of the image hash. if self.kinds.contains(&TlvKinds::SHA256) { estimate += 4 + 32; + } else if self.kinds.contains(&TlvKinds::SHA384) { + estimate += 4 + 48; } // Add an estimate in for each of the signature algorithms. @@ -390,11 +398,11 @@ impl ManifestGen for TlvGen { // stored as signed integers. As such, the size can vary by 2 bytes, // if for example the 256-bit value has the high bit, it takes an // extra 0 byte to avoid it being seen as a negative number. - if cfg!(feature = "use-p384-curve") { - estimate += 4 + 48; // keyhash + if self.kinds.contains(&TlvKinds::SHA384) { + estimate += 4 + 48; // SHA384 estimate += 4 + 104; // ECDSA384 (varies) } else { - estimate += 4 + 32; // keyhash + estimate += 4 + 32; // SHA256 estimate += 4 + 72; // ECDSA256 (varies) } } @@ -479,7 +487,7 @@ impl ManifestGen for TlvGen { // Placeholder for the size. result.write_u16::(0).unwrap(); - if self.kinds.contains(&TlvKinds::SHA256) { + if self.kinds.iter().any(|v| v == &TlvKinds::SHA256 || v == &TlvKinds::SHA384) { // If a signature is not requested, corrupt the hash we are // generating. But, if there is a signature, output the // correct hash. We want the hash test to pass so that the @@ -497,13 +505,20 @@ impl ManifestGen for TlvGen { if corrupt_hash { sig_payload[0] ^= 1; } - - let hash = digest::digest(&digest::SHA256, &sig_payload); + let (hash,hash_size,tlv_kind) = if self.kinds.contains(&TlvKinds::SHA256) + { + let hash = digest::digest(&digest::SHA256, &sig_payload); + (hash,32,TlvKinds::SHA256) + } + else { + let hash = digest::digest(&digest::SHA384, &sig_payload); + (hash,48,TlvKinds::SHA384) + }; let hash = hash.as_ref(); - assert!(hash.len() == 32); - result.write_u16::(TlvKinds::SHA256 as u16).unwrap(); - result.write_u16::(32).unwrap(); + assert!(hash.len() == hash_size); + result.write_u16::(tlv_kind as u16).unwrap(); + result.write_u16::(hash_size as u16).unwrap(); result.extend_from_slice(hash); // Undo the corruption. @@ -565,25 +580,25 @@ impl ManifestGen for TlvGen { if self.kinds.contains(&TlvKinds::ECDSASIG) { let rng = rand::SystemRandom::new(); - let (signature, keyhash) = if cfg!(feature = "use-p384-curve") { + let (signature, keyhash, keyhash_size) = if self.kinds.contains(&TlvKinds::SHA384) { let keyhash = digest::digest(&digest::SHA384, ECDSAP384_PUB_KEY); let key_bytes = pem::parse(include_bytes!("../../root-ec-p384-pkcs8.pem").as_ref()).unwrap(); let sign_algo = &ECDSA_P384_SHA384_ASN1_SIGNING; let key_pair = EcdsaKeyPair::from_pkcs8(sign_algo, &key_bytes.contents).unwrap(); - (key_pair.sign(&rng, &sig_payload).unwrap(), keyhash) + (key_pair.sign(&rng, &sig_payload).unwrap(), keyhash, 48) } else { let keyhash = digest::digest(&digest::SHA256, ECDSA256_PUB_KEY); let key_bytes = pem::parse(include_bytes!("../../root-ec-p256-pkcs8.pem").as_ref()).unwrap(); let sign_algo = &ECDSA_P256_SHA256_ASN1_SIGNING; let key_pair = EcdsaKeyPair::from_pkcs8(sign_algo, &key_bytes.contents).unwrap(); - (key_pair.sign(&rng, &sig_payload).unwrap(), keyhash) + (key_pair.sign(&rng, &sig_payload).unwrap(), keyhash, 32) }; // Write public key let keyhash_slice = keyhash.as_ref(); - assert!(keyhash_slice.len() == 32); + assert!(keyhash_slice.len() == keyhash_size); result.write_u16::(TlvKinds::KEYHASH as u16).unwrap(); - result.write_u16::(32).unwrap(); + result.write_u16::(keyhash_size as u16).unwrap(); result.extend_from_slice(keyhash_slice); // Write signature