BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod) { BN_BLINDING *ret=NULL; bn_check_top(mod); if ((ret=(BN_BLINDING *)OPENSSL_malloc(sizeof(BN_BLINDING))) == NULL) { BNerr(BN_F_BN_BLINDING_NEW,ERR_R_MALLOC_FAILURE); return(NULL); } memset(ret,0,sizeof(BN_BLINDING)); if (A != NULL) { if ((ret->A = BN_dup(A)) == NULL) goto err; } if (Ai != NULL) { if ((ret->Ai = BN_dup(Ai)) == NULL) goto err; } /* save a copy of mod in the BN_BLINDING structure */ if ((ret->mod = BN_dup(mod)) == NULL) goto err; if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0) BN_set_flags(ret->mod, BN_FLG_CONSTTIME); ret->counter = BN_BLINDING_COUNTER; CRYPTO_THREADID_current(&ret->tid); return(ret); err: if (ret != NULL) BN_BLINDING_free(ret); return(NULL); }
void BN_free(BIGNUM *a) { if (a == NULL) return; bn_check_top(a); if ((a->d != NULL) && !(BN_get_flags(a,BN_FLG_STATIC_DATA))) OPENSSL_free(a->d); if (a->flags & BN_FLG_MALLOCED) OPENSSL_free(a); else { a->d = NULL; } }
BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod) { BN_BLINDING *ret = NULL; bn_check_top(mod); if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) { BNerr(BN_F_BN_BLINDING_NEW, ERR_R_MALLOC_FAILURE); return NULL; } ret->lock = CRYPTO_THREAD_lock_new(); if (ret->lock == NULL) { BNerr(BN_F_BN_BLINDING_NEW, ERR_R_MALLOC_FAILURE); OPENSSL_free(ret); return NULL; } BN_BLINDING_set_current_thread(ret); if (A != NULL) { if ((ret->A = BN_dup(A)) == NULL) goto err; } if (Ai != NULL) { if ((ret->Ai = BN_dup(Ai)) == NULL) goto err; } /* save a copy of mod in the BN_BLINDING structure */ if ((ret->mod = BN_dup(mod)) == NULL) goto err; if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0) BN_set_flags(ret->mod, BN_FLG_CONSTTIME); /* * Set the counter to the special value -1 to indicate that this is * never-used fresh blinding that does not need updating before first * use. */ ret->counter = -1; return ret; err: BN_BLINDING_free(ret); return NULL; }
static int bn_blinding_create_param(BN_BLINDING *b, const RSA *rsa, BN_CTX *ctx) { int retry_counter = 32; do { if (!BN_rand_range(b->A, rsa->n)) { OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); return 0; } /* `BN_from_montgomery` + `BN_mod_inverse_no_branch` is equivalent to, but * more efficient than, `BN_mod_inverse_no_branch` + `BN_to_montgomery`. */ if (!BN_from_montgomery(b->Ai, b->A, rsa->mont_n, ctx)) { return 0; } assert(BN_get_flags(b->A, BN_FLG_CONSTTIME)); int no_inverse; if (BN_mod_inverse_no_branch(b->Ai, &no_inverse, b->Ai, rsa->n, ctx) == NULL) { /* this should almost never happen for good RSA keys */ if (no_inverse) { if (retry_counter-- == 0) { OPENSSL_PUT_ERROR(RSA, RSA_R_TOO_MANY_ITERATIONS); return 0; } ERR_clear_error(); } else { OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); return 0; } } else { break; } } while (1); if (!BN_mod_exp_mont(b->A, b->A, rsa->e, rsa->n, ctx, rsa->mont_n)) { OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); return 0; } if (!BN_to_montgomery(b->A, b->A, rsa->mont_n, ctx)) { OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); return 0; } return 1; }
BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod) { BN_BLINDING *ret = NULL; ret = (BN_BLINDING*) OPENSSL_malloc(sizeof(BN_BLINDING)); if (ret == NULL) { OPENSSL_PUT_ERROR(RSA, BN_BLINDING_new, ERR_R_MALLOC_FAILURE); return NULL; } memset(ret, 0, sizeof(BN_BLINDING)); if (A != NULL) { ret->A = BN_dup(A); if (ret->A == NULL) { goto err; } } if (Ai != NULL) { ret->Ai = BN_dup(Ai); if (ret->Ai == NULL) { goto err; } } /* save a copy of mod in the BN_BLINDING structure */ ret->mod = BN_dup(mod); if (ret->mod == NULL) { goto err; } if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0) { BN_set_flags(ret->mod, BN_FLG_CONSTTIME); } /* Set the counter to the special value -1 * to indicate that this is never-used fresh blinding * that does not need updating before first use. */ ret->counter = -1; return ret; err: if (ret != NULL) { BN_BLINDING_free(ret); } return NULL; }
BN_BLINDING *BN_BLINDING_new (const BIGNUM * A, const BIGNUM * Ai, BIGNUM * mod) { BN_BLINDING *ret = NULL; bn_check_top (mod); if ((ret = (BN_BLINDING *) OPENSSL_malloc (sizeof (BN_BLINDING))) == NULL) { BNerr (BN_F_BN_BLINDING_NEW, ERR_R_MALLOC_FAILURE); return (NULL); } memset (ret, 0, sizeof (BN_BLINDING)); if (A != NULL) { if ((ret->A = BN_dup (A)) == NULL) goto err; } if (Ai != NULL) { if ((ret->Ai = BN_dup (Ai)) == NULL) goto err; } /* save a copy of mod in the BN_BLINDING structure */ if ((ret->mod = BN_dup (mod)) == NULL) goto err; if (BN_get_flags (mod, BN_FLG_CONSTTIME) != 0) BN_set_flags (ret->mod, BN_FLG_CONSTTIME); /* Set the counter to the special value -1 * to indicate that this is never-used fresh blinding * that does not need updating before first use. */ ret->counter = -1; CRYPTO_THREADID_current (&ret->tid); return (ret); err: if (ret != NULL) BN_BLINDING_free (ret); return (NULL); }
BIGNUM *BN_mod_inverse(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx) { BIGNUM *A,*B,*X,*Y,*M,*D,*T,*R=NULL; BIGNUM *ret=NULL; int sign; 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); } bn_check_top(a); bn_check_top(n); BN_CTX_start(ctx); A = BN_CTX_get(ctx); B = BN_CTX_get(ctx); X = BN_CTX_get(ctx); D = BN_CTX_get(ctx); M = BN_CTX_get(ctx); Y = BN_CTX_get(ctx); T = BN_CTX_get(ctx); if (T == NULL) goto err; if (in == NULL) R=BN_new(); else R=in; if (R == NULL) goto err; BN_one(X); BN_zero(Y); if (BN_copy(B,a) == NULL) goto err; if (BN_copy(A,n) == NULL) goto err; A->neg = 0; if (B->neg || (BN_ucmp(B, A) >= 0)) { if (!BN_nnmod(B, B, A, ctx)) goto err; } sign = -1; /* From B = a mod |n|, A = |n| it follows that * * 0 <= B < A, * -sign*X*a == B (mod |n|), * sign*Y*a == A (mod |n|). */ if (BN_is_odd(n) && (BN_num_bits(n) <= (BN_BITS <= 32 ? 450 : 2048))) { /* Binary inversion algorithm; requires odd modulus. * This is faster than the general algorithm if the modulus * is sufficiently small (about 400 .. 500 bits on 32-bit * sytems, but much more on 64-bit systems) */ int shift; while (!BN_is_zero(B)) { /* * 0 < B < |n|, * 0 < A <= |n|, * (1) -sign*X*a == B (mod |n|), * (2) sign*Y*a == A (mod |n|) */ /* Now divide B by the maximum possible power of two in the integers, * and divide X by the same value mod |n|. * When we're done, (1) still holds. */ shift = 0; while (!BN_is_bit_set(B, shift)) /* note that 0 < B */ { shift++; if (BN_is_odd(X)) { if (!BN_uadd(X, X, n)) goto err; } /* now X is even, so we can easily divide it by two */ if (!BN_rshift1(X, X)) goto err; } if (shift > 0) { if (!BN_rshift(B, B, shift)) goto err; } /* Same for A and Y. Afterwards, (2) still holds. */ shift = 0; while (!BN_is_bit_set(A, shift)) /* note that 0 < A */ { shift++; if (BN_is_odd(Y)) { if (!BN_uadd(Y, Y, n)) goto err; } /* now Y is even */ if (!BN_rshift1(Y, Y)) goto err; } if (shift > 0) { if (!BN_rshift(A, A, shift)) goto err; } /* We still have (1) and (2). * Both A and B are odd. * The following computations ensure that * * 0 <= B < |n|, * 0 < A < |n|, * (1) -sign*X*a == B (mod |n|), * (2) sign*Y*a == A (mod |n|), * * and that either A or B is even in the next iteration. */ if (BN_ucmp(B, A) >= 0) { /* -sign*(X + Y)*a == B - A (mod |n|) */ if (!BN_uadd(X, X, Y)) goto err; /* NB: we could use BN_mod_add_quick(X, X, Y, n), but that * actually makes the algorithm slower */ if (!BN_usub(B, B, A)) goto err; } else { /* sign*(X + Y)*a == A - B (mod |n|) */ if (!BN_uadd(Y, Y, X)) goto err; /* as above, BN_mod_add_quick(Y, Y, X, n) would slow things down */ if (!BN_usub(A, A, B)) goto err; } } } else { /* general inversion algorithm */ while (!BN_is_zero(B)) { BIGNUM *tmp; /* * 0 < B < A, * (*) -sign*X*a == B (mod |n|), * sign*Y*a == A (mod |n|) */ /* (D, M) := (A/B, A%B) ... */ if (BN_num_bits(A) == BN_num_bits(B)) { if (!BN_one(D)) goto err; if (!BN_sub(M,A,B)) goto err; } else if (BN_num_bits(A) == BN_num_bits(B) + 1) { /* A/B is 1, 2, or 3 */ if (!BN_lshift1(T,B)) goto err; if (BN_ucmp(A,T) < 0) { /* A < 2*B, so D=1 */ if (!BN_one(D)) goto err; if (!BN_sub(M,A,B)) goto err; } else { /* A >= 2*B, so D=2 or D=3 */ if (!BN_sub(M,A,T)) goto err; if (!BN_add(D,T,B)) goto err; /* use D (:= 3*B) as temp */ if (BN_ucmp(A,D) < 0) { /* A < 3*B, so D=2 */ if (!BN_set_word(D,2)) goto err; /* M (= A - 2*B) already has the correct value */ } else { /* only D=3 remains */ if (!BN_set_word(D,3)) goto err; /* currently M = A - 2*B, but we need M = A - 3*B */ if (!BN_sub(M,M,B)) goto err; } } } else { if (!BN_div(D,M,A,B,ctx)) goto err; } /* Now * A = D*B + M; * thus we have * (**) sign*Y*a == D*B + M (mod |n|). */ tmp=A; /* keep the BIGNUM object, the value does not matter */ /* (A, B) := (B, A mod B) ... */ A=B; B=M; /* ... so we have 0 <= B < A again */ /* Since the former M is now B and the former B is now A, * (**) translates into * sign*Y*a == D*A + B (mod |n|), * i.e. * sign*Y*a - D*A == B (mod |n|). * Similarly, (*) translates into * -sign*X*a == A (mod |n|). * * Thus, * sign*Y*a + D*sign*X*a == B (mod |n|), * i.e. * sign*(Y + D*X)*a == B (mod |n|). * * So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at * -sign*X*a == B (mod |n|), * sign*Y*a == A (mod |n|). * Note that X and Y stay non-negative all the time. */ /* most of the time D is very small, so we can optimize tmp := D*X+Y */ if (BN_is_one(D)) { if (!BN_add(tmp,X,Y)) goto err; } else { if (BN_is_word(D,2)) { if (!BN_lshift1(tmp,X)) goto err; } else if (BN_is_word(D,4)) { if (!BN_lshift(tmp,X,2)) goto err; } else if (D->top == 1) { if (!BN_copy(tmp,X)) goto err; if (!BN_mul_word(tmp,D->d[0])) goto err; } else { if (!BN_mul(tmp,D,X,ctx)) goto err; } if (!BN_add(tmp,tmp,Y)) goto err; } M=Y; /* keep the BIGNUM object, the value does not matter */ Y=X; X=tmp; sign = -sign; } } /* * The while loop (Euclid's algorithm) ends when * A == gcd(a,n); * we have * sign*Y*a == A (mod |n|), * where Y is non-negative. */ if (sign < 0) { if (!BN_sub(Y,n,Y)) goto err; } /* Now Y*a == A (mod |n|). */ if (BN_is_one(A)) { /* Y*a == 1 (mod |n|) */ if (!Y->neg && BN_ucmp(Y,n) < 0) { if (!BN_copy(R,Y)) goto err; } else { if (!BN_nnmod(R,Y,n,ctx)) goto err; } } else { BNerr(BN_F_BN_MOD_INVERSE,BN_R_NO_INVERSE); goto err; } ret=R; err: if ((ret == NULL) && (in == NULL)) BN_free(R); BN_CTX_end(ctx); bn_check_top(ret); return(ret); }
int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { int ret = 0; int top, al, bl; BIGNUM *rr; #if defined(BN_MUL_COMBA) || defined(BN_RECURSION) int i; #endif #ifdef BN_RECURSION BIGNUM *t = NULL; int j = 0, k; #endif bn_check_top(a); bn_check_top(b); bn_check_top(r); al = a->top; bl = b->top; if ((al == 0) || (bl == 0)) { BN_zero(r); return (1); } top = al + bl; BN_CTX_start(ctx); if ((r == a) || (r == b)) { if ((rr = BN_CTX_get(ctx)) == NULL) goto err; } else rr = r; #if defined(BN_MUL_COMBA) || defined(BN_RECURSION) i = al - bl; #endif #ifdef BN_MUL_COMBA if (i == 0) { # if 0 if (al == 4) { if (bn_wexpand(rr, 8) == NULL) goto err; rr->top = 8; bn_mul_comba4(rr->d, a->d, b->d); goto end; } # endif if (al == 8) { if (bn_wexpand(rr, 16) == NULL) goto err; rr->top = 16; bn_mul_comba8(rr->d, a->d, b->d); goto end; } } #endif /* BN_MUL_COMBA */ #ifdef BN_RECURSION if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL)) { if (i >= -1 && i <= 1) { /* * Find out the power of two lower or equal to the longest of the * two numbers */ if (i >= 0) { j = BN_num_bits_word((BN_ULONG)al); } if (i == -1) { j = BN_num_bits_word((BN_ULONG)bl); } j = 1 << (j - 1); assert(j <= al || j <= bl); k = j + j; t = BN_CTX_get(ctx); if (t == NULL) goto err; if (al > j || bl > j) { if (bn_wexpand(t, k * 4) == NULL) goto err; if (bn_wexpand(rr, k * 4) == NULL) goto err; bn_mul_part_recursive(rr->d, a->d, b->d, j, al - j, bl - j, t->d); } else { /* al <= j || bl <= j */ if (bn_wexpand(t, k * 2) == NULL) goto err; if (bn_wexpand(rr, k * 2) == NULL) goto err; bn_mul_recursive(rr->d, a->d, b->d, j, al - j, bl - j, t->d); } rr->top = top; goto end; } # if 0 if (i == 1 && !BN_get_flags(b, BN_FLG_STATIC_DATA)) { BIGNUM *tmp_bn = (BIGNUM *)b; if (bn_wexpand(tmp_bn, al) == NULL) goto err; tmp_bn->d[bl] = 0; bl++; i--; } else if (i == -1 && !BN_get_flags(a, BN_FLG_STATIC_DATA)) { BIGNUM *tmp_bn = (BIGNUM *)a; if (bn_wexpand(tmp_bn, bl) == NULL) goto err; tmp_bn->d[al] = 0; al++; i++; } if (i == 0) { /* symmetric and > 4 */ /* 16 or larger */ j = BN_num_bits_word((BN_ULONG)al); j = 1 << (j - 1); k = j + j; t = BN_CTX_get(ctx); if (al == j) { /* exact multiple */ if (bn_wexpand(t, k * 2) == NULL) goto err; if (bn_wexpand(rr, k * 2) == NULL) goto err; bn_mul_recursive(rr->d, a->d, b->d, al, t->d); } else { if (bn_wexpand(t, k * 4) == NULL) goto err; if (bn_wexpand(rr, k * 4) == NULL) goto err; bn_mul_part_recursive(rr->d, a->d, b->d, al - j, j, t->d); } rr->top = top; goto end; } # endif } #endif /* BN_RECURSION */ if (bn_wexpand(rr, top) == NULL) goto err; rr->top = top; bn_mul_normal(rr->d, a->d, al, b->d, bl); #if defined(BN_MUL_COMBA) || defined(BN_RECURSION) end: #endif rr->neg = a->neg ^ b->neg; bn_correct_top(rr); if (r != rr && BN_copy(r, rr) == NULL) goto err; ret = 1; err: bn_check_top(r); BN_CTX_end(ctx); return (ret); }
int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor, BN_CTX *ctx) { int norm_shift,i,loop; BIGNUM *tmp,wnum,*snum,*sdiv,*res; BN_ULONG *resp,*wnump; BN_ULONG d0,d1; int num_n,div_n; /* Invalid zero-padding would have particularly bad consequences * in the case of 'num', so don't just rely on bn_check_top() for this one * (bn_check_top() works only for BN_DEBUG builds) */ if (num->top > 0 && num->d[num->top - 1] == 0) { BNerr(BN_F_BN_DIV,BN_R_NOT_INITIALIZED); return 0; } bn_check_top(num); if ((BN_get_flags(num, BN_FLG_CONSTTIME) != 0) || (BN_get_flags(divisor, BN_FLG_CONSTTIME) != 0)) { return BN_div_no_branch(dv, rm, num, divisor, ctx); } bn_check_top(dv); bn_check_top(rm); /* bn_check_top(num); */ /* 'num' has been checked already */ bn_check_top(divisor); if (BN_is_zero(divisor)) { BNerr(BN_F_BN_DIV,BN_R_DIV_BY_ZERO); return(0); } if (BN_ucmp(num,divisor) < 0) { if (rm != NULL) { if (BN_copy(rm,num) == NULL) return(0); } if (dv != NULL) BN_zero(dv); return(1); } BN_CTX_start(ctx); tmp=BN_CTX_get(ctx); snum=BN_CTX_get(ctx); sdiv=BN_CTX_get(ctx); if (dv == NULL) res=BN_CTX_get(ctx); else res=dv; if (sdiv == NULL || res == NULL || tmp == NULL || snum == NULL) goto err; /* First we normalise the numbers */ norm_shift=BN_BITS2-((BN_num_bits(divisor))%BN_BITS2); if (!(BN_lshift(sdiv,divisor,norm_shift))) goto err; sdiv->neg=0; norm_shift+=BN_BITS2; if (!(BN_lshift(snum,num,norm_shift))) goto err; snum->neg=0; div_n=sdiv->top; num_n=snum->top; loop=num_n-div_n; /* Lets setup a 'window' into snum * This is the part that corresponds to the current * 'area' being divided */ wnum.neg = 0; wnum.d = &(snum->d[loop]); wnum.top = div_n; /* only needed when BN_ucmp messes up the values between top and max */ wnum.dmax = snum->dmax - loop; /* so we don't step out of bounds */ /* Get the top 2 words of sdiv */ /* div_n=sdiv->top; */ d0=sdiv->d[div_n-1]; d1=(div_n == 1)?0:sdiv->d[div_n-2]; /* pointer to the 'top' of snum */ wnump= &(snum->d[num_n-1]); /* Setup to 'res' */ res->neg= (num->neg^divisor->neg); if (!bn_wexpand(res,(loop+1))) goto err; res->top=loop; resp= &(res->d[loop-1]); /* space for temp */ if (!bn_wexpand(tmp,(div_n+1))) goto err; if (BN_ucmp(&wnum,sdiv) >= 0) { /* If BN_DEBUG_RAND is defined BN_ucmp changes (via * bn_pollute) the const bignum arguments => * clean the values between top and max again */ bn_clear_top2max(&wnum); bn_sub_words(wnum.d, wnum.d, sdiv->d, div_n); *resp=1; } else res->top--; /* if res->top == 0 then clear the neg value otherwise decrease * the resp pointer */ if (res->top == 0) res->neg = 0; else resp--; for (i=0; i<loop-1; i++, wnump--, resp--) { BN_ULONG q,l0; /* the first part of the loop uses the top two words of * snum and sdiv to calculate a BN_ULONG q such that * | wnum - sdiv * q | < sdiv */ #if defined(BN_DIV3W) && !defined(OPENSSL_NO_ASM) BN_ULONG bn_div_3_words(BN_ULONG*,BN_ULONG,BN_ULONG); q=bn_div_3_words(wnump,d1,d0); #else BN_ULONG n0,n1,rem=0; n0=wnump[0]; n1=wnump[-1]; if (n0 == d0) q=BN_MASK2; else /* n0 < d0 */ { #ifdef BN_LLONG BN_ULLONG t2; #if defined(BN_LLONG) && defined(BN_DIV2W) && !defined(bn_div_words) q=(BN_ULONG)(((((BN_ULLONG)n0)<<BN_BITS2)|n1)/d0); #else q=bn_div_words(n0,n1,d0); #ifdef BN_DEBUG_LEVITTE TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR,"DEBUG: bn_div_words(0x%08X,0x%08X,0x%08\ X) -> 0x%08X\n", n0, n1, d0, q); #endif #endif #ifndef REMAINDER_IS_ALREADY_CALCULATED /* * rem doesn't have to be BN_ULLONG. The least we * know it's less that d0, isn't it? */ rem=(n1-q*d0)&BN_MASK2; #endif t2=(BN_ULLONG)d1*q; for (;;) { if (t2 <= ((((BN_ULLONG)rem)<<BN_BITS2)|wnump[-2])) break; q--; rem += d0; if (rem < d0) break; /* don't let rem overflow */ t2 -= d1; } #else /* !BN_LLONG */ BN_ULONG t2l,t2h; q=bn_div_words(n0,n1,d0); #ifdef BN_DEBUG_LEVITTE TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR,"DEBUG: bn_div_words(0x%08X,0x%08X,0x%08\ X) -> 0x%08X\n", n0, n1, d0, q); #endif #ifndef REMAINDER_IS_ALREADY_CALCULATED rem=(n1-q*d0)&BN_MASK2; #endif #if defined(BN_UMULT_LOHI) BN_UMULT_LOHI(t2l,t2h,d1,q); #elif defined(BN_UMULT_HIGH) t2l = d1 * q; t2h = BN_UMULT_HIGH(d1,q); #else { BN_ULONG ql, qh; t2l=LBITS(d1); t2h=HBITS(d1); ql =LBITS(q); qh =HBITS(q); mul64(t2l,t2h,ql,qh); /* t2=(BN_ULLONG)d1*q; */ } #endif for (;;) { if ((t2h < rem) || ((t2h == rem) && (t2l <= wnump[-2]))) break; q--; rem += d0; if (rem < d0) break; /* don't let rem overflow */ if (t2l < d1) t2h--; t2l -= d1; } #endif /* !BN_LLONG */ } #endif /* !BN_DIV3W */ l0=bn_mul_words(tmp->d,sdiv->d,div_n,q); tmp->d[div_n]=l0; wnum.d--; /* ingore top values of the bignums just sub the two * BN_ULONG arrays with bn_sub_words */ if (bn_sub_words(wnum.d, wnum.d, tmp->d, div_n+1)) { /* Note: As we have considered only the leading * two BN_ULONGs in the calculation of q, sdiv * q * might be greater than wnum (but then (q-1) * sdiv * is less or equal than wnum) */ q--; if (bn_add_words(wnum.d, wnum.d, sdiv->d, div_n)) /* we can't have an overflow here (assuming * that q != 0, but if q == 0 then tmp is * zero anyway) */ (*wnump)++; } /* store part of the result */ *resp = q; } bn_correct_top(snum); if (rm != NULL) { /* Keep a copy of the neg flag in num because if rm==num * BN_rshift() will overwrite it. */ int neg = num->neg; BN_rshift(rm,snum,norm_shift); if (!BN_is_zero(rm)) rm->neg = neg; bn_check_top(rm); } BN_CTX_end(ctx); return(1); err: bn_check_top(rm); BN_CTX_end(ctx); return(0); }
int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) { int ret = 0; BIGNUM *Ri, *R; BIGNUM tmod; BN_ULONG buf[2]; if (BN_is_zero(mod)) { OPENSSL_PUT_ERROR(BN, BN_R_DIV_BY_ZERO); return 0; } BN_CTX_start(ctx); Ri = BN_CTX_get(ctx); if (Ri == NULL) { goto err; } R = &mont->RR; /* grab RR as a temp */ if (!BN_copy(&mont->N, mod)) { goto err; /* Set N */ } if (BN_get_flags(mod, BN_FLG_CONSTTIME)) { BN_set_flags(&mont->N, BN_FLG_CONSTTIME); } mont->N.neg = 0; BN_init(&tmod); tmod.d = buf; tmod.dmax = 2; tmod.neg = 0; BN_zero(R); if (!BN_set_bit(R, BN_MONT_CTX_N0_LIMBS * BN_BITS2)) { goto err; } tmod.top = 0; buf[0] = mod->d[0]; if (buf[0] != 0) { tmod.top = 1; } buf[1] = 0; if (BN_MONT_CTX_N0_LIMBS == 2 && mod->top > 1 && mod->d[1] != 0) { buf[1] = mod->d[1]; tmod.top = 2; } if (BN_mod_inverse(Ri, R, &tmod, ctx) == NULL) { goto err; } if (!BN_lshift(Ri, Ri, BN_MONT_CTX_N0_LIMBS * BN_BITS2)) { goto err; /* R*Ri */ } const BIGNUM *Ri_dividend; if (!BN_is_zero(Ri)) { if (!BN_usub(Ri, Ri, BN_value_one())) { goto err; } Ri_dividend = Ri; } else { /* Ri == 0 so Ri - 1 == -1. -1 % tmod == 0xff..ff. */ static const BN_ULONG kMinusOneLimbs[BN_MONT_CTX_N0_LIMBS] = { BN_MASK2, #if BN_MONT_CTX_N0_LIMBS == 2 BN_MASK2 #endif }; STATIC_BIGNUM_DIAGNOSTIC_PUSH static const BIGNUM kMinusOne = STATIC_BIGNUM(kMinusOneLimbs); STATIC_BIGNUM_DIAGNOSTIC_POP Ri_dividend = &kMinusOne; } if (!BN_div(Ri, NULL, Ri_dividend, &tmod, ctx)) { goto err; } mont->n0[0] = 0; if (Ri->top > 0) { mont->n0[0] = Ri->d[0]; } mont->n0[1] = 0; if (BN_MONT_CTX_N0_LIMBS == 2 && Ri->top > 1) { mont->n0[1] = Ri->d[1]; } /* RR = (2^ri)^2 == 2^(ri*2) == 1 << (ri*2), which has its (ri*2)th bit set. */ int ri = (BN_num_bits(mod) + (BN_BITS2 - 1)) / BN_BITS2 * BN_BITS2; BN_zero(&(mont->RR)); if (!BN_set_bit(&(mont->RR), ri * 2)) { goto err; } if (!BN_mod(&(mont->RR), &(mont->RR), &(mont->N), ctx)) { goto err; } ret = 1; err: BN_CTX_end(ctx); return ret; }
int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx) { int top,al,bl; BIGNUM *rr; int ret = 0; #if defined(BN_MUL_COMBA) || defined(BN_RECURSION) int i; #endif #ifdef BN_RECURSION BIGNUM *t; int j,k; #endif #ifdef BN_COUNT printf("BN_mul %d * %d\n",a->top,b->top); #endif bn_check_top(a); bn_check_top(b); bn_check_top(r); al=a->top; bl=b->top; if ((al == 0) || (bl == 0)) { BN_zero(r); return(1); } top=al+bl; BN_CTX_start(ctx); if ((r == a) || (r == b)) { if ((rr = BN_CTX_get(ctx)) == NULL) goto err; } else rr = r; rr->neg=a->neg^b->neg; #if defined(BN_MUL_COMBA) || defined(BN_RECURSION) i = al-bl; #endif #ifdef BN_MUL_COMBA if (i == 0) { # if 0 if (al == 4) { if (bn_wexpand(rr,8) == NULL) goto err; rr->top=8; bn_mul_comba4(rr->d,a->d,b->d); goto end; } # endif if (al == 8) { if (bn_wexpand(rr,16) == NULL) goto err; rr->top=16; bn_mul_comba8(rr->d,a->d,b->d); goto end; } } #endif /* BN_MUL_COMBA */ #ifdef BN_RECURSION if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL)) { if (i == 1 && !BN_get_flags(b,BN_FLG_STATIC_DATA)) { if (bn_wexpand(b,al) == NULL) goto err; b->d[bl]=0; bl++; i--; } else if (i == -1 && !BN_get_flags(a,BN_FLG_STATIC_DATA)) { if (bn_wexpand(a,bl) == NULL) goto err; a->d[al]=0; al++; i++; } if (i == 0) { /* symmetric and > 4 */ /* 16 or larger */ j=BN_num_bits_word((BN_ULONG)al); j=1<<(j-1); k=j+j; t = BN_CTX_get(ctx); if (al == j) /* exact multiple */ { if (bn_wexpand(t,k*2) == NULL) goto err; if (bn_wexpand(rr,k*2) == NULL) goto err; bn_mul_recursive(rr->d,a->d,b->d,al,t->d); } else { if (bn_wexpand(a,k) == NULL) goto err; if (bn_wexpand(b,k) == NULL) goto err; if (bn_wexpand(t,k*4) == NULL) goto err; if (bn_wexpand(rr,k*4) == NULL) goto err; for (i=a->top; i<k; i++) a->d[i]=0; for (i=b->top; i<k; i++) b->d[i]=0; bn_mul_part_recursive(rr->d,a->d,b->d,al-j,j,t->d); } rr->top=top; goto end; } } #endif /* BN_RECURSION */ if (bn_wexpand(rr,top) == NULL) goto err; rr->top=top; bn_mul_normal(rr->d,a->d,al,b->d,bl); #if defined(BN_MUL_COMBA) || defined(BN_RECURSION) end: #endif bn_fix_top(rr); if (r != rr) BN_copy(r,rr); ret=1; err: BN_CTX_end(ctx); return(ret); }
int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { int ret = 0; int top, al, bl; BIGNUM *rr; #if defined(BN_MUL_COMBA) || defined(BN_RECURSION) int i; #endif #ifdef BN_RECURSION BIGNUM *t = NULL; int j = 0, k; #endif #ifdef BN_COUNT fprintf(stderr, "BN_mul %d * %d\n", a->top, b->top); #endif bn_check_top(a); bn_check_top(b); bn_check_top(r); al = a->top; bl = b->top; if ((al == 0) || (bl == 0)) { BN_zero(r); return (1); } top = al + bl; BN_CTX_start(ctx); if ((r == a) || (r == b)) { if ((rr = BN_CTX_get(ctx)) == NULL) goto err; } else /* Changes for cryptlib - pcg */ { /* Usually we can set: rr = r; but in the cases where t gets large (see the check further down for overflow due to k * 2 / k * 4) the value of rr needs to be large as well. We can't predict in advance when this will occur so we have to use an extended-size bignum for rr in all cases */ rr = ( BIGNUM * ) BN_CTX_get_ext( ctx, BIGNUM_EXT_MUL1 ); if( rr == NULL ) goto err; } /* End changes for cryptlib - pcg */ rr->neg = a->neg ^ b->neg; #if defined(BN_MUL_COMBA) || defined(BN_RECURSION) i = al - bl; #endif #ifdef BN_MUL_COMBA if (i == 0) { # if 0 if (al == 4) { if (bn_wexpand(rr, 8) == NULL) goto err; rr->top = 8; bn_mul_comba4(rr->d, a->d, b->d); goto end; } # endif if (al == 8) { if (bn_wexpand(rr, 16) == NULL) goto err; rr->top = 16; bn_mul_comba8(rr->d, a->d, b->d); goto end; } } #endif /* BN_MUL_COMBA */ #ifdef BN_RECURSION if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL)) { if (i >= -1 && i <= 1) { /* * Find out the power of two lower or equal to the longest of the * two numbers */ if (i >= 0) { j = BN_num_bits_word((BN_ULONG)al); } if (i == -1) { j = BN_num_bits_word((BN_ULONG)bl); } j = 1 << (j - 1); assert(j <= al || j <= bl); k = j + j; /* Changes for cryptlib - pcg */ if( ( k * 2 > BIGNUM_ALLOC_WORDS ) || \ ( ( al > j || bl > j ) && ( k * 4 > BIGNUM_ALLOC_WORDS ) ) ) { /* We're about to expand the temporary bignum that we're using to an enormous size, get a special extended-size bignum that won't result in a storage size-check error when used */ t = BN_CTX_get_ext( ctx, BIGNUM_EXT_MUL2 ); } else t = BN_CTX_get(ctx); /* End changes for cryptlib - pcg */ if (t == NULL) goto err; if (al > j || bl > j) { if (bn_wexpand(t, k * 4) == NULL) goto err; if (bn_wexpand(rr, k * 4) == NULL) goto err; bn_mul_part_recursive(rr->d, a->d, b->d, j, al - j, bl - j, t->d); } else { /* al <= j || bl <= j */ if (bn_wexpand(t, k * 2) == NULL) goto err; if (bn_wexpand(rr, k * 2) == NULL) goto err; bn_mul_recursive(rr->d, a->d, b->d, j, al - j, bl - j, t->d); } rr->top = top; goto end; } # if 0 if (i == 1 && !BN_get_flags(b, BN_FLG_STATIC_DATA)) { BIGNUM *tmp_bn = (BIGNUM *)b; if (bn_wexpand(tmp_bn, al) == NULL) goto err; tmp_bn->d[bl] = 0; bl++; i--; } else if (i == -1 && !BN_get_flags(a, BN_FLG_STATIC_DATA)) { BIGNUM *tmp_bn = (BIGNUM *)a; if (bn_wexpand(tmp_bn, bl) == NULL) goto err; tmp_bn->d[al] = 0; al++; i++; } if (i == 0) { /* symmetric and > 4 */ /* 16 or larger */ j = BN_num_bits_word((BN_ULONG)al); j = 1 << (j - 1); k = j + j; t = BN_CTX_get(ctx); if (al == j) { /* exact multiple */ if (bn_wexpand(t, k * 2) == NULL) goto err; if (bn_wexpand(rr, k * 2) == NULL) goto err; bn_mul_recursive(rr->d, a->d, b->d, al, t->d); } else { if (bn_wexpand(t, k * 4) == NULL) goto err; if (bn_wexpand(rr, k * 4) == NULL) goto err; bn_mul_part_recursive(rr->d, a->d, b->d, al - j, j, t->d); } rr->top = top; goto end; } # endif } #endif /* BN_RECURSION */ if (bn_wexpand(rr, top) == NULL) goto err; rr->top = top; bn_mul_normal(rr->d, a->d, al, b->d, bl); #if defined(BN_MUL_COMBA) || defined(BN_RECURSION) end: #endif bn_correct_top(rr); if (r != rr) BN_copy(r, rr); ret = 1; err: bn_check_top(r); BN_CTX_end_ext( ctx, BIGNUM_EXT_MUL1 ); /* pcg */ return (ret); }
int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) { int i, ret = 0; BIGNUM *Ri, *R; if (BN_is_zero(mod)) return 0; BN_CTX_start(ctx); if ((Ri = BN_CTX_get(ctx)) == NULL) goto err; R = &(mont->RR); /* grab RR as a temp */ if (!BN_copy(&(mont->N), mod)) goto err; /* Set N */ if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0) BN_set_flags(&(mont->N), BN_FLG_CONSTTIME); mont->N.neg = 0; #ifdef MONT_WORD { BIGNUM tmod; BN_ULONG buf[2]; bn_init(&tmod); tmod.d = buf; tmod.dmax = 2; tmod.neg = 0; if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0) BN_set_flags(&tmod, BN_FLG_CONSTTIME); mont->ri = (BN_num_bits(mod) + (BN_BITS2 - 1)) / BN_BITS2 * BN_BITS2; # if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32) /* * Only certain BN_BITS2<=32 platforms actually make use of n0[1], * and we could use the #else case (with a shorter R value) for the * others. However, currently only the assembler files do know which * is which. */ BN_zero(R); if (!(BN_set_bit(R, 2 * BN_BITS2))) goto err; tmod.top = 0; if ((buf[0] = mod->d[0])) tmod.top = 1; if ((buf[1] = mod->top > 1 ? mod->d[1] : 0)) tmod.top = 2; if (BN_is_one(&tmod)) BN_zero(Ri); else if ((BN_mod_inverse(Ri, R, &tmod, ctx)) == NULL) goto err; if (!BN_lshift(Ri, Ri, 2 * BN_BITS2)) goto err; /* R*Ri */ if (!BN_is_zero(Ri)) { if (!BN_sub_word(Ri, 1)) goto err; } else { /* if N mod word size == 1 */ if (bn_expand(Ri, (int)sizeof(BN_ULONG) * 2) == NULL) goto err; /* Ri-- (mod double word size) */ Ri->neg = 0; Ri->d[0] = BN_MASK2; Ri->d[1] = BN_MASK2; Ri->top = 2; } if (!BN_div(Ri, NULL, Ri, &tmod, ctx)) goto err; /* * Ni = (R*Ri-1)/N, keep only couple of least significant words: */ mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0; mont->n0[1] = (Ri->top > 1) ? Ri->d[1] : 0; # else BN_zero(R); if (!(BN_set_bit(R, BN_BITS2))) goto err; /* R */ buf[0] = mod->d[0]; /* tmod = N mod word size */ buf[1] = 0; tmod.top = buf[0] != 0 ? 1 : 0; /* Ri = R^-1 mod N */ if (BN_is_one(&tmod)) BN_zero(Ri); else if ((BN_mod_inverse(Ri, R, &tmod, ctx)) == NULL) goto err; if (!BN_lshift(Ri, Ri, BN_BITS2)) goto err; /* R*Ri */ if (!BN_is_zero(Ri)) { if (!BN_sub_word(Ri, 1)) goto err; } else { /* if N mod word size == 1 */ if (!BN_set_word(Ri, BN_MASK2)) goto err; /* Ri-- (mod word size) */ } if (!BN_div(Ri, NULL, Ri, &tmod, ctx)) goto err; /* * Ni = (R*Ri-1)/N, keep only least significant word: */ mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0; mont->n0[1] = 0; # endif } #else /* !MONT_WORD */ { /* bignum version */ mont->ri = BN_num_bits(&mont->N); BN_zero(R); if (!BN_set_bit(R, mont->ri)) goto err; /* R = 2^ri */ /* Ri = R^-1 mod N */ if ((BN_mod_inverse(Ri, R, &mont->N, ctx)) == NULL) goto err; if (!BN_lshift(Ri, Ri, mont->ri)) goto err; /* R*Ri */ if (!BN_sub_word(Ri, 1)) goto err; /* * Ni = (R*Ri-1) / N */ if (!BN_div(&(mont->Ni), NULL, Ri, &mont->N, ctx)) goto err; } #endif /* setup RR for conversions */ BN_zero(&(mont->RR)); if (!BN_set_bit(&(mont->RR), mont->ri * 2)) goto err; if (!BN_mod(&(mont->RR), &(mont->RR), &(mont->N), ctx)) goto err; for (i = mont->RR.top, ret = mont->N.top; i < ret; i++) mont->RR.d[i] = 0; mont->RR.top = ret; mont->RR.flags |= BN_FLG_FIXED_TOP; ret = 1; err: BN_CTX_end(ctx); return ret; }