Skip to content

Commit

Permalink
[nrf noup] PSA implementation of x25519 and ed25519 verification
Browse files Browse the repository at this point in the history
The commit provides implementation of image verification with
ed25519 and encryption/decryption support where random key
is encrypted using x25519.

Issues:
 - sha256 used with ed25519 verification
 - key passed via context in raw farm instead of key id

Signed-off-by: Dominik Ermel <dominik.ermel@nordicsemi.no>
  • Loading branch information
de-nordic committed Jul 25, 2024
1 parent b99d1f2 commit b13dc97
Show file tree
Hide file tree
Showing 5 changed files with 636 additions and 57 deletions.
37 changes: 36 additions & 1 deletion boot/bootutil/include/bootutil/crypto/aes_ctr.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#include "mcuboot_config/mcuboot_config.h"

#if (defined(MCUBOOT_USE_MBED_TLS) + \
defined(MCUBOOT_USE_TINYCRYPT)) != 1
defined(MCUBOOT_USE_TINYCRYPT) + defined(MCUBOOT_USE_PSA_CRYPTO)) != 1
#error "One crypto backend must be defined: either MBED_TLS or TINYCRYPT"
#endif

Expand All @@ -38,12 +38,47 @@
#define BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE TC_AES_BLOCK_SIZE
#endif /* MCUBOOT_USE_TINYCRYPT */


#if defined(MCUBOOT_USE_PSA_CRYPTO)
#include <psa/crypto.h>
#include "bootutil/enc_key_public.h"
/* To fix: why is it always named BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE */
#define BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE BOOT_ENC_KEY_SIZE
#define BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE (16)
#endif

#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

#if defined(MCUBOOT_USE_PSA_CRYPTO)
typedef struct {
/* Fixme: This should not be, here, psa_key_id should be passed */
uint8_t key[BOOT_ENC_KEY_SIZE];
} bootutil_aes_ctr_context;

void bootutil_aes_ctr_init(bootutil_aes_ctr_context *ctx);

static inline void bootutil_aes_ctr_drop(bootutil_aes_ctr_context *ctx)
{
memset(ctx, 0, sizeof(ctx));
}

static inline int bootutil_aes_ctr_set_key(bootutil_aes_ctr_context *ctx, const uint8_t *k)
{
memcpy(ctx->key, k, sizeof(ctx->key));

return 0;
}

int bootutil_aes_ctr_encrypt(bootutil_aes_ctr_context *ctx, uint8_t *counter,
const uint8_t *m, uint32_t mlen, size_t blk_off, uint8_t *c);
int bootutil_aes_ctr_decrypt(bootutil_aes_ctr_context *ctx, uint8_t *counter,
const uint8_t *c, uint32_t clen, size_t blk_off, uint8_t *m);
#endif

#if defined(MCUBOOT_USE_MBED_TLS)
typedef mbedtls_aes_context bootutil_aes_ctr_context;
static inline void bootutil_aes_ctr_init(bootutil_aes_ctr_context *ctx)
Expand Down
71 changes: 71 additions & 0 deletions boot/bootutil/src/ed25519_psa.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Copyright (c) 2020 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/
#include <assert.h>
#include <string.h>
#include <stdint.h>

#include <mcuboot_config/mcuboot_config.h>
#include "bootutil/bootutil_log.h"

#include <psa/crypto.h>
#include <psa/crypto_types.h>

BOOT_LOG_MODULE_DECLARE(ed25519_psa);

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

int ED25519_verify(const uint8_t *message, size_t message_len,
const uint8_t signature[64],
const uint8_t public_key[32])
{
/* Set to any error */
psa_status_t status = PSA_ERROR_BAD_STATE;
psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
psa_key_id_t kid;
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\n", status);
return 0;
}

status = PSA_ERROR_BAD_STATE;

psa_set_key_type(&key_attr,
PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_TWISTED_EDWARDS));
psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_VERIFY_MESSAGE);
psa_set_key_algorithm(&key_attr, PSA_ALG_PURE_EDDSA);

status = psa_import_key(&key_attr, public_key, EDDSA_KEY_LENGTH, &kid);
if (status != PSA_SUCCESS) {
BOOT_LOG_ERR("ED25519 key import failed %d", status);
return 0;
}

status = psa_verify_message(kid, PSA_ALG_PURE_EDDSA, message, message_len,
signature, EDDSA_SIGNAGURE_LENGTH);
if (status != PSA_SUCCESS) {
BOOT_LOG_ERR("ED25519 signature verification failed %d", status);
ret = 0;
/* Pass through to destroy key */
} else {
ret = 1;
/* Pass through to destroy key */
}

status = psa_destroy_key(kid);

if (status != PSA_SUCCESS) {
/* Just for logging */
BOOT_LOG_WRN("Failed to destroy key %d", status);
}

return ret;
}
114 changes: 60 additions & 54 deletions boot/bootutil/src/encrypted.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "bootutil/crypto/ecdh_p256.h"
#endif

#if !defined(MCUBOOT_USE_PSA_CRYPTO)
#if defined(MCUBOOT_ENCRYPT_X25519)
#include "bootutil/crypto/ecdh_x25519.h"
#endif
Expand All @@ -35,6 +36,7 @@
#include "mbedtls/oid.h"
#include "mbedtls/asn1.h"
#endif
#endif

#include "bootutil/image.h"
#include "bootutil/enc_key.h"
Expand All @@ -43,6 +45,30 @@

#include "bootutil_priv.h"

#define EXPECTED_ENC_LEN BOOT_ENC_TLV_SIZE

#if defined(MCUBOOT_ENCRYPT_RSA)
# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_RSA2048
#elif defined(MCUBOOT_ENCRYPT_KW)
# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_KW
#elif defined(MCUBOOT_ENCRYPT_EC256)
# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_EC256
# define EC_PUBK_INDEX (0)
# define EC_TAG_INDEX (65)
# define EC_CIPHERKEY_INDEX (65 + 32)
_Static_assert(EC_CIPHERKEY_INDEX + BOOT_ENC_KEY_SIZE == EXPECTED_ENC_LEN,
"Please fix ECIES-P256 component indexes");
#elif defined(MCUBOOT_ENCRYPT_X25519)
# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_X25519
# define EC_PUBK_INDEX (0)
# define EC_TAG_INDEX (32)
# define EC_CIPHERKEY_INDEX (32 + 32)
_Static_assert(EC_CIPHERKEY_INDEX + BOOT_ENC_KEY_SIZE == EXPECTED_ENC_LEN,
"Please fix ECIES-X25519 component indexes");
#endif

/* NOUP Fixme: */
#if !defined(CONFIG_BOOT_ED25519_PSA)
#if defined(MCUBOOT_ENCRYPT_EC256) || defined(MCUBOOT_ENCRYPT_X25519)
#if defined(_compare)
static inline int bootutil_constant_time_compare(const uint8_t *a, const uint8_t *b, size_t size)
Expand Down Expand Up @@ -336,60 +362,6 @@ hkdf(uint8_t *ikm, uint16_t ikm_len, uint8_t *info, uint16_t info_len,
}
#endif

int
boot_enc_init(struct enc_key_data *enc_state, uint8_t slot)
{
bootutil_aes_ctr_init(&enc_state[slot].aes_ctr);
return 0;
}

int
boot_enc_drop(struct enc_key_data *enc_state, uint8_t slot)
{
bootutil_aes_ctr_drop(&enc_state[slot].aes_ctr);
enc_state[slot].valid = 0;
return 0;
}

int
boot_enc_set_key(struct enc_key_data *enc_state, uint8_t slot,
const struct boot_status *bs)
{
int rc;

rc = bootutil_aes_ctr_set_key(&enc_state[slot].aes_ctr, bs->enckey[slot]);
if (rc != 0) {
boot_enc_drop(enc_state, slot);
return -1;
}

enc_state[slot].valid = 1;

return 0;
}

#define EXPECTED_ENC_LEN BOOT_ENC_TLV_SIZE

#if defined(MCUBOOT_ENCRYPT_RSA)
# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_RSA2048
#elif defined(MCUBOOT_ENCRYPT_KW)
# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_KW
#elif defined(MCUBOOT_ENCRYPT_EC256)
# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_EC256
# define EC_PUBK_INDEX (0)
# define EC_TAG_INDEX (65)
# define EC_CIPHERKEY_INDEX (65 + 32)
_Static_assert(EC_CIPHERKEY_INDEX + BOOT_ENC_KEY_SIZE == EXPECTED_ENC_LEN,
"Please fix ECIES-P256 component indexes");
#elif defined(MCUBOOT_ENCRYPT_X25519)
# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_X25519
# define EC_PUBK_INDEX (0)
# define EC_TAG_INDEX (32)
# define EC_CIPHERKEY_INDEX (32 + 32)
_Static_assert(EC_CIPHERKEY_INDEX + BOOT_ENC_KEY_SIZE == EXPECTED_ENC_LEN,
"Please fix ECIES-X25519 component indexes");
#endif

#if ( (defined(MCUBOOT_ENCRYPT_RSA) && defined(MCUBOOT_USE_MBED_TLS) && !defined(MCUBOOT_USE_PSA_CRYPTO)) || \
(defined(MCUBOOT_ENCRYPT_EC256) && defined(MCUBOOT_USE_MBED_TLS)) )
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
Expand Down Expand Up @@ -602,6 +574,7 @@ boot_decrypt_key(const uint8_t *buf, uint8_t *enckey)

return rc;
}
#endif /* CONFIG_BOOT_ED25519_PSA */

/*
* Load encryption key.
Expand Down Expand Up @@ -656,6 +629,39 @@ boot_enc_load(struct enc_key_data *enc_state, int slot,
return boot_decrypt_key(buf, bs->enckey[slot]);
}

int
boot_enc_init(struct enc_key_data *enc_state, uint8_t slot)
{
bootutil_aes_ctr_init(&enc_state[slot].aes_ctr);
return 0;
}

int
boot_enc_drop(struct enc_key_data *enc_state, uint8_t slot)
{
bootutil_aes_ctr_drop(&enc_state[slot].aes_ctr);
enc_state[slot].valid = 0;
return 0;
}

int
boot_enc_set_key(struct enc_key_data *enc_state, uint8_t slot,
const struct boot_status *bs)
{
int rc;

rc = bootutil_aes_ctr_set_key(&enc_state[slot].aes_ctr, bs->enckey[slot]);
if (rc != 0) {
boot_enc_drop(enc_state, slot);
return -1;
}

enc_state[slot].valid = 1;

return 0;
}


bool
boot_enc_valid(struct enc_key_data *enc_state, int slot)
{
Expand Down
Loading

0 comments on commit b13dc97

Please sign in to comment.