bootutil/crypto: Refactor the RSA signature verification and encryption
This patch refactor the RSA operations done by the signature verification
module and by the encrypted images decryption module. Previous solution is
tightly coupled with Mbed TLS, while this patch provides an abstraction of
the RSA functionalities in a dedicated crypto abstraction header, crypto/rsa.h
that supports both Mbed TLS APIs and PSA Crypto APIs. In case of PSA Crypto,
the verification scheme is directly provided by the crypto backend hence it
simplifies the operations done in the image verification module.
Signed-off-by: Antonio de Angelis <Antonio.deAngelis@arm.com>
Change-Id: I973bc3374b62eee2d7717c2368bce7611d37a0c8
diff --git a/boot/bootutil/src/encrypted.c b/boot/bootutil/src/encrypted.c
index fdd9852..82435a4 100644
--- a/boot/bootutil/src/encrypted.c
+++ b/boot/bootutil/src/encrypted.c
@@ -2,7 +2,7 @@
* SPDX-License-Identifier: Apache-2.0
*
* Copyright (c) 2018-2019 JUUL Labs
- * Copyright (c) 2019-2021 Arm Limited
+ * Copyright (c) 2019-2023 Arm Limited
*/
#include "mcuboot_config/mcuboot_config.h"
@@ -13,13 +13,8 @@
#include <string.h>
#if defined(MCUBOOT_ENCRYPT_RSA)
-#include "mbedtls/rsa.h"
-#if MBEDTLS_VERSION_NUMBER >= 0x03000000
-#include "rsa_alt_helpers.h"
-#else
-#include "mbedtls/rsa_internal.h"
-#endif
-#include "mbedtls/asn1.h"
+#define BOOTUTIL_CRYPTO_RSA_CRYPT_ENABLED
+#include "bootutil/crypto/rsa.h"
#endif
#if defined(MCUBOOT_ENCRYPT_KW)
@@ -93,74 +88,6 @@
}
#endif /* MCUBOOT_ENCRYPT_KW */
-#if defined(MCUBOOT_ENCRYPT_RSA)
-static int
-parse_rsa_enckey(mbedtls_rsa_context *ctx, uint8_t **p, uint8_t *end)
-{
- size_t len;
-
- if (mbedtls_asn1_get_tag(p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
- return -1;
- }
-
- if (*p + len != end) {
- return -2;
- }
-
- /* Non-optional fields. */
- if ( /* version */
- mbedtls_asn1_get_int(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(ver)) != 0 ||
- /* public modulus */
- mbedtls_asn1_get_mpi(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(N)) != 0 ||
- /* public exponent */
- mbedtls_asn1_get_mpi(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(E)) != 0 ||
- /* private exponent */
- mbedtls_asn1_get_mpi(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(D)) != 0 ||
- /* primes */
- mbedtls_asn1_get_mpi(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(P)) != 0 ||
- mbedtls_asn1_get_mpi(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(Q)) != 0) {
-
- return -3;
- }
-
-#if !defined(MBEDTLS_RSA_NO_CRT)
- /*
- * DP/DQ/QP are only used inside mbedTLS if it was built with the
- * Chinese Remainder Theorem enabled (default). In case it is disabled
- * we parse, or if not available, we calculate those values.
- */
- if (*p < end) {
- if ( /* d mod (p-1) and d mod (q-1) */
- mbedtls_asn1_get_mpi(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(DP)) != 0 ||
- mbedtls_asn1_get_mpi(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(DQ)) != 0 ||
- /* q ^ (-1) mod p */
- mbedtls_asn1_get_mpi(p, end, &ctx->MBEDTLS_CONTEXT_MEMBER(QP)) != 0) {
-
- return -4;
- }
- } else {
- if (mbedtls_rsa_deduce_crt(&ctx->MBEDTLS_CONTEXT_MEMBER(P),
- &ctx->MBEDTLS_CONTEXT_MEMBER(Q),
- &ctx->MBEDTLS_CONTEXT_MEMBER(D),
- &ctx->MBEDTLS_CONTEXT_MEMBER(DP),
- &ctx->MBEDTLS_CONTEXT_MEMBER(DQ),
- &ctx->MBEDTLS_CONTEXT_MEMBER(QP)) != 0) {
- return -5;
- }
- }
-#endif
-
- ctx->MBEDTLS_CONTEXT_MEMBER(len) = mbedtls_mpi_size(&ctx->MBEDTLS_CONTEXT_MEMBER(N));
-
- if (mbedtls_rsa_check_privkey(ctx) != 0) {
- return -6;
- }
-
- return 0;
-}
-#endif
-
#if defined(MCUBOOT_ENCRYPT_EC256)
static const uint8_t ec_pubkey_oid[] = MBEDTLS_OID_EC_ALG_UNRESTRICTED;
static const uint8_t ec_secp256r1_oid[] = MBEDTLS_OID_EC_GRP_SECP256R1;
@@ -460,8 +387,8 @@
"Please fix ECIES-X25519 component indexes");
#endif
-#if defined(MCUBOOT_ENCRYPT_RSA) || \
- (defined(MCUBOOT_ENCRYPT_EC256) && defined(MCUBOOT_USE_MBED_TLS))
+#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
static int fake_rng(void *p_rng, unsigned char *output, size_t len)
{
@@ -474,9 +401,9 @@
return 0;
}
-#endif
-#endif /* defined(MCUBOOT_ENCRYPT_RSA) ||
- defined(MCUBOOT_ENCRYPT_EC256) && defined(MCUBOOT_USE_MBED_TLS) */
+#endif /* MBEDTLS_VERSION_NUMBER */
+#endif /* (MCUBOOT_ENCRYPT_RSA && MCUBOOT_USE_MBED_TLS && !MCUBOOT_USE_PSA_CRYPTO) ||
+ (MCUBOOT_ENCRYPT_EC256 && MCUBOOT_USE_MBED_TLS) */
/*
* Decrypt an encryption key TLV.
@@ -488,7 +415,7 @@
boot_enc_decrypt(const uint8_t *buf, uint8_t *enckey)
{
#if defined(MCUBOOT_ENCRYPT_RSA)
- mbedtls_rsa_context rsa;
+ bootutil_rsa_context rsa;
uint8_t *cp;
uint8_t *cpend;
size_t olen;
@@ -515,28 +442,22 @@
#if defined(MCUBOOT_ENCRYPT_RSA)
-#if MBEDTLS_VERSION_NUMBER >= 0x03000000
- mbedtls_rsa_init(&rsa);
- mbedtls_rsa_set_padding(&rsa, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
-#else
- mbedtls_rsa_init(&rsa, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
-#endif
+ bootutil_rsa_init(&rsa);
cp = (uint8_t *)bootutil_enc_key.key;
cpend = cp + *bootutil_enc_key.len;
- rc = parse_rsa_enckey(&rsa, &cp, cpend);
+ /* The enckey is encrypted through RSA so for decryption we need the private key */
+ rc = bootutil_rsa_parse_private_key(&rsa, &cp, cpend);
if (rc) {
- mbedtls_rsa_free(&rsa);
+ bootutil_rsa_drop(&rsa);
return rc;
}
-#if MBEDTLS_VERSION_NUMBER >= 0x03000000
- rc = mbedtls_rsa_rsaes_oaep_decrypt(&rsa, fake_rng, NULL,
- NULL, 0, &olen, buf, enckey, BOOT_ENC_KEY_SIZE);
-#else
- rc = mbedtls_rsa_rsaes_oaep_decrypt(&rsa, NULL, NULL, MBEDTLS_RSA_PRIVATE,
- NULL, 0, &olen, buf, enckey, BOOT_ENC_KEY_SIZE);
-#endif
- mbedtls_rsa_free(&rsa);
+
+ rc = bootutil_rsa_oaep_decrypt(&rsa, &olen, buf, enckey, BOOT_ENC_KEY_SIZE);
+ bootutil_rsa_drop(&rsa);
+ if (rc) {
+ return rc;
+ }
#endif /* defined(MCUBOOT_ENCRYPT_RSA) */