Internal version of BN_mod_inverse allowing checking of no-inverse without
authorDr. Stephen Henson <steve@openssl.org>
Wed, 26 Jan 2011 16:59:47 +0000 (16:59 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Wed, 26 Jan 2011 16:59:47 +0000 (16:59 +0000)
need to inspect error queue.

crypto/bn/bn_blind.c
crypto/bn/bn_gcd.c
crypto/bn/bn_lcl.h

index e060592..6e00f43 100644 (file)
@@ -331,12 +331,12 @@ BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
                ret->m_ctx = m_ctx;
 
        do {
+               int rv;
                if (!BN_rand_range(ret->A, ret->mod)) goto err;
-               if (BN_mod_inverse(ret->Ai, ret->A, ret->mod, ctx) == NULL)
+               if (!int_bn_mod_inverse(ret->Ai, ret->A, ret->mod, ctx, &rv))
                        {
                        /* this should almost never happen for good RSA keys */
-                       unsigned long error = ERR_peek_last_error();
-                       if (ERR_GET_REASON(error) == BN_R_NO_INVERSE)
+                       if (rv)
                                {
                                if (retry_counter-- == 0)
                                {
@@ -344,7 +344,6 @@ BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
                                                BN_R_TOO_MANY_ITERATIONS);
                                        goto err;
                                }
-                               ERR_clear_error();
                                }
                        else
                                goto err;
index 4a35211..45b417b 100644 (file)
@@ -205,13 +205,28 @@ err:
 /* solves ax == 1 (mod n) */
 static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in,
         const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx);
+
 BIGNUM *BN_mod_inverse(BIGNUM *in,
        const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
        {
+       BIGNUM *rv;
+       int noinv;
+       rv = int_bn_mod_inverse(in, a, n, ctx, &noinv);
+       if (noinv)
+               BNerr(BN_F_BN_MOD_INVERSE,BN_R_NO_INVERSE);
+       return rv;
+       }
+
+BIGNUM *int_bn_mod_inverse(BIGNUM *in,
+       const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx, int *pnoinv)
+       {
        BIGNUM *A,*B,*X,*Y,*M,*D,*T,*R=NULL;
        BIGNUM *ret=NULL;
        int sign;
 
+       if (pnoinv)
+               *pnoinv = 0;
+
        if ((BN_get_flags(a, BN_FLG_CONSTTIME) != 0) || (BN_get_flags(n, BN_FLG_CONSTTIME) != 0))
                {
                return BN_mod_inverse_no_branch(in, a, n, ctx);
@@ -488,7 +503,8 @@ BIGNUM *BN_mod_inverse(BIGNUM *in,
                }
        else
                {
-               BNerr(BN_F_BN_MOD_INVERSE,BN_R_NO_INVERSE);
+               if (pnoinv)
+                       *pnoinv = 1;
                goto err;
                }
        ret=R;
index d7dff0d..ce085b5 100644 (file)
@@ -497,6 +497,9 @@ BN_ULONG bn_sub_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
        int cl, int dl);
 int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num);
 
+BIGNUM *int_bn_mod_inverse(BIGNUM *in,
+       const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx, int *noinv);
+
 #ifdef  __cplusplus
 }
 #endif