From 2f73edbbc477aa288ec9215bce8fa8a29014b158 Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Mon, 27 Mar 2023 15:49:24 +0200 Subject: [PATCH] Prevent mpi_mod_write from corrupting the input Allocate a working buffer to store the converted value needed for the mpi_mod_write function. Signed-off-by: Gabor Mezei --- library/bignum_mod.c | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/library/bignum_mod.c b/library/bignum_mod.c index e986865a1..916d34a66 100644 --- a/library/bignum_mod.c +++ b/library/bignum_mod.c @@ -383,38 +383,46 @@ int mbedtls_mpi_mod_write(const mbedtls_mpi_mod_residue *r, size_t buflen, mbedtls_mpi_mod_ext_rep ext_rep) { - int ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; - /* Do our best to check if r and m have been set up */ if (r->limbs == 0 || N->limbs == 0) { - goto cleanup; + return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; } if (r->limbs != N->limbs) { - goto cleanup; + return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; } + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_mpi_uint *working_memory = r->p; + size_t working_memory_len = sizeof(mbedtls_mpi_uint) * r->limbs; + if (N->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY) { - ret = mbedtls_mpi_mod_raw_from_mont_rep(r->p, N); + + working_memory = mbedtls_calloc(r->limbs, sizeof(mbedtls_mpi_uint)); + + if (working_memory == NULL) { + ret = MBEDTLS_ERR_MPI_ALLOC_FAILED; + goto cleanup; + } + + memcpy(working_memory, r->p, working_memory_len); + + ret = mbedtls_mpi_mod_raw_from_mont_rep(working_memory, N); if (ret != 0) { goto cleanup; } } - ret = mbedtls_mpi_mod_raw_write(r->p, N, buf, buflen, ext_rep); - - if (N->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY) { - /* If this fails, the value of r is corrupted and we want to return - * this error (as opposed to the error code from the write above) to - * let the caller know. If it succeeds, we want to return the error - * code from write above. */ - int conv_ret = mbedtls_mpi_mod_raw_to_mont_rep(r->p, N); - if (ret == 0) { - ret = conv_ret; - } - } + ret = mbedtls_mpi_mod_raw_write(working_memory, N, buf, buflen, ext_rep); cleanup: + if (N->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY && + working_memory != NULL) { + + mbedtls_platform_zeroize(working_memory, working_memory_len); + mbedtls_free(working_memory); + } + return ret; } /* END MERGE SLOT 7 */