Skip to content

Commit 615a9df

Browse files
de-nordicnordicjm
authored andcommitted
bootutil: PSA implementation of x25519 and ed25519 verification
The commit provides implementation of image verification with ed25519 and encryption/decryption support where random key is encrypted using x25519. Signed-off-by: Dominik Ermel <[email protected]>
1 parent e5c0078 commit 615a9df

File tree

6 files changed

+624
-57
lines changed

6 files changed

+624
-57
lines changed

boot/bootutil/include/bootutil/crypto/aes_ctr.h

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
#include "mcuboot_config/mcuboot_config.h"
1616

1717
#if (defined(MCUBOOT_USE_MBED_TLS) + \
18-
defined(MCUBOOT_USE_TINYCRYPT)) != 1
19-
#error "One crypto backend must be defined: either MBED_TLS or TINYCRYPT"
18+
defined(MCUBOOT_USE_TINYCRYPT) + defined(MCUBOOT_USE_PSA_CRYPTO)) != 1
19+
#error "One crypto backend must be defined: either MBED_TLS or TINYCRYPT or PSA"
2020
#endif
2121

2222
#if defined(MCUBOOT_USE_MBED_TLS)
@@ -38,12 +38,45 @@
3838
#define BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE TC_AES_BLOCK_SIZE
3939
#endif /* MCUBOOT_USE_TINYCRYPT */
4040

41+
#if defined(MCUBOOT_USE_PSA_CRYPTO)
42+
#include <psa/crypto.h>
43+
#include "bootutil/enc_key_public.h"
44+
#define BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE BOOT_ENC_KEY_SIZE
45+
#define BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE (16)
46+
#endif
47+
4148
#include <stdint.h>
4249

4350
#ifdef __cplusplus
4451
extern "C" {
4552
#endif
4653

54+
#if defined(MCUBOOT_USE_PSA_CRYPTO)
55+
typedef struct {
56+
/* Fixme: This should not be, here, psa_key_id should be passed */
57+
uint8_t key[BOOT_ENC_KEY_SIZE];
58+
} bootutil_aes_ctr_context;
59+
60+
void bootutil_aes_ctr_init(bootutil_aes_ctr_context *ctx);
61+
62+
static inline void bootutil_aes_ctr_drop(bootutil_aes_ctr_context *ctx)
63+
{
64+
memset(ctx, 0, sizeof(ctx));
65+
}
66+
67+
static inline int bootutil_aes_ctr_set_key(bootutil_aes_ctr_context *ctx, const uint8_t *k)
68+
{
69+
memcpy(ctx->key, k, sizeof(ctx->key));
70+
71+
return 0;
72+
}
73+
74+
int bootutil_aes_ctr_encrypt(bootutil_aes_ctr_context *ctx, uint8_t *counter,
75+
const uint8_t *m, uint32_t mlen, size_t blk_off, uint8_t *c);
76+
int bootutil_aes_ctr_decrypt(bootutil_aes_ctr_context *ctx, uint8_t *counter,
77+
const uint8_t *c, uint32_t clen, size_t blk_off, uint8_t *m);
78+
#endif
79+
4780
#if defined(MCUBOOT_USE_MBED_TLS)
4881
typedef mbedtls_aes_context bootutil_aes_ctr_context;
4982
static inline void bootutil_aes_ctr_init(bootutil_aes_ctr_context *ctx)

boot/bootutil/pkg.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ pkg.ign_files.BOOTUTIL_SINGLE_APPLICATION_SLOT:
4747

4848
pkg.ign_files:
4949
- "ram_load.c"
50+
- "ed25519_psa.c" # Currently no PSA for mynewet
51+
- "encrypted_psa.c"
5052

5153
pkg.deps.BOOTUTIL_USE_MBED_TLS:
5254
- "@apache-mynewt-core/crypto/mbedtls"

boot/bootutil/src/ed25519_psa.c

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
#include <assert.h>
7+
#include <string.h>
8+
#include <stdint.h>
9+
10+
#include <mcuboot_config/mcuboot_config.h>
11+
#include "bootutil/bootutil_log.h"
12+
13+
#include <psa/crypto.h>
14+
#include <psa/crypto_types.h>
15+
16+
BOOT_LOG_MODULE_REGISTER(ed25519_psa);
17+
18+
#define SHA512_DIGEST_LENGTH 64
19+
#define EDDSA_KEY_LENGTH 32
20+
#define EDDSA_SIGNAGURE_LENGTH 64
21+
22+
int ED25519_verify(const uint8_t *message, size_t message_len,
23+
const uint8_t signature[EDDSA_SIGNAGURE_LENGTH],
24+
const uint8_t public_key[EDDSA_KEY_LENGTH])
25+
{
26+
/* Set to any error */
27+
psa_status_t status = PSA_ERROR_BAD_STATE;
28+
psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
29+
psa_key_id_t kid;
30+
int ret = 0; /* Fail by default */
31+
32+
/* Initialize PSA Crypto */
33+
status = psa_crypto_init();
34+
if (status != PSA_SUCCESS) {
35+
BOOT_LOG_ERR("PSA crypto init failed %d\n", status);
36+
return 0;
37+
}
38+
39+
status = PSA_ERROR_BAD_STATE;
40+
41+
psa_set_key_type(&key_attr,
42+
PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_TWISTED_EDWARDS));
43+
psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_VERIFY_MESSAGE);
44+
psa_set_key_algorithm(&key_attr, PSA_ALG_PURE_EDDSA);
45+
46+
status = psa_import_key(&key_attr, public_key, EDDSA_KEY_LENGTH, &kid);
47+
if (status != PSA_SUCCESS) {
48+
BOOT_LOG_ERR("ED25519 key import failed %d", status);
49+
return 0;
50+
}
51+
52+
status = psa_verify_message(kid, PSA_ALG_PURE_EDDSA, message, message_len,
53+
signature, EDDSA_SIGNAGURE_LENGTH);
54+
if (status != PSA_SUCCESS) {
55+
BOOT_LOG_ERR("ED25519 signature verification failed %d", status);
56+
ret = 0;
57+
/* Pass through to destroy key */
58+
} else {
59+
ret = 1;
60+
/* Pass through to destroy key */
61+
}
62+
63+
status = psa_destroy_key(kid);
64+
65+
if (status != PSA_SUCCESS) {
66+
/* Just for logging */
67+
BOOT_LOG_WRN("Failed to destroy key %d", status);
68+
}
69+
70+
return ret;
71+
}

