sim: Actually test invalid signatures

Currently, the tests that appear to be testing for invalid signatures
are actually just testing that images aren't used if the entire TLV
block is missing.  Fix this by being more subtle about our corruptions.
If there is no signature, corrupt that data being used to generate the
hash.  Otherwise, modify the data before it goes into the signature, but
generate a valid SHA256 in the TLV.  This way, we exercise the signature
itself being corrupt.

Signed-off-by: David Brown <david.brown@linaro.org>
This commit is contained in:
David Brown 2019-12-06 15:04:00 -07:00 committed by David Brown
parent 4fae8b8743
commit e90b13f9a9
2 changed files with 46 additions and 6 deletions

View File

@ -1149,12 +1149,10 @@ fn install_image(flash: &mut SimMultiFlash, slot: &SlotInfo, len: usize,
}
// Build the TLV itself.
let mut b_tlv = if bad_sig {
let good_sig = &mut tlv.make_tlv();
vec![0; good_sig.len()]
} else {
tlv.make_tlv()
};
if bad_sig {
tlv.corrupt_sig();
}
let mut b_tlv = tlv.make_tlv();
let dev = flash.get_mut(&dev_id).unwrap();

View File

@ -80,6 +80,10 @@ pub trait ManifestGen {
/// protecting.
fn add_bytes(&mut self, bytes: &[u8]);
/// Set an internal flag indicating that the next `make_tlv` should
/// corrupt the signature.
fn corrupt_sig(&mut self);
/// Construct the manifest for this payload.
fn make_tlv(self: Box<Self>) -> Vec<u8>;
@ -101,6 +105,8 @@ pub struct TlvGen {
payload: Vec<u8>,
dependencies: Vec<Dependency>,
enc_key: Vec<u8>,
/// Should this signature be corrupted.
gen_corrupted: bool,
}
#[derive(Debug)]
@ -258,6 +264,10 @@ impl ManifestGen for TlvGen {
});
}
fn corrupt_sig(&mut self) {
self.gen_corrupted = true;
}
/// Compute the TLV given the specified block of data.
fn make_tlv(self: Box<Self>) -> Vec<u8> {
let mut protected_tlv: Vec<u8> = vec![];
@ -303,6 +313,25 @@ impl ManifestGen for TlvGen {
result.write_u16::<LittleEndian>(self.get_size()).unwrap();
if self.kinds.contains(&TlvKinds::SHA256) {
// 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
// signature verification can be validated.
let mut corrupt_hash = self.gen_corrupted;
for k in &[TlvKinds::RSA2048, TlvKinds::RSA3072,
TlvKinds::ECDSA224, TlvKinds::ECDSA256,
TlvKinds::ED25519]
{
if self.kinds.contains(k) {
corrupt_hash = false;
break;
}
}
if corrupt_hash {
sig_payload[0] ^= 1;
}
let hash = digest::digest(&digest::SHA256, &sig_payload);
let hash = hash.as_ref();
@ -310,6 +339,18 @@ impl ManifestGen for TlvGen {
result.write_u16::<LittleEndian>(TlvKinds::SHA256 as u16).unwrap();
result.write_u16::<LittleEndian>(32).unwrap();
result.extend_from_slice(hash);
// Undo the corruption.
if corrupt_hash {
sig_payload[0] ^= 1;
}
}
if self.gen_corrupted {
// Corrupt what is signed by modifying the input to the
// signature code.
sig_payload[0] ^= 1;
}
if self.kinds.contains(&TlvKinds::RSA2048) ||
@ -375,6 +416,7 @@ impl ManifestGen for TlvGen {
result.write_u16::<LittleEndian>(TlvKinds::ECDSA256 as u16).unwrap();
// signature must be padded...
let mut signature = signature.as_ref().to_vec();
while signature.len() < 72 {