Move key_id from header into TLV
Remove the key_id field from the image header. There are two problems
with this field. First, it is only an integer offset, and so causes an
unnecessarily tight coupling between the particular keys built into the
bootloader, and the key that is used to sign. Second, it makes the
key_id part of the image header, which is included in the signature.
This makes it impossible to later sign the image with a different
signature.
Instead of the key-id, add a TLV KEYHASH entry. This will hold the
SHA256 of the public key that the signature is against. Each signature
placed in the TLV should be preceeded by this entry to indicate the
public key used.
The signature check will check each signature, and if the KEYHASH is
known and the signature type is supported, it will be checked. As long
as at least one signature is considered valid, the image will be
considered signed. This also allows the image to be signed with
multiple signatures to support having different devices with possibly
different keys compiled into the bootloaders.
Based on work by Marko Kiiskila <marko@runtime.io>
Signed-off-by: Marko Kiiskila <marko@runtime.io>
Signed-off-by: David Brown <david.brown@linaro.org>
diff --git a/sim/Cargo.lock b/sim/Cargo.lock
index 3ec6405..bc9bb00 100644
--- a/sim/Cargo.lock
+++ b/sim/Cargo.lock
@@ -2,7 +2,6 @@
name = "bootsim"
version = "0.1.0"
dependencies = [
- "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"docopt 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -58,11 +57,6 @@
]
[[package]]
-name = "bitflags"
-version = "0.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
name = "byteorder"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -374,7 +368,6 @@
"checksum backtrace 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "72f9b4182546f4b04ebc4ab7f84948953a118bd6021a1b6a6c909e3e94f6be76"
"checksum backtrace-sys 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3a0d842ea781ce92be2bf78a9b38883948542749640b8378b3b2f03d1fd9f1ff"
"checksum base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "30e93c03064e7590d0466209155251b90c22e37fab1daf2771582598b5827557"
-"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
"checksum byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff81738b726f5d099632ceaffe7fb65b90212e8dce59d518729e7e8634032d3d"
"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
"checksum coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c06169f5beb7e31c7c67ebf5540b8b472d23e3eade3b2ec7d1f5b504a85f91bd"
diff --git a/sim/Cargo.toml b/sim/Cargo.toml
index 1a76597..1466589 100644
--- a/sim/Cargo.toml
+++ b/sim/Cargo.toml
@@ -21,7 +21,6 @@
env_logger = "0.4"
simflash = { path = "simflash" }
mcuboot-sys = { path = "mcuboot-sys" }
-bitflags = "0.9"
ring = { version = "0.11", features = ["rsa_signing"] }
untrusted = "0.5"
pem = "0.4"
diff --git a/sim/src/main.rs b/sim/src/main.rs
index a2b1a93..9e38172 100644
--- a/sim/src/main.rs
+++ b/sim/src/main.rs
@@ -1,7 +1,6 @@
#[macro_use] extern crate log;
extern crate ring;
extern crate env_logger;
-#[macro_use] extern crate bitflags;
extern crate docopt;
extern crate libc;
extern crate pem;
diff --git a/sim/src/rsa_pub_key-rs.txt b/sim/src/rsa_pub_key-rs.txt
new file mode 100644
index 0000000..288759d
--- /dev/null
+++ b/sim/src/rsa_pub_key-rs.txt
@@ -0,0 +1,37 @@
+/* Autogenerated by imgtool.py, do not edit. */
+static RSA_PUB_KEY: &'static [u8] = &[
+ 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01,
+ 0x00, 0xd1, 0x06, 0x08, 0x1a, 0x18, 0x44, 0x2c,
+ 0x18, 0xe8, 0xfb, 0xfd, 0xf7, 0x0d, 0xa3, 0x4f,
+ 0x1f, 0xbb, 0xee, 0x5e, 0xf9, 0xaa, 0xd2, 0x4b,
+ 0x18, 0xd3, 0x5a, 0xe9, 0x6d, 0x18, 0x80, 0x19,
+ 0xf9, 0xf0, 0x9c, 0x34, 0x1b, 0xcb, 0xf3, 0xbc,
+ 0x74, 0xdb, 0x42, 0xe7, 0x8c, 0x7f, 0x10, 0x53,
+ 0x7e, 0x43, 0x5e, 0x0d, 0x57, 0x2c, 0x44, 0xd1,
+ 0x67, 0x08, 0x0f, 0x0d, 0xbb, 0x5c, 0xee, 0xec,
+ 0xb3, 0x99, 0xdf, 0xe0, 0x4d, 0x84, 0x0b, 0xaa,
+ 0x77, 0x41, 0x60, 0xed, 0x15, 0x28, 0x49, 0xa7,
+ 0x01, 0xb4, 0x3c, 0x10, 0xe6, 0x69, 0x8c, 0x2f,
+ 0x5f, 0xac, 0x41, 0x4d, 0x9e, 0x5c, 0x14, 0xdf,
+ 0xf2, 0xf8, 0xcf, 0x3d, 0x1e, 0x6f, 0xe7, 0x5b,
+ 0xba, 0xb4, 0xa9, 0xc8, 0x88, 0x7e, 0x47, 0x3c,
+ 0x94, 0xc3, 0x77, 0x67, 0x54, 0x4b, 0xaa, 0x8d,
+ 0x38, 0x35, 0xca, 0x62, 0x61, 0x7e, 0xb7, 0xe1,
+ 0x15, 0xdb, 0x77, 0x73, 0xd4, 0xbe, 0x7b, 0x72,
+ 0x21, 0x89, 0x69, 0x24, 0xfb, 0xf8, 0x65, 0x6e,
+ 0x64, 0x3e, 0xc8, 0x0e, 0xd7, 0x85, 0xd5, 0x5c,
+ 0x4a, 0xe4, 0x53, 0x0d, 0x2f, 0xff, 0xb7, 0xfd,
+ 0xf3, 0x13, 0x39, 0x83, 0x3f, 0xa3, 0xae, 0xd2,
+ 0x0f, 0xa7, 0x6a, 0x9d, 0xf9, 0xfe, 0xb8, 0xce,
+ 0xfa, 0x2a, 0xbe, 0xaf, 0xb8, 0xe0, 0xfa, 0x82,
+ 0x37, 0x54, 0xf4, 0x3e, 0xe1, 0x2b, 0xd0, 0xd3,
+ 0x08, 0x58, 0x18, 0xf6, 0x5e, 0x4c, 0xc8, 0x88,
+ 0x81, 0x31, 0xad, 0x5f, 0xb0, 0x82, 0x17, 0xf2,
+ 0x8a, 0x69, 0x27, 0x23, 0xf3, 0xab, 0x87, 0x3e,
+ 0x93, 0x1a, 0x1d, 0xfe, 0xe8, 0xf8, 0x1a, 0x24,
+ 0x66, 0x59, 0xf8, 0x1c, 0xab, 0xdc, 0xce, 0x68,
+ 0x1b, 0x66, 0x64, 0x35, 0xec, 0xfa, 0x0d, 0x11,
+ 0x9d, 0xaf, 0x5c, 0x3a, 0xa7, 0xd1, 0x67, 0xc6,
+ 0x47, 0xef, 0xb1, 0x4b, 0x2c, 0x62, 0xe1, 0xd1,
+ 0xc9, 0x02, 0x03, 0x01, 0x00, 0x01,
+];
diff --git a/sim/src/tlv.rs b/sim/src/tlv.rs
index f4c88b0..c9e4a6d 100644
--- a/sim/src/tlv.rs
+++ b/sim/src/tlv.rs
@@ -13,22 +13,11 @@
use ring::{digest, rand, signature};
use untrusted;
-bitflags! {
- struct Flags: u32 {
- const FLAG_PIC = 0x000001;
- const FLAG_SHA256 = 0x000002;
- const FLAG_PKCS15_RSA2048_SHA256 = 0x000004;
- const FLAG_ECDSA224_SHA256 = 0x000008;
- const FLAG_NON_BOOTABLE = 0x000010;
- const FLAG_ECDSA256_SHA256 = 0x000020;
- const FLAG_PKCS1_PSS_RSA2048_SHA256 = 0x000040;
- }
-}
-
#[repr(u8)]
#[derive(Copy, Clone, PartialEq, Eq)]
#[allow(dead_code)] // TODO: For now
pub enum TlvKinds {
+ KEYHASH = 0x01,
SHA256 = 0x10,
RSA2048 = 0x20,
ECDSA224 = 0x21,
@@ -36,7 +25,7 @@
}
pub struct TlvGen {
- flags: Flags,
+ flags: u32,
kinds: Vec<TlvKinds>,
size: u16,
payload: Vec<u8>,
@@ -47,7 +36,7 @@
#[allow(dead_code)]
pub fn new_hash_only() -> TlvGen {
TlvGen {
- flags: FLAG_SHA256,
+ flags: 0,
kinds: vec![TlvKinds::SHA256],
size: 4 + 32,
payload: vec![],
@@ -57,8 +46,8 @@
#[allow(dead_code)]
pub fn new_rsa_pss() -> TlvGen {
TlvGen {
- flags: FLAG_SHA256 | FLAG_PKCS1_PSS_RSA2048_SHA256,
- kinds: vec![TlvKinds::SHA256, TlvKinds::RSA2048],
+ flags: 0,
+ kinds: vec![TlvKinds::SHA256, TlvKinds::KEYHASH, TlvKinds::RSA2048],
size: 4 + 32 + 4 + 256,
payload: vec![],
}
@@ -66,7 +55,7 @@
/// Retrieve the header flags for this configuration. This can be called at any time.
pub fn get_flags(&self) -> u32 {
- self.flags.bits()
+ self.flags
}
/// Retrieve the size that the TLV will occupy. This can be called at any time.
@@ -96,6 +85,17 @@
}
if self.kinds.contains(&TlvKinds::RSA2048) {
+ // Output the hash of the public key.
+ let hash = digest::digest(&digest::SHA256, RSA_PUB_KEY);
+ let hash = hash.as_ref();
+
+ assert!(hash.len() == 32);
+ result.push(TlvKinds::KEYHASH as u8);
+ result.push(0);
+ result.push(32);
+ result.push(0);
+ result.extend_from_slice(hash);
+
// For now assume PSS.
let key_bytes = pem::parse(include_bytes!("../../root-rsa-2048.pem").as_ref()).unwrap();
assert_eq!(key_bytes.tag, "RSA PRIVATE KEY");
@@ -117,3 +117,5 @@
result
}
}
+
+include!("rsa_pub_key-rs.txt");