mbedtls: add RSA helper layer on MbedTLS

Add RSA helper layer on top on MbedTLS PK and RSA library.
Introduce _LEGACY and _MBEDTLS kconfigs for RSA helper legacy and
MbedTLS implementations respectively.

Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
Acked-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
This commit is contained in:
Raymond Mao 2024-10-03 14:50:36 -07:00 committed by Tom Rini
parent 513a15db0d
commit 1df80a4f5f
3 changed files with 133 additions and 1 deletions

View file

@ -118,11 +118,13 @@ config LEGACY_CRYPTO_CERT
bool "legacy certificate libraries" bool "legacy certificate libraries"
select ASYMMETRIC_PUBLIC_KEY_LEGACY if \ select ASYMMETRIC_PUBLIC_KEY_LEGACY if \
ASYMMETRIC_PUBLIC_KEY_SUBTYPE ASYMMETRIC_PUBLIC_KEY_SUBTYPE
select RSA_PUBLIC_KEY_PARSER_LEGACY if RSA_PUBLIC_KEY_PARSER
select X509_CERTIFICATE_PARSER_LEGACY if X509_CERTIFICATE_PARSER select X509_CERTIFICATE_PARSER_LEGACY if X509_CERTIFICATE_PARSER
select PKCS7_MESSAGE_PARSER_LEGACY if PKCS7_MESSAGE_PARSER select PKCS7_MESSAGE_PARSER_LEGACY if PKCS7_MESSAGE_PARSER
select MSCODE_PARSER_LEGACY if MSCODE_PARSER select MSCODE_PARSER_LEGACY if MSCODE_PARSER
select SPL_ASYMMETRIC_PUBLIC_KEY_LEGACY if \ select SPL_ASYMMETRIC_PUBLIC_KEY_LEGACY if \
SPL_ASYMMETRIC_PUBLIC_KEY_SUBTYPE SPL_ASYMMETRIC_PUBLIC_KEY_SUBTYPE
select SPL_RSA_PUBLIC_KEY_PARSER_LEGACY if SPL_RSA_PUBLIC_KEY_PARSER
help help
Enable legacy certificate libraries. Enable legacy certificate libraries.
@ -135,6 +137,14 @@ config ASYMMETRIC_PUBLIC_KEY_LEGACY
This option chooses legacy certificate library for asymmetric public This option chooses legacy certificate library for asymmetric public
key crypto algorithm. key crypto algorithm.
config RSA_PUBLIC_KEY_PARSER_LEGACY
bool "RSA public key parser with legacy certificate library"
depends on ASYMMETRIC_PUBLIC_KEY_LEGACY
select ASN1_DECODER_LEGACY
help
This option chooses legacy certificate library for RSA public key
parser.
config X509_CERTIFICATE_PARSER_LEGACY config X509_CERTIFICATE_PARSER_LEGACY
bool "X.509 certificate parser with legacy certificate library" bool "X.509 certificate parser with legacy certificate library"
depends on ASYMMETRIC_PUBLIC_KEY_LEGACY depends on ASYMMETRIC_PUBLIC_KEY_LEGACY
@ -168,6 +178,14 @@ config SPL_ASYMMETRIC_PUBLIC_KEY_LEGACY
This option chooses legacy certificate library for asymmetric public This option chooses legacy certificate library for asymmetric public
key crypto algorithm in SPL. key crypto algorithm in SPL.
config SPL_RSA_PUBLIC_KEY_PARSER_LEGACY
bool "RSA public key parser with legacy certificate library in SPL"
depends on SPL_ASYMMETRIC_PUBLIC_KEY_LEGACY
select SPL_ASN1_DECODER_LEGACY
help
This option chooses legacy certificate library for RSA public key
parser in SPL.
endif # SPL endif # SPL
endif # LEGACY_CRYPTO_CERT endif # LEGACY_CRYPTO_CERT
@ -310,11 +328,13 @@ config MBEDTLS_LIB_X509
bool "MbedTLS certificate libraries" bool "MbedTLS certificate libraries"
select ASYMMETRIC_PUBLIC_KEY_MBEDTLS if \ select ASYMMETRIC_PUBLIC_KEY_MBEDTLS if \
ASYMMETRIC_PUBLIC_KEY_SUBTYPE ASYMMETRIC_PUBLIC_KEY_SUBTYPE
select RSA_PUBLIC_KEY_PARSER_MBEDTLS if RSA_PUBLIC_KEY_PARSER
select X509_CERTIFICATE_PARSER_MBEDTLS if X509_CERTIFICATE_PARSER select X509_CERTIFICATE_PARSER_MBEDTLS if X509_CERTIFICATE_PARSER
select PKCS7_MESSAGE_PARSER_MBEDTLS if PKCS7_MESSAGE_PARSER select PKCS7_MESSAGE_PARSER_MBEDTLS if PKCS7_MESSAGE_PARSER
select MSCODE_PARSER_MBEDTLS if MSCODE_PARSER select MSCODE_PARSER_MBEDTLS if MSCODE_PARSER
select SPL_ASYMMETRIC_PUBLIC_KEY_MBEDTLS if \ select SPL_ASYMMETRIC_PUBLIC_KEY_MBEDTLS if \
SPL_ASYMMETRIC_PUBLIC_KEY_SUBTYPE SPL_ASYMMETRIC_PUBLIC_KEY_SUBTYPE
select SPL_RSA_PUBLIC_KEY_PARSER_MBEDTLS if SPL_RSA_PUBLIC_KEY_PARSER
help help
Enable MbedTLS certificate libraries. Enable MbedTLS certificate libraries.
@ -327,6 +347,14 @@ config ASYMMETRIC_PUBLIC_KEY_MBEDTLS
This option chooses MbedTLS certificate library for asymmetric public This option chooses MbedTLS certificate library for asymmetric public
key crypto algorithm. key crypto algorithm.
config RSA_PUBLIC_KEY_PARSER_MBEDTLS
bool "RSA public key parser with MbedTLS certificate library"
depends on ASYMMETRIC_PUBLIC_KEY_MBEDTLS
select ASN1_DECODER_MBEDTLS
help
This option chooses MbedTLS certificate library for RSA public key
parser.
config X509_CERTIFICATE_PARSER_MBEDTLS config X509_CERTIFICATE_PARSER_MBEDTLS
bool "X.509 certificate parser with MbedTLS certificate library" bool "X.509 certificate parser with MbedTLS certificate library"
depends on ASYMMETRIC_PUBLIC_KEY_MBEDTLS depends on ASYMMETRIC_PUBLIC_KEY_MBEDTLS
@ -360,6 +388,14 @@ config SPL_ASYMMETRIC_PUBLIC_KEY_MBEDTLS
This option chooses MbedTLS certificate library for asymmetric public This option chooses MbedTLS certificate library for asymmetric public
key crypto algorithm in SPL. key crypto algorithm in SPL.
config SPL_RSA_PUBLIC_KEY_PARSER_MBEDTLS
bool "RSA public key parser with MbedTLS certificate library in SPL"
depends on SPL_ASYMMETRIC_PUBLIC_KEY_MBEDTLS
select SPL_ASN1_DECODER_MBEDTLS
help
This option chooses MbedTLS certificate library for RSA public key
parser in SPL.
endif # SPL endif # SPL
endif # MBEDTLS_LIB_X509 endif # MBEDTLS_LIB_X509

