From ca8b8e7c31f856e329e03f4857bbeb9cb066d03e Mon Sep 17 00:00:00 2001 From: Peter Kolbus Date: Thu, 24 Sep 2020 11:11:50 -0500 Subject: [PATCH] Restore retry in rsa_prepare_blinding() Starting with commit 49e94e3, the do/while loop in `rsa_prepare_blinding()` was changed to a `do...while(0)`, which prevents retry from being effective and leaves dead code. Restore the while condition to retry, and lift the calls to finish the computation out of the while loop by by observing that they are performed only when `mbedtls_mpi_inv_mod()` returns zero. Signed-off-by: Peter Kolbus --- ChangeLog.d/fix-rsa-blinding.txt | 6 ++++++ library/rsa.c | 13 ++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) create mode 100644 ChangeLog.d/fix-rsa-blinding.txt diff --git a/ChangeLog.d/fix-rsa-blinding.txt b/ChangeLog.d/fix-rsa-blinding.txt new file mode 100644 index 000000000..a13572c9a --- /dev/null +++ b/ChangeLog.d/fix-rsa-blinding.txt @@ -0,0 +1,6 @@ +Bugfix + * Fix rsa_prepare_blinding() to retry when the blinding value is not + invertible (mod N), instead of returning MBEDTLS_ERR_RSA_RNG_FAILED. This + addresses a regression but is rare in practice (approx. 1 in 2/sqrt(N)). + Found by Synopsys Coverity, fix contributed by Peter Kolbus (Garmin). + Fixes #3647. diff --git a/library/rsa.c b/library/rsa.c index 84d87de0d..d6abd65d4 100644 --- a/library/rsa.c +++ b/library/rsa.c @@ -811,15 +811,14 @@ static int rsa_prepare_blinding( mbedtls_rsa_context *ctx, * which one, we just loop and choose new values for both of them. * (Each iteration succeeds with overwhelming probability.) */ ret = mbedtls_mpi_inv_mod( &ctx->Vi, &ctx->Vi, &ctx->N ); - if( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ) - continue; - if( ret != 0 ) + if( ret != 0 && ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ) goto cleanup; - /* Finish the computation of Vf^-1 = R * (R Vf)^-1 */ - MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &R ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) ); - } while( 0 ); + } while( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ); + + /* Finish the computation of Vf^-1 = R * (R Vf)^-1 */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &R ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) ); /* Blinding value: Vi = Vf^(-e) mod N * (Vi already contains Vf^-1 at this point) */