Add encrypted image support on sim
This adds new cargo features to allow running tests of encrypted
images with both RSA-OAEP and AES-128-KW.
When installing images on the simulated flash, both a plain and an
encrypted images are created. When encrypted image support is enabled,
verification of images in slot1 match against the encrypted image,
otherwise plain images are used.
PS: Also fixes ImageHeader to match bootutil definition.
Signed-off-by: Fabio Utzig <utzig@apache.org>
diff --git a/sim/Cargo.lock b/sim/Cargo.lock
index 8fa80f2..066f925 100644
--- a/sim/Cargo.lock
+++ b/sim/Cargo.lock
@@ -1,4 +1,35 @@
[[package]]
+name = "aes-ctr"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "aes-soft 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "aesni 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ctr 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "stream-cipher 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "aes-soft"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "block-cipher-trait 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "opaque-debug 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "aesni"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "block-cipher-trait 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "opaque-debug 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "stream-cipher 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "aho-corasick"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -39,14 +70,33 @@
]
[[package]]
+name = "base64"
+version = "0.9.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "bitflags"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "block-cipher-trait"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "bootsim"
version = "0.1.0"
dependencies = [
+ "aes-ctr 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "base64 0.9.2 (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.54 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -63,6 +113,11 @@
]
[[package]]
+name = "byte-tools"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "byteorder"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -87,6 +142,15 @@
]
[[package]]
+name = "ctr"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "block-cipher-trait 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "stream-cipher 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "dbghelp-sys"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -159,6 +223,14 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "generic-array"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "kernel32-sys"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -215,6 +287,11 @@
]
[[package]]
+name = "opaque-debug"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "pem"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -337,6 +414,14 @@
]
[[package]]
+name = "stream-cipher"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "strsim"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -369,6 +454,11 @@
]
[[package]]
+name = "typenum"
+version = "1.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "unicode-xid"
version = "0.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -407,15 +497,22 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
+"checksum aes-ctr 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f65958ff3692041c36fc009261ccd63f24cd8e0dc1164266f068c2387e8b4e4f"
+"checksum aes-soft 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "67cc03b0a090a05cb01e96998a01905d7ceedce1bc23b756c0bb7faa0682ccb1"
+"checksum aesni 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6810b7fb9f2bb4f76f05ac1c170b8dde285b6308955dc3afd89710268c958d9e"
"checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4"
"checksum backtrace 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8709cc7ec06f6f0ae6c2c7e12f6ed41540781f72b488d83734978295ceae182e"
"checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661"
"checksum base64 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c4a342b450b268e1be8036311e2c613d7f8a7ed31214dff1cc3b60852a3168d"
+"checksum base64 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "85415d2594767338a74a30c1d370b2f3262ec1b4ed2d7bba5b3faf4de40467d9"
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
+"checksum block-cipher-trait 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "370424437b9459f3dfd68428ed9376ddfe03d8b70ede29cc533b3557df186ab4"
+"checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"
"checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23"
"checksum cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a9b13a57efd6b30ecd6598ebdb302cca617930b5470647570468a65d12ef9719"
"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 ctr 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50ac3add446ec1f8fe3dc007cd838f5b22bbf33186394feac505451ecc43c018"
"checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850"
"checksum docopt 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3b5b93718f8b3e5544fcc914c43de828ca6c6ace23e0332c6080a2977b49787a"
"checksum either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "740178ddf48b1a9e878e6d6509a1442a2d42fd2928aae8e7a6f8a36fb01981b3"
@@ -425,6 +522,7 @@
"checksum fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c0581a4e363262e52b87f59ee2afe3415361c6ec35e665924eb08afe8ff159"
"checksum fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "43f3795b4bae048dc6123a6b972cadde2e676f9ded08aef6bb77f5f157684a82"
"checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb"
+"checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d"
@@ -432,6 +530,7 @@
"checksum log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "880f77541efa6e5cc74e76910c9884d9859683118839d6a1dc3b11e63512565b"
"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
"checksum num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "514f0d73e64be53ff320680ca671b64fe3fb91da01e1ae2ddc99eb51d453b20d"
+"checksum opaque-debug 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d620c9c26834b34f039489ac0dfdb12c7ac15ccaf818350a64c9b5334a452ad7"
"checksum pem 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97b2fe7dc63bbe9ad4cc7510f33b8ac45242c8032acaa460193c05d852aa74d8"
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
"checksum rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6475140dfd8655aeb72e1fd4b7a1cc1c202be65d71669476e392fe62532b9edd"
@@ -446,10 +545,12 @@
"checksum serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "1c57ab4ec5fa85d08aaf8ed9245899d9bbdd66768945b21113b84d5f595cb6a1"
"checksum serde_derive 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "02c92ea07b6e49b959c1481804ebc9bfd92d3c459f1274c9a9546829e42a66ce"
"checksum serde_derive_internals 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75c6aac7b99801a16db5b40b7bf0d7e4ba16e76fbf231e32a4677f271cac0603"
+"checksum stream-cipher 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "30dc6118470d69ce0fdcf7e6f95e95853f7f4f72f80d835d4519577c323814ab"
"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
"checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963"
+"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
"checksum untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f392d7819dbe58833e26872f5f6f0d68b7bbbe90fc3667e98731c4a15ad9a7ae"
diff --git a/sim/Cargo.toml b/sim/Cargo.toml
index 29fb0d4..84fbabe 100644
--- a/sim/Cargo.toml
+++ b/sim/Cargo.toml
@@ -10,6 +10,8 @@
sig-ecdsa = ["mcuboot-sys/sig-ecdsa"]
overwrite-only = ["mcuboot-sys/overwrite-only"]
validate-slot0 = ["mcuboot-sys/validate-slot0"]
+enc-rsa = ["mcuboot-sys/enc-rsa"]
+enc-kw = ["mcuboot-sys/enc-kw"]
[build-dependencies]
gcc = "0.3.54"
@@ -27,6 +29,8 @@
ring = { version = "0.12.1", features = ["rsa_signing"] }
untrusted = "0.5"
pem = "0.5"
+aes-ctr = "0.1.0"
+base64 = "0.9.2"
# The simulator runs very slowly without optimization. A value of 1
# compiles in about half the time, but runs about 5-6 times slower. 2
diff --git a/sim/mcuboot-sys/Cargo.toml b/sim/mcuboot-sys/Cargo.toml
index 7846875..25d5652 100644
--- a/sim/mcuboot-sys/Cargo.toml
+++ b/sim/mcuboot-sys/Cargo.toml
@@ -23,6 +23,12 @@
# Disable validation of slot0
validate-slot0 = []
+# Encrypt image in slot1 using RSA-OAEP-2048
+enc-rsa = []
+
+# Encrypt image in slot1 using AES-KW-128
+enc-kw = []
+
[build-dependencies]
gcc = "0.3.54"
diff --git a/sim/mcuboot-sys/build.rs b/sim/mcuboot-sys/build.rs
index 2c28dbb..ea958f6 100644
--- a/sim/mcuboot-sys/build.rs
+++ b/sim/mcuboot-sys/build.rs
@@ -13,6 +13,8 @@
let sig_ecdsa = env::var("CARGO_FEATURE_SIG_ECDSA").is_ok();
let overwrite_only = env::var("CARGO_FEATURE_OVERWRITE_ONLY").is_ok();
let validate_slot0 = env::var("CARGO_FEATURE_VALIDATE_SLOT0").is_ok();
+ let enc_rsa = env::var("CARGO_FEATURE_ENC_RSA").is_ok();
+ let enc_kw = env::var("CARGO_FEATURE_ENC_KW").is_ok();
let mut conf = gcc::Build::new();
conf.define("__BOOTSIM__", None);
@@ -73,6 +75,49 @@
conf.define("MCUBOOT_OVERWRITE_ONLY_FAST", None);
}
+ if enc_rsa {
+ conf.define("MCUBOOT_ENCRYPT_RSA", None);
+ conf.define("MCUBOOT_ENC_IMAGES", None);
+ conf.define("MCUBOOT_USE_MBED_TLS", None);
+ conf.define("MBEDTLS_CONFIG_FILE", Some("<config-rsa.h>"));
+
+ conf.file("../../boot/bootutil/src/encrypted.c");
+ conf.file("csupport/keys.c");
+
+ conf.include("mbedtls/include");
+ conf.file("mbedtls/library/sha256.c");
+
+ conf.file("mbedtls/library/platform.c");
+ conf.file("mbedtls/library/platform_util.c");
+ conf.file("mbedtls/library/rsa.c");
+ conf.file("mbedtls/library/rsa_internal.c");
+ conf.file("mbedtls/library/md.c");
+ conf.file("mbedtls/library/md_wrap.c");
+ conf.file("mbedtls/library/aes.c");
+ conf.file("mbedtls/library/bignum.c");
+ conf.file("mbedtls/library/asn1parse.c");
+ }
+
+ if enc_kw {
+ conf.define("MCUBOOT_ENCRYPT_KW", None);
+ conf.define("MCUBOOT_ENC_IMAGES", None);
+ conf.define("MCUBOOT_USE_MBED_TLS", None);
+ conf.define("MBEDTLS_CONFIG_FILE", Some("<config-kw.h>"));
+
+ conf.file("../../boot/bootutil/src/encrypted.c");
+ conf.file("csupport/keys.c");
+
+ conf.include("mbedtls/include");
+ conf.file("mbedtls/library/sha256.c");
+
+ conf.file("mbedtls/library/platform.c");
+ conf.file("mbedtls/library/platform_util.c");
+ conf.file("mbedtls/library/nist_kw.c");
+ conf.file("mbedtls/library/cipher.c");
+ conf.file("mbedtls/library/cipher_wrap.c");
+ conf.file("mbedtls/library/aes.c");
+ }
+
conf.file("../../boot/bootutil/src/image_validate.c");
if sig_rsa {
conf.file("../../boot/bootutil/src/image_rsa.c");
diff --git a/sim/mcuboot-sys/csupport/keys.c b/sim/mcuboot-sys/csupport/keys.c
index aa8272f..6e4f3f5 100644
--- a/sim/mcuboot-sys/csupport/keys.c
+++ b/sim/mcuboot-sys/csupport/keys.c
@@ -65,8 +65,6 @@
0x8b, 0x68, 0x34, 0xcc, 0x3a, 0x6a, 0xfc, 0x53,
0x8e, 0xfa, 0xc1, };
const unsigned int root_pub_der_len = 91;
-#else
-#error "No public key available for given signing algorithm."
#endif
#if defined(HAVE_KEYS)
@@ -78,3 +76,125 @@
};
const int bootutil_key_cnt = 1;
#endif
+
+#if defined(MCUBOOT_ENCRYPT_RSA)
+unsigned char enc_key[] = {
+ 0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00,
+ 0xb4, 0x26, 0x14, 0x49, 0x3d, 0x16, 0x13, 0x3a, 0x6d, 0x9c, 0x84, 0xa9,
+ 0x8b, 0x6a, 0x10, 0x20, 0x61, 0xef, 0x48, 0x04, 0xa4, 0x4b, 0x24, 0xf3,
+ 0x00, 0x32, 0xac, 0x22, 0xe0, 0x30, 0x27, 0x70, 0x18, 0xe5, 0x55, 0xc8,
+ 0xb8, 0x05, 0x34, 0x03, 0xb0, 0xf8, 0xa5, 0x96, 0xd2, 0x48, 0x58, 0xef,
+ 0x70, 0xb0, 0x09, 0xdb, 0xe3, 0x58, 0x62, 0xef, 0x99, 0x63, 0x01, 0xb2,
+ 0x89, 0xc4, 0xb3, 0xf6, 0x9e, 0x62, 0xbf, 0x4d, 0xc2, 0x8a, 0xd0, 0xc9,
+ 0x4d, 0x43, 0xa3, 0xd8, 0xe5, 0x1d, 0xec, 0x62, 0x63, 0x08, 0xe2, 0x20,
+ 0xa5, 0xfc, 0x78, 0xd0, 0x3e, 0x74, 0xc8, 0xa4, 0x1b, 0x36, 0xad, 0x7b,
+ 0xf5, 0x06, 0xae, 0x4d, 0x51, 0x9b, 0x40, 0xce, 0x30, 0x4f, 0x6c, 0xea,
+ 0xf9, 0xe9, 0x74, 0xea, 0x06, 0xee, 0x9c, 0xe4, 0x14, 0x68, 0x20, 0xb9,
+ 0x3d, 0xe7, 0x11, 0x14, 0x8b, 0x25, 0xa3, 0xff, 0x4c, 0x8a, 0xf3, 0x53,
+ 0xee, 0x6b, 0x3e, 0xef, 0x34, 0xcd, 0x6a, 0x3f, 0x62, 0x68, 0xc0, 0xff,
+ 0x78, 0x4c, 0xb0, 0xc3, 0xe6, 0x96, 0x61, 0xfc, 0x1f, 0x18, 0xf1, 0x7a,
+ 0x82, 0xe2, 0x8f, 0x35, 0xa8, 0x2b, 0x86, 0x16, 0xa4, 0x46, 0xfb, 0xac,
+ 0x7e, 0x41, 0xdb, 0x02, 0x05, 0x91, 0x6d, 0xdf, 0xc1, 0xde, 0x13, 0x95,
+ 0x9c, 0xf9, 0x9e, 0x5e, 0x72, 0xba, 0xa7, 0x25, 0x93, 0xfb, 0xdc, 0xe8,
+ 0xab, 0x86, 0x45, 0x88, 0x47, 0x2d, 0xed, 0xee, 0xee, 0x97, 0x9e, 0xce,
+ 0x5d, 0x9b, 0x04, 0x04, 0x40, 0x7c, 0xcb, 0x7c, 0x3d, 0x2c, 0x74, 0xab,
+ 0xa4, 0xcc, 0x64, 0xa3, 0x5c, 0x95, 0x3d, 0xd4, 0xa2, 0xdc, 0x92, 0xb2,
+ 0xc8, 0x18, 0xcb, 0xf9, 0x00, 0x39, 0x81, 0x8f, 0x8f, 0x40, 0xc2, 0xdf,
+ 0x99, 0x29, 0xac, 0x8a, 0xc2, 0x3b, 0xd8, 0xa4, 0xf2, 0xad, 0xaf, 0x74,
+ 0xc0, 0x11, 0xc7, 0x99, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01,
+ 0x00, 0x42, 0x47, 0x80, 0x4f, 0x31, 0xda, 0x5d, 0x58, 0xb1, 0xdb, 0x54,
+ 0x33, 0xcc, 0xc7, 0x49, 0x07, 0xa1, 0x00, 0x98, 0x4e, 0x9c, 0xe3, 0xc8,
+ 0xc4, 0x5e, 0xde, 0x45, 0xd6, 0xcf, 0x04, 0xe8, 0x7d, 0xa5, 0xab, 0x3a,
+ 0xd4, 0x8e, 0x5f, 0xdb, 0xb3, 0x3f, 0xf9, 0x3b, 0x73, 0x32, 0x0a, 0xcc,
+ 0x2d, 0xcc, 0x17, 0xf8, 0x88, 0x9e, 0x2c, 0x76, 0xba, 0x10, 0x85, 0x0c,
+ 0xaa, 0xd3, 0x65, 0x3b, 0x91, 0x10, 0xd4, 0xe3, 0xed, 0x88, 0x15, 0xea,
+ 0x9b, 0x25, 0x82, 0x2d, 0x56, 0x2f, 0x75, 0xc2, 0xf2, 0xaf, 0xdd, 0x24,
+ 0xd5, 0x3e, 0x3c, 0x95, 0x76, 0x88, 0x84, 0x0f, 0x0d, 0xd1, 0xb5, 0x5c,
+ 0x3e, 0xae, 0xf7, 0xb6, 0x49, 0x5c, 0x2c, 0xf2, 0xba, 0xe9, 0xab, 0x4f,
+ 0x37, 0x64, 0x9b, 0x30, 0x18, 0xaa, 0x54, 0x40, 0x04, 0xea, 0x3d, 0x25,
+ 0x4d, 0x02, 0x29, 0x71, 0x6f, 0x4d, 0x82, 0x9b, 0xc3, 0x44, 0x2a, 0x9d,
+ 0x0c, 0x98, 0xd3, 0xc8, 0x15, 0x0d, 0x04, 0x93, 0x60, 0x30, 0xc7, 0x5e,
+ 0x79, 0xea, 0x53, 0x9d, 0xc0, 0x0e, 0x81, 0xac, 0x90, 0xbc, 0x9e, 0x1e,
+ 0xd2, 0x28, 0x0f, 0x10, 0xf5, 0x1f, 0xdf, 0x38, 0x7f, 0x8a, 0x90, 0x8d,
+ 0x49, 0x07, 0x7d, 0x78, 0xcb, 0xa7, 0xef, 0x92, 0x6d, 0x3b, 0x13, 0x95,
+ 0x9b, 0xba, 0x83, 0xc6, 0xb3, 0x71, 0x25, 0x27, 0x07, 0x99, 0x54, 0x82,
+ 0x3d, 0xec, 0xc5, 0xf8, 0xb4, 0xa0, 0x38, 0x7a, 0x59, 0x6a, 0x0b, 0xca,
+ 0x69, 0x6c, 0x17, 0xa4, 0x18, 0xe0, 0xb4, 0xaa, 0x89, 0x99, 0x8f, 0xcb,
+ 0x71, 0x34, 0x09, 0x1b, 0x6e, 0xe6, 0x87, 0x00, 0xb5, 0xba, 0x70, 0x8a,
+ 0x29, 0x3d, 0x9a, 0x06, 0x18, 0x2d, 0x66, 0x5e, 0x61, 0x37, 0xeb, 0xdd,
+ 0x5e, 0xc8, 0x28, 0x92, 0x05, 0x30, 0xfd, 0xb8, 0x65, 0xb1, 0x7f, 0xbf,
+ 0x2d, 0x55, 0x12, 0x91, 0xc1, 0x02, 0x81, 0x81, 0x00, 0xda, 0x65, 0xda,
+ 0x38, 0x7c, 0x18, 0xfb, 0x00, 0x11, 0x60, 0xeb, 0x37, 0x65, 0xb8, 0x83,
+ 0x62, 0x88, 0xc4, 0x3a, 0x4e, 0x64, 0x6a, 0xf3, 0x3e, 0x4e, 0xc0, 0x34,
+ 0x19, 0x8a, 0xcb, 0x4a, 0xca, 0x2f, 0x5d, 0x50, 0x7a, 0xac, 0xf7, 0x9e,
+ 0x87, 0x5a, 0xfc, 0x4d, 0x49, 0xd7, 0xf9, 0x21, 0xf5, 0x0b, 0x6f, 0x57,
+ 0x41, 0x3d, 0x8f, 0xb8, 0xec, 0x7f, 0xcc, 0x92, 0x09, 0xbe, 0xd3, 0xa4,
+ 0xc3, 0x14, 0x85, 0x21, 0x5d, 0x05, 0xa3, 0xaa, 0x20, 0xf6, 0x62, 0x44,
+ 0x50, 0x03, 0x5e, 0x53, 0x4a, 0xcd, 0x6a, 0xb6, 0x65, 0x8e, 0x4e, 0x4b,
+ 0x3f, 0x25, 0xc6, 0x16, 0x31, 0xf5, 0x99, 0x13, 0x77, 0x42, 0xda, 0xdc,
+ 0x70, 0x4d, 0x65, 0xb0, 0x99, 0x0f, 0xdf, 0x5a, 0xb1, 0x45, 0xf0, 0xb9,
+ 0x8e, 0xa0, 0xae, 0x4f, 0x4d, 0x65, 0x09, 0x84, 0xb5, 0x38, 0x29, 0xbf,
+ 0x69, 0xe0, 0x88, 0x1f, 0x27, 0x02, 0x81, 0x81, 0x00, 0xd3, 0x2a, 0x59,
+ 0xec, 0x28, 0xc3, 0x0d, 0x4f, 0x92, 0x96, 0xca, 0x67, 0x94, 0xfc, 0x2e,
+ 0xa6, 0x86, 0x68, 0x45, 0x53, 0x92, 0xcc, 0x86, 0x7f, 0x8a, 0xe1, 0x5d,
+ 0xe8, 0x1d, 0x9e, 0xbb, 0x1e, 0x00, 0x26, 0x1d, 0x80, 0x12, 0xff, 0x9c,
+ 0x11, 0x0a, 0xbd, 0xa6, 0xc3, 0x8d, 0x48, 0xda, 0xfc, 0x10, 0xf7, 0x7a,
+ 0x16, 0x07, 0x15, 0xa0, 0x3a, 0xd3, 0x94, 0xfb, 0x52, 0x87, 0x39, 0xee,
+ 0xe7, 0xc4, 0x26, 0x49, 0x16, 0xc6, 0xc0, 0x83, 0x25, 0xbf, 0x6a, 0x4e,
+ 0x8c, 0x0b, 0x10, 0x85, 0x66, 0xab, 0x7e, 0xae, 0xac, 0x4c, 0x69, 0x3c,
+ 0x44, 0xeb, 0xcd, 0xe9, 0xf6, 0x64, 0x8b, 0x4a, 0xd8, 0x6a, 0x4d, 0x6d,
+ 0x47, 0xa9, 0xb8, 0x55, 0x72, 0xc1, 0xfd, 0xf4, 0x81, 0x4c, 0x66, 0xbe,
+ 0x49, 0xf2, 0x75, 0x4f, 0x80, 0xf1, 0x20, 0x38, 0xb8, 0x6a, 0x1b, 0x75,
+ 0x41, 0x30, 0x0f, 0x1b, 0x3f, 0x02, 0x81, 0x80, 0x09, 0x35, 0xfa, 0x7a,
+ 0x1f, 0x61, 0xbe, 0x54, 0x46, 0x67, 0x5c, 0x04, 0x3e, 0x1a, 0x06, 0x10,
+ 0x85, 0xcc, 0x20, 0xd9, 0x65, 0x8a, 0xcd, 0x2f, 0x77, 0x8a, 0xcb, 0xa7,
+ 0xb8, 0x1e, 0xd2, 0xcc, 0xac, 0x2a, 0xb7, 0x56, 0x35, 0x2d, 0x4c, 0x56,
+ 0x51, 0x14, 0x0a, 0xfe, 0x6e, 0x49, 0x67, 0x91, 0x3a, 0x26, 0x3b, 0xfb,
+ 0xd8, 0x68, 0xd3, 0x57, 0xc6, 0x1c, 0x0e, 0x9c, 0xb2, 0x9b, 0xa2, 0x7b,
+ 0x47, 0xc6, 0x45, 0x9d, 0xf2, 0xba, 0xf0, 0x55, 0xeb, 0x8e, 0x41, 0x6b,
+ 0x4e, 0x79, 0x0f, 0xf2, 0x3b, 0xaf, 0xa0, 0x79, 0xb0, 0x02, 0xc5, 0x51,
+ 0xa8, 0x7a, 0x2e, 0x3d, 0x75, 0x2a, 0x3b, 0x93, 0xf0, 0x11, 0xe2, 0xf2,
+ 0x29, 0x91, 0x7c, 0x5d, 0x38, 0x3a, 0x27, 0x4d, 0x0a, 0xb2, 0x18, 0x61,
+ 0x57, 0x8d, 0x82, 0x72, 0xb5, 0x2c, 0x2d, 0x98, 0xa7, 0x01, 0xbb, 0xbc,
+ 0xef, 0x67, 0x4e, 0x49, 0x02, 0x81, 0x81, 0x00, 0xb2, 0x70, 0x53, 0x54,
+ 0x70, 0x8d, 0x82, 0xad, 0xff, 0x1d, 0x55, 0x24, 0x7a, 0x8d, 0x2f, 0x8e,
+ 0xa0, 0x7d, 0x74, 0x37, 0xcf, 0x10, 0xed, 0x86, 0xd1, 0x80, 0xe7, 0xad,
+ 0xc1, 0x79, 0xe4, 0x7c, 0xd1, 0x7b, 0x63, 0xea, 0x5a, 0x23, 0x8d, 0x6a,
+ 0x09, 0x3d, 0x81, 0xb2, 0x35, 0xad, 0x9e, 0xfe, 0xea, 0x07, 0x76, 0x2f,
+ 0x2f, 0x05, 0x63, 0x44, 0xd2, 0x8e, 0x4e, 0x61, 0xca, 0xcb, 0x75, 0xca,
+ 0x7b, 0xc2, 0x2e, 0x79, 0x04, 0xb2, 0xa1, 0x20, 0x40, 0xc4, 0x40, 0x63,
+ 0xae, 0xe5, 0xe3, 0x14, 0x83, 0x4e, 0xa5, 0xa4, 0x0b, 0x5d, 0xd2, 0x04,
+ 0x1b, 0x8f, 0x01, 0x69, 0xa8, 0x44, 0xdc, 0x96, 0x4c, 0x1d, 0xe9, 0x7e,
+ 0x69, 0x38, 0xcf, 0x5c, 0x0d, 0xf9, 0xdf, 0xa7, 0x73, 0x3c, 0x4f, 0x08,
+ 0x85, 0xce, 0x03, 0xc4, 0xdd, 0xfd, 0x70, 0x70, 0xc5, 0x99, 0x36, 0x58,
+ 0x43, 0x98, 0x40, 0x59, 0x02, 0x81, 0x81, 0x00, 0xd5, 0xaa, 0xfb, 0xec,
+ 0x8d, 0xc6, 0xdd, 0xfa, 0x2b, 0x5a, 0x24, 0xd0, 0xda, 0x58, 0xbd, 0x87,
+ 0x92, 0x1a, 0x29, 0x62, 0x13, 0x1d, 0x4b, 0x79, 0x1b, 0xbe, 0x79, 0x7d,
+ 0xad, 0x79, 0xca, 0x17, 0x75, 0xda, 0xe8, 0x32, 0xe8, 0xa0, 0x9e, 0xa8,
+ 0x77, 0x53, 0xac, 0x38, 0xd6, 0xeb, 0xe6, 0x22, 0x65, 0xc4, 0xaa, 0x4c,
+ 0xc8, 0xd0, 0x33, 0x1a, 0x1e, 0xbe, 0xbd, 0x73, 0x09, 0x4a, 0xfa, 0x85,
+ 0x5c, 0xf3, 0x0c, 0x9c, 0x81, 0x56, 0x30, 0xa7, 0xf7, 0x9b, 0xf4, 0x92,
+ 0x9c, 0x6b, 0x93, 0x6a, 0x00, 0x33, 0xdc, 0x2f, 0x54, 0x1e, 0x78, 0xd4,
+ 0x97, 0xec, 0x24, 0xa2, 0xdb, 0x3d, 0x03, 0x33, 0x09, 0xb2, 0x2c, 0x03,
+ 0x05, 0x40, 0xde, 0x52, 0xf2, 0x9b, 0xfa, 0x00, 0x8d, 0x4b, 0xfe, 0x5b,
+ 0x9b, 0x9c, 0x73, 0xad, 0xfb, 0x7a, 0x00, 0x42, 0x62, 0x9e, 0xa0, 0x95,
+ 0x55, 0x50, 0x32, 0x87
+};
+static unsigned int enc_key_len = 1192;
+const struct bootutil_key bootutil_enc_key = {
+ .key = enc_key,
+ .len = &enc_key_len,
+};
+#endif
+
+#if defined(MCUBOOT_ENCRYPT_KW)
+unsigned char enc_key[] = {
+ 0xd1, 0x5a, 0x04, 0x95, 0xc4, 0xc2, 0xa8, 0xff, 0x30, 0x78, 0xce, 0x49,
+ 0xb5, 0xfc, 0xb2, 0xdd
+};
+static unsigned int enc_key_len = 16;
+const struct bootutil_key bootutil_enc_key = {
+ .key = enc_key,
+ .len = &enc_key_len,
+};
+#endif
diff --git a/sim/mcuboot-sys/csupport/run.c b/sim/mcuboot-sys/csupport/run.c
index 17a10f1..f8aaccd 100644
--- a/sim/mcuboot-sys/csupport/run.c
+++ b/sim/mcuboot-sys/csupport/run.c
@@ -17,6 +17,15 @@
#include "../../../ext/tinycrypt/lib/include/tinycrypt/ecc_dsa.h"
#endif
+#ifdef MCUBOOT_ENCRYPT_RSA
+#include "mbedtls/rsa.h"
+#include "mbedtls/asn1.h"
+#endif
+
+#ifdef MCUBOOT_ENCRYPT_KW
+#include "mbedtls/nist_kw.h"
+#endif
+
#define BOOT_LOG_LEVEL BOOT_LOG_LEVEL_ERROR
#include <bootutil/bootutil_log.h>
@@ -45,6 +54,155 @@
#endif
}
+#ifdef MCUBOOT_ENCRYPT_RSA
+static int
+parse_pubkey(mbedtls_rsa_context *ctx, uint8_t **p, uint8_t *end)
+{
+ int rc;
+ size_t len;
+
+ if ((rc = mbedtls_asn1_get_tag(p, end, &len,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
+ return -1;
+ }
+
+ if (*p + len != end) {
+ return -2;
+ }
+
+ if ((rc = mbedtls_asn1_get_tag(p, end, &len,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
+ return -3;
+ }
+
+ *p += len;
+
+ if ((rc = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_BIT_STRING)) != 0) {
+ return -4;
+ }
+
+ if (**p != MBEDTLS_ASN1_PRIMITIVE) {
+ return -5;
+ }
+
+ *p += 1;
+
+ if ((rc = mbedtls_asn1_get_tag(p, end, &len,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
+ return -6;
+ }
+
+ if (mbedtls_asn1_get_mpi(p, end, &ctx->N) != 0) {
+ return -7;
+ }
+
+ if (mbedtls_asn1_get_mpi(p, end, &ctx->E) != 0) {
+ return -8;
+ }
+
+ ctx->len = mbedtls_mpi_size(&ctx->N);
+
+ if (*p != end) {
+ return -9;
+ }
+
+ if (mbedtls_rsa_check_pubkey(ctx) != 0) {
+ return -10;
+ }
+
+ return 0;
+}
+
+static int
+fake_rng(void *p_rng, unsigned char *output, size_t len)
+{
+ size_t i;
+
+ (void)p_rng;
+ for (i = 0; i < len; i++) {
+ output[i] = (char)i;
+ }
+
+ return 0;
+}
+#endif
+
+int mbedtls_platform_set_calloc_free(void * (*calloc_func)(size_t, size_t),
+ void (*free_func)(void *));
+
+int rsa_oaep_encrypt_(const uint8_t *pubkey, unsigned pubkey_len,
+ const uint8_t *seckey, unsigned seckey_len,
+ uint8_t *encbuf)
+{
+#ifdef MCUBOOT_ENCRYPT_RSA
+ mbedtls_rsa_context ctx;
+ uint8_t *cp;
+ uint8_t *cpend;
+ int rc;
+
+ mbedtls_platform_set_calloc_free(calloc, free);
+
+ mbedtls_rsa_init(&ctx, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
+
+ cp = (uint8_t *)pubkey;
+ cpend = cp + pubkey_len;
+
+ rc = parse_pubkey(&ctx, &cp, cpend);
+ if (rc) {
+ goto done;
+ }
+
+ rc = mbedtls_rsa_rsaes_oaep_encrypt(&ctx, fake_rng, NULL, MBEDTLS_RSA_PUBLIC,
+ NULL, 0, seckey_len, seckey, encbuf);
+ if (rc) {
+ goto done;
+ }
+
+done:
+ mbedtls_rsa_free(&ctx);
+ return rc;
+
+#else
+ (void)pubkey;
+ (void)pubkey_len;
+ (void)seckey;
+ (void)seckey_len;
+ (void)encbuf;
+ return 0;
+#endif
+}
+
+int kw_encrypt_(const uint8_t *kek, const uint8_t *seckey, uint8_t *encbuf)
+{
+#ifdef MCUBOOT_ENCRYPT_KW
+ mbedtls_nist_kw_context kw;
+ size_t olen;
+ int rc;
+
+ mbedtls_platform_set_calloc_free(calloc, free);
+
+ mbedtls_nist_kw_init(&kw);
+
+ rc = mbedtls_nist_kw_setkey(&kw, MBEDTLS_CIPHER_ID_AES, kek, 128, 1);
+ if (rc) {
+ goto done;
+ }
+
+ rc = mbedtls_nist_kw_wrap(&kw, MBEDTLS_KW_MODE_KW, seckey, 16, encbuf,
+ &olen, 24);
+
+done:
+ mbedtls_nist_kw_free(&kw);
+ return rc;
+
+#else
+ (void)kek;
+ (void)seckey;
+ (void)encbuf;
+ return 0;
+#endif
+}
+
uint8_t sim_flash_align = 1;
uint8_t flash_area_align(const struct flash_area *area)
{
@@ -73,17 +231,12 @@
static struct area_desc *flash_areas;
-#ifdef MCUBOOT_SIGN_RSA
-int mbedtls_platform_set_calloc_free(void * (*calloc_func)(size_t, size_t),
- void (*free_func)(void *));
-#endif
-
int invoke_boot_go(struct area_desc *adesc)
{
int res;
struct boot_rsp rsp;
-#ifdef MCUBOOT_SIGN_RSA
+#if defined(MCUBOOT_SIGN_RSA)
mbedtls_platform_set_calloc_free(calloc, free);
#endif
diff --git a/sim/mcuboot-sys/src/c.rs b/sim/mcuboot-sys/src/c.rs
index 3b944c6..45624ed 100644
--- a/sim/mcuboot-sys/src/c.rs
+++ b/sim/mcuboot-sys/src/c.rs
@@ -60,6 +60,28 @@
}
}
+pub fn rsa_oaep_encrypt(pubkey: &[u8], seckey: &[u8]) -> Result<[u8; 256], &'static str> {
+ unsafe {
+ let mut encbuf: [u8; 256] = [0; 256];
+ if raw::rsa_oaep_encrypt_(pubkey.as_ptr(), pubkey.len() as u32,
+ seckey.as_ptr(), seckey.len() as u32,
+ encbuf.as_mut_ptr()) == 0 {
+ return Ok(encbuf);
+ }
+ return Err("Failed to encrypt buffer");
+ }
+}
+
+pub fn kw_encrypt(kek: &[u8], seckey: &[u8]) -> Result<[u8; 24], &'static str> {
+ unsafe {
+ let mut encbuf = [0u8; 24];
+ if raw::kw_encrypt_(kek.as_ptr(), seckey.as_ptr(), encbuf.as_mut_ptr()) == 0 {
+ return Ok(encbuf);
+ }
+ return Err("Failed to encrypt buffer");
+ }
+}
+
mod raw {
use area::CAreaDesc;
use libc;
@@ -83,5 +105,12 @@
pub fn ecdsa256_sign_(privkey: *const u8, hash: *const u8,
hash_len: libc::c_uint,
signature: *mut u8) -> libc::c_int;
+
+ pub fn rsa_oaep_encrypt_(pubkey: *const u8, pubkey_len: libc::c_uint,
+ seckey: *const u8, seckey_len: libc::c_uint,
+ encbuf: *mut u8) -> libc::c_int;
+
+ pub fn kw_encrypt_(kek: *const u8, seckey: *const u8,
+ encbuf: *mut u8) -> libc::c_int;
}
}
diff --git a/sim/src/lib.rs b/sim/src/lib.rs
index 1e8ba8a..e7ad671 100644
--- a/sim/src/lib.rs
+++ b/sim/src/lib.rs
@@ -1,5 +1,7 @@
#[macro_use] extern crate log;
extern crate ring;
+extern crate aes_ctr;
+extern crate base64;
extern crate env_logger;
extern crate docopt;
extern crate libc;
@@ -18,6 +20,9 @@
use std::mem;
use std::process;
use std::slice;
+use aes_ctr::Aes128Ctr;
+use aes_ctr::stream_cipher::generic_array::GenericArray;
+use aes_ctr::stream_cipher::{NewFixStreamCipher, StreamCipherCore};
mod caps;
mod tlv;
@@ -26,7 +31,7 @@
use simflash::{Flash, SimFlash};
use mcuboot_sys::{c, AreaDesc, FlashId};
use caps::Caps;
-use tlv::TlvGen;
+use tlv::{TlvGen, TlvFlags, AES_SEC_KEY};
const USAGE: &'static str = "
Mcuboot simulator
@@ -183,12 +188,14 @@
let slot0 = SlotInfo {
base_off: slot0_base as usize,
trailer_off: slot1_base - offset_from_end,
+ len: slot0_len as usize,
};
// And an upgrade image.
let slot1 = SlotInfo {
base_off: slot1_base as usize,
trailer_off: scratch_base - offset_from_end,
+ len: slot1_len as usize,
};
Run {
@@ -216,15 +223,14 @@
/// Construct an `Images` that doesn't expect an upgrade to happen.
pub fn make_no_upgrade_image(&self) -> Images {
let mut flash = self.flash.clone();
- let primary = install_image(&mut flash, self.slots[0].base_off, 32784, false);
- let upgrade = install_image(&mut flash, self.slots[1].base_off, 41928, false);
+ let primaries = install_image(&mut flash, &self.slots, 0, 32784, false);
+ let upgrades = install_image(&mut flash, &self.slots, 1, 41928, false);
Images {
flash: flash,
areadesc: self.areadesc.clone(),
- slot0: self.slots[0].clone(),
- slot1: self.slots[1].clone(),
- primary: primary,
- upgrade: upgrade,
+ slots: [self.slots[0].clone(), self.slots[1].clone()],
+ primaries: primaries,
+ upgrades: upgrades,
total_count: None,
align: self.align,
erased_val: self.erased_val,
@@ -234,7 +240,7 @@
/// Construct an `Images` for normal testing.
pub fn make_image(&self) -> Images {
let mut images = self.make_no_upgrade_image();
- mark_upgrade(&mut images.flash, &images.slot1);
+ mark_upgrade(&mut images.flash, &images.slots[1]);
// upgrades without fails, counts number of flash operations
let total_count = match images.run_basic_upgrade() {
@@ -250,15 +256,14 @@
pub fn make_bad_slot1_image(&self) -> Images {
let mut bad_flash = self.flash.clone();
- let primary = install_image(&mut bad_flash, self.slots[0].base_off, 32784, false);
- let upgrade = install_image(&mut bad_flash, self.slots[1].base_off, 41928, true);
+ let primaries = install_image(&mut bad_flash, &self.slots, 0, 32784, false);
+ let upgrades = install_image(&mut bad_flash, &self.slots, 1, 41928, true);
Images {
flash: bad_flash,
areadesc: self.areadesc.clone(),
- slot0: self.slots[0].clone(),
- slot1: self.slots[1].clone(),
- primary: primary,
- upgrade: upgrade,
+ slots: [self.slots[0].clone(), self.slots[1].clone()],
+ primaries: primaries,
+ upgrades: upgrades,
total_count: None,
align: self.align,
erased_val: self.erased_val,
@@ -380,7 +385,7 @@
let (fl, total_count) = try_upgrade(&self.flash, &self, None);
info!("Total flash operation count={}", total_count);
- if !verify_image(&fl, self.slot0.base_off, &self.upgrade) {
+ if !verify_image(&fl, &self.slots, 0, &self.upgrades) {
warn!("Image mismatch after first boot");
Err(())
} else {
@@ -402,7 +407,7 @@
for count in 2 .. 5 {
info!("Try revert: {}", count);
let fl = try_revert(&self.flash, &self.areadesc, count, self.align);
- if !verify_image(&fl, self.slot0.base_off, &self.primary) {
+ if !verify_image(&fl, &self.slots, 0, &self.primaries) {
error!("Revert failure on count {}", count);
fails += 1;
}
@@ -421,25 +426,25 @@
info!("Try interruption at {}", i);
let (fl, count) = try_upgrade(&self.flash, &self, Some(i));
info!("Second boot, count={}", count);
- if !verify_image(&fl, self.slot0.base_off, &self.upgrade) {
+ if !verify_image(&fl, &self.slots, 0, &self.upgrades) {
warn!("FAIL at step {} of {}", i, total_flash_ops);
fails += 1;
}
- if !verify_trailer(&fl, self.slot0.trailer_off, BOOT_MAGIC_GOOD,
+ if !verify_trailer(&fl, self.slots[0].trailer_off, BOOT_MAGIC_GOOD,
BOOT_FLAG_SET, BOOT_FLAG_SET) {
warn!("Mismatched trailer for Slot 0");
fails += 1;
}
- if !verify_trailer(&fl, self.slot1.trailer_off, BOOT_MAGIC_UNSET,
+ if !verify_trailer(&fl, self.slots[1].trailer_off, BOOT_MAGIC_UNSET,
BOOT_FLAG_UNSET, BOOT_FLAG_UNSET) {
warn!("Mismatched trailer for Slot 1");
fails += 1;
}
if Caps::SwapUpgrade.present() {
- if !verify_image(&fl, self.slot1.base_off, &self.primary) {
+ if !verify_image(&fl, &self.slots, 1, &self.primaries) {
warn!("Slot 1 FAIL at step {} of {}", i, total_flash_ops);
fails += 1;
}
@@ -465,9 +470,9 @@
total_flash_ops, total_fails);
info!("Random interruptions at reset points={:?}", total_counts);
- let slot0_ok = verify_image(&fl, self.slot0.base_off, &self.upgrade);
+ let slot0_ok = verify_image(&fl, &self.slots, 0, &self.upgrades);
let slot1_ok = if Caps::SwapUpgrade.present() {
- verify_image(&fl, self.slot1.base_off, &self.primary)
+ verify_image(&fl, &self.slots, 1, &self.primaries)
} else {
true
};
@@ -477,12 +482,12 @@
if slot1_ok { "ok" } else { "fail" });
fails += 1;
}
- if !verify_trailer(&fl, self.slot0.trailer_off, BOOT_MAGIC_GOOD,
+ if !verify_trailer(&fl, self.slots[0].trailer_off, BOOT_MAGIC_GOOD,
BOOT_FLAG_SET, BOOT_FLAG_SET) {
error!("Mismatched trailer for Slot 0");
fails += 1;
}
- if !verify_trailer(&fl, self.slot1.trailer_off, BOOT_MAGIC_UNSET,
+ if !verify_trailer(&fl, self.slots[1].trailer_off, BOOT_MAGIC_UNSET,
BOOT_FLAG_UNSET, BOOT_FLAG_UNSET) {
error!("Mismatched trailer for Slot 1");
fails += 1;
@@ -539,25 +544,25 @@
//FIXME: copy_done is written by boot_go, is it ok if no copy
// was ever done?
- if !verify_image(&fl, self.slot0.base_off, &self.upgrade) {
+ if !verify_image(&fl, &self.slots, 0, &self.upgrades) {
warn!("Slot 0 image verification FAIL");
fails += 1;
}
- if !verify_trailer(&fl, self.slot0.trailer_off, BOOT_MAGIC_GOOD,
+ if !verify_trailer(&fl, self.slots[0].trailer_off, BOOT_MAGIC_GOOD,
BOOT_FLAG_UNSET, BOOT_FLAG_SET) {
warn!("Mismatched trailer for Slot 0");
fails += 1;
}
- if !verify_trailer(&fl, self.slot1.trailer_off, BOOT_MAGIC_UNSET,
+ if !verify_trailer(&fl, self.slots[1].trailer_off, BOOT_MAGIC_UNSET,
BOOT_FLAG_UNSET, BOOT_FLAG_UNSET) {
warn!("Mismatched trailer for Slot 1");
fails += 1;
}
// Marks image in slot0 as permanent, no revert should happen...
- mark_permanent_upgrade(&mut fl, &self.slot0, self.align, self.erased_val);
+ mark_permanent_upgrade(&mut fl, &self.slots[0], self.align, self.erased_val);
- if !verify_trailer(&fl, self.slot0.trailer_off, BOOT_MAGIC_GOOD,
+ if !verify_trailer(&fl, self.slots[0].trailer_off, BOOT_MAGIC_GOOD,
BOOT_FLAG_SET, BOOT_FLAG_SET) {
warn!("Mismatched trailer for Slot 0");
fails += 1;
@@ -569,12 +574,12 @@
fails += 1;
}
- if !verify_trailer(&fl, self.slot0.trailer_off, BOOT_MAGIC_GOOD,
+ if !verify_trailer(&fl, self.slots[0].trailer_off, BOOT_MAGIC_GOOD,
BOOT_FLAG_SET, BOOT_FLAG_SET) {
warn!("Mismatched trailer for Slot 0");
fails += 1;
}
- if !verify_image(&fl, self.slot0.base_off, &self.upgrade) {
+ if !verify_image(&fl, &self.slots, 0, &self.upgrades) {
warn!("Failed image verification");
fails += 1;
}
@@ -594,10 +599,10 @@
info!("Try non-revert on imgtool generated image");
- mark_upgrade(&mut fl, &self.slot0);
+ mark_upgrade(&mut fl, &self.slots[0]);
// This simulates writing an image created by imgtool to Slot 0
- if !verify_trailer(&fl, self.slot0.trailer_off, BOOT_MAGIC_GOOD,
+ if !verify_trailer(&fl, self.slots[0].trailer_off, BOOT_MAGIC_GOOD,
BOOT_FLAG_UNSET, BOOT_FLAG_UNSET) {
warn!("Mismatched trailer for Slot 0");
fails += 1;
@@ -611,16 +616,16 @@
}
// State should not have changed
- if !verify_image(&fl, self.slot0.base_off, &self.primary) {
+ if !verify_image(&fl, &self.slots, 0, &self.primaries) {
warn!("Failed image verification");
fails += 1;
}
- if !verify_trailer(&fl, self.slot0.trailer_off, BOOT_MAGIC_GOOD,
+ if !verify_trailer(&fl, self.slots[0].trailer_off, BOOT_MAGIC_GOOD,
BOOT_FLAG_UNSET, BOOT_FLAG_UNSET) {
warn!("Mismatched trailer for Slot 0");
fails += 1;
}
- if !verify_trailer(&fl, self.slot1.trailer_off, BOOT_MAGIC_UNSET,
+ if !verify_trailer(&fl, self.slots[1].trailer_off, BOOT_MAGIC_UNSET,
BOOT_FLAG_UNSET, BOOT_FLAG_UNSET) {
warn!("Mismatched trailer for Slot 1");
fails += 1;
@@ -641,11 +646,11 @@
info!("Try upgrade image with bad signature");
- mark_upgrade(&mut fl, &self.slot0);
- mark_permanent_upgrade(&mut fl, &self.slot0, self.align, self.erased_val);
- mark_upgrade(&mut fl, &self.slot1);
+ mark_upgrade(&mut fl, &self.slots[0]);
+ mark_permanent_upgrade(&mut fl, &self.slots[0], self.align, self.erased_val);
+ mark_upgrade(&mut fl, &self.slots[1]);
- if !verify_trailer(&fl, self.slot0.trailer_off, BOOT_MAGIC_GOOD,
+ if !verify_trailer(&fl, self.slots[0].trailer_off, BOOT_MAGIC_GOOD,
BOOT_FLAG_SET, BOOT_FLAG_UNSET) {
warn!("Mismatched trailer for Slot 0");
fails += 1;
@@ -659,11 +664,11 @@
}
// State should not have changed
- if !verify_image(&fl, self.slot0.base_off, &self.primary) {
+ if !verify_image(&fl, &self.slots, 0, &self.primaries) {
warn!("Failed image verification");
fails += 1;
}
- if !verify_trailer(&fl, self.slot0.trailer_off, BOOT_MAGIC_GOOD,
+ if !verify_trailer(&fl, self.slots[0].trailer_off, BOOT_MAGIC_GOOD,
BOOT_FLAG_SET, BOOT_FLAG_UNSET) {
warn!("Mismatched trailer for Slot 0");
fails += 1;
@@ -683,10 +688,22 @@
// FIXME: could get status sz from bootloader
#[cfg(not(feature = "overwrite-only"))]
+ #[cfg(not(feature = "enc-rsa"))]
+ #[cfg(not(feature = "enc-kw"))]
fn status_sz(&self) -> usize {
self.trailer_sz() - (16 + 24)
}
+ #[cfg(feature = "enc-rsa")]
+ fn status_sz(&self) -> usize {
+ self.trailer_sz() - (16 + 24 + 32)
+ }
+
+ #[cfg(feature = "enc-kw")]
+ fn status_sz(&self) -> usize {
+ self.trailer_sz() - (16 + 24 + 32)
+ }
+
/// This test runs a simple upgrade with no fails in the images, but
/// allowing for fails in the status area. This should run to the end
/// and warn that write fails were detected...
@@ -700,9 +717,9 @@
info!("Try swap with status fails");
- mark_permanent_upgrade(&mut fl, &self.slot1, self.align, self.erased_val);
+ mark_permanent_upgrade(&mut fl, &self.slots[1], self.align, self.erased_val);
- let status_off = self.slot1.base_off - self.trailer_sz();
+ let status_off = self.slots[1].base_off - self.trailer_sz();
// Always fail writes to status area...
let _ = fl.add_bad_region(status_off, self.status_sz(), 1.0);
@@ -720,13 +737,13 @@
fails += 1;
}
- if !verify_trailer(&fl, self.slot0.trailer_off, BOOT_MAGIC_GOOD,
+ if !verify_trailer(&fl, self.slots[0].trailer_off, BOOT_MAGIC_GOOD,
BOOT_FLAG_SET, BOOT_FLAG_SET) {
warn!("Mismatched trailer for Slot 0");
fails += 1;
}
- if !verify_image(&fl, self.slot0.base_off, &self.upgrade) {
+ if !verify_image(&fl, &self.slots, 0, &self.upgrades) {
warn!("Failed image verification");
fails += 1;
}
@@ -758,9 +775,9 @@
info!("Try interrupted swap with status fails");
- mark_permanent_upgrade(&mut fl, &self.slot1, self.align, self.erased_val);
+ mark_permanent_upgrade(&mut fl, &self.slots[1], self.align, self.erased_val);
- let status_off = self.slot1.base_off - self.trailer_sz();
+ let status_off = self.slots[1].base_off - self.trailer_sz();
// Mark the status area as a bad area
let _ = fl.add_bad_region(status_off, self.status_sz(), 0.5);
@@ -805,9 +822,9 @@
info!("Try interrupted swap with status fails");
- mark_permanent_upgrade(&mut fl, &self.slot1, self.align, self.erased_val);
+ mark_permanent_upgrade(&mut fl, &self.slots[1], self.align, self.erased_val);
- let status_off = self.slot1.base_off - self.trailer_sz();
+ let status_off = self.slots[1].base_off - self.trailer_sz();
// Mark the status area as a bad area
let _ = fl.add_bad_region(status_off, self.status_sz(), 1.0);
@@ -835,7 +852,7 @@
// Clone the flash to have a new copy.
let mut fl = flash.clone();
- mark_permanent_upgrade(&mut fl, &images.slot1, images.align, images.erased_val);
+ mark_permanent_upgrade(&mut fl, &images.slots[1], images.align, images.erased_val);
let mut counter = stop.unwrap_or(0);
@@ -883,7 +900,7 @@
fails += 1;
}
- if !verify_trailer(&fl, images.slot0.trailer_off, None, None, BOOT_FLAG_UNSET) {
+ if !verify_trailer(&fl, images.slots[0].trailer_off, None, None, BOOT_FLAG_UNSET) {
warn!("copy_done should be unset");
fails += 1;
}
@@ -894,20 +911,20 @@
fails += 1;
}
- if !verify_image(&fl, images.slot0.base_off, &images.upgrade) {
+ if !verify_image(&fl, &images.slots, 0, &images.upgrades) {
warn!("Image in slot 0 before revert is invalid at stop={}", stop);
fails += 1;
}
- if !verify_image(&fl, images.slot1.base_off, &images.primary) {
+ if !verify_image(&fl, &images.slots, 1, &images.primaries) {
warn!("Image in slot 1 before revert is invalid at stop={}", stop);
fails += 1;
}
- if !verify_trailer(&fl, images.slot0.trailer_off, BOOT_MAGIC_GOOD,
+ if !verify_trailer(&fl, images.slots[0].trailer_off, BOOT_MAGIC_GOOD,
BOOT_FLAG_UNSET, BOOT_FLAG_SET) {
warn!("Mismatched trailer for Slot 0 before revert");
fails += 1;
}
- if !verify_trailer(&fl, images.slot1.trailer_off, BOOT_MAGIC_UNSET,
+ if !verify_trailer(&fl, images.slots[1].trailer_off, BOOT_MAGIC_UNSET,
BOOT_FLAG_UNSET, BOOT_FLAG_UNSET) {
warn!("Mismatched trailer for Slot 1 before revert");
fails += 1;
@@ -920,20 +937,20 @@
fails += 1;
}
- if !verify_image(&fl, images.slot0.base_off, &images.primary) {
+ if !verify_image(&fl, &images.slots, 0, &images.primaries) {
warn!("Image in slot 0 after revert is invalid at stop={}", stop);
fails += 1;
}
- if !verify_image(&fl, images.slot1.base_off, &images.upgrade) {
+ if !verify_image(&fl, &images.slots, 1, &images.upgrades) {
warn!("Image in slot 1 after revert is invalid at stop={}", stop);
fails += 1;
}
- if !verify_trailer(&fl, images.slot0.trailer_off, BOOT_MAGIC_GOOD,
+ if !verify_trailer(&fl, images.slots[0].trailer_off, BOOT_MAGIC_GOOD,
BOOT_FLAG_SET, BOOT_FLAG_SET) {
warn!("Mismatched trailer for Slot 1 after revert");
fails += 1;
}
- if !verify_trailer(&fl, images.slot1.trailer_off, BOOT_MAGIC_UNSET,
+ if !verify_trailer(&fl, images.slots[1].trailer_off, BOOT_MAGIC_UNSET,
BOOT_FLAG_UNSET, BOOT_FLAG_UNSET) {
warn!("Mismatched trailer for Slot 1 after revert");
fails += 1;
@@ -946,7 +963,7 @@
total_ops: i32, count: usize) -> (SimFlash, Vec<i32>) {
let mut fl = flash.clone();
- mark_permanent_upgrade(&mut fl, &images.slot1, images.align, images.erased_val);
+ mark_permanent_upgrade(&mut fl, &images.slots[1], images.align, images.erased_val);
let mut rng = rand::thread_rng();
let mut resets = vec![0i32; count];
@@ -985,20 +1002,19 @@
/// Install a "program" into the given image. This fakes the image header, or at least all of the
/// fields used by the given code. Returns a copy of the image that was written.
-fn install_image(flash: &mut Flash, offset: usize, len: usize,
- bad_sig: bool) -> Vec<u8> {
- let offset0 = offset;
+fn install_image(flash: &mut Flash, slots: &[SlotInfo], slot: usize, len: usize,
+ bad_sig: bool) -> [Option<Vec<u8>>; 2] {
+ let offset = slots[slot].base_off;
+ let slot_len = slots[slot].len;
let mut tlv = make_tlv();
// Generate a boot header. Note that the size doesn't include the header.
let header = ImageHeader {
magic: 0x96f3b83d,
- tlv_size: tlv.get_size(),
- _pad1: 0,
+ load_addr: 0,
hdr_size: 32,
- key_id: 0,
- _pad2: 0,
+ _pad1: 0,
img_size: len as u32,
flags: tlv.get_flags(),
ver: ImageVersion {
@@ -1007,7 +1023,7 @@
revision: 1,
build_num: offset as u32,
},
- _pad3: 0,
+ _pad2: 0,
};
let b_header = header.as_raw();
@@ -1017,35 +1033,106 @@
mem::size_of::<ImageHeader>()) };
*/
assert_eq!(b_header.len(), 32);
- flash.write(offset, &b_header).unwrap();
- let offset = offset + b_header.len();
// The core of the image itself is just pseudorandom data.
- let mut buf = vec![0; len];
- splat(&mut buf, offset);
- tlv.add_bytes(&buf);
+ let mut b_img = vec![0; len];
+ splat(&mut b_img, offset);
- // Get and append the TLV itself.
- if bad_sig {
- let good_sig = &mut tlv.make_tlv();
- buf.append(&mut vec![0; good_sig.len()]);
- } else {
- buf.append(&mut tlv.make_tlv());
+ // TLV signatures work over plain image
+ tlv.add_bytes(&b_img);
+
+ // Generate encrypted images
+ let flag = TlvFlags::ENCRYPTED as u32;
+ let is_encrypted = (tlv.get_flags() & flag) == flag;
+ let mut b_encimg = vec![];
+ if is_encrypted {
+ let key = GenericArray::from_slice(AES_SEC_KEY);
+ let nonce = GenericArray::from_slice(&[0; 16]);
+ let mut cipher = Aes128Ctr::new(&key, &nonce);
+ b_encimg = b_img.clone();
+ cipher.apply_keystream(&mut b_encimg);
}
+ // Build the TLV itself.
+ let mut b_tlv = if bad_sig {
+ let good_sig = &mut tlv.make_tlv();
+ vec![0; good_sig.len()]
+ } else {
+ tlv.make_tlv()
+ };
+
// Pad the block to a flash alignment (8 bytes).
- while buf.len() % 8 != 0 {
- buf.push(0xFF);
+ while b_tlv.len() % 8 != 0 {
+ //FIXME: should be erase_val?
+ b_tlv.push(0xFF);
}
- flash.write(offset, &buf).unwrap();
- let offset = offset + buf.len();
+ let mut buf = vec![];
+ buf.append(&mut b_header.to_vec());
+ buf.append(&mut b_img);
+ buf.append(&mut b_tlv.clone());
- // Copy out the image so that we can verify that the image was installed correctly later.
- let mut copy = vec![0u8; offset - offset0];
- flash.read(offset0, &mut copy).unwrap();
+ let mut encbuf = vec![];
+ if is_encrypted {
+ encbuf.append(&mut b_header.to_vec());
+ encbuf.append(&mut b_encimg);
+ encbuf.append(&mut b_tlv);
+ }
- copy
+ let result: [Option<Vec<u8>>; 2];
+
+ // Since images are always non-encrypted in slot0, we first write an
+ // encrypted image, re-read to use for verification, erase + flash
+ // un-encrypted. In slot1 the image is written un-encrypted, and if
+ // encryption is requested, it follows an erase + flash encrypted.
+
+ if slot == 0 {
+ let enc_copy: Option<Vec<u8>>;
+
+ if is_encrypted {
+ flash.write(offset, &encbuf).unwrap();
+
+ let mut enc = vec![0u8; encbuf.len()];
+ flash.read(offset, &mut enc).unwrap();
+
+ enc_copy = Some(enc);
+
+ flash.erase(offset, slot_len).unwrap();
+ } else {
+ enc_copy = None;
+ }
+
+ flash.write(offset, &buf).unwrap();
+
+ let mut copy = vec![0u8; buf.len()];
+ flash.read(offset, &mut copy).unwrap();
+
+ result = [Some(copy), enc_copy];
+ } else {
+ flash.write(offset, &buf).unwrap();
+
+ let mut copy = vec![0u8; buf.len()];
+ flash.read(offset, &mut copy).unwrap();
+
+ let enc_copy: Option<Vec<u8>>;
+
+ if is_encrypted {
+ flash.erase(offset, slot_len).unwrap();
+
+ flash.write(offset, &encbuf).unwrap();
+
+ let mut enc = vec![0u8; encbuf.len()];
+ flash.read(offset, &mut enc).unwrap();
+
+ enc_copy = Some(enc);
+ } else {
+ enc_copy = None;
+ }
+
+ result = [Some(copy), enc_copy];
+ }
+
+ result
}
// The TLV in use depends on what kind of signature we are verifying.
@@ -1059,21 +1146,64 @@
TlvGen::new_ecdsa()
}
+#[cfg(feature = "enc-rsa")]
+fn make_tlv() -> TlvGen {
+ TlvGen::new_enc_rsa()
+}
+
+#[cfg(feature = "enc-kw")]
+fn make_tlv() -> TlvGen {
+ TlvGen::new_enc_kw()
+}
+
#[cfg(not(feature = "sig-rsa"))]
#[cfg(not(feature = "sig-ecdsa"))]
+#[cfg(not(feature = "enc-rsa"))]
+#[cfg(not(feature = "enc-kw"))]
fn make_tlv() -> TlvGen {
TlvGen::new_hash_only()
}
+#[cfg(feature = "enc-rsa")]
+fn find_image(images: &[Option<Vec<u8>>; 2], slot: usize) -> &Vec<u8> {
+ match &images[slot] {
+ Some(image) => return image,
+ None => panic!("Invalid image"),
+ }
+}
+
+#[cfg(feature = "enc-kw")]
+fn find_image(images: &[Option<Vec<u8>>; 2], slot: usize) -> &Vec<u8> {
+ match &images[slot] {
+ Some(image) => return image,
+ None => panic!("Invalid image"),
+ }
+}
+
+#[cfg(not(feature = "enc-rsa"))]
+#[cfg(not(feature = "enc-kw"))]
+fn find_image(images: &[Option<Vec<u8>>; 2], _slot: usize) -> &Vec<u8> {
+ match &images[0] {
+ Some(image) => return image,
+ None => panic!("Invalid image"),
+ }
+}
+
/// Verify that given image is present in the flash at the given offset.
-fn verify_image(flash: &Flash, offset: usize, buf: &[u8]) -> bool {
+fn verify_image(flash: &Flash, slots: &[SlotInfo], slot: usize,
+ images: &[Option<Vec<u8>>; 2]) -> bool {
+ let image = find_image(images, slot);
+ let buf = image.as_slice();
+
let mut copy = vec![0u8; buf.len()];
+ let offset = slots[slot].base_off;
flash.read(offset, &mut copy).unwrap();
if buf != ©[..] {
for i in 0 .. buf.len() {
if buf[i] != copy[i] {
- info!("First failure at {:#x}", offset + i);
+ info!("First failure for slot{} at {:#x} {:#x}!={:#x}",
+ slot, offset + i, buf[i], copy[i]);
break;
}
}
@@ -1153,15 +1283,13 @@
#[repr(C)]
pub struct ImageHeader {
magic: u32,
- tlv_size: u16,
- key_id: u8,
- _pad1: u8,
+ load_addr: u32,
hdr_size: u16,
- _pad2: u16,
+ _pad1: u16,
img_size: u32,
flags: u32,
ver: ImageVersion,
- _pad3: u32,
+ _pad2: u32,
}
impl AsRaw for ImageHeader {}
@@ -1178,15 +1306,15 @@
struct SlotInfo {
base_off: usize,
trailer_off: usize,
+ len: usize,
}
pub struct Images {
flash: SimFlash,
areadesc: AreaDesc,
- slot0: SlotInfo,
- slot1: SlotInfo,
- primary: Vec<u8>,
- upgrade: Vec<u8>,
+ slots: [SlotInfo; 2],
+ primaries: [Option<Vec<u8>>; 2],
+ upgrades: [Option<Vec<u8>>; 2],
total_count: Option<i32>,
align: u8,
erased_val: u8,
diff --git a/sim/src/tlv.rs b/sim/src/tlv.rs
index 79e89fd..7878dd2 100644
--- a/sim/src/tlv.rs
+++ b/sim/src/tlv.rs
@@ -10,6 +10,7 @@
use std::sync::Arc;
use pem;
+use base64;
use ring::{digest, rand, signature};
use untrusted;
use mcuboot_sys::c;
@@ -23,6 +24,16 @@
RSA2048 = 0x20,
ECDSA224 = 0x21,
ECDSA256 = 0x22,
+ ENCRSA2048 = 0x30,
+ ENCKW128 = 0x31,
+}
+
+#[allow(dead_code, non_camel_case_types)]
+pub enum TlvFlags {
+ PIC = 0x01,
+ NON_BOOTABLE = 0x02,
+ ENCRYPTED = 0x04,
+ RAM_LOAD = 0x20,
}
pub struct TlvGen {
@@ -32,6 +43,8 @@
payload: Vec<u8>,
}
+pub const AES_SEC_KEY: &[u8; 16] = b"0123456789ABCDEF";
+
impl TlvGen {
/// Construct a new tlv generator that will only contain a hash of the data.
#[allow(dead_code)]
@@ -64,6 +77,26 @@
}
}
+ #[allow(dead_code)]
+ pub fn new_enc_rsa() -> TlvGen {
+ TlvGen {
+ flags: TlvFlags::ENCRYPTED as u32,
+ kinds: vec![TlvKinds::SHA256, TlvKinds::ENCRSA2048],
+ size: 4 + 32 + 4 + 256,
+ payload: vec![],
+ }
+ }
+
+ #[allow(dead_code)]
+ pub fn new_enc_kw() -> TlvGen {
+ TlvGen {
+ flags: TlvFlags::ENCRYPTED as u32,
+ kinds: vec![TlvKinds::SHA256, TlvKinds::ENCKW128],
+ size: 4 + 32 + 4 + 24,
+ payload: vec![],
+ }
+ }
+
/// Retrieve the header flags for this configuration. This can be called at any time.
pub fn get_flags(&self) -> u32 {
self.flags
@@ -212,6 +245,41 @@
result.extend(der);
}
+ if self.kinds.contains(&TlvKinds::ENCRSA2048) {
+ let key_bytes = pem::parse(include_bytes!("../../enc-rsa2048-pub.pem")
+ .as_ref()).unwrap();
+ assert_eq!(key_bytes.tag, "PUBLIC KEY");
+
+ let encbuf = match c::rsa_oaep_encrypt(&key_bytes.contents, AES_SEC_KEY) {
+ Ok(v) => v,
+ Err(_) => panic!("Failed to encrypt secret key"),
+ };
+
+ assert!(encbuf.len() == 256);
+ result.push(TlvKinds::ENCRSA2048 as u8);
+ result.push(0);
+ result.push(0);
+ result.push(1);
+ result.extend_from_slice(&encbuf);
+ }
+
+ if self.kinds.contains(&TlvKinds::ENCKW128) {
+ let key_bytes = base64::decode(
+ include_str!("../../enc-aes128kw.b64").trim()).unwrap();
+
+ let encbuf = match c::kw_encrypt(&key_bytes, AES_SEC_KEY) {
+ Ok(v) => v,
+ Err(_) => panic!("Failed to encrypt secret key"),
+ };
+
+ assert!(encbuf.len() == 24);
+ result.push(TlvKinds::ENCKW128 as u8);
+ result.push(0);
+ result.push(24);
+ result.push(0);
+ result.extend_from_slice(&encbuf);
+ }
+
result
}
}