View file

@ -18,6 +18,7 @@ obj-$(CONFIG_$(SPL_)X509_CERTIFICATE_PARSER_MBEDTLS) += \
x509_cert_parser.o x509_cert_parser.o
obj-$(CONFIG_$(SPL_)PKCS7_MESSAGE_PARSER_MBEDTLS) += pkcs7_parser.o obj-$(CONFIG_$(SPL_)PKCS7_MESSAGE_PARSER_MBEDTLS) += pkcs7_parser.o
obj-$(CONFIG_$(SPL_)MSCODE_PARSER_MBEDTLS) += mscode_parser.o obj-$(CONFIG_$(SPL_)MSCODE_PARSER_MBEDTLS) += mscode_parser.o
obj-$(CONFIG_$(SPL_)RSA_PUBLIC_KEY_PARSER_MBEDTLS) += rsa_helper.o
# MbedTLS crypto library # MbedTLS crypto library
obj-$(CONFIG_MBEDTLS_LIB) += mbedtls_lib_crypto.o obj-$(CONFIG_MBEDTLS_LIB) += mbedtls_lib_crypto.o
@ -39,7 +40,7 @@ mbedtls_lib_x509-$(CONFIG_$(SPL_)ASN1_DECODER) += \
$(MBEDTLS_LIB_DIR)/asn1parse.o \ $(MBEDTLS_LIB_DIR)/asn1parse.o \
$(MBEDTLS_LIB_DIR)/asn1write.o \ $(MBEDTLS_LIB_DIR)/asn1write.o \
$(MBEDTLS_LIB_DIR)/oid.o $(MBEDTLS_LIB_DIR)/oid.o
mbedtls_lib_x509-$(CONFIG_$(SPL_)RSA_PUBLIC_KEY_PARSER) += \ mbedtls_lib_x509-$(CONFIG_$(SPL_)RSA_PUBLIC_KEY_PARSER_MBEDTLS) += \
$(MBEDTLS_LIB_DIR)/bignum.o \ $(MBEDTLS_LIB_DIR)/bignum.o \
$(MBEDTLS_LIB_DIR)/bignum_core.o \ $(MBEDTLS_LIB_DIR)/bignum_core.o \
$(MBEDTLS_LIB_DIR)/rsa.o \ $(MBEDTLS_LIB_DIR)/rsa.o \

