Message ID | 20240528140955.1960172-22-raymond.mao@linaro.org |
---|---|
State | RFC |
Delegated to: | Tom Rini |
Headers | show |
Series | Integrate MbedTLS v3.6 LTS with U-Boot | expand |
Hi Raymond, [...] > + > +/** > + * 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", > + (unsigned int)-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", > + (unsigned int)-ret); Why do we need to cast the result here? Just print ret Also, would it make sense to create a mapping between mbedTLS API errors and internal error codes? instead of doing ret -EINVAL etc we could have something like ret = mbedtls_to_errno(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", > + (unsigned int)-ret); Same here > + 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", > + (unsigned int)-ret); and here > + ret = -EINVAL; > + > + kfree(rsa_key->e); > +clean_modulus: > + kfree(rsa_key->n); > +clean_pubkey: > + mbedtls_pk_free(&pk); > + return ret; > +} > -- > 2.25.1 > Thanks /Ilias
Hi Ilias, On Fri, 31 May 2024 at 06:00, Ilias Apalodimas <ilias.apalodimas@linaro.org> wrote: > Hi Raymond, > > [...] > > > + > > +/** > > + * 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", > > + (unsigned int)-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", > > + (unsigned int)-ret); > > Why do we need to cast the result here? Just print ret > Also, would it make sense to create a mapping between mbedTLS API > errors and internal error codes? > instead of doing ret -EINVAL etc we could have something like > ret = mbedtls_to_errno(ret); > > I can remove all the cast. But it is not able to 1/1 map the mbedtls errors to general ones via a helper function since the error code should reflect the current scenario of the operation. Even with the same MbedTLS API and same error code, the purpose of caller is different, it is hard to get them mapped in a common interpretation. [...] Regards, Raymond
diff --git a/lib/mbedtls/Makefile b/lib/mbedtls/Makefile index f0b8a1c4003..dab110891af 100644 --- a/lib/mbedtls/Makefile +++ b/lib/mbedtls/Makefile @@ -27,6 +27,7 @@ x509_mbedtls-$(CONFIG_$(SPL_)ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key.o x509_mbedtls-$(CONFIG_$(SPL_)X509_CERTIFICATE_PARSER) += x509_cert_parser.o x509_mbedtls-$(CONFIG_$(SPL_)PKCS7_MESSAGE_PARSER) += pkcs7_parser.o x509_mbedtls-$(CONFIG_$(SPL_)MSCODE_PARSER) += mscode_parser.o +x509_mbedtls-$(CONFIG_$(SPL_)RSA_PUBLIC_KEY_PARSER) += rsa_helper.o obj-$(CONFIG_MBEDTLS_LIB_CRYPTO) += mbedtls_lib_crypto.o mbedtls_lib_crypto-y := \ diff --git a/lib/mbedtls/rsa_helper.c b/lib/mbedtls/rsa_helper.c new file mode 100644 index 00000000000..956e550c856 --- /dev/null +++ b/lib/mbedtls/rsa_helper.c @@ -0,0 +1,99 @@ +// 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 <external/mbedtls/library/common.h> +#include <external/mbedtls/include/mbedtls/pk.h> +#include <external/mbedtls/include/mbedtls/rsa.h> +#include <external/mbedtls/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", + (unsigned int)-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", + (unsigned int)-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", + (unsigned int)-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", + (unsigned int)-ret); + ret = -EINVAL; + + kfree(rsa_key->e); +clean_modulus: + kfree(rsa_key->n); +clean_pubkey: + mbedtls_pk_free(&pk); + return ret; +}
Add RSA helper layer on top on MbedTLS PK and RSA library. Signed-off-by: Raymond Mao <raymond.mao@linaro.org> --- Changes in v2 - Initial patch. Changes in v3 - None. lib/mbedtls/Makefile | 1 + lib/mbedtls/rsa_helper.c | 99 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 lib/mbedtls/rsa_helper.c