sim: Add test support for x25519 encrypted images
Signed-off-by: Fabio Utzig <utzig@apache.org>
diff --git a/sim/src/image.rs b/sim/src/image.rs
index 2c99694..420a14f 100644
--- a/sim/src/image.rs
+++ b/sim/src/image.rs
@@ -1310,6 +1310,12 @@
} else {
TlvGen::new_ecies_p256()
}
+ } else if Caps::EncX25519.present() {
+ if Caps::Ed25519.present() {
+ TlvGen::new_ed25519_ecies_x25519()
+ } else {
+ TlvGen::new_ecies_x25519()
+ }
} else {
// The non-encrypted configuration.
if Caps::RSA2048.present() {
@@ -1331,7 +1337,7 @@
/// is unencrypted, and slot 1 is encrypted.
fn find(&self, slot: usize) -> &Vec<u8> {
let encrypted = Caps::EncRsa.present() || Caps::EncKw.present() ||
- Caps::EncEc256.present();
+ Caps::EncEc256.present() || Caps::EncX25519.present();
match (encrypted, slot) {
(false, _) => &self.plain,
(true, 0) => &self.plain,
diff --git a/sim/src/tlv.rs b/sim/src/tlv.rs
index c8200e6..23f8bb8 100644
--- a/sim/src/tlv.rs
+++ b/sim/src/tlv.rs
@@ -53,6 +53,7 @@
ENCRSA2048 = 0x30,
ENCKW128 = 0x31,
ENCEC256 = 0x32,
+ ENCX25519 = 0x33,
DEPENDENCY = 0x40,
}
@@ -222,6 +223,24 @@
..Default::default()
}
}
+
+ #[allow(dead_code)]
+ pub fn new_ecies_x25519() -> TlvGen {
+ TlvGen {
+ flags: TlvFlags::ENCRYPTED as u32,
+ kinds: vec![TlvKinds::SHA256, TlvKinds::ENCX25519],
+ ..Default::default()
+ }
+ }
+
+ #[allow(dead_code)]
+ pub fn new_ed25519_ecies_x25519() -> TlvGen {
+ TlvGen {
+ flags: TlvFlags::ENCRYPTED as u32,
+ kinds: vec![TlvKinds::SHA256, TlvKinds::ED25519, TlvKinds::ENCX25519],
+ ..Default::default()
+ }
+ }
}
impl ManifestGen for TlvGen {
@@ -480,12 +499,21 @@
result.extend_from_slice(&encbuf);
}
- if self.kinds.contains(&TlvKinds::ENCEC256) {
- let key_bytes = pem::parse(include_bytes!("../../enc-ec256-pub.pem").as_ref()).unwrap();
+ if self.kinds.contains(&TlvKinds::ENCEC256) || self.kinds.contains(&TlvKinds::ENCX25519) {
+ let key_bytes = if self.kinds.contains(&TlvKinds::ENCEC256) {
+ pem::parse(include_bytes!("../../enc-ec256-pub.pem").as_ref()).unwrap()
+ } else {
+ pem::parse(include_bytes!("../../enc-x25519-pub.pem").as_ref()).unwrap()
+ };
assert_eq!(key_bytes.tag, "PUBLIC KEY");
let rng = rand::SystemRandom::new();
- let pk = match agreement::EphemeralPrivateKey::generate(&agreement::ECDH_P256, &rng) {
+ let alg = if self.kinds.contains(&TlvKinds::ENCEC256) {
+ &agreement::ECDH_P256
+ } else {
+ &agreement::X25519
+ };
+ let pk = match agreement::EphemeralPrivateKey::generate(alg, &rng) {
Ok(v) => v,
Err(_) => panic!("Failed to generate ephemeral keypair"),
};
@@ -495,7 +523,11 @@
Err(_) => panic!("Failed computing ephemeral public key"),
};
- let peer_pubk = agreement::UnparsedPublicKey::new(&agreement::ECDH_P256, &key_bytes.contents[26..]);
+ let peer_pubk = if self.kinds.contains(&TlvKinds::ENCEC256) {
+ agreement::UnparsedPublicKey::new(&agreement::ECDH_P256, &key_bytes.contents[26..])
+ } else {
+ agreement::UnparsedPublicKey::new(&agreement::X25519, &key_bytes.contents[12..])
+ };
#[derive(Debug, PartialEq)]
struct OkmLen<T: core::fmt::Debug + PartialEq>(T);
@@ -539,9 +571,15 @@
buf.append(&mut tag.as_ref().to_vec());
buf.append(&mut cipherkey);
- assert!(buf.len() == 113);
- result.write_u16::<LittleEndian>(TlvKinds::ENCEC256 as u16).unwrap();
- result.write_u16::<LittleEndian>(113).unwrap();
+ if self.kinds.contains(&TlvKinds::ENCEC256) {
+ assert!(buf.len() == 113);
+ result.write_u16::<LittleEndian>(TlvKinds::ENCEC256 as u16).unwrap();
+ result.write_u16::<LittleEndian>(113).unwrap();
+ } else {
+ assert!(buf.len() == 80);
+ result.write_u16::<LittleEndian>(TlvKinds::ENCX25519 as u16).unwrap();
+ result.write_u16::<LittleEndian>(80).unwrap();
+ }
result.extend_from_slice(&buf);
}