forked from rpms/openssl
- use localhost in testsuite, hopefully fixes slow build in koji
- CVE-2007-3108 - fix side channel attack on private keys (#250577) - make ssl session cache id matching strict (#233599)
This commit is contained in:
parent
b191bc7a11
commit
aa64c417f5
69
openssl-0.9.7a-ssl-strict-matching.patch
Normal file
69
openssl-0.9.7a-ssl-strict-matching.patch
Normal file
@ -0,0 +1,69 @@
|
||||
*) In the SSL/TLS server implementation, be strict about session ID
|
||||
context matching (which matters if an application uses a single
|
||||
external cache for different purposes). Previously,
|
||||
out-of-context reuse was forbidden only if SSL_VERIFY_PEER was
|
||||
set. This did ensure strict client verification, but meant that,
|
||||
with applications using a single external cache for quite
|
||||
different requirements, clients could circumvent ciphersuite
|
||||
restrictions for a given session ID context by starting a session
|
||||
in a different context.
|
||||
diff -up openssl-0.9.7a/ssl/ssl_sess.c.strict-matching openssl-0.9.7a/ssl/ssl_sess.c
|
||||
--- openssl-0.9.7a/ssl/ssl_sess.c.strict-matching 2002-11-28 09:09:03.000000000 +0100
|
||||
+++ openssl-0.9.7a/ssl/ssl_sess.c 2007-08-02 16:17:29.000000000 +0200
|
||||
@@ -322,33 +322,35 @@ int ssl_get_prev_session(SSL *s, unsigne
|
||||
|
||||
/* Now ret is non-NULL, and we own one of its reference counts. */
|
||||
|
||||
- if((s->verify_mode&SSL_VERIFY_PEER)
|
||||
- && (!s->sid_ctx_length || ret->sid_ctx_length != s->sid_ctx_length
|
||||
- || memcmp(ret->sid_ctx,s->sid_ctx,ret->sid_ctx_length)))
|
||||
- {
|
||||
+ if (ret->sid_ctx_length != s->sid_ctx_length
|
||||
+ || memcmp(ret->sid_ctx,s->sid_ctx,ret->sid_ctx_length))
|
||||
+ {
|
||||
/* We've found the session named by the client, but we don't
|
||||
* want to use it in this context. */
|
||||
-
|
||||
- if (s->sid_ctx_length == 0)
|
||||
- {
|
||||
- /* application should have used SSL[_CTX]_set_session_id_context
|
||||
- * -- we could tolerate this and just pretend we never heard
|
||||
- * of this session, but then applications could effectively
|
||||
- * disable the session cache by accident without anyone noticing */
|
||||
|
||||
- SSLerr(SSL_F_SSL_GET_PREV_SESSION,SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED);
|
||||
- fatal = 1;
|
||||
- goto err;
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
#if 0 /* The client cannot always know when a session is not appropriate,
|
||||
- * so we shouldn't generate an error message. */
|
||||
+ * so we shouldn't generate an error message. */
|
||||
|
||||
- SSLerr(SSL_F_SSL_GET_PREV_SESSION,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
|
||||
+ SSLerr(SSL_F_SSL_GET_PREV_SESSION,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
|
||||
#endif
|
||||
- goto err; /* treat like cache miss */
|
||||
- }
|
||||
+ goto err; /* treat like cache miss */
|
||||
+ }
|
||||
+
|
||||
+ if((s->verify_mode & SSL_VERIFY_PEER) && s->sid_ctx_length == 0)
|
||||
+ {
|
||||
+ /* We can't be sure if this session is being used out of
|
||||
+ * context, which is especially important for SSL_VERIFY_PEER.
|
||||
+ * The application should have used SSL[_CTX]_set_session_id_context.
|
||||
+ *
|
||||
+ * For this error case, we generate an error instead of treating
|
||||
+ * the event like a cache miss (otherwise it would be easy for
|
||||
+ * applications to effectively disable the session cache by
|
||||
+ * accident without anyone noticing).
|
||||
+ */
|
||||
+
|
||||
+ SSLerr(SSL_F_SSL_GET_PREV_SESSION,SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED);
|
||||
+ fatal = 1;
|
||||
+ goto err;
|
||||
}
|
||||
|
||||
if (ret->cipher == NULL)
|
932
openssl-0.9.8b-cve-2007-3108.patch
Normal file
932
openssl-0.9.8b-cve-2007-3108.patch
Normal file
@ -0,0 +1,932 @@
|
||||
diff -up openssl-0.9.8b/crypto/rsa/rsa.h.no-branch openssl-0.9.8b/crypto/rsa/rsa.h
|
||||
--- openssl-0.9.8b/crypto/rsa/rsa.h.no-branch 2007-08-03 13:58:54.000000000 +0200
|
||||
+++ openssl-0.9.8b/crypto/rsa/rsa.h 2007-08-03 13:58:58.000000000 +0200
|
||||
@@ -189,13 +189,17 @@ struct rsa_st
|
||||
* default (ignoring RSA_FLAG_BLINDING),
|
||||
* but other engines might not need it
|
||||
*/
|
||||
-#define RSA_FLAG_NO_EXP_CONSTTIME 0x0100 /* new with 0.9.7h; the built-in RSA
|
||||
- * implementation now uses constant time
|
||||
- * modular exponentiation for secret exponents
|
||||
- * by default. This flag causes the
|
||||
- * faster variable sliding window method to
|
||||
- * be used for all exponents.
|
||||
- */
|
||||
+#define RSA_FLAG_NO_CONSTTIME 0x0100 /* new with 0.9.8f; the built-in RSA
|
||||
+ * implementation now uses constant time
|
||||
+ * operations by default in private key operations,
|
||||
+ * e.g., constant time modular exponentiation,
|
||||
+ * modular inverse without leaking branches,
|
||||
+ * division without leaking branches. This
|
||||
+ * flag disables these constant time
|
||||
+ * operations and results in faster RSA
|
||||
+ * private key operations.
|
||||
+ */
|
||||
+#define RSA_FLAG_NO_EXP_CONSTTIME RSA_FLAG_NO_CONSTTIME /* deprecated name for the flag*/
|
||||
|
||||
#define RSA_PKCS1_PADDING 1
|
||||
#define RSA_SSLV23_PADDING 2
|
||||
diff -up openssl-0.9.8b/crypto/rsa/rsa_lib.c.no-branch openssl-0.9.8b/crypto/rsa/rsa_lib.c
|
||||
--- openssl-0.9.8b/crypto/rsa/rsa_lib.c.no-branch 2005-11-25 15:26:12.000000000 +0100
|
||||
+++ openssl-0.9.8b/crypto/rsa/rsa_lib.c 2007-08-03 13:58:58.000000000 +0200
|
||||
@@ -361,7 +361,8 @@ err:
|
||||
|
||||
BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx)
|
||||
{
|
||||
- BIGNUM *e;
|
||||
+ BIGNUM local_n;
|
||||
+ BIGNUM *e,*n;
|
||||
BN_CTX *ctx;
|
||||
BN_BLINDING *ret = NULL;
|
||||
|
||||
@@ -400,7 +401,16 @@ BN_BLINDING *RSA_setup_blinding(RSA *rsa
|
||||
RAND_add(rsa->d->d, rsa->d->dmax * sizeof rsa->d->d[0], 0.0);
|
||||
}
|
||||
|
||||
- ret = BN_BLINDING_create_param(NULL, e, rsa->n, ctx,
|
||||
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
+ {
|
||||
+ /* Set BN_FLG_CONSTTIME flag */
|
||||
+ n = &local_n;
|
||||
+ BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME);
|
||||
+ }
|
||||
+ else
|
||||
+ n = rsa->n;
|
||||
+
|
||||
+ ret = BN_BLINDING_create_param(NULL, e, n, ctx,
|
||||
rsa->meth->bn_mod_exp, rsa->_method_mod_n);
|
||||
if (ret == NULL)
|
||||
{
|
||||
diff -up openssl-0.9.8b/crypto/rsa/rsa_gen.c.no-branch openssl-0.9.8b/crypto/rsa/rsa_gen.c
|
||||
--- openssl-0.9.8b/crypto/rsa/rsa_gen.c.no-branch 2006-03-14 00:12:08.000000000 +0100
|
||||
+++ openssl-0.9.8b/crypto/rsa/rsa_gen.c 2007-08-03 13:58:58.000000000 +0200
|
||||
@@ -85,6 +85,8 @@ int RSA_generate_key_ex(RSA *rsa, int bi
|
||||
static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
|
||||
{
|
||||
BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL,*tmp;
|
||||
+ BIGNUM local_r0,local_d,local_p;
|
||||
+ BIGNUM *pr0,*d,*p;
|
||||
int bitsp,bitsq,ok= -1,n=0;
|
||||
BN_CTX *ctx=NULL;
|
||||
|
||||
@@ -165,16 +167,39 @@ static int rsa_builtin_keygen(RSA *rsa,
|
||||
if (!BN_sub(r1,rsa->p,BN_value_one())) goto err; /* p-1 */
|
||||
if (!BN_sub(r2,rsa->q,BN_value_one())) goto err; /* q-1 */
|
||||
if (!BN_mul(r0,r1,r2,ctx)) goto err; /* (p-1)(q-1) */
|
||||
- if (!BN_mod_inverse(rsa->d,rsa->e,r0,ctx)) goto err; /* d */
|
||||
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
+ {
|
||||
+ pr0 = &local_r0;
|
||||
+ BN_with_flags(pr0, r0, BN_FLG_CONSTTIME);
|
||||
+ }
|
||||
+ else
|
||||
+ pr0 = r0;
|
||||
+ if (!BN_mod_inverse(rsa->d,rsa->e,pr0,ctx)) goto err; /* d */
|
||||
+
|
||||
+ /* set up d for correct BN_FLG_CONSTTIME flag */
|
||||
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
+ {
|
||||
+ d = &local_d;
|
||||
+ BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
|
||||
+ }
|
||||
+ else
|
||||
+ d = rsa->d;
|
||||
|
||||
/* calculate d mod (p-1) */
|
||||
- if (!BN_mod(rsa->dmp1,rsa->d,r1,ctx)) goto err;
|
||||
+ if (!BN_mod(rsa->dmp1,d,r1,ctx)) goto err;
|
||||
|
||||
/* calculate d mod (q-1) */
|
||||
- if (!BN_mod(rsa->dmq1,rsa->d,r2,ctx)) goto err;
|
||||
+ if (!BN_mod(rsa->dmq1,d,r2,ctx)) goto err;
|
||||
|
||||
/* calculate inverse of q mod p */
|
||||
- if (!BN_mod_inverse(rsa->iqmp,rsa->q,rsa->p,ctx)) goto err;
|
||||
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
+ {
|
||||
+ p = &local_p;
|
||||
+ BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
|
||||
+ }
|
||||
+ else
|
||||
+ p = rsa->p;
|
||||
+ if (!BN_mod_inverse(rsa->iqmp,rsa->q,p,ctx)) goto err;
|
||||
|
||||
ok=1;
|
||||
err:
|
||||
diff -up openssl-0.9.8b/crypto/rsa/rsa_eay.c.no-branch openssl-0.9.8b/crypto/rsa/rsa_eay.c
|
||||
--- openssl-0.9.8b/crypto/rsa/rsa_eay.c.no-branch 2007-08-03 13:58:54.000000000 +0200
|
||||
+++ openssl-0.9.8b/crypto/rsa/rsa_eay.c 2007-08-03 13:58:58.000000000 +0200
|
||||
@@ -429,11 +429,11 @@ static int RSA_eay_private_encrypt(int f
|
||||
BIGNUM local_d;
|
||||
BIGNUM *d = NULL;
|
||||
|
||||
- if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
|
||||
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
{
|
||||
BN_init(&local_d);
|
||||
d = &local_d;
|
||||
- BN_with_flags(d, rsa->d, BN_FLG_EXP_CONSTTIME);
|
||||
+ BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
|
||||
}
|
||||
else
|
||||
d = rsa->d;
|
||||
@@ -551,10 +551,10 @@ static int RSA_eay_private_decrypt(int f
|
||||
BIGNUM local_d;
|
||||
BIGNUM *d = NULL;
|
||||
|
||||
- if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
|
||||
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
{
|
||||
d = &local_d;
|
||||
- BN_with_flags(d, rsa->d, BN_FLG_EXP_CONSTTIME);
|
||||
+ BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
|
||||
}
|
||||
else
|
||||
d = rsa->d;
|
||||
@@ -724,8 +724,9 @@ err:
|
||||
static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *r1,*m1,*vrfy;
|
||||
- BIGNUM local_dmp1, local_dmq1;
|
||||
- BIGNUM *dmp1, *dmq1;
|
||||
+ BIGNUM local_dmp1,local_dmq1,local_c,local_r1;
|
||||
+ BIGNUM *dmp1,*dmq1,*c,*pr1;
|
||||
+ int bn_flags;
|
||||
int ret=0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
@@ -733,26 +734,72 @@ static int RSA_eay_mod_exp(BIGNUM *r0, c
|
||||
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;
|
||||
+
|
||||
+ /* 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;
|
||||
+
|
||||
MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
|
||||
|
||||
- if (!BN_mod(r1,I,rsa->q,ctx)) goto err;
|
||||
- if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
|
||||
+ /* compute I mod q */
|
||||
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
+ {
|
||||
+ c = &local_c;
|
||||
+ BN_with_flags(c, I, BN_FLG_CONSTTIME);
|
||||
+ if (!BN_mod(r1,c,rsa->q,ctx)) goto err;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if (!BN_mod(r1,I,rsa->q,ctx)) goto err;
|
||||
+ }
|
||||
+
|
||||
+ /* compute r1^dmq1 mod q */
|
||||
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
{
|
||||
dmq1 = &local_dmq1;
|
||||
- BN_with_flags(dmq1, rsa->dmq1, BN_FLG_EXP_CONSTTIME);
|
||||
+ BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME);
|
||||
}
|
||||
else
|
||||
dmq1 = rsa->dmq1;
|
||||
if (!rsa->meth->bn_mod_exp(m1,r1,dmq1,rsa->q,ctx,
|
||||
rsa->_method_mod_q)) goto err;
|
||||
|
||||
- if (!BN_mod(r1,I,rsa->p,ctx)) goto err;
|
||||
- if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
|
||||
+ /* compute I mod p */
|
||||
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
+ {
|
||||
+ c = &local_c;
|
||||
+ BN_with_flags(c, I, BN_FLG_CONSTTIME);
|
||||
+ if (!BN_mod(r1,c,rsa->p,ctx)) goto err;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if (!BN_mod(r1,I,rsa->p,ctx)) goto err;
|
||||
+ }
|
||||
+
|
||||
+ /* compute r1^dmp1 mod p */
|
||||
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
{
|
||||
dmp1 = &local_dmp1;
|
||||
- BN_with_flags(dmp1, rsa->dmp1, BN_FLG_EXP_CONSTTIME);
|
||||
+ BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME);
|
||||
}
|
||||
else
|
||||
dmp1 = rsa->dmp1;
|
||||
@@ -766,7 +813,17 @@ static int RSA_eay_mod_exp(BIGNUM *r0, c
|
||||
if (!BN_add(r0,r0,rsa->p)) goto err;
|
||||
|
||||
if (!BN_mul(r1,r0,rsa->iqmp,ctx)) goto err;
|
||||
- if (!BN_mod(r0,r1,rsa->p,ctx)) goto err;
|
||||
+
|
||||
+ /* Turn BN_FLG_CONSTTIME flag on before division operation */
|
||||
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
+ {
|
||||
+ pr1 = &local_r1;
|
||||
+ BN_with_flags(pr1, r1, BN_FLG_CONSTTIME);
|
||||
+ }
|
||||
+ else
|
||||
+ pr1 = r1;
|
||||
+ if (!BN_mod(r0,pr1,rsa->p,ctx)) goto err;
|
||||
+
|
||||
/* If p < q it is occasionally possible for the correction of
|
||||
* adding 'p' if r0 is negative above to leave the result still
|
||||
* negative. This can break the private key operations: the following
|
||||
@@ -799,10 +856,10 @@ static int RSA_eay_mod_exp(BIGNUM *r0, c
|
||||
BIGNUM local_d;
|
||||
BIGNUM *d = NULL;
|
||||
|
||||
- if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
|
||||
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
{
|
||||
d = &local_d;
|
||||
- BN_with_flags(d, rsa->d, BN_FLG_EXP_CONSTTIME);
|
||||
+ BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
|
||||
}
|
||||
else
|
||||
d = rsa->d;
|
||||
diff -up openssl-0.9.8b/crypto/rsa/rsa_test.c.no-branch openssl-0.9.8b/crypto/rsa/rsa_test.c
|
||||
--- openssl-0.9.8b/crypto/rsa/rsa_test.c.no-branch 2005-05-16 03:43:31.000000000 +0200
|
||||
+++ openssl-0.9.8b/crypto/rsa/rsa_test.c 2007-08-03 13:58:58.000000000 +0200
|
||||
@@ -242,7 +242,7 @@ int main(int argc, char *argv[])
|
||||
clen = key3(key, ctext_ex);
|
||||
break;
|
||||
}
|
||||
- if (v/3 > 1) key->flags |= RSA_FLAG_NO_EXP_CONSTTIME;
|
||||
+ if (v/3 >= 1) key->flags |= RSA_FLAG_NO_CONSTTIME;
|
||||
|
||||
num = RSA_public_encrypt(plen, ptext_ex, ctext, key,
|
||||
RSA_PKCS1_PADDING);
|
||||
diff -up openssl-0.9.8b/crypto/bn/bn.h.no-branch openssl-0.9.8b/crypto/bn/bn.h
|
||||
--- openssl-0.9.8b/crypto/bn/bn.h.no-branch 2007-08-03 13:58:54.000000000 +0200
|
||||
+++ openssl-0.9.8b/crypto/bn/bn.h 2007-08-03 13:58:58.000000000 +0200
|
||||
@@ -245,8 +245,15 @@ extern "C" {
|
||||
|
||||
#define BN_FLG_MALLOCED 0x01
|
||||
#define BN_FLG_STATIC_DATA 0x02
|
||||
-#define BN_FLG_EXP_CONSTTIME 0x04 /* avoid leaking exponent information through timings
|
||||
- * (BN_mod_exp_mont() will call BN_mod_exp_mont_consttime) */
|
||||
+#define BN_FLG_CONSTTIME 0x04 /* avoid leaking exponent information through timing,
|
||||
+ * BN_mod_exp_mont() will call BN_mod_exp_mont_consttime,
|
||||
+ * BN_div() will call BN_div_no_branch,
|
||||
+ * BN_mod_inverse() will call BN_mod_inverse_no_branch.
|
||||
+ */
|
||||
+#define BN_FLG_EXP_CONSTTIME BN_FLG_CONSTTIME /* deprecated name for the flag */
|
||||
+ /* avoid leaking exponent information through timings
|
||||
+ * (BN_mod_exp_mont() will call BN_mod_exp_mont_consttime) */
|
||||
+
|
||||
#ifndef OPENSSL_NO_DEPRECATED
|
||||
#define BN_FLG_FREE 0x8000 /* used for debuging */
|
||||
#endif
|
||||
@@ -534,7 +541,7 @@ BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_M
|
||||
#define BN_BLINDING_NO_UPDATE 0x00000001
|
||||
#define BN_BLINDING_NO_RECREATE 0x00000002
|
||||
|
||||
-BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod);
|
||||
+BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, /* const */ BIGNUM *mod);
|
||||
void BN_BLINDING_free(BN_BLINDING *b);
|
||||
int BN_BLINDING_update(BN_BLINDING *b,BN_CTX *ctx);
|
||||
int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
|
||||
@@ -546,7 +553,7 @@ void BN_BLINDING_set_thread_id(BN_BLINDI
|
||||
unsigned long BN_BLINDING_get_flags(const BN_BLINDING *);
|
||||
void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long);
|
||||
BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
|
||||
- const BIGNUM *e, BIGNUM *m, BN_CTX *ctx,
|
||||
+ const BIGNUM *e, /* const */ BIGNUM *m, BN_CTX *ctx,
|
||||
int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
|
||||
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx),
|
||||
BN_MONT_CTX *m_ctx);
|
||||
diff -up openssl-0.9.8b/crypto/bn/bn_mont.c.no-branch openssl-0.9.8b/crypto/bn/bn_mont.c
|
||||
--- openssl-0.9.8b/crypto/bn/bn_mont.c.no-branch 2007-08-03 13:58:54.000000000 +0200
|
||||
+++ openssl-0.9.8b/crypto/bn/bn_mont.c 2007-08-03 13:58:58.000000000 +0200
|
||||
@@ -159,6 +159,7 @@ int BN_from_montgomery(BIGNUM *ret, cons
|
||||
BIGNUM *n,*r;
|
||||
BN_ULONG *ap,*np,*rp,n0,v,*nrp;
|
||||
int al,nl,max,i,x,ri;
|
||||
+ size_t m1,m2;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
if ((r = BN_CTX_get(ctx)) == NULL) goto err;
|
||||
@@ -176,7 +177,6 @@ int BN_from_montgomery(BIGNUM *ret, cons
|
||||
|
||||
max=(nl+al+1); /* allow for overflow (no?) XXX */
|
||||
if (bn_wexpand(r,max) == NULL) goto err;
|
||||
- if (bn_wexpand(ret,max) == NULL) goto err;
|
||||
|
||||
r->neg=a->neg^n->neg;
|
||||
np=n->d;
|
||||
@@ -228,37 +228,56 @@ int BN_from_montgomery(BIGNUM *ret, cons
|
||||
}
|
||||
bn_correct_top(r);
|
||||
|
||||
- /* mont->ri will be a multiple of the word size */
|
||||
-#if 0
|
||||
- BN_rshift(ret,r,mont->ri);
|
||||
-#else
|
||||
+ /* mont->ri will be a multiple of the word size and below code
|
||||
+ * is kind of BN_rshift(ret,r,mont->ri) equivalent */
|
||||
+ if (r->top <= ri)
|
||||
+ {
|
||||
+ ret->top=0;
|
||||
+ retn=1;
|
||||
+ goto err;
|
||||
+ }
|
||||
+ al=r->top-ri;
|
||||
+ if (bn_wexpand(ret,ri) == NULL) goto err;
|
||||
+ x=0-(((al-ri)>>(sizeof(al)*8-1))&1);
|
||||
+ ret->top=x=(ri&~x)|(al&x); /* min(ri,al) */
|
||||
ret->neg = r->neg;
|
||||
- x=ri;
|
||||
+
|
||||
rp=ret->d;
|
||||
- ap= &(r->d[x]);
|
||||
- if (r->top < x)
|
||||
- al=0;
|
||||
- else
|
||||
- al=r->top-x;
|
||||
- ret->top=al;
|
||||
- al-=4;
|
||||
- for (i=0; i<al; i+=4)
|
||||
+ ap=&(r->d[ri]);
|
||||
+
|
||||
+ v=bn_sub_words(rp,ap,np,ri);
|
||||
+ /* this -----------------------^^ works even in al<ri case
|
||||
+ * thanks to zealous zeroing of top of the vector in the
|
||||
+ * beginning. */
|
||||
+
|
||||
+ /* if (al==ri && !v) || al>ri) nrp=rp; else nrp=ap; */
|
||||
+ /* in other words if subtraction result is real, then
|
||||
+ * trick unconditional memcpy below to perform in-place
|
||||
+ * "refresh" instead of actual copy. */
|
||||
+ m1=0-(size_t)(((al-ri)>>(sizeof(al)*8-1))&1); /* al<ri */
|
||||
+ m2=0-(size_t)(((ri-al)>>(sizeof(al)*8-1))&1); /* al>ri */
|
||||
+ m1|=m2; /* (al!=ri) */
|
||||
+ m1|=(0-(size_t)v); /* (al!=ri || v) */
|
||||
+ m1&=~m2; /* (al!=ri || v) && !al>ri */
|
||||
+ nrp=(BN_ULONG *)(((size_t)rp&~m1)|((size_t)ap&m1));
|
||||
+
|
||||
+ /* 'i<ri' is chosen to eliminate dependency on input data, even
|
||||
+ * though it results in redundant copy in al<ri case. */
|
||||
+ for (i=0,ri-=4; i<ri; i+=4)
|
||||
{
|
||||
BN_ULONG t1,t2,t3,t4;
|
||||
|
||||
- t1=ap[i+0];
|
||||
- t2=ap[i+1];
|
||||
- t3=ap[i+2];
|
||||
- t4=ap[i+3];
|
||||
- rp[i+0]=t1;
|
||||
- rp[i+1]=t2;
|
||||
+ t1=nrp[i+0];
|
||||
+ t2=nrp[i+1];
|
||||
+ t3=nrp[i+2]; ap[i+0]=0;
|
||||
+ t4=nrp[i+3]; ap[i+1]=0;
|
||||
+ rp[i+0]=t1; ap[i+2]=0;
|
||||
+ rp[i+1]=t2; ap[i+3]=0;
|
||||
rp[i+2]=t3;
|
||||
rp[i+3]=t4;
|
||||
}
|
||||
- al+=4;
|
||||
- for (; i<al; i++)
|
||||
- rp[i]=ap[i];
|
||||
-#endif
|
||||
+ for (ri+=4; i<ri; i++)
|
||||
+ rp[i]=nrp[i], ap[i]=0;
|
||||
#else /* !MONT_WORD */
|
||||
BIGNUM *t1,*t2;
|
||||
|
||||
@@ -276,12 +295,12 @@ int BN_from_montgomery(BIGNUM *ret, cons
|
||||
if (!BN_mul(t1,t2,&mont->N,ctx)) goto err;
|
||||
if (!BN_add(t2,a,t1)) goto err;
|
||||
if (!BN_rshift(ret,t2,mont->ri)) goto err;
|
||||
-#endif /* MONT_WORD */
|
||||
|
||||
if (BN_ucmp(ret, &(mont->N)) >= 0)
|
||||
{
|
||||
if (!BN_usub(ret,ret,&(mont->N))) goto err;
|
||||
}
|
||||
+#endif /* MONT_WORD */
|
||||
retn=1;
|
||||
bn_check_top(ret);
|
||||
err:
|
||||
diff -up openssl-0.9.8b/crypto/bn/bn_lib.c.no-branch openssl-0.9.8b/crypto/bn/bn_lib.c
|
||||
--- openssl-0.9.8b/crypto/bn/bn_lib.c.no-branch 2005-05-03 22:27:00.000000000 +0200
|
||||
+++ openssl-0.9.8b/crypto/bn/bn_lib.c 2007-08-03 13:58:58.000000000 +0200
|
||||
@@ -763,7 +763,7 @@ int BN_is_bit_set(const BIGNUM *a, int n
|
||||
i=n/BN_BITS2;
|
||||
j=n%BN_BITS2;
|
||||
if (a->top <= i) return 0;
|
||||
- return((a->d[i]&(((BN_ULONG)1)<<j))?1:0);
|
||||
+ return(((a->d[i])>>j)&((BN_ULONG)1));
|
||||
}
|
||||
|
||||
int BN_mask_bits(BIGNUM *a, int n)
|
||||
diff -up openssl-0.9.8b/crypto/bn/bn_blind.c.no-branch openssl-0.9.8b/crypto/bn/bn_blind.c
|
||||
--- openssl-0.9.8b/crypto/bn/bn_blind.c.no-branch 2005-05-26 06:30:48.000000000 +0200
|
||||
+++ openssl-0.9.8b/crypto/bn/bn_blind.c 2007-08-03 13:58:58.000000000 +0200
|
||||
@@ -131,7 +131,7 @@ struct bn_blinding_st
|
||||
BN_MONT_CTX *m_ctx);
|
||||
};
|
||||
|
||||
-BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod)
|
||||
+BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, /* const */ BIGNUM *mod)
|
||||
{
|
||||
BN_BLINDING *ret=NULL;
|
||||
|
||||
@@ -151,7 +151,12 @@ BN_BLINDING *BN_BLINDING_new(const BIGNU
|
||||
{
|
||||
if ((ret->Ai = BN_dup(Ai)) == NULL) goto err;
|
||||
}
|
||||
- ret->mod = mod;
|
||||
+
|
||||
+ /* 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;
|
||||
return(ret);
|
||||
err:
|
||||
@@ -167,6 +172,7 @@ void BN_BLINDING_free(BN_BLINDING *r)
|
||||
if (r->A != NULL) BN_free(r->A );
|
||||
if (r->Ai != NULL) BN_free(r->Ai);
|
||||
if (r->e != NULL) BN_free(r->e );
|
||||
+ if (r->mod != NULL) BN_free(r->mod);
|
||||
OPENSSL_free(r);
|
||||
}
|
||||
|
||||
@@ -278,7 +284,7 @@ void BN_BLINDING_set_flags(BN_BLINDING *
|
||||
}
|
||||
|
||||
BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
|
||||
- const BIGNUM *e, BIGNUM *m, BN_CTX *ctx,
|
||||
+ const BIGNUM *e, /* const */ BIGNUM *m, BN_CTX *ctx,
|
||||
int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
|
||||
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx),
|
||||
BN_MONT_CTX *m_ctx)
|
||||
diff -up openssl-0.9.8b/crypto/bn/bn_div.c.no-branch openssl-0.9.8b/crypto/bn/bn_div.c
|
||||
--- openssl-0.9.8b/crypto/bn/bn_div.c.no-branch 2005-08-29 01:20:43.000000000 +0200
|
||||
+++ openssl-0.9.8b/crypto/bn/bn_div.c 2007-08-03 13:58:58.000000000 +0200
|
||||
@@ -169,13 +169,15 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, cons
|
||||
#endif /* OPENSSL_NO_ASM */
|
||||
|
||||
|
||||
-/* BN_div computes dv := num / divisor, rounding towards zero, and sets up
|
||||
- * rm such that dv*divisor + rm = num holds.
|
||||
+/* BN_div[_no_branch] computes dv := num / divisor, rounding towards
|
||||
+ * zero, and sets up rm such that dv*divisor + rm = num holds.
|
||||
* Thus:
|
||||
* dv->neg == num->neg ^ divisor->neg (unless the result is zero)
|
||||
* rm->neg == num->neg (unless the remainder is zero)
|
||||
* If 'dv' or 'rm' is NULL, the respective value is not returned.
|
||||
*/
|
||||
+static int BN_div_no_branch(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num,
|
||||
+ const BIGNUM *divisor, BN_CTX *ctx);
|
||||
int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
@@ -185,6 +187,11 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const
|
||||
BN_ULONG d0,d1;
|
||||
int num_n,div_n;
|
||||
|
||||
+ if (BN_get_flags(num, 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);
|
||||
@@ -397,4 +404,229 @@ err:
|
||||
return(0);
|
||||
}
|
||||
|
||||
+
|
||||
+/* BN_div_no_branch is a special version of BN_div. It does not contain
|
||||
+ * branches that may leak sensitive information.
|
||||
+ */
|
||||
+static int BN_div_no_branch(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;
|
||||
+
|
||||
+ bn_check_top(dv);
|
||||
+ bn_check_top(rm);
|
||||
+ bn_check_top(num);
|
||||
+ bn_check_top(divisor);
|
||||
+
|
||||
+ if (BN_is_zero(divisor))
|
||||
+ {
|
||||
+ BNerr(BN_F_BN_DIV,BN_R_DIV_BY_ZERO);
|
||||
+ return(0);
|
||||
+ }
|
||||
+
|
||||
+ 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) 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;
|
||||
+
|
||||
+ /* Since we don't know whether snum is larger than sdiv,
|
||||
+ * we pad snum with enough zeroes without changing its
|
||||
+ * value.
|
||||
+ */
|
||||
+ if (snum->top <= sdiv->top+1)
|
||||
+ {
|
||||
+ if (bn_wexpand(snum, sdiv->top + 2) == NULL) goto err;
|
||||
+ for (i = snum->top; i < sdiv->top + 2; i++) snum->d[i] = 0;
|
||||
+ snum->top = sdiv->top + 2;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if (bn_wexpand(snum, snum->top + 1) == NULL) goto err;
|
||||
+ snum->d[snum->top] = 0;
|
||||
+ snum->top ++;
|
||||
+ }
|
||||
+
|
||||
+ 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-1;
|
||||
+ resp= &(res->d[loop-1]);
|
||||
+
|
||||
+ /* space for temp */
|
||||
+ if (!bn_wexpand(tmp,(div_n+1))) goto err;
|
||||
+
|
||||
+ /* 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
|
||||
+ fprintf(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,ql,qh;
|
||||
+
|
||||
+ q=bn_div_words(n0,n1,d0);
|
||||
+#ifdef BN_DEBUG_LEVITTE
|
||||
+ fprintf(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
|
||||
+ 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_correct_top(res);
|
||||
+ BN_CTX_end(ctx);
|
||||
+ return(1);
|
||||
+err:
|
||||
+ bn_check_top(rm);
|
||||
+ BN_CTX_end(ctx);
|
||||
+ return(0);
|
||||
+ }
|
||||
+
|
||||
#endif
|
||||
diff -up openssl-0.9.8b/crypto/bn/bn_gcd.c.no-branch openssl-0.9.8b/crypto/bn/bn_gcd.c
|
||||
--- openssl-0.9.8b/crypto/bn/bn_gcd.c.no-branch 2005-08-29 01:20:43.000000000 +0200
|
||||
+++ openssl-0.9.8b/crypto/bn/bn_gcd.c 2007-08-03 13:58:58.000000000 +0200
|
||||
@@ -203,6 +203,8 @@ 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)
|
||||
{
|
||||
@@ -210,6 +212,11 @@ BIGNUM *BN_mod_inverse(BIGNUM *in,
|
||||
BIGNUM *ret=NULL;
|
||||
int sign;
|
||||
|
||||
+ if (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);
|
||||
|
||||
@@ -491,3 +498,157 @@ err:
|
||||
bn_check_top(ret);
|
||||
return(ret);
|
||||
}
|
||||
+
|
||||
+
|
||||
+/* BN_mod_inverse_no_branch is a special version of BN_mod_inverse.
|
||||
+ * It does not contain branches that may leak sensitive information.
|
||||
+ */
|
||||
+static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in,
|
||||
+ const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
|
||||
+ {
|
||||
+ BIGNUM *A,*B,*X,*Y,*M,*D,*T,*R=NULL;
|
||||
+ BIGNUM local_A, local_B;
|
||||
+ BIGNUM *pA, *pB;
|
||||
+ BIGNUM *ret=NULL;
|
||||
+ int sign;
|
||||
+
|
||||
+ 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))
|
||||
+ {
|
||||
+ /* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
|
||||
+ * BN_div_no_branch will be called eventually.
|
||||
+ */
|
||||
+ pB = &local_B;
|
||||
+ BN_with_flags(pB, B, BN_FLG_CONSTTIME);
|
||||
+ if (!BN_nnmod(B, pB, 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|).
|
||||
+ */
|
||||
+
|
||||
+ while (!BN_is_zero(B))
|
||||
+ {
|
||||
+ BIGNUM *tmp;
|
||||
+
|
||||
+ /*
|
||||
+ * 0 < B < A,
|
||||
+ * (*) -sign*X*a == B (mod |n|),
|
||||
+ * sign*Y*a == A (mod |n|)
|
||||
+ */
|
||||
+
|
||||
+ /* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
|
||||
+ * BN_div_no_branch will be called eventually.
|
||||
+ */
|
||||
+ pA = &local_A;
|
||||
+ BN_with_flags(pA, A, BN_FLG_CONSTTIME);
|
||||
+
|
||||
+ /* (D, M) := (A/B, A%B) ... */
|
||||
+ if (!BN_div(D,M,pA,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.
|
||||
+ */
|
||||
+
|
||||
+ 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);
|
||||
+ }
|
24
openssl-0.9.8b-test-use-localhost.patch
Normal file
24
openssl-0.9.8b-test-use-localhost.patch
Normal file
@ -0,0 +1,24 @@
|
||||
diff -up openssl-0.9.8b/ssl/ssltest.c.use-localhost openssl-0.9.8b/ssl/ssltest.c
|
||||
--- openssl-0.9.8b/ssl/ssltest.c.use-localhost 2006-02-24 18:58:35.000000000 +0100
|
||||
+++ openssl-0.9.8b/ssl/ssltest.c 2007-08-03 14:06:16.000000000 +0200
|
||||
@@ -839,19 +839,8 @@ bad:
|
||||
#ifndef OPENSSL_NO_KRB5
|
||||
if (c_ssl && c_ssl->kssl_ctx)
|
||||
{
|
||||
- char localhost[MAXHOSTNAMELEN+2];
|
||||
-
|
||||
- if (gethostname(localhost, sizeof localhost-1) == 0)
|
||||
- {
|
||||
- localhost[sizeof localhost-1]='\0';
|
||||
- if(strlen(localhost) == sizeof localhost-1)
|
||||
- {
|
||||
- BIO_printf(bio_err,"localhost name too long\n");
|
||||
- goto end;
|
||||
- }
|
||||
kssl_ctx_setstring(c_ssl->kssl_ctx, KSSL_SERVER,
|
||||
- localhost);
|
||||
- }
|
||||
+ "localhost");
|
||||
}
|
||||
#endif /* OPENSSL_NO_KRB5 */
|
||||
|
15
openssl.spec
15
openssl.spec
@ -21,7 +21,7 @@
|
||||
Summary: The OpenSSL toolkit
|
||||
Name: openssl
|
||||
Version: 0.9.8b
|
||||
Release: 13%{?dist}
|
||||
Release: 14%{?dist}
|
||||
Source: openssl-%{version}-usa.tar.bz2
|
||||
Source1: hobble-openssl
|
||||
Source2: Makefile.certificate
|
||||
@ -63,8 +63,11 @@ Patch60: openssl-0.9.8b-cve-2006-4343.patch
|
||||
Patch61: openssl-0.9.8b-aliasing-bug.patch
|
||||
Patch62: openssl-0.9.8b-x509-name-cmp.patch
|
||||
Patch63: openssl-0.9.8b-x509-add-dir.patch
|
||||
Patch64: openssl-0.9.8b-test-use-localhost.patch
|
||||
Patch65: openssl-0.9.8b-cve-2007-3108.patch
|
||||
Patch66: openssl-0.9.7a-ssl-strict-matching.patch
|
||||
|
||||
License: BSDish
|
||||
License: OpenSSL
|
||||
Group: System Environment/Libraries
|
||||
URL: http://www.openssl.org/
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-root
|
||||
@ -136,6 +139,9 @@ from other formats to the formats used by the OpenSSL toolkit.
|
||||
%patch61 -p1 -b .aliasing-bug
|
||||
%patch62 -p1 -b .name-cmp
|
||||
%patch63 -p1 -b .add-dir
|
||||
%patch64 -p1 -b .use-localhost
|
||||
%patch65 -p1 -b .no-branch
|
||||
%patch66 -p1 -b .strict-matching
|
||||
|
||||
# Modify the various perl scripts to reference perl in the right location.
|
||||
perl util/perlpath.pl `dirname %{__perl}`
|
||||
@ -376,6 +382,11 @@ rm -rf $RPM_BUILD_ROOT/%{_bindir}/openssl_fips_fingerprint
|
||||
%postun -p /sbin/ldconfig
|
||||
|
||||
%changelog
|
||||
* Fri Aug 3 2007 Tomas Mraz <tmraz@redhat.com> 0.9.8b-14
|
||||
- use localhost in testsuite, hopefully fixes slow build in koji
|
||||
- CVE-2007-3108 - fix side channel attack on private keys (#250577)
|
||||
- make ssl session cache id matching strict (#233599)
|
||||
|
||||
* Wed Jul 25 2007 Tomas Mraz <tmraz@redhat.com> 0.9.8b-13
|
||||
- allow building on ARM architectures (#245417)
|
||||
- use reference timestamps to prevent multilib conflicts (#218064)
|
||||
|
Loading…
Reference in New Issue
Block a user