boot/bootutil/src/encrypted.c

Lines changed: 60 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*
44
* Copyright (c) 2018-2019 JUUL Labs
55
* Copyright (c) 2019-2024 Arm Limited
6+
* Copyright (c) 2025 Nordic Semiconductor ASA
67
*/
78

89
#include "mcuboot_config/mcuboot_config.h"
@@ -25,6 +26,7 @@
2526
#include "bootutil/crypto/ecdh_p256.h"
2627
#endif
2728

29+
#if !defined(MCUBOOT_USE_PSA_CRYPTO)
2830
#if defined(MCUBOOT_ENCRYPT_X25519)
2931
#include "bootutil/crypto/ecdh_x25519.h"
3032
#endif
@@ -35,6 +37,7 @@
3537
#include "mbedtls/oid.h"
3638
#include "mbedtls/asn1.h"
3739
#endif
40+
#endif
3841

3942
#include "bootutil/image.h"
4043
#include "bootutil/enc_key.h"
@@ -43,6 +46,30 @@
4346

4447
#include "bootutil_priv.h"
4548

49+
#define EXPECTED_ENC_LEN BOOT_ENC_TLV_SIZE
50+
51+
#if defined(MCUBOOT_ENCRYPT_RSA)
52+
# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_RSA2048
53+
#elif defined(MCUBOOT_ENCRYPT_KW)
54+
# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_KW
55+
#elif defined(MCUBOOT_ENCRYPT_EC256)
56+
# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_EC256
57+
# define EC_PUBK_INDEX (0)
58+
# define EC_TAG_INDEX (65)
59+
# define EC_CIPHERKEY_INDEX (65 + 32)
60+
_Static_assert(EC_CIPHERKEY_INDEX + BOOT_ENC_KEY_SIZE == EXPECTED_ENC_LEN,
61+
"Please fix ECIES-P256 component indexes");
62+
#elif defined(MCUBOOT_ENCRYPT_X25519)
63+
# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_X25519
64+
# define EC_PUBK_INDEX (0)
65+
# define EC_TAG_INDEX (32)
66+
# define EC_CIPHERKEY_INDEX (32 + 32)
67+
_Static_assert(EC_CIPHERKEY_INDEX + BOOT_ENC_KEY_SIZE == EXPECTED_ENC_LEN,
68+
"Please fix ECIES-X25519 component indexes");
69+
#endif
70+
71+
/* NOUP Fixme: */
72+
#if !defined(CONFIG_BOOT_ED25519_PSA)
4673
#if defined(MCUBOOT_ENCRYPT_EC256) || defined(MCUBOOT_ENCRYPT_X25519)
4774
#if defined(_compare)
4875
static inline int bootutil_constant_time_compare(const uint8_t *a, const uint8_t *b, size_t size)
@@ -351,60 +378,6 @@ int boot_enc_retrieve_private_key(struct bootutil_key **private_key)
351378
}
352379
#endif /* !MCUBOOT_ENC_BUILTIN_KEY */
353380

