Skip to content

Commit c9425a6

Browse files
committed
[nrf noup] bootloader: Add RSA support via PSA core lite
-This commit adds RSA support via PSA core lite. -This commit removes dependencies for legacy Mbed TLS APIs for RSA. -The change is provided as an additional source file to prevent continued conflict-resolution when MCUboot is synchronized with upstream. The original image_rsa.c is not used. Instead image_rsa_nrf.c is used -Adding BOOT_USE_MBEDTLS_INCLUDES and removing a few wordy comments. This Kconfig is used e.g. when TinyCrypt is used for ECC support. Signed-off-by: Frank Audun Kvamtrø <frank.kvamtro@nordicsemi.no> # Conflicts: # boot/zephyr/Kconfig
1 parent 5e0f695 commit c9425a6

3 files changed

Lines changed: 217 additions & 23 deletions

File tree

boot/bootutil/src/image_rsa_nrf.c

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
/*
2+
* Copyright (c) 2026 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
*/
6+
7+
8+
#include <string.h>
9+
10+
#include "mcuboot_config/mcuboot_config.h"
11+
12+
#include "bootutil/sign_key.h"
13+
14+
#include <assert.h>
15+
#include <string.h>
16+
#include <stdint.h>
17+
18+
#include "bootutil/bootutil_log.h"
19+
#include "bootutil/crypto/sha.h"
20+
#include "bootutil_priv.h"
21+
22+
BOOT_LOG_MODULE_DECLARE(mcuboot);
23+
24+
#ifdef MCUBOOT_SIGN_RSA
25+
#include <psa/crypto.h>
26+
#include <psa/crypto_types.h>
27+
#include <zephyr/sys/util.h>
28+
#include "bootutil_priv.h"
29+
#include "bootutil/sign_key.h"
30+
#include "bootutil/fault_injection_hardening.h"
31+
#ifdef CONFIG_NCS_MCUBOOT_LCS_AWARE
32+
#include <nrf_lcs/nrf_lcs.h>
33+
#endif
34+
#define RSA_SIGNATURE_LENGTH (256)
35+
#define RSA_PUBLIC_KEY_BIT_SIZE (2048)
36+
37+
extern const unsigned int rsa_pub_key_len;
38+
39+
int rsa_verify(const uint8_t *message, size_t message_len,
40+
const uint8_t signature[RSA_SIGNATURE_LENGTH],
41+
const uint8_t public_key[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE])
42+
{
43+
/* Set to any error */
44+
psa_status_t status = PSA_ERROR_BAD_STATE;
45+
psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
46+
int ret = 0; /* Fail by default */
47+
psa_key_id_t key_id;
48+
49+
BOOT_LOG_DBG("rsa_verify: PSA implementation, plain key");
50+
51+
/* Initialize PSA Crypto */
52+
status = psa_crypto_init();
53+
if (status != PSA_SUCCESS) {
54+
BOOT_LOG_ERR("PSA crypto init failed %d\n", status);
55+
return 0;
56+
}
57+
58+
status = PSA_ERROR_BAD_STATE;
59+
60+
psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_VERIFY_HASH);
61+
psa_set_key_lifetime(&key_attr, PSA_KEY_LIFETIME_VOLATILE);
62+
psa_set_key_algorithm(&key_attr, PSA_ALG_RSA_PSS(PSA_ALG_SHA_256));
63+
psa_set_key_type(&key_attr, PSA_KEY_TYPE_RSA_PUBLIC_KEY);
64+
psa_set_key_bits(&key_attr, RSA_PUBLIC_KEY_BIT_SIZE);
65+
66+
BOOT_LOG_DBG("Importing RSA PSS key of size: %d", rsa_pub_key_len);
67+
68+
status = psa_import_key(&key_attr, public_key, rsa_pub_key_len,
69+
&key_id);
70+
if (status != PSA_SUCCESS) {
71+
BOOT_LOG_ERR("RSA import key failed %d", status);
72+
ret = 0;
73+
}
74+
75+
BOOT_LOG_DBG("Key imported. key_id: %d", (int)key_id);
76+
77+
status = PSA_ERROR_BAD_STATE;
78+
79+
BOOT_LOG_INF("Verifying RSA PSS with signature len: %d", RSA_SIGNATURE_LENGTH);
80+
81+
status = psa_verify_hash(key_id, PSA_ALG_RSA_PSS(PSA_ALG_SHA_256),
82+
message, message_len, signature, RSA_SIGNATURE_LENGTH);
83+
if (status != PSA_SUCCESS) {
84+
BOOT_LOG_ERR("RSA signature verification failed %d", status);
85+
ret = 0;
86+
} else {
87+
BOOT_LOG_INF("RSA signature verification successful");
88+
ret = 1;
89+
}
90+
91+
status = psa_destroy_key(key_id);
92+
if (status != PSA_SUCCESS) {
93+
BOOT_LOG_ERR("Failed to destroy imported public key: %d", status);
94+
ret = 0;
95+
} else {
96+
BOOT_LOG_DBG("Destroyed imported key");
97+
}
98+
99+
return ret;
100+
}
101+
102+
103+
static fih_ret
104+
bootutil_verify(uint8_t *buf, uint32_t blen,
105+
uint8_t *sig, size_t slen,
106+
uint8_t key_id)
107+
{
108+
int rc;
109+
FIH_DECLARE(fih_rc, FIH_FAILURE);
110+
uint8_t *pubkey = NULL;
111+
112+
#ifdef CONFIG_NCS_MCUBOOT_LCS_AWARE
113+
if (nrf_lcs_get() != NRF_LCS_SECURED) {
114+
if (key_id != CONFIG_NCS_MCUBOOT_MANUFACTURING_APP_KEY_IDENTIFIER) {
115+
BOOT_LOG_ERR("bootutil_verify_sig: invalid key ID %d for non-secured device", key_id);
116+
FIH_RET(FIH_FAILURE);
117+
}
118+
BOOT_LOG_DBG("bootutil_verify_sig: using manufacturing application key ID %d", key_id);
119+
}
120+
#endif /* CONFIG_NCS_MCUBOOT_LCS_AWARE */
121+
122+
BOOT_LOG_DBG("bootutil_verify_sig: RSA key_id %d", key_id);
123+
124+
if (slen != RSA_SIGNATURE_LENGTH) {
125+
BOOT_LOG_DBG("bootutil_verify: expected slen %d, got %u",
126+
RSA_SIGNATURE_LENGTH, (unsigned int)slen);
127+
FIH_SET(fih_rc, FIH_FAILURE);
128+
goto out;
129+
}
130+
131+
pubkey = (uint8_t *)bootutil_keys[key_id].key;
132+
133+
BOOT_LOG_DBG("bootutil_verify: RSA key_id %d", (int)key_id);
134+
135+
rc = rsa_verify(buf, blen, sig, pubkey);
136+
137+
BOOT_LOG_DBG("bootutil_verify: rsa_verify status %d", rc);
138+
139+
if (rc == 0) {
140+
/* if verify returns 0, there was an error. */
141+
FIH_SET(fih_rc, FIH_FAILURE);
142+
goto out;
143+
}
144+
145+
FIH_SET(fih_rc, FIH_SUCCESS);
146+
out:
147+
148+
FIH_RET(fih_rc);
149+
}
150+
151+
/* Hash signature verification function.
152+
* Verifies hash against provided signature.
153+
* The function verifies that hash is of expected size and then
154+
* calls bootutil_verify to do the signature verification.
155+
*/
156+
fih_ret
157+
bootutil_verify_sig(uint8_t *hash, uint32_t hlen,
158+
uint8_t *sig, size_t slen,
159+
uint8_t key_id)
160+
{
161+
FIH_DECLARE(fih_rc, FIH_FAILURE);
162+
163+
BOOT_LOG_DBG("bootutil_verify_sig: RSA key_id %d", (int)key_id);
164+
165+
if (hlen != IMAGE_HASH_SIZE) {
166+
BOOT_LOG_DBG("bootutil_verify_sig: expected hlen %d, got %d",
167+
IMAGE_HASH_SIZE, hlen);
168+
FIH_SET(fih_rc, FIH_FAILURE);
169+
goto out;
170+
}
171+
172+
FIH_CALL(bootutil_verify, fih_rc, hash, IMAGE_HASH_SIZE, sig,
173+
slen, key_id);
174+
175+
out:
176+
FIH_RET(fih_rc);
177+
}
178+
179+
/* Image verification function.
180+
* The function directly calls bootutil_verify to verify signature
181+
* of image.
182+
*/
183+
fih_ret
184+
bootutil_verify_img(uint8_t *img, uint32_t size,
185+
uint8_t *sig, size_t slen,
186+
uint8_t key_id)
187+
{
188+
FIH_DECLARE(fih_rc, FIH_FAILURE);
189+
190+
BOOT_LOG_DBG("bootutil_verify_img: RSA key_id %d", (int)key_id);
191+
192+
FIH_CALL(bootutil_verify, fih_rc, img, size, sig,
193+
slen, key_id);
194+
195+
FIH_RET(fih_rc);
196+
}
197+
198+
#endif /* MCUBOOT_SIGN_RSA */

