Skip to content

Commit

Permalink
[nrf noup] bootutil: Add support for KMU stored ED25519 signature key
Browse files Browse the repository at this point in the history
The commit adds verification of image using keys stored in KMU.

Signed-off-by: Dominik Ermel <[email protected]>
(cherry picked from commit 1dbca8f)
  • Loading branch information
de-nordic authored and rlubos committed Oct 24, 2024
1 parent d5aa215 commit 40543f1
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 6 deletions.
51 changes: 51 additions & 0 deletions boot/bootutil/src/ed25519_psa.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,28 @@

#include <psa/crypto.h>
#include <psa/crypto_types.h>
#if defined(CONFIG_BOOT_SIGNATURE_USING_KMU)
#include <cracen_psa_kmu.h>
#endif

BOOT_LOG_MODULE_DECLARE(ed25519_psa);

#define SHA512_DIGEST_LENGTH 64
#define EDDSA_KEY_LENGTH 32
#define EDDSA_SIGNAGURE_LENGTH 64

#if defined(CONFIG_BOOT_SIGNATURE_USING_KMU)
/* List of KMU stored key ids available for MCUboot */
#define MAKE_PSA_KMU_KEY_ID(id) PSA_KEY_HANDLE_FROM_CRACEN_KMU_SLOT(CRACEN_KMU_KEY_USAGE_SCHEME_RAW, id)
static psa_key_id_t kmu_key_ids[3] = {
MAKE_PSA_KMU_KEY_ID(226),
MAKE_PSA_KMU_KEY_ID(228),
MAKE_PSA_KMU_KEY_ID(230)
};
#define KMU_KEY_COUNT (sizeof(kmu_key_ids)/sizeof(kmu_key_ids[0]))
#endif

#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU)
int ED25519_verify(const uint8_t *message, size_t message_len,
const uint8_t signature[EDDSA_SIGNAGURE_LENGTH],
const uint8_t public_key[EDDSA_KEY_LENGTH])
Expand Down Expand Up @@ -69,3 +84,39 @@ int ED25519_verify(const uint8_t *message, size_t message_len,

return ret;
}
#else
int ED25519_verify(const uint8_t *message, size_t message_len,
const uint8_t signature[EDDSA_SIGNAGURE_LENGTH],
const uint8_t public_key[EDDSA_KEY_LENGTH])
{
ARG_UNUSED(public_key);
/* Set to any error */
psa_status_t status = PSA_ERROR_BAD_STATE;
int ret = 0; /* Fail by default */

/* Initialize PSA Crypto */
status = psa_crypto_init();
if (status != PSA_SUCCESS) {
BOOT_LOG_ERR("PSA crypto init failed %d", status);
return 0;
}

status = PSA_ERROR_BAD_STATE;

for (int i = 0; i < KMU_KEY_COUNT; ++i) {
psa_key_id_t kid = kmu_key_ids[i];

status = psa_verify_message(kid, PSA_ALG_PURE_EDDSA, message,
message_len, signature,
EDDSA_SIGNAGURE_LENGTH);
if (status == PSA_SUCCESS) {
ret = 1;
break;
}

BOOT_LOG_ERR("ED25519 signature verification failed %d", status);
}

return ret;
}
#endif
19 changes: 15 additions & 4 deletions boot/bootutil/src/image_ed25519.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,16 @@
#include "bootutil/crypto/sha.h"

#define EDDSA_SIGNATURE_LENGTH 64

static const uint8_t ed25519_pubkey_oid[] = MBEDTLS_OID_ISO_IDENTIFIED_ORG "\x65\x70";
#define NUM_ED25519_BYTES 32

extern int ED25519_verify(const uint8_t *message, size_t message_len,
const uint8_t signature[EDDSA_SIGNATURE_LENGTH],
const uint8_t public_key[NUM_ED25519_BYTES]);

#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU)

static const uint8_t ed25519_pubkey_oid[] = MBEDTLS_OID_ISO_IDENTIFIED_ORG "\x65\x70";

/*
* Parse the public key used for signing.
*/
Expand Down Expand Up @@ -71,21 +73,25 @@ bootutil_import_key(uint8_t **cp, uint8_t *end)

return 0;
}
#endif

fih_ret
bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, size_t slen,
uint8_t key_id)
{
int rc;
FIH_DECLARE(fih_rc, FIH_FAILURE);
uint8_t *pubkey;
uint8_t *pubkey = NULL;
#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU)
uint8_t *end;
#endif

if (hlen != IMAGE_HASH_SIZE || slen != EDDSA_SIGNATURE_LENGTH) {
FIH_SET(fih_rc, FIH_FAILURE);
goto out;
}

#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU)
pubkey = (uint8_t *)bootutil_keys[key_id].key;
end = pubkey + *bootutil_keys[key_id].len;

Expand All @@ -94,6 +100,7 @@ bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, size_t slen,
FIH_SET(fih_rc, FIH_FAILURE);
goto out;
}
#endif

rc = ED25519_verify(hash, IMAGE_HASH_SIZE, sig, pubkey);

