diff --git a/root-ec-p384-pkcs8.pem b/root-ec-p384-pkcs8.pem new file mode 100644 index 00000000..4d4894cc --- /dev/null +++ b/root-ec-p384-pkcs8.pem @@ -0,0 +1,6 @@ +-----BEGIN PRIVATE KEY----- +MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDC8ZQWjooCCaLQJ9DJN +KMyPoUoFcqGluXGu13Zf526RX6TdRhnkExtL1T7fC13n32ChZANiAAQMdsqucjql +6PDU8Ra1Au93oRuTYXjACSZ7O0Cc7kmF4MlP5/K6l2zzgmUULPUMczNNMueb00LM +lVrl4vX0bkXg7SA1XK9SNYHU3JzjniI++z8iENpwAzetqPJI/jpgaaU= +-----END PRIVATE KEY----- diff --git a/root-ec-p384.pem b/root-ec-p384.pem new file mode 100644 index 00000000..916c8003 --- /dev/null +++ b/root-ec-p384.pem @@ -0,0 +1,6 @@ +-----BEGIN EC PRIVATE KEY----- +MIGkAgEBBDC8ZQWjooCCaLQJ9DJNKMyPoUoFcqGluXGu13Zf526RX6TdRhnkExtL +1T7fC13n32CgBwYFK4EEACKhZANiAAQMdsqucjql6PDU8Ra1Au93oRuTYXjACSZ7 +O0Cc7kmF4MlP5/K6l2zzgmUULPUMczNNMueb00LMlVrl4vX0bkXg7SA1XK9SNYHU +3JzjniI++z8iENpwAzetqPJI/jpgaaU= +-----END EC PRIVATE KEY----- diff --git a/sim/Cargo.toml b/sim/Cargo.toml index 1689a3c4..7cef823d 100644 --- a/sim/Cargo.toml +++ b/sim/Cargo.toml @@ -11,6 +11,8 @@ sig-rsa = ["mcuboot-sys/sig-rsa"] sig-rsa3072 = ["mcuboot-sys/sig-rsa3072"] sig-ecdsa = ["mcuboot-sys/sig-ecdsa"] sig-ecdsa-mbedtls = ["mcuboot-sys/sig-ecdsa-mbedtls"] +sig-ecdsa-psa = ["mcuboot-sys/sig-ecdsa-psa", "mcuboot-sys/psa-crypto-api"] +sig-p384 = ["mcuboot-sys/sig-p384"] sig-ed25519 = ["mcuboot-sys/sig-ed25519"] overwrite-only = ["mcuboot-sys/overwrite-only"] swap-move = ["mcuboot-sys/swap-move"] @@ -31,7 +33,6 @@ direct-xip = ["mcuboot-sys/direct-xip"] downgrade-prevention = ["mcuboot-sys/downgrade-prevention"] max-align-32 = ["mcuboot-sys/max-align-32"] hw-rollback-protection = ["mcuboot-sys/hw-rollback-protection"] -psa-crypto-api = ["mcuboot-sys/psa-crypto-api"] [dependencies] byteorder = "1.4" diff --git a/sim/mcuboot-sys/Cargo.toml b/sim/mcuboot-sys/Cargo.toml index f4f2aceb..ab97bbfe 100644 --- a/sim/mcuboot-sys/Cargo.toml +++ b/sim/mcuboot-sys/Cargo.toml @@ -24,6 +24,12 @@ sig-ecdsa = [] # Verify ECDSA (secp256r1) signatures using mbed TLS sig-ecdsa-mbedtls = [] +# Verify ECDSA (p256 or p384) signatures using PSA Crypto API +sig-ecdsa-psa = [] + +# Enable P384 Curve support (instead of P256) for PSA Crypto +sig-p384 = [] + # Verify ED25519 signatures. sig-ed25519 = [] diff --git a/sim/mcuboot-sys/build.rs b/sim/mcuboot-sys/build.rs index 88316eff..4221292f 100644 --- a/sim/mcuboot-sys/build.rs +++ b/sim/mcuboot-sys/build.rs @@ -15,6 +15,8 @@ fn main() { let sig_rsa3072 = env::var("CARGO_FEATURE_SIG_RSA3072").is_ok(); let sig_ecdsa = env::var("CARGO_FEATURE_SIG_ECDSA").is_ok(); let sig_ecdsa_mbedtls = env::var("CARGO_FEATURE_SIG_ECDSA_MBEDTLS").is_ok(); + let sig_ecdsa_psa = env::var("CARGO_FEATURE_SIG_ECDSA_PSA").is_ok(); + let sig_p384 = env::var("CARGO_FEATURE_SIG_P384").is_ok(); let sig_ed25519 = env::var("CARGO_FEATURE_SIG_ED25519").is_ok(); let overwrite_only = env::var("CARGO_FEATURE_OVERWRITE_ONLY").is_ok(); let swap_move = env::var("CARGO_FEATURE_SWAP_MOVE").is_ok(); @@ -205,6 +207,24 @@ fn main() { conf.file("../../ext/mbedtls/library/ecp_curves.c"); conf.file("../../ext/mbedtls/library/platform.c"); conf.file("../../ext/mbedtls/library/platform_util.c"); + } else if sig_ecdsa_psa { + conf.conf.include("../../ext/mbedtls/include"); + + if sig_p384 { + conf.conf.define("MCUBOOT_SIGN_EC384", None); + conf.file("../../ext/mbedtls/library/sha512.c"); + } else { + conf.conf.define("MCUBOOT_SIGN_EC256", None); + conf.file("../../ext/mbedtls/library/sha256.c"); + } + + conf.file("csupport/keys.c"); + conf.file("../../ext/mbedtls/library/asn1parse.c"); + conf.file("../../ext/mbedtls/library/bignum.c"); + conf.file("../../ext/mbedtls/library/ecp.c"); + conf.file("../../ext/mbedtls/library/ecp_curves.c"); + conf.file("../../ext/mbedtls/library/platform.c"); + conf.file("../../ext/mbedtls/library/platform_util.c"); } else if sig_ed25519 { conf.conf.define("MCUBOOT_SIGN_ED25519", None); conf.conf.define("MCUBOOT_USE_TINYCRYPT", None); @@ -421,17 +441,19 @@ fn main() { conf.conf.define("MBEDTLS_CONFIG_FILE", Some("")); } else if enc_aes256_x25519 { conf.conf.define("MBEDTLS_CONFIG_FILE", Some("")); + } else if sig_ecdsa_psa { + conf.conf.define("MBEDTLS_CONFIG_FILE", Some("")); } conf.file("../../boot/bootutil/src/image_validate.c"); if sig_rsa || sig_rsa3072 { conf.file("../../boot/bootutil/src/image_rsa.c"); - } else if sig_ecdsa || sig_ecdsa_mbedtls { - conf.conf.include("../../ext/mbedtls/include"); + } else if sig_ecdsa || sig_ecdsa_mbedtls || sig_ecdsa_psa { conf.file("../../boot/bootutil/src/image_ecdsa.c"); } else if sig_ed25519 { conf.file("../../boot/bootutil/src/image_ed25519.c"); } + conf.file("../../boot/bootutil/src/loader.c"); conf.file("../../boot/bootutil/src/swap_misc.c"); conf.file("../../boot/bootutil/src/swap_scratch.c"); diff --git a/sim/mcuboot-sys/csupport/config-ec-psa.h b/sim/mcuboot-sys/csupport/config-ec-psa.h new file mode 100644 index 00000000..709330ff --- /dev/null +++ b/sim/mcuboot-sys/csupport/config-ec-psa.h @@ -0,0 +1,37 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2023 Arm Limited + */ + +#ifndef MCUBOOT_PSA_CRYPTO_CONFIG_ECDSA +#define MCUBOOT_PSA_CRYPTO_CONFIG_ECDSA + +#if defined(MCUBOOT_USE_PSA_CRYPTO) +#include "config-add-psa-crypto.h" +#endif + +#define MBEDTLS_ECP_C +#define MBEDTLS_ECP_NIST_OPTIM +#define MBEDTLS_ECDSA_C + +/* mbed TLS modules */ +#define MBEDTLS_ASN1_PARSE_C +#define MBEDTLS_ASN1_WRITE_C +#define MBEDTLS_AES_C +#define MBEDTLS_BIGNUM_C +#define MBEDTLS_MD_C +#define MBEDTLS_OID_C +#if defined(MCUBOOT_SIGN_EC384) +#define MBEDTLS_SHA384_C +#define MBEDTLS_SHA512_C +#define MBEDTLS_ECP_DP_SECP384R1_ENABLED +#else +#define MBEDTLS_SHA256_C +#define MBEDTLS_SHA224_C +#define MBEDTLS_ECP_DP_SECP256R1_ENABLED +#endif /* MCUBOOT_SIGN_EC384 */ + +#include "mbedtls/check_config.h" + +#endif /* MCUBOOT_PSA_CRYPTO_CONFIG_ECDSA */ diff --git a/sim/mcuboot-sys/csupport/keys.c b/sim/mcuboot-sys/csupport/keys.c index f9325be4..82a746ba 100644 --- a/sim/mcuboot-sys/csupport/keys.c +++ b/sim/mcuboot-sys/csupport/keys.c @@ -106,8 +106,10 @@ const unsigned char root_pub_der[] = { }; const unsigned int root_pub_der_len = 398; #endif -#elif defined(MCUBOOT_SIGN_EC256) +#elif defined(MCUBOOT_SIGN_EC256) || \ + defined(MCUBOOT_SIGN_EC384) #define HAVE_KEYS +#ifndef MCUBOOT_SIGN_EC384 const unsigned char root_pub_der[] = { 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, @@ -122,6 +124,26 @@ const unsigned char root_pub_der[] = { 0x8b, 0x68, 0x34, 0xcc, 0x3a, 0x6a, 0xfc, 0x53, 0x8e, 0xfa, 0xc1, }; const unsigned int root_pub_der_len = 91; +#else /* MCUBOOT_SIGN_EC384 */ +const unsigned char root_pub_der[] = { + 0x30, 0x76, 0x30, 0x10, 0x06, 0x07, 0x2a, 0x86, + 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, 0x2b, + 0x81, 0x04, 0x00, 0x22, 0x03, 0x62, 0x00, 0x04, + 0x0c, 0x76, 0xca, 0xae, 0x72, 0x3a, 0xa5, 0xe8, + 0xf0, 0xd4, 0xf1, 0x16, 0xb5, 0x02, 0xef, 0x77, + 0xa1, 0x1b, 0x93, 0x61, 0x78, 0xc0, 0x09, 0x26, + 0x7b, 0x3b, 0x40, 0x9c, 0xee, 0x49, 0x85, 0xe0, + 0xc9, 0x4f, 0xe7, 0xf2, 0xba, 0x97, 0x6c, 0xf3, + 0x82, 0x65, 0x14, 0x2c, 0xf5, 0x0c, 0x73, 0x33, + 0x4d, 0x32, 0xe7, 0x9b, 0xd3, 0x42, 0xcc, 0x95, + 0x5a, 0xe5, 0xe2, 0xf5, 0xf4, 0x6e, 0x45, 0xe0, + 0xed, 0x20, 0x35, 0x5c, 0xaf, 0x52, 0x35, 0x81, + 0xd4, 0xdc, 0x9c, 0xe3, 0x9e, 0x22, 0x3e, 0xfb, + 0x3f, 0x22, 0x10, 0xda, 0x70, 0x03, 0x37, 0xad, + 0xa8, 0xf2, 0x48, 0xfe, 0x3a, 0x60, 0x69, 0xa5, +}; +const unsigned int root_pub_der_len = 120; +#endif /* MCUBOOT_SIGN_EC384 */ #elif defined(MCUBOOT_SIGN_ED25519) #define HAVE_KEYS const unsigned char root_pub_der[] = { diff --git a/sim/src/caps.rs b/sim/src/caps.rs index 54631730..d8dd068e 100644 --- a/sim/src/caps.rs +++ b/sim/src/caps.rs @@ -29,6 +29,7 @@ pub enum Caps { RamLoad = (1 << 16), DirectXip = (1 << 17), HwRollbackProtection = (1 << 18), + EcdsaP384 = (1 << 19), } impl Caps { @@ -39,7 +40,7 @@ impl Caps { /// Does this build have ECDSA of some type enabled for signatures. pub fn has_ecdsa() -> bool { - Caps::EcdsaP256.present() + Caps::EcdsaP256.present() || Caps::EcdsaP384.present() } /// Query for the number of images that have been configured into this diff --git a/sim/src/ecdsa_pub_key-rs.txt b/sim/src/ecdsa_pub_key-rs.txt index e3a0cc1a..3d864367 100644 --- a/sim/src/ecdsa_pub_key-rs.txt +++ b/sim/src/ecdsa_pub_key-rs.txt @@ -12,3 +12,21 @@ static ECDSA256_PUB_KEY: &[u8] = &[ 0x8b, 0x68, 0x34, 0xcc, 0x3a, 0x6a, 0xfc, 0x53, 0x8e, 0xfa, 0xc1, ]; + +static ECDSAP384_PUB_KEY: &[u8] = &[ + 0x30, 0x76, 0x30, 0x10, 0x06, 0x07, 0x2a, 0x86, + 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, 0x2b, + 0x81, 0x04, 0x00, 0x22, 0x03, 0x62, 0x00, 0x04, + 0x0c, 0x76, 0xca, 0xae, 0x72, 0x3a, 0xa5, 0xe8, + 0xf0, 0xd4, 0xf1, 0x16, 0xb5, 0x02, 0xef, 0x77, + 0xa1, 0x1b, 0x93, 0x61, 0x78, 0xc0, 0x09, 0x26, + 0x7b, 0x3b, 0x40, 0x9c, 0xee, 0x49, 0x85, 0xe0, + 0xc9, 0x4f, 0xe7, 0xf2, 0xba, 0x97, 0x6c, 0xf3, + 0x82, 0x65, 0x14, 0x2c, 0xf5, 0x0c, 0x73, 0x33, + 0x4d, 0x32, 0xe7, 0x9b, 0xd3, 0x42, 0xcc, 0x95, + 0x5a, 0xe5, 0xe2, 0xf5, 0xf4, 0x6e, 0x45, 0xe0, + 0xed, 0x20, 0x35, 0x5c, 0xaf, 0x52, 0x35, 0x81, + 0xd4, 0xdc, 0x9c, 0xe3, 0x9e, 0x22, 0x3e, 0xfb, + 0x3f, 0x22, 0x10, 0xda, 0x70, 0x03, 0x37, 0xad, + 0xa8, 0xf2, 0x48, 0xfe, 0x3a, 0x60, 0x69, 0xa5, +]; diff --git a/sim/src/image.rs b/sim/src/image.rs index 54e4f31b..632dfa56 100644 --- a/sim/src/image.rs +++ b/sim/src/image.rs @@ -1999,7 +1999,7 @@ fn make_tlv() -> TlvGen { TlvGen::new_rsa_pss() } else if Caps::RSA3072.present() { TlvGen::new_rsa3072_pss() - } else if Caps::EcdsaP256.present() { + } else if Caps::EcdsaP256.present() || Caps::EcdsaP384.present() { TlvGen::new_ecdsa() } else if Caps::Ed25519.present() { TlvGen::new_ed25519() diff --git a/sim/src/tlv.rs b/sim/src/tlv.rs index 5541f112..9a7e14f9 100644 --- a/sim/src/tlv.rs +++ b/sim/src/tlv.rs @@ -29,6 +29,7 @@ use ring::signature::{ EcdsaKeyPair, ECDSA_P256_SHA256_ASN1_SIGNING, Ed25519KeyPair, + ECDSA_P384_SHA384_ASN1_SIGNING, }; use aes::{ Aes128, @@ -385,12 +386,17 @@ impl ManifestGen for TlvGen { estimate += 4 + 64; // ED25519 signature. } if self.kinds.contains(&TlvKinds::ECDSASIG) { - estimate += 4 + 32; // keyhash - - // ECDSA signatures are encoded as ASN.1 with the x and y values stored as signed - // integers. As such, the size can vary by 2 bytes, if the 256-bit value has the high - // bit, it takes an extra 0 byte to avoid it being seen as a negative number. - estimate += 4 + 72; // ECDSA256 (varies) + // ECDSA signatures are encoded as ASN.1 with the x and y values + // stored as signed integers. As such, the size can vary by 2 bytes, + // if for example the 256-bit value has the high bit, it takes an + // extra 0 byte to avoid it being seen as a negative number. + if cfg!(feature = "use-p384-curve") { + estimate += 4 + 48; // keyhash + estimate += 4 + 104; // ECDSA384 (varies) + } else { + estimate += 4 + 32; // keyhash + estimate += 4 + 72; // ECDSA256 (varies) + } } // Estimate encryption. @@ -559,11 +565,19 @@ impl ManifestGen for TlvGen { if self.kinds.contains(&TlvKinds::ECDSASIG) { let rng = rand::SystemRandom::new(); - let keyhash = digest::digest(&digest::SHA256, ECDSA256_PUB_KEY); - let key_bytes = pem::parse(include_bytes!("../../root-ec-p256-pkcs8.pem").as_ref()).unwrap(); - let sign_algo = &ECDSA_P256_SHA256_ASN1_SIGNING; - let key_pair = EcdsaKeyPair::from_pkcs8(sign_algo, &key_bytes.contents).unwrap(); - let signature = key_pair.sign(&rng,&sig_payload).unwrap(); + let (signature, keyhash) = if cfg!(feature = "use-p384-curve") { + let keyhash = digest::digest(&digest::SHA384, ECDSAP384_PUB_KEY); + let key_bytes = pem::parse(include_bytes!("../../root-ec-p384-pkcs8.pem").as_ref()).unwrap(); + let sign_algo = &ECDSA_P384_SHA384_ASN1_SIGNING; + let key_pair = EcdsaKeyPair::from_pkcs8(sign_algo, &key_bytes.contents).unwrap(); + (key_pair.sign(&rng, &sig_payload).unwrap(), keyhash) + } else { + let keyhash = digest::digest(&digest::SHA256, ECDSA256_PUB_KEY); + let key_bytes = pem::parse(include_bytes!("../../root-ec-p256-pkcs8.pem").as_ref()).unwrap(); + let sign_algo = &ECDSA_P256_SHA256_ASN1_SIGNING; + let key_pair = EcdsaKeyPair::from_pkcs8(sign_algo, &key_bytes.contents).unwrap(); + (key_pair.sign(&rng, &sig_payload).unwrap(), keyhash) + }; // Write public key let keyhash_slice = keyhash.as_ref(); @@ -578,6 +592,7 @@ impl ManifestGen for TlvGen { result.write_u16::(signature.len() as u16).unwrap(); result.extend_from_slice(&signature); } + if self.kinds.contains(&TlvKinds::ED25519) { let keyhash = digest::digest(&digest::SHA256, ED25519_PUB_KEY); let keyhash = keyhash.as_ref();