From fbd73884829416df55f3cd7531db42d7e89f4568 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 3 Dec 2025 11:26:09 +0100 Subject: [PATCH] RSA: handle low-probability events in a uniform way MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously we were looping in one case but not even checking the other. Let's check both cases and error out immediately. The error path should never be taken in pratice anyway. Signed-off-by: Manuel Pégourié-Gonnard --- library/rsa.c | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/library/rsa.c b/library/rsa.c index b0194cefe6..41a437ba3f 100644 --- a/library/rsa.c +++ b/library/rsa.c @@ -1313,16 +1313,15 @@ static int rsa_gen_rand_with_inverse(const mbedtls_rsa_context *ctx, mbedtls_mpi_init(&G); - mbedtls_mpi_lset(&G, 0); - do { - if (count++ > 10) { - ret = MBEDTLS_ERR_RSA_RNG_FAILED; - goto cleanup; - } + MBEDTLS_MPI_CHK(mbedtls_mpi_random(A, 1, &ctx->N, f_rng, p_rng)); + MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(&G, B, A, &ctx->N)); - MBEDTLS_MPI_CHK(mbedtls_mpi_random(A, 1, &ctx->N, f_rng, p_rng)); - MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(&G, B, A, &ctx->N)); - } while (mbedtls_mpi_cmp_int(&G, 1) != 0); + if (mbedtls_mpi_cmp_int(&G, 1) != 0) { + /* This happens if we're unlucky enough to draw a multiple of P or Q, + * of it one of them is not a prime and G is one of its factors. */ + ret = MBEDTLS_ERR_RSA_RNG_FAILED; + goto cleanup; + } cleanup: mbedtls_mpi_free(&G); @@ -1330,18 +1329,29 @@ cleanup: return ret; #else int ret; - mbedtls_mpi Ap, Aq, Bp, Bq; + mbedtls_mpi Ap, Aq, Bp, Bq, G; mbedtls_mpi_init(&Ap); mbedtls_mpi_init(&Aq); mbedtls_mpi_init(&Bp); mbedtls_mpi_init(&Bq); + mbedtls_mpi_init(&G); /* Generate Ap in [1, P) and compute Bp = Ap^-1 mod P */ MBEDTLS_MPI_CHK(mbedtls_mpi_random(&Ap, 1, &ctx->P, f_rng, p_rng)); - MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(NULL, &Bp, &Ap, &ctx->P)); + MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(&G, &Bp, &Ap, &ctx->P)); + if (mbedtls_mpi_cmp_int(&G, 1) != 0) { + /* This can only happen if P was not a prime. */ + ret = MBEDTLS_ERR_RSA_RNG_FAILED; + goto cleanup; + } /* Generate Ap in [1, Q) and compute Bq = Aq^-1 mod P */ MBEDTLS_MPI_CHK(mbedtls_mpi_random(&Aq, 1, &ctx->Q, f_rng, p_rng)); - MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(NULL, &Bq, &Aq, &ctx->Q)); + MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(&G, &Bq, &Aq, &ctx->Q)); + if (mbedtls_mpi_cmp_int(&G, 1) != 0) { + /* This can only happen if Q was not a prime. */ + ret = MBEDTLS_ERR_RSA_RNG_FAILED; + goto cleanup; + } /* Reconstruct A and B */ MBEDTLS_MPI_CHK(rsa_apply_crt(A, &Ap, &Aq, ctx)); @@ -1350,6 +1360,7 @@ cleanup: cleanup: mbedtls_mpi_free(&Ap); mbedtls_mpi_free(&Aq); mbedtls_mpi_free(&Bp); mbedtls_mpi_free(&Bq); + mbedtls_mpi_free(&G); return ret; #endif