sim: Use a trait object for TlvGen
In preparation for adding support for differing manifest types, abstract
the TlvGen with a trait object `ManifestGen`. This will allow alternate
implementations to be made.
Signed-off-by: David Brown <david.brown@linaro.org>
diff --git a/sim/src/image.rs b/sim/src/image.rs
index b940b6e..f67d049 100644
--- a/sim/src/image.rs
+++ b/sim/src/image.rs
@@ -19,7 +19,7 @@
use simflash::{Flash, SimFlashMap};
use mcuboot_sys::{c, AreaDesc};
use crate::caps::Caps;
-use crate::tlv::{TlvGen, TlvFlags, AES_SEC_KEY};
+use crate::tlv::{ManifestGen, TlvGen, TlvFlags, AES_SEC_KEY};
impl Images {
/// A simple upgrade without forced failures.
@@ -649,7 +649,7 @@
let slot_len = slots[slot].len;
let dev_id = slots[slot].dev_id;
- let mut tlv = make_tlv();
+ let mut tlv: Box<dyn ManifestGen> = Box::new(make_tlv());
const HDR_SIZE: usize = 32;
diff --git a/sim/src/tlv.rs b/sim/src/tlv.rs
index 03390db..63a3d7c 100644
--- a/sim/src/tlv.rs
+++ b/sim/src/tlv.rs
@@ -41,6 +41,20 @@
RAM_LOAD = 0x20,
}
+/// A generator for manifests. The format of the manifest can be either a
+/// traditional "TLV" or a SUIT-style manifest.
+pub trait ManifestGen {
+ /// Retrieve the flags value for this particular manifest type.
+ fn get_flags(&self) -> u32;
+
+ /// Add a sequence of bytes to the payload that the manifest is
+ /// protecting.
+ fn add_bytes(&mut self, bytes: &[u8]);
+
+ /// Construct the manifest for this payload.
+ fn make_tlv(self: Box<Self>) -> Vec<u8>;
+}
+
pub struct TlvGen {
flags: u32,
kinds: Vec<TlvKinds>,
@@ -132,23 +146,56 @@
}
}
- /// Retrieve the header flags for this configuration. This can be called at any time.
- pub fn get_flags(&self) -> u32 {
- self.flags
- }
-
/// Retrieve the size that the TLV will occupy. This can be called at any time.
pub fn get_size(&self) -> u16 {
4 + self.size
}
+ /// Create a DER representation of one ec curve point
+ fn _make_der_int(&self, x: &[u8]) -> Vec<u8> {
+ assert!(x.len() == 32);
+
+ let mut i: Vec<u8> = vec![0x02];
+ if x[0] >= 0x7f {
+ i.push(33);
+ i.push(0);
+ } else {
+ i.push(32);
+ }
+ i.extend(x);
+ i
+ }
+
+ /// Create an ecdsa256 TLV
+ fn _make_der_sequence(&self, r: Vec<u8>, s: Vec<u8>) -> Vec<u8> {
+ let mut der: Vec<u8> = vec![0x30];
+ der.push(r.len() as u8 + s.len() as u8);
+ der.extend(r);
+ der.extend(s);
+ let mut size = der.len();
+ // must pad up to 72 bytes...
+ while size <= 72 {
+ der.push(0);
+ der[1] += 1;
+ size += 1;
+ }
+ der
+ }
+}
+
+impl ManifestGen for TlvGen {
+ /// Retrieve the header flags for this configuration. This can be called at any time.
+ fn get_flags(&self) -> u32 {
+ self.flags
+ }
+
/// Add bytes to the covered hash.
- pub fn add_bytes(&mut self, bytes: &[u8]) {
+ fn add_bytes(&mut self, bytes: &[u8]) {
self.payload.extend_from_slice(bytes);
}
/// Compute the TLV given the specified block of data.
- pub fn make_tlv(self) -> Vec<u8> {
+ fn make_tlv(self: Box<Self>) -> Vec<u8> {
let mut result: Vec<u8> = vec![];
let size = self.get_size();