diff --git a/components/mbedtls/port/esp32/bignum.c b/components/mbedtls/port/esp32/bignum.c index d94b255aa3..2b55bc4c7d 100644 --- a/components/mbedtls/port/esp32/bignum.c +++ b/components/mbedtls/port/esp32/bignum.c @@ -67,7 +67,12 @@ void esp_mpi_interrupt_clear( void ) these additional words will be zeroed in the memory buffer. */ -static inline void mpi_to_mem_block(uint32_t mem_base, const mbedtls_mpi *mpi, size_t hw_words) + +/* Please see detailed note inside the function body below. + * Relevant: https://github.com/espressif/esp-idf/issues/8710 and IDF-6029 + */ +static inline void __attribute__((optimize("-fno-tree-loop-distribute-patterns"))) + mpi_to_mem_block(uint32_t mem_base, const mbedtls_mpi *mpi, size_t hw_words) { uint32_t *pbase = (uint32_t *)mem_base; uint32_t copy_words = MIN(hw_words, mpi->MBEDTLS_PRIVATE(n)); @@ -81,6 +86,26 @@ static inline void mpi_to_mem_block(uint32_t mem_base, const mbedtls_mpi *mpi, s for (uint32_t i = copy_words; i < hw_words; i++) { pbase[i] = 0; } + +#if _INTERNAL_DEBUG_PURPOSE + /* + * With Xtensa GCC 11.2.0 (from ESP-IDF v5.x), it was observed that above zero initialization + * loop gets optimized to `memset` call from the ROM library. This was causing an issue that + * specific write (store) operation to the MPI peripheral block was getting lost erroneously. + * Following data re-verify loop could catch it during runtime. + * + * As a workaround, we are disabling loop distribute patterns for this function and hence + * compiler does not enforce usage of `memset` (or `memcpy`) calls for this routine. It + * appears that `-ftree-loop-distribute-patterns` was enabled with O2/Os starting from + * GCC-10.x. It is quite possible that there is some issue with DPORT write with sequence of + * store instructions as generated by `memset` call, but for now this should serve as good + * interim workaround without any impact on the performance. + * + * Please see IDF-6029 for more details. + */ + + //for (uint32_t i = copy_words; i < hw_words; i++) { assert(pbase[i] == 0); } +#endif } /* Read mbedTLS MPI bignum back from hardware memory block. diff --git a/components/mbedtls/port/esp_bignum.c b/components/mbedtls/port/esp_bignum.c index 96601e056c..0cc987cbfa 100644 --- a/components/mbedtls/port/esp_bignum.c +++ b/components/mbedtls/port/esp_bignum.c @@ -642,6 +642,13 @@ static int mpi_mult_mpi_failover_mod_mult( mbedtls_mpi *Z, const mbedtls_mpi *X, esp_mpi_read_result_hw_op(Z, hw_words); Z->MBEDTLS_PRIVATE(s) = X->MBEDTLS_PRIVATE(s) * Y->MBEDTLS_PRIVATE(s); + /* + * If this condition fails then most likely hardware peripheral + * has produced an incorrect result for MPI operation. This can + * happen if data fed to the peripheral register was incorrect. + * Relevant: https://github.com/espressif/esp-idf/issues/8710#issuecomment-1249178698 + */ + assert(mpi_words(Z) == z_words); cleanup: esp_mpi_disable_hardware_hw_op(); return ret;