Merge pull request #3717 from pkolbus/issue-3647
Restore retry in rsa_prepare_blinding()
diff --git a/ChangeLog.d/fix-rsa-blinding.txt b/ChangeLog.d/fix-rsa-blinding.txt
new file mode 100644
index 0000000..a13572c
--- /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 84d87de..d6abd65 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -811,15 +811,14 @@
* 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) */