boot/zephyr/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ zephyr_library_sources(
118118
${BOOT_DIR}/bootutil/src/mcuboot_manifest.c
119119
${BOOT_DIR}/bootutil/src/tlv.c
120120
${BOOT_DIR}/bootutil/src/encrypted.c
121-
${BOOT_DIR}/bootutil/src/image_rsa.c
121+
${BOOT_DIR}/bootutil/src/image_rsa_nrf.c
122122
${BOOT_DIR}/bootutil/src/image_ecdsa.c
123123
${BOOT_DIR}/bootutil/src/image_ed25519.c
124124
${BOOT_DIR}/bootutil/src/bootutil_misc.c

boot/zephyr/Kconfig

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,19 @@ config MCUBOOT
2222
select MCUBOOT_BOOTUTIL_LIB
2323
select REBOOT if SECURE_BOOT
2424

25+
config BOOT_USE_MBEDTLS_INCLUDES
26+
bool
27+
# Hidden option
28+
select NRF_SECURITY
29+
help
30+
Hidden option set if Mbed TLS includes are needed. The includes comes
31+
from Oberon PSA crypto. This is required for ASN.1 encoding information
32+
via the include <mbedtls_oid.h> which is used regardless of implementation.
33+
2534
config BOOT_USE_MBEDTLS
2635
bool
2736
# Hidden option
37+
select BOOT_USES_MBEDTLS_INCLUDES
2838
help
2939
Use mbedTLS for crypto primitives.
3040

@@ -258,26 +268,15 @@ choice BOOT_SIGNATURE_TYPE
258268
config BOOT_SIGNATURE_TYPE_NONE
259269
bool "No signature; use only hash check"
260270
select BOOT_USE_TINYCRYPT if !SOC_SERIES_NRF54L
261-
select BOOT_USE_PSA_CRYPTO if SOC_SERIES_NRF54L
271+
select BOOT_USE_PSA_CRYPTO
262272
select BOOT_IMG_HASH_ALG_SHA256_ALLOW
263273

264274
config BOOT_SIGNATURE_TYPE_RSA
265275
bool "RSA signatures"
266-
select BOOT_USE_MBEDTLS
267-
select PSA_CRYPTO
268-
select PSA_WANT_KEY_TYPE_AES
269-
select PSA_WANT_ALG_CTR
270-
select MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS
271-
select MBEDTLS_ASN1_PARSE_C
272-
select MBEDTLS_MD_C
273-
select MBEDTLS_SHA256_C
274-
select MBEDTLS_RSA_C
275-
select MBEDTLS_PKCS1_V15
276-
select MBEDTLS_PKCS1_V21
277-
select MBEDTLS_KEY_EXCHANGE_RSA_ENABLED if NRF_SECURITY
278-
select MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
279-
select MBEDTLS_PLATFORM_SNPRINTF_ALT
280-
select BOOT_ENCRYPTION_SUPPORT
276+
select BOOT_USE_PSA_CRYPTO
277+
select PSA_WANT_ALG_SHA_256
278+
select PSA_WANT_ALG_RSA_PSS
279+
select PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY
281280
select BOOT_IMG_HASH_ALG_SHA256_ALLOW
282281

283282
if BOOT_SIGNATURE_TYPE_RSA
@@ -287,13 +286,12 @@ config BOOT_SIGNATURE_TYPE_RSA_LEN
287286
default 2048
288287
endif
289288

289+
290290
config BOOT_SIGNATURE_TYPE_ECDSA_P256
291291
bool "Elliptic curve digital signatures with curve P-256"
292292
select BOOT_ENCRYPTION_SUPPORT
293293
select BOOT_IMG_HASH_ALG_SHA256_ALLOW
294-
# Enable nrf_security for include paths to oberon-psa-crypto which has mbedtls headers
295-
# (e.g. crypto_oid.h), needed also in cases other than BOOT_ECDSA_PSA.
296-
select NRF_SECURITY
294+
select BOOT_USE_MBEDTLS_INCLUDES
297295
imply MBEDTLS_ASN1_PARSE_C
298296

299297
if BOOT_SIGNATURE_TYPE_ECDSA_P256
@@ -336,11 +334,9 @@ config BOOT_SIGNATURE_TYPE_ED25519
336334
bool "Edwards curve digital signatures using ed25519"
337335
select BOOT_ENCRYPTION_SUPPORT if !BOOT_SIGNATURE_TYPE_PURE
338336
select BOOT_IMG_HASH_ALG_SHA256_ALLOW if !BOOT_SIGNATURE_TYPE_PURE
337+
select BOOT_USE_MBEDTLS_INCLUDES
339338
# The SHA is used only for key hashing, not for images.
340339
select BOOT_SIGNATURE_TYPE_PURE_ALLOW
341-
# Enable nrf_security for include paths to oberon-psa-crypto which has mbedtls headers
342-
# (e.g. crypto_oid.h), needed also in cases other than BOOT_ED25519_PSA.
343-
select NRF_SECURITY
344340
help
345341
This is ed25519 signature calculated over SHA512 of SHA256 of application
346342
image.

0 commit comments

Comments
 (0)