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 <roland.mikhel@arm.com> Change-Id: I364eefe334e4fe6668b8a3b97991b5dbb0c80104
This commit is contained in:
parent
03c9ad0781
commit
fb5507b4a4
|
@ -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 = "sig-p384") {
|
||||
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::<LittleEndian>(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::<LittleEndian>(TlvKinds::SHA256 as u16).unwrap();
|
||||
result.write_u16::<LittleEndian>(32).unwrap();
|
||||
assert!(hash.len() == hash_size);
|
||||
result.write_u16::<LittleEndian>(tlv_kind as u16).unwrap();
|
||||
result.write_u16::<LittleEndian>(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::<LittleEndian>(TlvKinds::KEYHASH as u16).unwrap();
|
||||
result.write_u16::<LittleEndian>(32).unwrap();
|
||||
result.write_u16::<LittleEndian>(keyhash_size as u16).unwrap();
|
||||
result.extend_from_slice(keyhash_slice);
|
||||
|
||||
// Write signature
|
||||
|
|
Loading…
Reference in New Issue