Infineon: Switch to 1.9.0 code base, add xmc7000 family support, refactor memory layer
diff --git a/sim/src/tlv.rs b/sim/src/tlv.rs
index 6680b4f..61d56a2 100644
--- a/sim/src/tlv.rs
+++ b/sim/src/tlv.rs
@@ -1,4 +1,4 @@
-// Copyright (c) 2017-2020 Linaro LTD
+// Copyright (c) 2017-2021 Linaro LTD
// Copyright (c) 2017-2020 JUUL Labs
// Copyright (c) 2021 Arm Limited
//
@@ -67,8 +67,8 @@
PIC = 0x01,
NON_BOOTABLE = 0x02,
ENCRYPTED_AES128 = 0x04,
- RAM_LOAD = 0x20,
ENCRYPTED_AES256 = 0x08,
+ RAM_LOAD = 0x20,
}
/// A generator for manifests. The format of the manifest can be either a
@@ -96,6 +96,11 @@
/// corrupt the signature.
fn corrupt_sig(&mut self);
+ /// Estimate the size of the TLV. This can be called before the payload is added (but after
+ /// other information is added). Some of the signature algorithms can generate variable sized
+ /// data, and therefore, this can slightly overestimate the size.
+ fn estimate_size(&self) -> usize;
+
/// Construct the manifest for this payload.
fn make_tlv(self: Box<Self>) -> Vec<u8>;
@@ -332,8 +337,67 @@
self.gen_corrupted = true;
}
+ fn estimate_size(&self) -> usize {
+ // Begin the estimate with the 4 byte header.
+ let mut estimate = 4;
+ // A very poor estimate.
+
+ // Estimate the size of the image hash.
+ if self.kinds.contains(&TlvKinds::SHA256) {
+ estimate += 4 + 32;
+ }
+
+ // Add an estimate in for each of the signature algorithms.
+ if self.kinds.contains(&TlvKinds::RSA2048) {
+ estimate += 4 + 32; // keyhash
+ estimate += 4 + 256; // RSA2048
+ }
+ if self.kinds.contains(&TlvKinds::RSA3072) {
+ estimate += 4 + 32; // keyhash
+ estimate += 4 + 384; // RSA3072
+ }
+ if self.kinds.contains(&TlvKinds::ECDSA256) {
+ estimate += 4 + 32; // keyhash
+
+ // ECDSA signatures are encoded as ASN.1 with the x and y values stored as signed
+ // integers. As such, the size can vary by 2 bytes, if the 256-bit value has the high
+ // bit, it takes an extra 0 byte to avoid it being seen as a negative number.
+ estimate += 4 + 72; // ECDSA256 (varies)
+ }
+ if self.kinds.contains(&TlvKinds::ED25519) {
+ estimate += 4 + 32; // keyhash
+ estimate += 4 + 64; // ED25519 signature.
+ }
+
+ // Estimate encryption.
+ let flag = TlvFlags::ENCRYPTED_AES256 as u32;
+ let aes256 = (self.get_flags() & flag) == flag;
+
+ if self.kinds.contains(&TlvKinds::ENCRSA2048) {
+ estimate += 4 + 256;
+ }
+ if self.kinds.contains(&TlvKinds::ENCKW) {
+ estimate += 4 + if aes256 { 40 } else { 24 };
+ }
+ if self.kinds.contains(&TlvKinds::ENCEC256) {
+ estimate += 4 + if aes256 { 129 } else { 113 };
+ }
+ if self.kinds.contains(&TlvKinds::ENCX25519) {
+ estimate += 4 + if aes256 { 96 } else { 80 };
+ }
+
+ // Gather the size of the dependency information.
+ if self.protect_size() > 0 {
+ estimate += 4 + (16 * self.dependencies.len());
+ }
+
+ estimate
+ }
+
/// Compute the TLV given the specified block of data.
fn make_tlv(self: Box<Self>) -> Vec<u8> {
+ let size_estimate = self.estimate_size();
+
let mut protected_tlv: Vec<u8> = vec![];
if self.protect_size() > 0 {
@@ -663,6 +727,25 @@
let mut size_buf = &mut result[npro_pos + 2 .. npro_pos + 4];
size_buf.write_u16::<LittleEndian>(size).unwrap();
+ // ECDSA is stored as an ASN.1 integer. For a 128-bit value, this maximally results in 33
+ // bytes of storage for each of the two values. If the high bit is zero, it will take 32
+ // bytes, if the top 8 bits are zero, it will take 31 bits, and so on. The smaller size
+ // will occur with decreasing likelihood. We'll allow this to get a bit smaller, hopefully
+ // allowing the tests to pass with false failures rare. For this case, we'll handle up to
+ // the top 16 bits of both numbers being all zeros (1 in 2^32).
+ if !Caps::has_ecdsa() {
+ if size_estimate != result.len() {
+ panic!("Incorrect size estimate: {} (actual {})", size_estimate, result.len());
+ }
+ } else {
+ if size_estimate < result.len() || size_estimate > result.len() + 6 {
+ panic!("Incorrect size estimate: {} (actual {})", size_estimate, result.len());
+ }
+ }
+ if size_estimate != result.len() {
+ log::warn!("Size off: {} actual {}", size_estimate, result.len());
+ }
+
result
}