95
lib/mbedtls/rsa_helper.c Normal file
View file

@ -0,0 +1,95 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* RSA helper functions using MbedTLS
*
* Copyright (c) 2024 Linaro Limited
* Author: Raymond Mao <raymond.mao@linaro.org>
*/
#include <linux/err.h>
#include <crypto/internal/rsa.h>
#include <library/common.h>
#include <mbedtls/pk.h>
#include <mbedtls/rsa.h>
#include <mbedtls/asn1.h>
/**
* rsa_parse_pub_key() - decodes the BER encoded buffer and stores in the
* provided struct rsa_key, pointers to the raw key as is,
* so that the caller can copy it or MPI parse it, etc.
*
* @rsa_key: struct rsa_key key representation
* @key: key in BER format
* @key_len: length of key
*
* Return: 0 on success or error code in case of error
*/
int rsa_parse_pub_key(struct rsa_key *rsa_key, const void *key,
unsigned int key_len)
{
int ret = 0;
mbedtls_pk_context pk;
mbedtls_rsa_context *rsa;
mbedtls_pk_init(&pk);
ret = mbedtls_pk_parse_public_key(&pk, (const unsigned char *)key,
key_len);
if (ret) {
pr_err("Failed to parse public key, ret:-0x%04x\n", -ret);
ret = -EINVAL;
goto clean_pubkey;
}
/* Ensure that it is a RSA key */
if (mbedtls_pk_get_type(&pk) != MBEDTLS_PK_RSA) {
pr_err("Non-RSA keys are not supported\n");
ret = -EKEYREJECTED;
goto clean_pubkey;
}
/* Get RSA key context */
rsa = mbedtls_pk_rsa(pk);
if (!rsa) {
pr_err("Failed to get RSA key context, ret:-0x%04x\n", -ret);
ret = -EINVAL;
goto clean_pubkey;
}
/* Parse modulus (n) */
rsa_key->n_sz = mbedtls_mpi_size(&rsa->N);
rsa_key->n = kzalloc(rsa_key->n_sz, GFP_KERNEL);
if (!rsa_key->n) {
ret = -ENOMEM;
goto clean_pubkey;
}
ret = mbedtls_mpi_write_binary(&rsa->N, (unsigned char *)rsa_key->n,
rsa_key->n_sz);
if (ret) {
pr_err("Failed to parse modulus (n), ret:-0x%04x\n", -ret);
ret = -EINVAL;
goto clean_modulus;
}
/* Parse public exponent (e) */
rsa_key->e_sz = mbedtls_mpi_size(&rsa->E);
rsa_key->e = kzalloc(rsa_key->e_sz, GFP_KERNEL);
if (!rsa_key->e) {
ret = -ENOMEM;
goto clean_modulus;
}
ret = mbedtls_mpi_write_binary(&rsa->E, (unsigned char *)rsa_key->e,
rsa_key->e_sz);
if (!ret)
return 0;
pr_err("Failed to parse public exponent (e), ret:-0x%04x\n", -ret);
ret = -EINVAL;
kfree(rsa_key->e);
clean_modulus:
kfree(rsa_key->n);
clean_pubkey:
mbedtls_pk_free(&pk);
return ret;
}