Skip to content

Commit 9771028

Browse files
committed
Add ed25519 verification to sim
Signed-off-by: Fabio Utzig <[email protected]>
1 parent 4876484 commit 9771028

File tree

10 files changed

+97
-1
lines changed

10 files changed

+97
-1
lines changed

boot/bootutil/include/bootutil/caps.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ uint32_t bootutil_get_caps(void);
4141
#define BOOTUTIL_CAP_ENC_KW (1<<6)
4242
#define BOOTUTIL_CAP_VALIDATE_PRIMARY_SLOT (1<<7)
4343
#define BOOTUTIL_CAP_RSA3072 (1<<8)
44+
#define BOOTUTIL_CAP_ED25519 (1<<9)
4445

4546
/*
4647
* Query the number of images this bootloader is configured for. This

boot/bootutil/src/caps.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ uint32_t bootutil_get_caps(void)
3535
#if defined(MCUBOOT_SIGN_EC256)
3636
res |= BOOTUTIL_CAP_ECDSA_P256;
3737
#endif
38+
#if defined(MCUBOOT_SIGN_ED25519)
39+
res |= BOOTUTIL_CAP_ED25519;
40+
#endif
3841
#if defined(MCUBOOT_OVERWRITE_ONLY)
3942
res |= BOOTUTIL_CAP_OVERWRITE_UPGRADE;
4043
#else

sim/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ default = []
1010
sig-rsa = ["mcuboot-sys/sig-rsa"]
1111
sig-rsa3072 = ["mcuboot-sys/sig-rsa3072"]
1212
sig-ecdsa = ["mcuboot-sys/sig-ecdsa"]
13+
sig-ed25519 = ["mcuboot-sys/sig-ed25519"]
1314
overwrite-only = ["mcuboot-sys/overwrite-only"]
1415
validate-primary-slot = ["mcuboot-sys/validate-primary-slot"]
1516
enc-rsa = ["mcuboot-sys/enc-rsa"]

sim/mcuboot-sys/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ sig-rsa3072 = []
2121
# Verify ECDSA (secp256r1) signatures.
2222
sig-ecdsa = []
2323

24+
# Verify ED25519 signatures.
25+
sig-ed25519 = []
26+
2427
# Overwrite only upgrade
2528
overwrite-only = []
2629

sim/mcuboot-sys/build.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ fn main() {
1212
let sig_rsa = env::var("CARGO_FEATURE_SIG_RSA").is_ok();
1313
let sig_rsa3072 = env::var("CARGO_FEATURE_SIG_RSA3072").is_ok();
1414
let sig_ecdsa = env::var("CARGO_FEATURE_SIG_ECDSA").is_ok();
15+
let sig_ed25519 = env::var("CARGO_FEATURE_SIG_ED25519").is_ok();
1516
let overwrite_only = env::var("CARGO_FEATURE_OVERWRITE_ONLY").is_ok();
1617
let validate_primary_slot =
1718
env::var("CARGO_FEATURE_VALIDATE_PRIMARY_SLOT").is_ok();
@@ -37,7 +38,7 @@ fn main() {
3738
}
3839

3940
// Currently no more than one sig type can be used simultaneously.
40-
if vec![sig_rsa, sig_rsa3072, sig_ecdsa].iter()
41+
if vec![sig_rsa, sig_rsa3072, sig_ecdsa, sig_ed25519].iter()
4142
.fold(0, |sum, &v| sum + v as i32) > 1 {
4243
panic!("mcuboot does not support more than one sig type at the same time");
4344
}
@@ -83,6 +84,18 @@ fn main() {
8384

8485
conf.file("../../ext/mbedtls/src/platform_util.c");
8586
conf.file("../../ext/mbedtls/src/asn1parse.c");
87+
} else if sig_ed25519 {
88+
conf.define("MCUBOOT_SIGN_ED25519", None);
89+
conf.define("MCUBOOT_USE_MBED_TLS", None);
90+
91+
conf.include("mbedtls/include");
92+
conf.file("mbedtls/library/sha256.c");
93+
conf.file("mbedtls/library/sha512.c");
94+
conf.file("csupport/keys.c");
95+
conf.file("../../ext/fiat/src/curve25519.c");
96+
conf.file("mbedtls/library/platform.c");
97+
conf.file("mbedtls/library/platform_util.c");
98+
conf.file("mbedtls/library/asn1parse.c");
8699
} else {
87100
// Neither signature type, only verify sha256. The default
88101
// configuration file bundled with mbedTLS is sufficient.
@@ -148,6 +161,10 @@ fn main() {
148161
conf.file("../../ext/tinycrypt/lib/source/aes_encrypt.c");
149162
conf.file("../../ext/tinycrypt/lib/source/aes_decrypt.c");
150163
}
164+
165+
if sig_ed25519 {
166+
panic!("ed25519 does not support image encryption with KW yet");
167+
}
151168
}
152169

153170
if sig_rsa && enc_kw {
@@ -156,6 +173,8 @@ fn main() {
156173
conf.define("MBEDTLS_CONFIG_FILE", Some("<config-rsa.h>"));
157174
} else if sig_ecdsa && !enc_kw {
158175
conf.define("MBEDTLS_CONFIG_FILE", Some("<config-asn1.h>"));
176+
} else if sig_ed25519 {
177+
conf.define("MBEDTLS_CONFIG_FILE", Some("<config-ed25519.h>"));
159178
} else if enc_kw {
160179
conf.define("MBEDTLS_CONFIG_FILE", Some("<config-kw.h>"));
161180
}
@@ -165,6 +184,8 @@ fn main() {
165184
conf.file("../../boot/bootutil/src/image_rsa.c");
166185
} else if sig_ecdsa {
167186
conf.file("../../boot/bootutil/src/image_ec256.c");
187+
} else if sig_ed25519 {
188+
conf.file("../../boot/bootutil/src/image_ed25519.c");
168189
}
169190
conf.file("../../boot/bootutil/src/loader.c");
170191
conf.file("../../boot/bootutil/src/caps.c");

sim/mcuboot-sys/csupport/keys.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,17 @@ const unsigned char root_pub_der[] = {
122122
0x8b, 0x68, 0x34, 0xcc, 0x3a, 0x6a, 0xfc, 0x53,
123123
0x8e, 0xfa, 0xc1, };
124124
const unsigned int root_pub_der_len = 91;
125+
#elif defined(MCUBOOT_SIGN_ED25519)
126+
#define HAVE_KEYS
127+
const unsigned char root_pub_der[] = {
128+
0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65,
129+
0x70, 0x03, 0x21, 0x00, 0xd4, 0xb3, 0x1b, 0xa4,
130+
0x9a, 0x3a, 0xdd, 0x3f, 0x82, 0x5d, 0x10, 0xca,
131+
0x7f, 0x31, 0xb5, 0x0b, 0x0d, 0xe8, 0x7f, 0x37,
132+
0xcc, 0xc4, 0x9f, 0x1a, 0x40, 0x3a, 0x5c, 0x13,
133+
0x20, 0xff, 0xb4, 0xe0,
134+
};
135+
const unsigned int root_pub_der_len = 44;
125136
#endif
126137

127138
#if defined(HAVE_KEYS)

sim/src/caps.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ pub enum Caps {
1313
EncKw = (1 << 6),
1414
ValidatePrimarySlot = (1 << 7),
1515
RSA3072 = (1 << 8),
16+
Ed25519 = (1 << 9),
1617
}
1718

1819
impl Caps {

sim/src/ed25519_pub_key-rs.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
static ED25519_PUB_KEY: &'static [u8] = &[
2+
0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65,
3+
0x70, 0x03, 0x21, 0x00, 0xd4, 0xb3, 0x1b, 0xa4,
4+
0x9a, 0x3a, 0xdd, 0x3f, 0x82, 0x5d, 0x10, 0xca,
5+
0x7f, 0x31, 0xb5, 0x0b, 0x0d, 0xe8, 0x7f, 0x37,
6+
0xcc, 0xc4, 0x9f, 0x1a, 0x40, 0x3a, 0x5c, 0x13,
7+
0x20, 0xff, 0xb4, 0xe0,
8+
];

sim/src/image.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,6 +1168,8 @@ fn make_tlv() -> TlvGen {
11681168
TlvGen::new_rsa3072_pss()
11691169
} else if Caps::EcdsaP256.present() {
11701170
TlvGen::new_ecdsa()
1171+
} else if Caps::Ed25519.present() {
1172+
TlvGen::new_ed25519()
11711173
} else {
11721174
TlvGen::new_hash_only()
11731175
}

sim/src/tlv.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use ring::signature::{
1616
RSA_PSS_SHA256,
1717
EcdsaKeyPair,
1818
ECDSA_P256_SHA256_ASN1_SIGNING,
19+
Ed25519KeyPair,
1920
};
2021
use untrusted;
2122
use mcuboot_sys::c;
@@ -30,6 +31,7 @@ pub enum TlvKinds {
3031
ECDSA224 = 0x21,
3132
ECDSA256 = 0x22,
3233
RSA3072 = 0x23,
34+
ED25519 = 0x24,
3335
ENCRSA2048 = 0x30,
3436
ENCKW128 = 0x31,
3537
}
@@ -110,6 +112,16 @@ impl TlvGen {
110112
}
111113
}
112114

115+
#[allow(dead_code)]
116+
pub fn new_ed25519() -> TlvGen {
117+
TlvGen {
118+
flags: 0,
119+
kinds: vec![TlvKinds::SHA256, TlvKinds::ED25519],
120+
size: 4 + 32 + 4 + 32 + 4 + 64,
121+
payload: vec![],
122+
}
123+
}
124+
113125
#[allow(dead_code)]
114126
pub fn new_enc_rsa() -> TlvGen {
115127
TlvGen {
@@ -288,6 +300,38 @@ impl ManifestGen for TlvGen {
288300
result.extend_from_slice(signature.as_ref());
289301
}
290302

303+
if self.kinds.contains(&TlvKinds::ED25519) {
304+
let keyhash = digest::digest(&digest::SHA256, ED25519_PUB_KEY);
305+
let keyhash = keyhash.as_ref();
306+
307+
assert!(keyhash.len() == 32);
308+
result.push(TlvKinds::KEYHASH as u8);
309+
result.push(0);
310+
result.push(32);
311+
result.push(0);
312+
result.extend_from_slice(keyhash);
313+
314+
let hash = digest::digest(&digest::SHA256, &self.payload);
315+
let hash = hash.as_ref();
316+
assert!(hash.len() == 32);
317+
318+
let key_bytes = pem::parse(include_bytes!("../../root-ed25519.pem").as_ref()).unwrap();
319+
assert_eq!(key_bytes.tag, "PRIVATE KEY");
320+
321+
let seed = untrusted::Input::from(&key_bytes.contents[16..48]);
322+
let public = untrusted::Input::from(&ED25519_PUB_KEY[12..44]);
323+
let key_pair = Ed25519KeyPair::from_seed_and_public_key(seed, public).unwrap();
324+
let signature = key_pair.sign(&hash);
325+
326+
result.push(TlvKinds::ED25519 as u8);
327+
result.push(0);
328+
329+
let signature = signature.as_ref().to_vec();
330+
result.push((signature.len() & 0xFF) as u8);
331+
result.push(((signature.len() >> 8) & 0xFF) as u8);
332+
result.extend_from_slice(signature.as_ref());
333+
}
334+
291335
if self.kinds.contains(&TlvKinds::ENCRSA2048) {
292336
let key_bytes = pem::parse(include_bytes!("../../enc-rsa2048-pub.pem")
293337
.as_ref()).unwrap();
@@ -330,3 +374,4 @@ impl ManifestGen for TlvGen {
330374
include!("rsa_pub_key-rs.txt");
331375
include!("rsa3072_pub_key-rs.txt");
332376
include!("ecdsa_pub_key-rs.txt");
377+
include!("ed25519_pub_key-rs.txt");

0 commit comments

Comments
 (0)