Expand All @@ -115,14 +122,17 @@ bootutil_verify_img(const uint8_t *img, uint32_t size,
{
int rc;
FIH_DECLARE(fih_rc, FIH_FAILURE);
uint8_t *pubkey;
uint8_t *pubkey = NULL;
#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU)
uint8_t *end;
#endif

if (slen != EDDSA_SIGNATURE_LENGTH) {
FIH_SET(fih_rc, FIH_FAILURE);
goto out;
}

#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU)
pubkey = (uint8_t *)bootutil_keys[key_id].key;
end = pubkey + *bootutil_keys[key_id].len;

Expand All @@ -131,6 +141,7 @@ bootutil_verify_img(const uint8_t *img, uint32_t size,
FIH_SET(fih_rc, FIH_FAILURE);
goto out;
}
#endif

rc = ED25519_verify(img, size, sig, pubkey);

Expand Down
6 changes: 6 additions & 0 deletions boot/bootutil/src/image_validate.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ bootutil_img_hash(struct enc_key_data *enc_state, int image_index,
# define KEY_BUF_SIZE (SIG_BUF_SIZE + 24)
#endif /* !MCUBOOT_HW_KEY */

#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU)
#if !defined(MCUBOOT_HW_KEY)
static int
bootutil_find_key(uint8_t *keyhash, uint8_t keyhash_len)
Expand Down Expand Up @@ -310,6 +311,7 @@ bootutil_find_key(uint8_t image_index, uint8_t *key, uint16_t key_len)
}
#endif /* !MCUBOOT_HW_KEY */
#endif /* !MCUBOOT_BUILTIN_KEY */
#endif /* !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) */
#endif /* EXPECTED_SIG_TLV */

/**
Expand Down Expand Up @@ -626,6 +628,7 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index,
break;
}
#endif /* defined(EXPECTED_HASH_TLV) && !defined(MCUBOOT_SIGN_PURE) */
#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU)
#ifdef EXPECTED_KEY_TLV
case EXPECTED_KEY_TLV:
{
Expand Down Expand Up @@ -656,14 +659,17 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index,
break;
}
#endif /* EXPECTED_KEY_TLV */
#endif /* !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) */
#ifdef EXPECTED_SIG_TLV
case EXPECTED_SIG_TLV:
{
#if !defined(CONFIG_BOOT_SIGNATURE_USING_KMU)
/* Ignore this signature if it is out of bounds. */
if (key_id < 0 || key_id >= bootutil_key_cnt) {
key_id = -1;
continue;
}
#endif /* !defined(CONFIG_BOOT_SIGNATURE_USING_KMU) */
if (!EXPECTED_SIG_LEN(len) || len > sizeof(buf)) {
rc = -1;
goto out;
Expand Down
2 changes: 1 addition & 1 deletion boot/zephyr/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ if(CONFIG_MCUBOOT_SERIAL)
endif()
endif()

if(NOT CONFIG_BOOT_SIGNATURE_KEY_FILE STREQUAL "")
if(NOT CONFIG_BOOT_SIGNATURE_USING_KMU OR NOT CONFIG_BOOT_SIGNATURE_KEY_FILE STREQUAL "")
# CONF_FILE points to the KConfig configuration files of the bootloader.
foreach (filepath ${CONF_FILE})
file(READ ${filepath} temp_text)
Expand Down
30 changes: 29 additions & 1 deletion boot/zephyr/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ endchoice # BOOT_IMG_HASH_ALG

config BOOT_SIGNATURE_TYPE_PURE_ALLOW
bool
depends on NRF_SECURITY
help
Hidden option set by configurations that allow Pure variant,
for example ed25519. The pure variant means that image
Expand Down Expand Up @@ -293,6 +294,7 @@ config BOOT_ED25519_MBEDTLS

config BOOT_ED25519_PSA
bool "Use PSA crypto"
depends on NRF_SECURITY
select BOOT_USE_PSA_CRYPTO
select BOOT_ED25519_PSA_DEPENDENCIES
select BOOT_X25519_PSA_DEPENDENCIES if BOOT_ENCRYPT_IMAGE
Expand All @@ -302,6 +304,22 @@ endif

endchoice

config BOOT_SIGNATURE_USING_KMU
bool "Use KMU stored keys for signature verification"
depends on NRF_SECURITY
depends on CRACEN_LIB_KMU
select PSA_WANT_ALG_GCM
select PSA_WANT_KEY_TYPE_AES
select PSA_WANT_AES_KEY_SIZE_256
select PSA_WANT_ALG_SP800_108_COUNTER_CMAC
select PSA_WANT_ALG_CMAC
select PSA_WANT_ALG_ECB_NO_PADDING
help
MCUboot will use keys provisioned to the device key management unit for signature
verification instead of compiling in key data from a file.

if !BOOT_SIGNATURE_USING_KMU

config BOOT_SIGNATURE_KEY_FILE
string "PEM key file"
default "root-ec-p256.pem" if BOOT_SIGNATURE_TYPE_ECDSA_P256
Expand All @@ -319,6 +337,8 @@ config BOOT_SIGNATURE_KEY_FILE
with the public key information will be written in a format expected by
MCUboot.

endif

config MCUBOOT_CLEANUP_ARM_CORE
bool "Perform core cleanup before chain-load the application"
depends on CPU_CORTEX_M
Expand All @@ -335,10 +355,18 @@ config MCUBOOT_CLEANUP_ARM_CORE
start-up code which can cause a module fault and potentially make the
module irrecoverable.

# Disable MBEDTLS from being selected if NRF_SECURITY is enabled, and use default NRF_SECURITY
# configuration file for MBEDTLS
config MBEDTLS
depends on !NRF_SECURITY

config NRF_SECURITY
select MBEDTLS_PROMPTLESS

if MBEDTLS

config MBEDTLS_CFG_FILE
default "mcuboot-mbedtls-cfg.h"
default "mcuboot-mbedtls-cfg.h" if !NRF_SECURITY

endif

Expand Down

0 comments on commit 40543f1

Please sign in to comment.