summaryrefslogtreecommitdiff
path: root/lib/libcrypto/rsa/rsa_eay.c
diff options
context:
space:
mode:
authorDamien Miller <djm@cvs.openbsd.org>2006-06-27 05:07:04 +0000
committerDamien Miller <djm@cvs.openbsd.org>2006-06-27 05:07:04 +0000
commit0fa0c9fb7d6f4ad7a423044f28b55eaaedc63f28 (patch)
tree98d6947cd8474ab98b57494ebef50e97659be043 /lib/libcrypto/rsa/rsa_eay.c
parentecc645c71513728e7357c84aa8997b4dc2301936 (diff)
resolve conflicts
Diffstat (limited to 'lib/libcrypto/rsa/rsa_eay.c')
-rw-r--r--lib/libcrypto/rsa/rsa_eay.c247
1 files changed, 147 insertions, 100 deletions
diff --git a/lib/libcrypto/rsa/rsa_eay.c b/lib/libcrypto/rsa/rsa_eay.c
index d4caab3f953..be4ac96ce33 100644
--- a/lib/libcrypto/rsa/rsa_eay.c
+++ b/lib/libcrypto/rsa/rsa_eay.c
@@ -55,6 +55,59 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
+/* ====================================================================
+ * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
#include <stdio.h>
#include "cryptlib.h"
@@ -145,30 +198,13 @@ static int RSA_eay_public_encrypt(int flen, const unsigned char *from,
goto err;
}
- if ((rsa->_method_mod_n == NULL) && (rsa->flags & RSA_FLAG_CACHE_PUBLIC))
+ if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
{
- BN_MONT_CTX* bn_mont_ctx;
- if ((bn_mont_ctx=BN_MONT_CTX_new()) == NULL)
- goto err;
- if (!BN_MONT_CTX_set(bn_mont_ctx,rsa->n,ctx))
- {
- BN_MONT_CTX_free(bn_mont_ctx);
+ if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n,
+ CRYPTO_LOCK_RSA, rsa->n, ctx))
goto err;
- }
- if (rsa->_method_mod_n == NULL) /* other thread may have finished first */
- {
- CRYPTO_w_lock(CRYPTO_LOCK_RSA);
- if (rsa->_method_mod_n == NULL)
- {
- rsa->_method_mod_n = bn_mont_ctx;
- bn_mont_ctx = NULL;
- }
- CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
- }
- if (bn_mont_ctx)
- BN_MONT_CTX_free(bn_mont_ctx);
}
-
+
if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->e,rsa->n,ctx,
rsa->_method_mod_n)) goto err;
@@ -249,7 +285,7 @@ err:
static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding)
{
- BIGNUM f,ret;
+ BIGNUM f,ret, *res;
int i,j,k,num=0,r= -1;
unsigned char *buf=NULL;
BN_CTX *ctx=NULL;
@@ -331,19 +367,43 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
(rsa->dmp1 != NULL) &&
(rsa->dmq1 != NULL) &&
(rsa->iqmp != NULL)) )
- { if (!rsa->meth->rsa_mod_exp(&ret,&f,rsa)) goto err; }
+ {
+ if (!rsa->meth->rsa_mod_exp(&ret,&f,rsa)) goto err;
+ }
else
{
- if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->d,rsa->n,ctx,NULL)) goto err;
+ BIGNUM local_d;
+ BIGNUM *d = NULL;
+
+ if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
+ {
+ BN_init(&local_d);
+ d = &local_d;
+ BN_with_flags(d, rsa->d, BN_FLG_EXP_CONSTTIME);
+ }
+ else
+ d = rsa->d;
+ if (!rsa->meth->bn_mod_exp(&ret,&f,d,rsa->n,ctx,NULL)) goto err;
}
if (blinding)
if (!BN_BLINDING_invert(&ret, blinding, ctx)) goto err;
+ if (padding == RSA_X931_PADDING)
+ {
+ BN_sub(&f, rsa->n, &ret);
+ if (BN_cmp(&ret, &f))
+ res = &f;
+ else
+ res = &ret;
+ }
+ else
+ res = &ret;
+
/* put in leading 0 bytes if the number is less than the
* length of the modulus */
- j=BN_num_bytes(&ret);
- i=BN_bn2bin(&ret,&(to[num-j]));
+ j=BN_num_bytes(res);
+ i=BN_bn2bin(res,&(to[num-j]));
for (k=0; k<(num-i); k++)
to[k]=0;
@@ -444,10 +504,22 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
(rsa->dmp1 != NULL) &&
(rsa->dmq1 != NULL) &&
(rsa->iqmp != NULL)) )
- { if (!rsa->meth->rsa_mod_exp(&ret,&f,rsa)) goto err; }
+ {
+ if (!rsa->meth->rsa_mod_exp(&ret,&f,rsa)) goto err;
+ }
else
{
- if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->d,rsa->n,ctx,NULL))
+ BIGNUM local_d;
+ BIGNUM *d = NULL;
+
+ if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
+ {
+ d = &local_d;
+ BN_with_flags(d, rsa->d, BN_FLG_EXP_CONSTTIME);
+ }
+ else
+ d = rsa->d;
+ if (!rsa->meth->bn_mod_exp(&ret,&f,d,rsa->n,ctx,NULL))
goto err;
}
@@ -534,33 +606,20 @@ static int RSA_eay_public_decrypt(int flen, const unsigned char *from,
}
/* do the decrypt */
- if ((rsa->_method_mod_n == NULL) && (rsa->flags & RSA_FLAG_CACHE_PUBLIC))
+
+ if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
{
- BN_MONT_CTX* bn_mont_ctx;
- if ((bn_mont_ctx=BN_MONT_CTX_new()) == NULL)
- goto err;
- if (!BN_MONT_CTX_set(bn_mont_ctx,rsa->n,ctx))
- {
- BN_MONT_CTX_free(bn_mont_ctx);
+ if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n,
+ CRYPTO_LOCK_RSA, rsa->n, ctx))
goto err;
- }
- if (rsa->_method_mod_n == NULL) /* other thread may have finished first */
- {
- CRYPTO_w_lock(CRYPTO_LOCK_RSA);
- if (rsa->_method_mod_n == NULL)
- {
- rsa->_method_mod_n = bn_mont_ctx;
- bn_mont_ctx = NULL;
- }
- CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
- }
- if (bn_mont_ctx)
- BN_MONT_CTX_free(bn_mont_ctx);
}
-
+
if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->e,rsa->n,ctx,
rsa->_method_mod_n)) goto err;
+ if ((padding == RSA_X931_PADDING) && ((ret.d[0] & 0xf) != 12))
+ BN_sub(&ret, rsa->n, &ret);
+
p=buf;
i=BN_bn2bin(&ret,p);
@@ -594,6 +653,8 @@ err:
static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
{
BIGNUM r1,m1,vrfy;
+ BIGNUM local_dmp1, local_dmq1;
+ BIGNUM *dmp1, *dmq1;
int ret=0;
BN_CTX *ctx;
@@ -604,61 +665,34 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
if (rsa->flags & RSA_FLAG_CACHE_PRIVATE)
{
- if (rsa->_method_mod_p == NULL)
- {
- BN_MONT_CTX* bn_mont_ctx;
- if ((bn_mont_ctx=BN_MONT_CTX_new()) == NULL)
- goto err;
- if (!BN_MONT_CTX_set(bn_mont_ctx,rsa->p,ctx))
- {
- BN_MONT_CTX_free(bn_mont_ctx);
- goto err;
- }
- if (rsa->_method_mod_p == NULL) /* other thread may have finished first */
- {
- CRYPTO_w_lock(CRYPTO_LOCK_RSA);
- if (rsa->_method_mod_p == NULL)
- {
- rsa->_method_mod_p = bn_mont_ctx;
- bn_mont_ctx = NULL;
- }
- CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
- }
- if (bn_mont_ctx)
- BN_MONT_CTX_free(bn_mont_ctx);
- }
-
- if (rsa->_method_mod_q == NULL)
- {
- BN_MONT_CTX* bn_mont_ctx;
- if ((bn_mont_ctx=BN_MONT_CTX_new()) == NULL)
- goto err;
- if (!BN_MONT_CTX_set(bn_mont_ctx,rsa->q,ctx))
- {
- BN_MONT_CTX_free(bn_mont_ctx);
- goto err;
- }
- if (rsa->_method_mod_q == NULL) /* other thread may have finished first */
- {
- CRYPTO_w_lock(CRYPTO_LOCK_RSA);
- if (rsa->_method_mod_q == NULL)
- {
- rsa->_method_mod_q = bn_mont_ctx;
- bn_mont_ctx = NULL;
- }
- CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
- }
- if (bn_mont_ctx)
- BN_MONT_CTX_free(bn_mont_ctx);
- }
+ if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_p,
+ CRYPTO_LOCK_RSA, rsa->p, ctx))
+ goto err;
+ if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_q,
+ CRYPTO_LOCK_RSA, rsa->q, ctx))
+ goto err;
}
-
+
if (!BN_mod(&r1,I,rsa->q,ctx)) goto err;
- if (!rsa->meth->bn_mod_exp(&m1,&r1,rsa->dmq1,rsa->q,ctx,
+ if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
+ {
+ dmq1 = &local_dmq1;
+ BN_with_flags(dmq1, rsa->dmq1, BN_FLG_EXP_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->meth->bn_mod_exp(r0,&r1,rsa->dmp1,rsa->p,ctx,
+ if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
+ {
+ dmp1 = &local_dmp1;
+ BN_with_flags(dmp1, rsa->dmp1, BN_FLG_EXP_CONSTTIME);
+ }
+ else
+ dmp1 = rsa->dmp1;
+ if (!rsa->meth->bn_mod_exp(r0,&r1,dmp1,rsa->p,ctx,
rsa->_method_mod_p)) goto err;
if (!BN_sub(r0,r0,&m1)) goto err;
@@ -693,10 +727,23 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
if (vrfy.neg)
if (!BN_add(&vrfy, &vrfy, rsa->n)) goto err;
if (!BN_is_zero(&vrfy))
+ {
/* 'I' and 'vrfy' aren't congruent mod n. Don't leak
* miscalculated CRT output, just do a raw (slower)
* mod_exp and return that instead. */
- if (!rsa->meth->bn_mod_exp(r0,I,rsa->d,rsa->n,ctx,NULL)) goto err;
+
+ BIGNUM local_d;
+ BIGNUM *d = NULL;
+
+ if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
+ {
+ d = &local_d;
+ BN_with_flags(d, rsa->d, BN_FLG_EXP_CONSTTIME);
+ }
+ else
+ d = rsa->d;
+ if (!rsa->meth->bn_mod_exp(r0,I,d,rsa->n,ctx,NULL)) goto err;
+ }
}
ret=1;
err: