sim: Add RSA signature verification to simulator
Using the published debug keypair, generate a signature with it, to add
to the TLV. This verifies that signature verification works as
expected.
Signed-off-by: David Brown <david.brown@linaro.org>
diff --git a/sim/Cargo.lock b/sim/Cargo.lock
index 7b4e3a1..330fad9 100644
--- a/sim/Cargo.lock
+++ b/sim/Cargo.lock
@@ -8,10 +8,12 @@
"gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pem 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
"ring 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
"simflash 0.1.0",
+ "untrusted 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -23,6 +25,14 @@
]
[[package]]
+name = "aho-corasick"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "backtrace"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -46,11 +56,24 @@
]
[[package]]
+name = "base64"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[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"
+
+[[package]]
name = "cfg-if"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -107,6 +130,14 @@
]
[[package]]
+name = "error-chain"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "backtrace 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "futures"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -149,6 +180,14 @@
]
[[package]]
+name = "memchr"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "num_cpus"
version = "1.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -157,6 +196,17 @@
]
[[package]]
+name = "pem"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "rand"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -198,11 +248,28 @@
]
[[package]]
+name = "regex"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "regex-syntax"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "regex-syntax"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "ring"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -259,6 +326,23 @@
]
[[package]]
+name = "thread_local"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "unreachable"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "untrusted"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -269,6 +353,16 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "utf8-ranges"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "void"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "winapi"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -280,15 +374,19 @@
[metadata]
"checksum aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ca972c2ea5f742bfce5687b9aef75506a764f61d37f8f649047846a9686ddb66"
+"checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699"
"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"
"checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850"
"checksum docopt 0.6.86 (registry+https://github.com/rust-lang/crates.io-index)" = "4a7ef30445607f6fc8720f0a0a2c7442284b629cf0d049286860fae23e71c4d9"
"checksum either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18785c1ba806c258137c937e44ada9ee7e69a37e3c72077542cd2f069d78562a"
"checksum env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "15abd780e45b3ea4f76b4e9a26ff4843258dd8a3eed2775a0e7368c2e7936c2f"
+"checksum error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8"
"checksum error-chain 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "318cb3c71ee4cdea69fdc9e15c173b245ed6063e1709029e8fd32525a881120f"
"checksum futures 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "4b63a4792d4f8f686defe3b39b92127fea6344de5d38202b2ee5a11bbbf29d6a"
"checksum gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)" = "120d07f202dcc3f72859422563522b66fe6463a4c513df062874daad05f85f0a"
@@ -297,12 +395,16 @@
"checksum libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)" = "30885bcb161cf67054244d10d4a7f4835ffd58773bc72e07d35fecf472295503"
"checksum log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "880f77541efa6e5cc74e76910c9884d9859683118839d6a1dc3b11e63512565b"
"checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20"
+"checksum memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1dbccc0e46f1ea47b9f17e6d67c5a96bd27030519c519c9c91327e31275a47b4"
"checksum num_cpus 1.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aec53c34f2d0247c5ca5d32cca1478762f301740468ee9ee6dcb7a0dd7a0c584"
+"checksum pem 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6b8ecfb4eb6b5ec9f5ca17667a5d451275630bbf53c25eb1ae76e235bbf8bf26"
"checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d"
"checksum rayon 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a77c51c07654ddd93f6cb543c7a849863b03abc7e82591afda6dc8ad4ac3ac4a"
"checksum rayon-core 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7febc28567082c345f10cddc3612c6ea020fc3297a1977d472cf9fdb73e6e493"
"checksum regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f"
+"checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b"
"checksum regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957"
+"checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db"
"checksum ring 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2a6dc7fc06a05e6de183c5b97058582e9da2de0c136eafe49609769c507724"
"checksum rustc-demangle 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3058a43ada2c2d0b92b3ae38007a2d0fa5e9db971be260e0171408a4ff471c95"
"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
@@ -310,7 +412,11 @@
"checksum strsim 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "67f84c44fbb2f91db7fef94554e6b2ac05909c9c0b0bc23bb98d3a1aebfe7f7c"
"checksum thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03"
"checksum thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8576dbbfcaef9641452d5cf0df9b0e7eeab7694956dd33bb61515fb8f18cfdd5"
+"checksum thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1697c4b57aeeb7a536b647165a2825faddffb1d3bad386d507709bd51a90bb14"
+"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
"checksum untrusted 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6b65243989ef6aacd9c0d6bd2b822765c3361d8ed352185a6f3a41f3a718c673"
"checksum utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f"
+"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
+"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
diff --git a/sim/Cargo.toml b/sim/Cargo.toml
index c5b6d81..e1bb57a 100644
--- a/sim/Cargo.toml
+++ b/sim/Cargo.toml
@@ -16,7 +16,9 @@
env_logger = "0.3"
simflash = { path = "simflash" }
bitflags = "0.9"
-ring = "0.11"
+ring = { version = "0.11", features = ["rsa_signing"] }
+untrusted = "0.5"
+pem = "0.4"
[profile.test]
opt-level = 1
diff --git a/sim/build.rs b/sim/build.rs
index 186cea9..ba89a04 100644
--- a/sim/build.rs
+++ b/sim/build.rs
@@ -13,6 +13,8 @@
conf.file("../boot/bootutil/src/caps.c");
conf.file("../boot/bootutil/src/bootutil_misc.c");
conf.file("../boot/bootutil/src/image_validate.c");
+ conf.file("../boot/bootutil/src/image_rsa.c");
+ conf.file("../boot/zephyr/keys.c");
conf.file("csupport/run.c");
conf.include("../boot/bootutil/include");
conf.include("../boot/zephyr/include");
@@ -28,8 +30,14 @@
conf.include("mbedtls/include");
conf.file("mbedtls/library/sha256.c");
+ // Code for RSA.
+ conf.file("mbedtls/library/rsa.c");
+ conf.file("mbedtls/library/bignum.c");
+ conf.file("mbedtls/library/asn1parse.c");
+
// Test that signature/hashes are present.
conf.define("MCUBOOT_VALIDATE_SLOT0", None);
+ conf.define("MCUBOOT_SIGN_RSA", None);
conf.compile("libbootutil.a");
walk_dir("../boot").unwrap();
diff --git a/sim/csupport/run.c b/sim/csupport/run.c
index d52defd..5a817cc 100644
--- a/sim/csupport/run.c
+++ b/sim/csupport/run.c
@@ -42,11 +42,17 @@
static struct area_desc *flash_areas;
+void *(*mbedtls_calloc)(size_t n, size_t size);
+void (*mbedtls_free)(void *ptr);
+
int invoke_boot_go(struct area_desc *adesc)
{
int res;
struct boot_rsp rsp;
+ mbedtls_calloc = calloc;
+ mbedtls_free = free;
+
flash_areas = adesc;
if (setjmp(boot_jmpbuf) == 0) {
res = boot_go(&rsp);
diff --git a/sim/src/main.rs b/sim/src/main.rs
index 89be7ff..acd15a9 100644
--- a/sim/src/main.rs
+++ b/sim/src/main.rs
@@ -4,9 +4,11 @@
#[macro_use] extern crate bitflags;
extern crate docopt;
extern crate libc;
+extern crate pem;
extern crate rand;
extern crate rustc_serialize;
extern crate simflash;
+extern crate untrusted;
use docopt::Docopt;
use rand::{Rng, SeedableRng, XorShiftRng};
@@ -601,7 +603,7 @@
fn install_image(flash: &mut Flash, offset: usize, len: usize) -> Vec<u8> {
let offset0 = offset;
- let mut tlv = TlvGen::new_hash_only();
+ let mut tlv = TlvGen::new_rsa_pss();
// Generate a boot header. Note that the size doesn't include the header.
let header = ImageHeader {
diff --git a/sim/src/tlv.rs b/sim/src/tlv.rs
index ac6ac5d..59bdf2c 100644
--- a/sim/src/tlv.rs
+++ b/sim/src/tlv.rs
@@ -8,7 +8,10 @@
//! Because of this header, we have to make two passes. The first pass will compute the size of
//! the TLV, and the second pass will build the data for the TLV.
-use ring::digest;
+use std::sync::Arc;
+use pem;
+use ring::{digest, rand, signature};
+use untrusted;
bitflags! {
struct Flags: u32 {
@@ -41,6 +44,7 @@
impl TlvGen {
/// Construct a new tlv generator that will only contain a hash of the data.
+ #[allow(dead_code)]
pub fn new_hash_only() -> TlvGen {
TlvGen {
flags: FLAG_SHA256,
@@ -50,6 +54,16 @@
}
}
+ #[allow(dead_code)]
+ pub fn new_rsa_pss() -> TlvGen {
+ TlvGen {
+ flags: FLAG_SHA256 | FLAG_PKCS1_PSS_RSA2048_SHA256,
+ kinds: vec![TlvKinds::SHA256, TlvKinds::RSA2048],
+ size: 4 + 32 + 4 + 256,
+ payload: vec![],
+ }
+ }
+
/// Retrieve the header flags for this configuration. This can be called at any time.
pub fn get_flags(&self) -> u32 {
self.flags.bits()
@@ -81,6 +95,25 @@
result.extend_from_slice(hash);
}
+ if self.kinds.contains(&TlvKinds::RSA2048) {
+ // 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");
+ let key_bytes = untrusted::Input::from(&key_bytes.contents);
+ let key = signature::RSAKeyPair::from_der(key_bytes).unwrap();
+ let mut signer = signature::RSASigningState::new(Arc::new(key)).unwrap();
+ let rng = rand::SystemRandom::new();
+ let mut signature = vec![0; signer.key_pair().public_modulus_len()];
+ assert_eq!(signature.len(), 256);
+ signer.sign(&signature::RSA_PSS_SHA256, &rng, &self.payload, &mut signature).unwrap();
+
+ result.push(TlvKinds::RSA2048 as u8);
+ result.push(0);
+ result.push((signature.len() & 0xFF) as u8);
+ result.push(((signature.len() >> 8) & 0xFF) as u8);
+ result.extend_from_slice(&signature);
+ }
+
result
}
}