354-
int
355-
boot_enc_init(struct enc_key_data *enc_state, uint8_t slot)
356-
{
357-
bootutil_aes_ctr_init(&enc_state[slot].aes_ctr);
358-
return 0;
359-
}
360-
361-
int
362-
boot_enc_drop(struct enc_key_data *enc_state, uint8_t slot)
363-
{
364-
bootutil_aes_ctr_drop(&enc_state[slot].aes_ctr);
365-
enc_state[slot].valid = 0;
366-
return 0;
367-
}
368-
369-
int
370-
boot_enc_set_key(struct enc_key_data *enc_state, uint8_t slot,
371-
const struct boot_status *bs)
372-
{
373-
int rc;
374-
375-
rc = bootutil_aes_ctr_set_key(&enc_state[slot].aes_ctr, bs->enckey[slot]);
376-
if (rc != 0) {
377-
boot_enc_drop(enc_state, slot);
378-
return -1;
379-
}
380-
381-
enc_state[slot].valid = 1;
382-
383-
return 0;
384-
}
385-
386-
#define EXPECTED_ENC_LEN BOOT_ENC_TLV_SIZE
387-
388-
#if defined(MCUBOOT_ENCRYPT_RSA)
389-
# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_RSA2048
390-
#elif defined(MCUBOOT_ENCRYPT_KW)
391-
# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_KW
392-
#elif defined(MCUBOOT_ENCRYPT_EC256)
393-
# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_EC256
394-
# define EC_PUBK_INDEX (0)
395-
# define EC_TAG_INDEX (65)
396-
# define EC_CIPHERKEY_INDEX (65 + 32)
397-
_Static_assert(EC_CIPHERKEY_INDEX + BOOT_ENC_KEY_SIZE == EXPECTED_ENC_LEN,
398-
"Please fix ECIES-P256 component indexes");
399-
#elif defined(MCUBOOT_ENCRYPT_X25519)
400-
# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_X25519
401-
# define EC_PUBK_INDEX (0)
402-
# define EC_TAG_INDEX (32)
403-
# define EC_CIPHERKEY_INDEX (32 + 32)
404-
_Static_assert(EC_CIPHERKEY_INDEX + BOOT_ENC_KEY_SIZE == EXPECTED_ENC_LEN,
405-
"Please fix ECIES-X25519 component indexes");
406-
#endif
407-
408381
#if ( (defined(MCUBOOT_ENCRYPT_RSA) && defined(MCUBOOT_USE_MBED_TLS) && !defined(MCUBOOT_USE_PSA_CRYPTO)) || \
409382
(defined(MCUBOOT_ENCRYPT_EC256) && defined(MCUBOOT_USE_MBED_TLS)) )
410383
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
@@ -627,6 +600,7 @@ boot_decrypt_key(const uint8_t *buf, uint8_t *enckey)
627600

628601
return rc;
629602
}
603+
#endif /* CONFIG_BOOT_ED25519_PSA */
630604

631605
/*
632606
* Load encryption key.
@@ -694,6 +668,38 @@ boot_enc_load(struct boot_loader_state *state, int slot,
694668
return boot_decrypt_key(buf, bs->enckey[slot]);
695669
}
696670

671+
int
672+
boot_enc_init(struct enc_key_data *enc_state, uint8_t slot)
673+
{
674+
bootutil_aes_ctr_init(&enc_state[slot].aes_ctr);
675+
return 0;
676+
}
677+
678+
int
679+
boot_enc_drop(struct enc_key_data *enc_state, uint8_t slot)
680+
{
681+
bootutil_aes_ctr_drop(&enc_state[slot].aes_ctr);
682+
enc_state[slot].valid = 0;
683+
return 0;
684+
}
685+
686+
int
687+
boot_enc_set_key(struct enc_key_data *enc_state, uint8_t slot,
688+
const struct boot_status *bs)
689+
{
690+
int rc;
691+
692+
rc = bootutil_aes_ctr_set_key(&enc_state[slot].aes_ctr, bs->enckey[slot]);
693+
if (rc != 0) {
694+
boot_enc_drop(enc_state, slot);
695+
return -1;
696+
}
697+
698+
enc_state[slot].valid = 1;
699+
700+
return 0;
701+
}
702+
697703
bool
698704
boot_enc_valid(struct enc_key_data *enc_state, int slot)
699705
{

0 commit comments

Comments
 (0)