From 473dd5df7a1c02f3cdd13bc70cf214a88ed106ba Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Mon, 15 Jun 2026 11:39:01 +0530 Subject: [PATCH] fix(mbedtls): Fix cached Rinv size mismatch under private exponent blinding Prevent signature verification failures on targets that do not round hardware words to 16-word boundaries (e.g. ESP32-S3, ESP32-C6, and ESP32-P4), where exponent blinding can cause `num_words` to vary between calls, leading to reuse of an incorrectly sized cached `Rinv`. --- components/mbedtls/port/bignum/esp_bignum.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/components/mbedtls/port/bignum/esp_bignum.c b/components/mbedtls/port/bignum/esp_bignum.c index 1f9645cef89..42392c6e844 100644 --- a/components/mbedtls/port/bignum/esp_bignum.c +++ b/components/mbedtls/port/bignum/esp_bignum.c @@ -134,6 +134,7 @@ static int calculate_rinv(mbedtls_mpi *Rinv, const mbedtls_mpi *M, int num_words mbedtls_mpi_init(&RR); MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&RR, num_bits * 2, 1)); MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(Rinv, &RR, M)); + MBEDTLS_MPI_CHK(mbedtls_mpi_shrink(Rinv, num_words)); cleanup: mbedtls_mpi_free(&RR); @@ -417,7 +418,10 @@ static int esp_mpi_exp_mod( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_ } else { Rinv = _Rinv; } - if (Rinv->MBEDTLS_PRIVATE(p) == NULL) { + /* Rinv depends on num_words, which may vary with blinded exponents. + calculate_rinv() stores Rinv with exactly num_words limbs, so the + allocation size is used here as the cache tag. */ + if (Rinv->MBEDTLS_PRIVATE(p) == NULL || Rinv->MBEDTLS_PRIVATE(n) != num_words) { MBEDTLS_MPI_CHK(calculate_rinv(Rinv, M, num_words)); }