From 9ce6228b0f36fc8516aa74dc0eb0c2d726ea0b35 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 8001e58319a..df9aa24ce89 100644 --- a/components/mbedtls/port/bignum/esp_bignum.c +++ b/components/mbedtls/port/bignum/esp_bignum.c @@ -208,6 +208,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); @@ -415,7 +416,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)); }