Fix BN flag handling in RSA_eay_mod_exp() and BN_MONT_CTX_set() to get the expected BN_FLG_CONSTTIME behavior. [Bodo Moeller (Google)] openssl/crypto/bn/bn_mont.c 1.36.2.8 -> 1.36.2.9 --- openssl/crypto/bn/bn_mont.c 2007/11/11 20:43:23 1.36.2.8 +++ openssl/crypto/bn/bn_mont.c 2008/02/27 06:01:59 1.36.2.9 @@ -413,6 +413,8 @@ buf[0]=mod->d[0]; /* tmod = N mod word size */ buf[1]=0; + + BN_init(&tmod); tmod.d=buf; tmod.top = buf[0] != 0 ? 1 : 0; tmod.dmax=2; openssl/crypto/rsa/rsa_eay.c 1.46.2.8 -> 1.46.2.9 --- openssl/crypto/rsa/rsa_eay.c 2007/03/28 00:14:21 1.46.2.8 +++ openssl/crypto/rsa/rsa_eay.c 2008/02/27 06:02:00 1.46.2.9 @@ -151,13 +151,13 @@ } /* Usage example; - * MONT_HELPER(rsa, bn_ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err); + * MONT_HELPER(rsa->_method_mod_p, bn_ctx, rsa->p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err); */ -#define MONT_HELPER(rsa, ctx, m, pre_cond, err_instr) \ - if((pre_cond) && ((rsa)->_method_mod_##m == NULL) && \ - !BN_MONT_CTX_set_locked(&((rsa)->_method_mod_##m), \ +#define MONT_HELPER(method_mod, ctx, m, pre_cond, err_instr) \ + if ((pre_cond) && ((method_mod) == NULL) && \ + !BN_MONT_CTX_set_locked(&(method_mod), \ CRYPTO_LOCK_RSA, \ - (rsa)->m, (ctx))) \ + (m), (ctx))) \ err_instr static int RSA_eay_public_encrypt(int flen, const unsigned char *from, @@ -227,13 +227,13 @@ if (BN_bin2bn(buf,num,f) == NULL) goto err; if (BN_ucmp(f, rsa->n) >= 0) - { + { /* usually the padding functions would catch this */ RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS); goto err; } - MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); + MONT_HELPER(rsa->_method_mod_n, ctx, rsa->n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx, rsa->_method_mod_n)) goto err; @@ -436,9 +436,9 @@ BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); } else - d = rsa->d; + d= rsa->d; - MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); + MONT_HELPER(rsa->_method_mod_n, ctx, rsa->n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx, rsa->_method_mod_n)) goto err; @@ -559,7 +559,7 @@ else d = rsa->d; - MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); + MONT_HELPER(rsa->_method_mod_n, ctx, rsa->n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx, rsa->_method_mod_n)) goto err; @@ -669,7 +669,7 @@ goto err; } - MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); + MONT_HELPER(rsa->_method_mod_n, ctx, rsa->n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx, rsa->_method_mod_n)) goto err; @@ -717,7 +717,6 @@ BIGNUM *r1,*m1,*vrfy; BIGNUM local_dmp1,local_dmq1,local_c,local_r1; BIGNUM *dmp1,*dmq1,*c,*pr1; - int bn_flags; int ret=0; BN_CTX_start(ctx); @@ -725,31 +724,34 @@ m1 = BN_CTX_get(ctx); vrfy = BN_CTX_get(ctx); - /* Make sure mod_inverse in montgomerey intialization use correct - * BN_FLG_CONSTTIME flag. - */ - bn_flags = rsa->p->flags; - if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) - { - rsa->p->flags |= BN_FLG_CONSTTIME; - } - MONT_HELPER(rsa, ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err); - /* We restore bn_flags back */ - rsa->p->flags = bn_flags; + { + BIGNUM local_p, local_q; + BIGNUM *p = NULL, *q = NULL; - /* Make sure mod_inverse in montgomerey intialization use correct - * BN_FLG_CONSTTIME flag. - */ - bn_flags = rsa->q->flags; - if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) - { - rsa->q->flags |= BN_FLG_CONSTTIME; - } - MONT_HELPER(rsa, ctx, q, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err); - /* We restore bn_flags back */ - rsa->q->flags = bn_flags; + /* Make sure BN_mod_inverse in Montgomery intialization uses the + * BN_FLG_CONSTTIME flag (unless RSA_FLAG_NO_CONSTTIME is set) + */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + BN_init(&local_p); + p = &local_p; + BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME); + + BN_init(&local_q); + q = &local_q; + BN_with_flags(q, rsa->q, BN_FLG_CONSTTIME); + } + else + { + p = rsa->p; + q = rsa->q; + } + + MONT_HELPER(rsa->_method_mod_p, ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err); + MONT_HELPER(rsa->_method_mod_q, ctx, q, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err); + } - MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); + MONT_HELPER(rsa->_method_mod_n, ctx, rsa->n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); /* compute I mod q */ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) Fix DH with certain moduli. openssl/crypto/bn/bn_mul.c 1.36.4.1 -> 1.36.4.2 --- openssl/crypto/bn/bn_mul.c 2007/07/08 18:55:51 1.36.4.1 +++ openssl/crypto/bn/bn_mul.c 2007/11/03 20:10:10 1.36.4.2 @@ -389,6 +389,7 @@ * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0]) * a[1]*b[1] */ +/* dnX may not be positive, but n2/2+dnX has to be */ void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, int dna, int dnb, BN_ULONG *t) { @@ -398,7 +399,7 @@ BN_ULONG ln,lo,*p; # ifdef BN_COUNT - fprintf(stderr," bn_mul_recursive %d * %d\n",n2,n2); + fprintf(stderr," bn_mul_recursive %d%+d * %d%+d\n",n2,dna,n2,dnb); # endif # ifdef BN_MUL_COMBA # if 0 @@ -545,6 +546,7 @@ /* n+tn is the word length * t needs to be n*4 is size, as does r */ +/* tnX may not be negative but less than n */ void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n, int tna, int tnb, BN_ULONG *t) { @@ -553,8 +555,8 @@ BN_ULONG ln,lo,*p; # ifdef BN_COUNT - fprintf(stderr," bn_mul_part_recursive (%d+%d) * (%d+%d)\n", - tna, n, tnb, n); + fprintf(stderr," bn_mul_part_recursive (%d%+d) * (%d%+d)\n", + n, tna, n, tnb); # endif if (n < 8) { @@ -655,16 +657,19 @@ for (;;) { i/=2; - if (i <= tna && tna == tnb) + /* these simplified conditions work + * exclusively because difference + * between tna and tnb is 1 or 0 */ + if (i < tna || i < tnb) { - bn_mul_recursive(&(r[n2]), + bn_mul_part_recursive(&(r[n2]), &(a[n]),&(b[n]), i,tna-i,tnb-i,p); break; } - else if (i < tna || i < tnb) + else if (i == tna || i == tnb) { - bn_mul_part_recursive(&(r[n2]), + bn_mul_recursive(&(r[n2]), &(a[n]),&(b[n]), i,tna-i,tnb-i,p); break;