From f864e1ddbb1489cf3433b29299239ea97cdc6a0d Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Fri, 19 Nov 2021 14:40:37 +0530 Subject: [PATCH 1/5] mbedtls: update kconfig help to correct on supported MPI bits --- components/mbedtls/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/mbedtls/Kconfig b/components/mbedtls/Kconfig index 7b0f3c8a3e..1df5f1ffb9 100644 --- a/components/mbedtls/Kconfig +++ b/components/mbedtls/Kconfig @@ -277,7 +277,7 @@ menu "mbedTLS" Enable hardware accelerated multiple precision integer operations. Hardware accelerated multiplication, modulo multiplication, - and modular exponentiation for up to 4096 bit results. + and modular exponentiation for up to SOC_RSA_MAX_BIT_LEN bit results. These operations are used by RSA. From 0befb28237e7675eb8d7ad15d1e5d55e1fbeb41f Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Thu, 18 Nov 2021 17:40:09 +0530 Subject: [PATCH 2/5] mbedtls: fix hardware MPI (bignum) related regression In commit de22f3a4e5cdb9d7d40c74a191f5f0061a7d7d94, combination of hardware and software MPI (bignum) related approach was used to work around chip (e.g. ESP32-C3) limitation of max 3072 bits support. This was done using linker "--wrap" flag but since the relevant API is being used in same translation (compilation unit), hardware mode was not getting used in some cases (e.g., RSA key generation). This commit modified internal mbedTLS API and makes software+hardware combination deterministic. --- components/mbedtls/CMakeLists.txt | 4 -- components/mbedtls/port/esp_bignum.c | 38 +++++++++++++--- .../mbedtls/port/include/mbedtls/bignum.h | 45 +++++++++++++------ .../mbedtls/port/include/mbedtls/esp_config.h | 19 +++++--- tools/ci/check_copyright_ignore.txt | 1 - 5 files changed, 76 insertions(+), 31 deletions(-) diff --git a/components/mbedtls/CMakeLists.txt b/components/mbedtls/CMakeLists.txt index e7a26f0ff3..8065c8b43b 100644 --- a/components/mbedtls/CMakeLists.txt +++ b/components/mbedtls/CMakeLists.txt @@ -178,10 +178,6 @@ if(CONFIG_MBEDTLS_DYNAMIC_BUFFER) endforeach() endif() -if(CONFIG_MBEDTLS_HARDWARE_MPI) - target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_mpi_exp_mod") -endif() - set_property(TARGET mbedcrypto APPEND PROPERTY LINK_INTERFACE_LIBRARIES mbedtls) # Link mbedtls libraries to component library diff --git a/components/mbedtls/port/esp_bignum.c b/components/mbedtls/port/esp_bignum.c index ab78978246..4cd047ab40 100644 --- a/components/mbedtls/port/esp_bignum.c +++ b/components/mbedtls/port/esp_bignum.c @@ -67,8 +67,7 @@ static inline size_t bits_to_words(size_t bits) /* Return the number of words actually used to represent an mpi number. */ -int __wrap_mbedtls_mpi_exp_mod( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M, mbedtls_mpi *_Rinv ); -extern int __real_mbedtls_mpi_exp_mod( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M, mbedtls_mpi *_Rinv ); +#if defined(MBEDTLS_MPI_EXP_MOD_ALT) || defined(MBEDTLS_MPI_EXP_MOD_ALT_FALLBACK) static size_t mpi_words(const mbedtls_mpi *mpi) { @@ -80,6 +79,7 @@ static size_t mpi_words(const mbedtls_mpi *mpi) return 0; } +#endif //(MBEDTLS_MPI_EXP_MOD_ALT || MBEDTLS_MPI_EXP_MOD_ALT_FALLBACK) /** * @@ -182,6 +182,8 @@ cleanup: return ret; } +#if defined(MBEDTLS_MPI_EXP_MOD_ALT) || defined(MBEDTLS_MPI_EXP_MOD_ALT_FALLBACK) + #ifdef ESP_MPI_USE_MONT_EXP /* * Return the most significant one-bit. @@ -272,7 +274,7 @@ cleanup2: * (See RSA Accelerator section in Technical Reference for more about Mprime, Rinv) * */ -int __wrap_mbedtls_mpi_exp_mod( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M, mbedtls_mpi *_Rinv ) +static int esp_mpi_exp_mod( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M, mbedtls_mpi *_Rinv ) { int ret = 0; size_t x_words = mpi_words(X); @@ -302,11 +304,7 @@ int __wrap_mbedtls_mpi_exp_mod( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbed } if (num_words * 32 > SOC_RSA_MAX_BIT_LEN) { -#ifdef CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI - return __real_mbedtls_mpi_exp_mod(Z, X, Y, M, _Rinv); -#else return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; -#endif } /* Determine RR pointer, either _RR for cached value @@ -355,6 +353,32 @@ cleanup: return ret; } +#endif /* (MBEDTLS_MPI_EXP_MOD_ALT || MBEDTLS_MPI_EXP_MOD_ALT_FALLBACK) */ + +/* + * Sliding-window exponentiation: X = A^E mod N (HAC 14.85) + */ +int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, + const mbedtls_mpi *E, const mbedtls_mpi *N, + mbedtls_mpi *_RR ) +{ + int ret; +#if defined(MBEDTLS_MPI_EXP_MOD_ALT_FALLBACK) + /* Try hardware API first and then fallback to software */ + ret = esp_mpi_exp_mod( X, A, E, N, _RR ); + if( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ) { + ret = mbedtls_mpi_exp_mod_soft( X, A, E, N, _RR ); + } +#else + /* Hardware approach */ + ret = esp_mpi_exp_mod( X, A, E, N, _RR ); +#endif + /* Note: For software only approach, it gets handled in mbedTLS library. + This file is not part of build objects for that case */ + + return ret; +} + #if defined(MBEDTLS_MPI_MUL_MPI_ALT) /* MBEDTLS_MPI_MUL_MPI_ALT */ static int mpi_mult_mpi_failover_mod_mult( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t z_words); diff --git a/components/mbedtls/port/include/mbedtls/bignum.h b/components/mbedtls/port/include/mbedtls/bignum.h index a317c45606..4f84bed740 100644 --- a/components/mbedtls/port/include/mbedtls/bignum.h +++ b/components/mbedtls/port/include/mbedtls/bignum.h @@ -1,16 +1,8 @@ -// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once #include_next "mbedtls/bignum.h" @@ -77,4 +69,31 @@ void esp_mpi_release_hardware(void); */ int esp_mpi_mul_mpi_mod(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M); +#if CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI + +/** + * @brief Perform a sliding-window exponentiation: X = A^E mod N + * + * @param X The destination MPI. This must point to an initialized MPI. + * @param A The base of the exponentiation. + * This must point to an initialized MPI. + * @param E The exponent MPI. This must point to an initialized MPI. + * @param N The base for the modular reduction. This must point to an + * initialized MPI. + * @param _RR A helper MPI depending solely on \p N which can be used to + * speed-up multiple modular exponentiations for the same value + * of \p N. This may be \c NULL. If it is not \c NULL, it must + * point to an initialized MPI. + * + * @return \c 0 if successful. + * @return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * @return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \c N is negative or + * even, or if \c E is negative. + * @return Another negative error code on different kinds of failures. + * + */ +int mbedtls_mpi_exp_mod_soft(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *E, const mbedtls_mpi *N, mbedtls_mpi *_RR); + +#endif // CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI + #endif // CONFIG_MBEDTLS_HARDWARE_MPI diff --git a/components/mbedtls/port/include/mbedtls/esp_config.h b/components/mbedtls/port/include/mbedtls/esp_config.h index f36ebf9bc7..9c63118eb5 100644 --- a/components/mbedtls/port/include/mbedtls/esp_config.h +++ b/components/mbedtls/port/include/mbedtls/esp_config.h @@ -153,15 +153,22 @@ #undef MBEDTLS_MD5_ALT #endif -/* The following MPI (bignum) functions have ESP32 hardware support. - For exponential mod, both software and hardware implementation - will be compiled. If CONFIG_MBEDTLS_HARDWARE_MPI is enabled, mod APIs - will be wrapped to use hardware implementation. -*/ -#undef MBEDTLS_MPI_EXP_MOD_ALT +/* The following MPI (bignum) functions have hardware support. + * Uncommenting these macros will use the hardware-accelerated + * implementations. + */ #ifdef CONFIG_MBEDTLS_HARDWARE_MPI +#ifdef CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI + /* Prefer hardware and fallback to software */ + #define MBEDTLS_MPI_EXP_MOD_ALT_FALLBACK +#else + /* Hardware only mode */ + #define MBEDTLS_MPI_EXP_MOD_ALT +#endif #define MBEDTLS_MPI_MUL_MPI_ALT #else +#undef MBEDTLS_MPI_EXP_MOD_ALT_FALLBACK +#undef MBEDTLS_MPI_EXP_MOD_ALT #undef MBEDTLS_MPI_MUL_MPI_ALT #endif diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index 51d3a993f1..838da28acc 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -1915,7 +1915,6 @@ components/mbedtls/port/include/esp_crypto_shared_gdma.h components/mbedtls/port/include/esp_ds/esp_rsa_sign_alt.h components/mbedtls/port/include/esp_mem.h components/mbedtls/port/include/gcm_alt.h -components/mbedtls/port/include/mbedtls/bignum.h components/mbedtls/port/include/mbedtls/esp_config.h components/mbedtls/port/include/mbedtls/esp_debug.h components/mbedtls/port/include/md/esp_md.h From 1cae1fc18e72f6b823639b58b355d3f05d55ef22 Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Fri, 19 Nov 2021 14:39:46 +0530 Subject: [PATCH 3/5] mbedtls: update mbedtls submodule pointer for MPI API change --- components/mbedtls/mbedtls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/mbedtls/mbedtls b/components/mbedtls/mbedtls index 6465247f67..73cfa42bd3 160000 --- a/components/mbedtls/mbedtls +++ b/components/mbedtls/mbedtls @@ -1 +1 @@ -Subproject commit 6465247f67167518b8813ae2faaf422704e4b1a3 +Subproject commit 73cfa42bd39a704fa2706e3c1b1b532be5f19eed From 7a8c8f85766ae60b49528ac4b6fa631bc5892100 Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Fri, 26 Nov 2021 14:24:30 +0530 Subject: [PATCH 4/5] esp_bignum: move check for supported MPI bits at start of API This can allow hardware MPI API to return as soon as it identifies that it can handle require bitlength operation. --- components/mbedtls/port/esp_bignum.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/components/mbedtls/port/esp_bignum.c b/components/mbedtls/port/esp_bignum.c index 4cd047ab40..0c51fe44e6 100644 --- a/components/mbedtls/port/esp_bignum.c +++ b/components/mbedtls/port/esp_bignum.c @@ -277,19 +277,23 @@ cleanup2: static int esp_mpi_exp_mod( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M, mbedtls_mpi *_Rinv ) { int ret = 0; + + mbedtls_mpi Rinv_new; /* used if _Rinv == NULL */ + mbedtls_mpi *Rinv; /* points to _Rinv (if not NULL) othwerwise &RR_new */ + mbedtls_mpi_uint Mprime; + size_t x_words = mpi_words(X); size_t y_words = mpi_words(Y); size_t m_words = mpi_words(M); - /* "all numbers must be the same length", so choose longest number as cardinal length of operation... */ size_t num_words = esp_mpi_hardware_words(MAX(m_words, MAX(x_words, y_words))); - mbedtls_mpi Rinv_new; /* used if _Rinv == NULL */ - mbedtls_mpi *Rinv; /* points to _Rinv (if not NULL) othwerwise &RR_new */ - mbedtls_mpi_uint Mprime; + if (num_words * 32 > SOC_RSA_MAX_BIT_LEN) { + return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; + } if (mbedtls_mpi_cmp_int(M, 0) <= 0 || (M->p[0] & 1) == 0) { return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; @@ -303,10 +307,6 @@ static int esp_mpi_exp_mod( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_ return mbedtls_mpi_lset(Z, 1); } - if (num_words * 32 > SOC_RSA_MAX_BIT_LEN) { - return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; - } - /* Determine RR pointer, either _RR for cached value or local RR_new */ if (_Rinv == NULL) { From 70936f4c92af448af12e239a43c3525e2e006847 Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Thu, 2 Dec 2021 17:13:31 +0530 Subject: [PATCH 5/5] mbedtls: remove wrap from component.mk as well Note: This was not required in original MR, as master branch does not support GNU Make. --- components/mbedtls/component.mk | 4 ---- 1 file changed, 4 deletions(-) diff --git a/components/mbedtls/component.mk b/components/mbedtls/component.mk index 465fb5c16f..f550326bdd 100644 --- a/components/mbedtls/component.mk +++ b/components/mbedtls/component.mk @@ -75,10 +75,6 @@ WRAP_FUNCTIONS = mbedtls_ssl_handshake_client_step \ COMPONENT_SRCDIRS += port/dynamic endif -ifdef CONFIG_MBEDTLS_HARDWARE_MPI -WRAP_FUNCTIONS += mbedtls_mpi_exp_mod -endif - ifneq ($(origin WRAP_FUNCTIONS),undefined) WRAP_ARGUMENT := -Wl,--wrap= COMPONENT_ADD_LDFLAGS = -l$(COMPONENT_NAME) $(addprefix $(WRAP_ARGUMENT),$(WRAP_FUNCTIONS))