sim: PSA Crypto ECDSA enablement

This commit enables ECDSA signature verification using
PSA Crypto API.

Signed-off-by: Roland Mikhel <roland.mikhel@arm.com>
Change-Id: I33f559ecdd59b1ce41c6a2d5f315212300d585e3
diff --git a/root-ec-p384-pkcs8.pem b/root-ec-p384-pkcs8.pem
new file mode 100644
index 0000000..4d4894c
--- /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 0000000..916c800
--- /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 1689a3c..7cef823 100644
--- a/sim/Cargo.toml
+++ b/sim/Cargo.toml
@@ -11,6 +11,8 @@
 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 @@
 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 f4f2ace..ab97bbf 100644
--- a/sim/mcuboot-sys/Cargo.toml
+++ b/sim/mcuboot-sys/Cargo.toml
@@ -24,6 +24,12 @@
 # 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 88316ef..4221292 100644
--- a/sim/mcuboot-sys/build.rs
+++ b/sim/mcuboot-sys/build.rs
@@ -15,6 +15,8 @@
     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 @@
         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 @@
         conf.conf.define("MBEDTLS_CONFIG_FILE", Some("<config-kw.h>"));
     } else if enc_aes256_x25519 {
         conf.conf.define("MBEDTLS_CONFIG_FILE", Some("<config-ed25519.h>"));
+    } else if sig_ecdsa_psa {
+        conf.conf.define("MBEDTLS_CONFIG_FILE", Some("<config-ec-psa.h>"));
     }
 
     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 0000000..709330f
--- /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 f9325be..82a746b 100644
--- a/sim/mcuboot-sys/csupport/keys.c
+++ b/sim/mcuboot-sys/csupport/keys.c
@@ -106,8 +106,10 @@
 };
 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 @@
     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 5463173..d8dd068 100644
--- a/sim/src/caps.rs
+++ b/sim/src/caps.rs
@@ -29,6 +29,7 @@
     RamLoad              = (1 << 16),
     DirectXip            = (1 << 17),
     HwRollbackProtection = (1 << 18),
+    EcdsaP384            = (1 << 19),
 }
 
 impl Caps {
@@ -39,7 +40,7 @@
 
     /// 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 e3a0cc1..3d86436 100644
--- a/sim/src/ecdsa_pub_key-rs.txt
+++ b/sim/src/ecdsa_pub_key-rs.txt
@@ -12,3 +12,21 @@
     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 54e4f31..632dfa5 100644
--- a/sim/src/image.rs
+++ b/sim/src/image.rs
@@ -1999,7 +1999,7 @@
             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 5541f11..9a7e14f 100644
--- a/sim/src/tlv.rs
+++ b/sim/src/tlv.rs
@@ -29,6 +29,7 @@
     EcdsaKeyPair,
     ECDSA_P256_SHA256_ASN1_SIGNING,
     Ed25519KeyPair,
+    ECDSA_P384_SHA384_ASN1_SIGNING,
 };
 use aes::{
     Aes128,
@@ -385,12 +386,17 @@
             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 @@
 
         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 @@
             result.write_u16::<LittleEndian>(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();