diff --git a/sim/Cargo.toml b/sim/Cargo.toml index 38f1b3751..1689a3c4b 100644 --- a/sim/Cargo.toml +++ b/sim/Cargo.toml @@ -31,6 +31,7 @@ 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 c1403411b..f4f2aceb3 100644 --- a/sim/mcuboot-sys/Cargo.toml +++ b/sim/mcuboot-sys/Cargo.toml @@ -86,6 +86,9 @@ max-align-32 = [] # Enable hardware rollback protection hw-rollback-protection = [] +# Enable the PSA Crypto APIs where supported for cryptography related operations. +psa-crypto-api = [] + [build-dependencies] cc = "1.0.25" diff --git a/sim/mcuboot-sys/build.rs b/sim/mcuboot-sys/build.rs index a01844e42..88316effe 100644 --- a/sim/mcuboot-sys/build.rs +++ b/sim/mcuboot-sys/build.rs @@ -10,6 +10,7 @@ use std::path::{Path, PathBuf}; fn main() { // Feature flags. + let psa_crypto_api = env::var("CARGO_FEATURE_PSA_CRYPTO_API").is_ok(); let sig_rsa = env::var("CARGO_FEATURE_SIG_RSA").is_ok(); let sig_rsa3072 = env::var("CARGO_FEATURE_SIG_RSA3072").is_ok(); let sig_ecdsa = env::var("CARGO_FEATURE_SIG_ECDSA").is_ok(); @@ -87,6 +88,66 @@ fn main() { panic!("mcuboot does not support more than one sig type at the same time"); } + if psa_crypto_api { + if sig_ecdsa || enc_ec256 || enc_x25519 || + enc_aes256_ec256 || sig_ecdsa_mbedtls || enc_aes256_x25519 || + enc_kw || enc_aes256_kw { + conf.file("csupport/psa_crypto_init_stub.c"); + } else { + conf.conf.define("MCUBOOT_USE_PSA_CRYPTO", None); + conf.file("../../ext/mbedtls/library/aes.c"); + conf.file("../../ext/mbedtls/library/aesni.c"); + conf.file("../../ext/mbedtls/library/aria.c"); + conf.file("../../ext/mbedtls/library/asn1write.c"); + conf.file("../../ext/mbedtls/library/base64.c"); + conf.file("../../ext/mbedtls/library/camellia.c"); + conf.file("../../ext/mbedtls/library/ccm.c"); + conf.file("../../ext/mbedtls/library/chacha20.c"); + conf.file("../../ext/mbedtls/library/chachapoly.c"); + conf.file("../../ext/mbedtls/library/cipher.c"); + conf.file("../../ext/mbedtls/library/cipher_wrap.c"); + conf.file("../../ext/mbedtls/library/ctr_drbg.c"); + conf.file("../../ext/mbedtls/library/des.c"); + conf.file("../../ext/mbedtls/library/ecdsa.c"); + conf.file("../../ext/mbedtls/library/ecp.c"); + conf.file("../../ext/mbedtls/library/ecp_curves.c"); + conf.file("../../ext/mbedtls/library/entropy.c"); + conf.file("../../ext/mbedtls/library/entropy_poll.c"); + conf.file("../../ext/mbedtls/library/gcm.c"); + conf.file("../../ext/mbedtls/library/md5.c"); + conf.file("../../ext/mbedtls/library/nist_kw.c"); + conf.file("../../ext/mbedtls/library/oid.c"); + conf.file("../../ext/mbedtls/library/pem.c"); + conf.file("../../ext/mbedtls/library/pk.c"); + conf.file("../../ext/mbedtls/library/pkcs5.c"); + conf.file("../../ext/mbedtls/library/pkcs12.c"); + conf.file("../../ext/mbedtls/library/pkparse.c"); + conf.file("../../ext/mbedtls/library/pk_wrap.c"); + conf.file("../../ext/mbedtls/library/pkwrite.c"); + conf.file("../../ext/mbedtls/library/poly1305.c"); + conf.file("../../ext/mbedtls/library/psa_crypto.c"); + conf.file("../../ext/mbedtls/library/psa_crypto_cipher.c"); + conf.file("../../ext/mbedtls/library/psa_crypto_client.c"); + conf.file("../../ext/mbedtls/library/psa_crypto_driver_wrappers.c"); + conf.file("../../ext/mbedtls/library/psa_crypto_ecp.c"); + conf.file("../../ext/mbedtls/library/psa_crypto_hash.c"); + conf.file("../../ext/mbedtls/library/psa_crypto_mac.c"); + conf.file("../../ext/mbedtls/library/psa_crypto_rsa.c"); + conf.file("../../ext/mbedtls/library/psa_crypto_slot_management.c"); + conf.file("../../ext/mbedtls/library/psa_crypto_storage.c"); + conf.file("../../ext/mbedtls/library/psa_its_file.c"); + conf.file("../../ext/mbedtls/library/ripemd160.c"); + conf.file("../../ext/mbedtls/library/rsa_alt_helpers.c"); + conf.file("../../ext/mbedtls/library/sha1.c"); + conf.file("../../ext/mbedtls/library/sha512.c"); + conf.file("../../ext/mbedtls/tests/src/random.c"); + conf.conf.include("../../ext/mbedtls/library"); + } + + conf.conf.include("../../ext/mbedtls/tests/include/"); + conf.file("../../ext/mbedtls/tests/src/fake_external_rng_for_test.c"); + } + if sig_rsa || sig_rsa3072 { conf.conf.define("MCUBOOT_SIGN_RSA", None); // The Kconfig style defines must be added here as well because diff --git a/sim/mcuboot-sys/csupport/config-add-psa-crypto.h b/sim/mcuboot-sys/csupport/config-add-psa-crypto.h new file mode 100644 index 000000000..d825be138 --- /dev/null +++ b/sim/mcuboot-sys/csupport/config-add-psa-crypto.h @@ -0,0 +1,47 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2023 Arm Limited + */ + +#ifndef MCUBOOT_MBEDTLS_CONFIG_ADD_PSA_CRYPTO_H +#define MCUBOOT_MBEDTLS_CONFIG_ADD_PSA_CRYPTO_H + +#include "mbedtls/build_info.h" + +/* Enable PSA Crypto Core without support for the permanent storage + * Don't define MBEDTLS_PSA_CRYPTO_STORAGE_C to make sure that support + * for permanent keys is not enabled, as it is not usually required during boot + */ +#define MBEDTLS_PSA_CRYPTO_C +#define MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG + +#if defined(MCUBOOT_ENCRYPT_RSA) || defined(MCUBOOT_SIGN_RSA) + #define MBEDTLS_PK_C + #define MBEDTLS_CTR_DRBG_C + #define MBEDTLS_CIPHER_C + #define MBEDTLS_ENTROPY_C + #define MBEDTLS_PK_PARSE_C + #define MBEDTLS_PK_WRITE_C +#endif /* MCUBOOT_ENCRYPT_RSA || MCUBOOT_SIGN_RSA */ + +#if defined(MCUBOOT_ENCRYPT_EC256) || defined(MCUBOOT_ENCRYPT_X25519) + #define MBEDTLS_PLATFORM_FREE_MACRO free + #define MBEDTLS_PLATFORM_CALLOC_MACRO calloc +#endif /* MCUBOOT_ENCRYPT_EC256 || MCUBOOT_ENCRYPT_X25519 */ + +#if !defined(MCUBOOT_ENCRYPT_X25519) + #define MBEDTLS_PSA_BUILTIN_CIPHER 1 +#endif /* MCUBOOT_ENCRYPT_X25519 */ + +#if defined(MCUBOOT_ENCRYPT_KW) + #define MBEDTLS_PSA_CRYPTO_CONFIG + #define MBEDTLS_POLY1305_C +#endif /* MCUBOOT_ENCRYPT_KW */ + +#if MBEDTLS_VERSION_NUMBER == 0x03000000 +/* This PSA define is available only with more recent versions of 3.x */ +#define PSA_KEY_ID_NULL ((psa_key_id_t)0) // not overly happy with this being here +#endif /* MBEDTLS_VERSION_NUMBER == 0x03000000 */ + +#endif /* MCUBOOT_MBEDTLS_CONFIG_ADD_PSA_CRYPTO_H */ diff --git a/sim/mcuboot-sys/csupport/config-rsa-kw.h b/sim/mcuboot-sys/csupport/config-rsa-kw.h index bc3da7d81..1f1f4178a 100644 --- a/sim/mcuboot-sys/csupport/config-rsa-kw.h +++ b/sim/mcuboot-sys/csupport/config-rsa-kw.h @@ -1,7 +1,7 @@ /* * Minimal configuration for using TLS in the bootloader * - * Copyright (C) 2006-2021, ARM Limited, All Rights Reserved + * Copyright (C) 2006-2023, ARM Limited, All Rights Reserved * Copyright (C) 2016, Linaro Ltd * SPDX-License-Identifier: Apache-2.0 * @@ -29,6 +29,10 @@ #ifndef MCUBOOT_MBEDTLS_CONFIG_RSA_KW #define MCUBOOT_MBEDTLS_CONFIG_RSA_KW +#if defined(MCUBOOT_USE_PSA_CRYPTO) +#include "config-add-psa-crypto.h" +#endif /* defined(MCUBOOT_USE_PSA_CRYPTO) */ + #ifdef CONFIG_MCUBOOT_SERIAL /* Mcuboot uses mbedts-base64 for serial protocol encoding. */ #define MBEDTLS_BASE64_C diff --git a/sim/mcuboot-sys/csupport/config-rsa.h b/sim/mcuboot-sys/csupport/config-rsa.h index 055242049..c7767028b 100644 --- a/sim/mcuboot-sys/csupport/config-rsa.h +++ b/sim/mcuboot-sys/csupport/config-rsa.h @@ -1,7 +1,7 @@ /* * Minimal configuration for using TLS in the bootloader * - * Copyright (C) 2006-2021, ARM Limited, All Rights Reserved + * Copyright (C) 2006-2023, ARM Limited, All Rights Reserved * Copyright (C) 2016, Linaro Ltd * SPDX-License-Identifier: Apache-2.0 * @@ -29,6 +29,10 @@ #ifndef MCUBOOT_MBEDTLS_CONFIG_RSA #define MCUBOOT_MBEDTLS_CONFIG_RSA +#if defined(MCUBOOT_USE_PSA_CRYPTO) +#include "config-add-psa-crypto.h" +#endif + #ifdef CONFIG_MCUBOOT_SERIAL /* Mcuboot uses mbedts-base64 for serial protocol encoding. */ #define MBEDTLS_BASE64_C @@ -67,9 +71,6 @@ #define MBEDTLS_SHA224_C #define MBEDTLS_AES_C -/* Save RAM by adjusting to our exact needs */ -#define MBEDTLS_ECP_MAX_BITS 2048 - #if (CONFIG_BOOT_SIGNATURE_TYPE_RSA_LEN == 3072) #define MBEDTLS_MPI_MAX_SIZE 384 #else diff --git a/sim/mcuboot-sys/csupport/psa_crypto_init_stub.c b/sim/mcuboot-sys/csupport/psa_crypto_init_stub.c new file mode 100644 index 000000000..1362ac3fa --- /dev/null +++ b/sim/mcuboot-sys/csupport/psa_crypto_init_stub.c @@ -0,0 +1,22 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2023 Arm Limited + */ + +/* This file, and the methods within are required when PSA Crypto API is enabled + * (--features psa-crypto-api), but the selected combination of features does + * not rely on any PSA Crypto APIs, and will not be adding any of them to the build. + */ + +#include + +int psa_crypto_init() +{ + BOOT_LOG_SIM("psa_crypto_init() is being stubbed.\n"); + return 0; +} + +void mbedtls_test_enable_insecure_external_rng(){ + BOOT_LOG_SIM("mbedtls_test_enable_insecure_external_rng() is being stubbed.\n"); +} diff --git a/sim/mcuboot-sys/src/c.rs b/sim/mcuboot-sys/src/c.rs index 5d2c8ca1c..483ca8fb0 100644 --- a/sim/mcuboot-sys/src/c.rs +++ b/sim/mcuboot-sys/src/c.rs @@ -10,6 +10,9 @@ use crate::area::AreaDesc; use simflash::SimMultiFlash; use crate::api; +#[allow(unused)] +use std::sync::Once; + /// The result of an invocation of `boot_go`. This is intentionally opaque so that we can provide /// accessors for everything we need from this. #[derive(Debug)] @@ -66,6 +69,8 @@ impl BootGoResult { pub fn boot_go(multiflash: &mut SimMultiFlash, areadesc: &AreaDesc, counter: Option<&mut i32>, image_index: Option, catch_asserts: bool) -> BootGoResult { + init_crypto(); + for (&dev_id, flash) in multiflash.iter_mut() { api::set_flash(dev_id, flash); } @@ -183,5 +188,38 @@ mod raw { pub fn kw_encrypt_(kek: *const u8, seckey: *const u8, encbuf: *mut u8) -> libc::c_int; + + #[allow(unused)] + pub fn psa_crypto_init() -> u32; + + #[allow(unused)] + pub fn mbedtls_test_enable_insecure_external_rng(); } } + +#[allow(unused)] +static PSA_INIT_SYNC: Once = Once::new(); + +#[allow(unused)] +static MBEDTLS_EXTERNAL_RNG_ENABLE_SYNC: Once = Once::new(); + +#[cfg(feature = "psa-crypto-api")] +fn init_crypto() { + PSA_INIT_SYNC.call_once(|| { + assert_eq!(unsafe { raw::psa_crypto_init() }, 0); + }); + + /* The PSA APIs require properly initialisation of the entropy subsystem + * The configuration adds the option MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG when the + * psa-crypto-api feature is enabled. As a result the tests use the implementation + * of the test external rng that needs to be initialised before being able to use it + */ + MBEDTLS_EXTERNAL_RNG_ENABLE_SYNC.call_once(|| { + unsafe { raw::mbedtls_test_enable_insecure_external_rng() } + }); +} + +#[cfg(not(feature = "psa-crypto-api"))] +fn init_crypto() { + // When the feature is not enabled, the init is just empty +}