summaryrefslogtreecommitdiffstats
path: root/lib/libcrypto/rsa
diff options
context:
space:
mode:
authordjm <djm@openbsd.org>2008-09-06 12:17:47 +0000
committerdjm <djm@openbsd.org>2008-09-06 12:17:47 +0000
commit4fcf65c5c59fcf6124cf9f1fd81aa546850f974c (patch)
tree3c0b4c46d91bcb87c8eef7a1e84711159b17f71b /lib/libcrypto/rsa
parentimport of OpenSSL 0.9.8h (diff)
downloadwireguard-openbsd-4fcf65c5c59fcf6124cf9f1fd81aa546850f974c.tar.xz
wireguard-openbsd-4fcf65c5c59fcf6124cf9f1fd81aa546850f974c.zip
resolve conflicts
Diffstat (limited to 'lib/libcrypto/rsa')
-rw-r--r--lib/libcrypto/rsa/rsa.h96
-rw-r--r--lib/libcrypto/rsa/rsa_chk.c4
-rw-r--r--lib/libcrypto/rsa/rsa_eay.c539
-rw-r--r--lib/libcrypto/rsa/rsa_err.c22
-rw-r--r--lib/libcrypto/rsa/rsa_gen.c160
-rw-r--r--lib/libcrypto/rsa/rsa_lib.c130
-rw-r--r--lib/libcrypto/rsa/rsa_null.c15
-rw-r--r--lib/libcrypto/rsa/rsa_oaep.c38
-rw-r--r--lib/libcrypto/rsa/rsa_saos.c3
-rw-r--r--lib/libcrypto/rsa/rsa_sign.c4
-rw-r--r--lib/libcrypto/rsa/rsa_test.c32
11 files changed, 647 insertions, 396 deletions
diff --git a/lib/libcrypto/rsa/rsa.h b/lib/libcrypto/rsa/rsa.h
index dbed701e89e..6b5e4f8a9a0 100644
--- a/lib/libcrypto/rsa/rsa.h
+++ b/lib/libcrypto/rsa/rsa.h
@@ -64,25 +64,25 @@
#ifndef OPENSSL_NO_BIO
#include <openssl/bio.h>
#endif
-#include <openssl/bn.h>
#include <openssl/crypto.h>
#include <openssl/ossl_typ.h>
+#ifndef OPENSSL_NO_DEPRECATED
+#include <openssl/bn.h>
+#endif
#ifdef OPENSSL_NO_RSA
#error RSA is disabled.
#endif
-#if defined(OPENSSL_FIPS)
-#define FIPS_RSA_SIZE_T int
-#endif
-
#ifdef __cplusplus
extern "C" {
#endif
-typedef struct rsa_st RSA;
+/* Declared already in ossl_typ.h */
+/* typedef struct rsa_st RSA; */
+/* typedef struct rsa_meth_st RSA_METHOD; */
-typedef struct rsa_meth_st
+struct rsa_meth_st
{
const char *name;
int (*rsa_pub_enc)(int flen,const unsigned char *from,
@@ -97,7 +97,7 @@ typedef struct rsa_meth_st
int (*rsa_priv_dec)(int flen,const unsigned char *from,
unsigned char *to,
RSA *rsa,int padding);
- int (*rsa_mod_exp)(BIGNUM *r0,const BIGNUM *I,RSA *rsa); /* Can be null */
+ int (*rsa_mod_exp)(BIGNUM *r0,const BIGNUM *I,RSA *rsa,BN_CTX *ctx); /* Can be null */
int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx,
BN_MONT_CTX *m_ctx); /* Can be null */
@@ -118,8 +118,12 @@ typedef struct rsa_meth_st
int (*rsa_verify)(int dtype,
const unsigned char *m, unsigned int m_length,
unsigned char *sigbuf, unsigned int siglen, const RSA *rsa);
-
- } RSA_METHOD;
+/* If this callback is NULL, the builtin software RSA key-gen will be used. This
+ * is for behavioural compatibility whilst the code gets rewired, but one day
+ * it would be nice to assume there are no such things as "builtin software"
+ * implementations. */
+ int (*rsa_keygen)(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
+ };
struct rsa_st
{
@@ -152,12 +156,19 @@ struct rsa_st
* NULL */
char *bignum_data;
BN_BLINDING *blinding;
+ BN_BLINDING *mt_blinding;
};
-#define OPENSSL_RSA_MAX_MODULUS_BITS 16384
+#ifndef OPENSSL_RSA_MAX_MODULUS_BITS
+# define OPENSSL_RSA_MAX_MODULUS_BITS 16384
+#endif
-#define OPENSSL_RSA_SMALL_MODULUS_BITS 3072
-#define OPENSSL_RSA_MAX_PUBEXP_BITS 64 /* exponent limit enforced for "small" modulus only */
+#ifndef OPENSSL_RSA_SMALL_MODULUS_BITS
+# define OPENSSL_RSA_SMALL_MODULUS_BITS 3072
+#endif
+#ifndef OPENSSL_RSA_MAX_PUBEXP_BITS
+# define OPENSSL_RSA_MAX_PUBEXP_BITS 64 /* exponent limit enforced for "large" modulus only */
+#endif
#define RSA_3 0x3L
#define RSA_F4 0x10001L
@@ -184,13 +195,27 @@ 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
+#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.
+ */
+#ifndef OPENSSL_NO_DEPRECATED
+#define RSA_FLAG_NO_EXP_CONSTTIME RSA_FLAG_NO_CONSTTIME /* deprecated name for the flag*/
+ /* 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.
*/
+#endif
+
#define RSA_PKCS1_PADDING 1
#define RSA_SSLV23_PADDING 2
@@ -206,18 +231,17 @@ struct rsa_st
RSA * RSA_new(void);
RSA * RSA_new_method(ENGINE *engine);
int RSA_size(const RSA *);
+
+/* Deprecated version */
+#ifndef OPENSSL_NO_DEPRECATED
RSA * RSA_generate_key(int bits, unsigned long e,void
(*callback)(int,int,void *),void *cb_arg);
+#endif /* !defined(OPENSSL_NO_DEPRECATED) */
+
+/* New version */
+int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
+
int RSA_check_key(const RSA *);
-#ifdef OPENSSL_FIPS
-int RSA_X931_derive(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1, BIGNUM *q2,
- void (*cb)(int, int, void *), void *cb_arg,
- const BIGNUM *Xp1, const BIGNUM *Xp2, const BIGNUM *Xp,
- const BIGNUM *Xq1, const BIGNUM *Xq2, const BIGNUM *Xq,
- const BIGNUM *e);
-RSA *RSA_X931_generate_key(int bits, const BIGNUM *e,
- void (*cb)(int,int,void *), void *cb_arg);
-#endif
/* next 4 return -1 on error */
int RSA_public_encrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa,int padding);
@@ -257,11 +281,19 @@ int RSA_print_fp(FILE *fp, const RSA *r,int offset);
int RSA_print(BIO *bp, const RSA *r,int offset);
#endif
-int i2d_RSA_NET(const RSA *a, unsigned char **pp, int (*cb)(), int sgckey);
-RSA *d2i_RSA_NET(RSA **a, const unsigned char **pp, long length, int (*cb)(), int sgckey);
+int i2d_RSA_NET(const RSA *a, unsigned char **pp,
+ int (*cb)(char *buf, int len, const char *prompt, int verify),
+ int sgckey);
+RSA *d2i_RSA_NET(RSA **a, const unsigned char **pp, long length,
+ int (*cb)(char *buf, int len, const char *prompt, int verify),
+ int sgckey);
-int i2d_Netscape_RSA(const RSA *a, unsigned char **pp, int (*cb)());
-RSA *d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length, int (*cb)());
+int i2d_Netscape_RSA(const RSA *a, unsigned char **pp,
+ int (*cb)(char *buf, int len, const char *prompt,
+ int verify));
+RSA *d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length,
+ int (*cb)(char *buf, int len, const char *prompt,
+ int verify));
/* The following 2 functions sign and verify a X509_SIG ASN1 object
* inside PKCS#1 padded RSA encryption */
@@ -281,6 +313,7 @@ int RSA_verify_ASN1_OCTET_STRING(int type,
int RSA_blinding_on(RSA *rsa, BN_CTX *ctx);
void RSA_blinding_off(RSA *rsa);
+BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *ctx);
int RSA_padding_add_PKCS1_type_1(unsigned char *to,int tlen,
const unsigned char *f,int fl);
@@ -336,14 +369,21 @@ void ERR_load_RSA_strings(void);
/* Function codes. */
#define RSA_F_MEMORY_LOCK 100
+#define RSA_F_RSA_BUILTIN_KEYGEN 129
#define RSA_F_RSA_CHECK_KEY 123
#define RSA_F_RSA_EAY_PRIVATE_DECRYPT 101
#define RSA_F_RSA_EAY_PRIVATE_ENCRYPT 102
#define RSA_F_RSA_EAY_PUBLIC_DECRYPT 103
#define RSA_F_RSA_EAY_PUBLIC_ENCRYPT 104
#define RSA_F_RSA_GENERATE_KEY 105
+#define RSA_F_RSA_MEMORY_LOCK 130
#define RSA_F_RSA_NEW_METHOD 106
#define RSA_F_RSA_NULL 124
+#define RSA_F_RSA_NULL_MOD_EXP 131
+#define RSA_F_RSA_NULL_PRIVATE_DECRYPT 132
+#define RSA_F_RSA_NULL_PRIVATE_ENCRYPT 133
+#define RSA_F_RSA_NULL_PUBLIC_DECRYPT 134
+#define RSA_F_RSA_NULL_PUBLIC_ENCRYPT 135
#define RSA_F_RSA_PADDING_ADD_NONE 107
#define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP 121
#define RSA_F_RSA_PADDING_ADD_PKCS1_PSS 125
@@ -359,6 +399,7 @@ void ERR_load_RSA_strings(void);
#define RSA_F_RSA_PADDING_CHECK_X931 128
#define RSA_F_RSA_PRINT 115
#define RSA_F_RSA_PRINT_FP 116
+#define RSA_F_RSA_SETUP_BLINDING 136
#define RSA_F_RSA_SIGN 117
#define RSA_F_RSA_SIGN_ASN1_OCTET_STRING 118
#define RSA_F_RSA_VERIFY 119
@@ -392,6 +433,7 @@ void ERR_load_RSA_strings(void);
#define RSA_R_KEY_SIZE_TOO_SMALL 120
#define RSA_R_LAST_OCTET_INVALID 134
#define RSA_R_MODULUS_TOO_LARGE 105
+#define RSA_R_NO_PUBLIC_EXPONENT 140
#define RSA_R_NULL_BEFORE_BLOCK_MISSING 113
#define RSA_R_N_DOES_NOT_EQUAL_P_Q 127
#define RSA_R_OAEP_DECODING_ERROR 121
diff --git a/lib/libcrypto/rsa/rsa_chk.c b/lib/libcrypto/rsa/rsa_chk.c
index 002f2cb4872..9d848db8c6c 100644
--- a/lib/libcrypto/rsa/rsa_chk.c
+++ b/lib/libcrypto/rsa/rsa_chk.c
@@ -75,7 +75,7 @@ int RSA_check_key(const RSA *key)
}
/* p prime? */
- r = BN_is_prime(key->p, BN_prime_checks, NULL, NULL, NULL);
+ r = BN_is_prime_ex(key->p, BN_prime_checks, NULL, NULL);
if (r != 1)
{
ret = r;
@@ -85,7 +85,7 @@ int RSA_check_key(const RSA *key)
}
/* q prime? */
- r = BN_is_prime(key->q, BN_prime_checks, NULL, NULL, NULL);
+ r = BN_is_prime_ex(key->q, BN_prime_checks, NULL, NULL);
if (r != 1)
{
ret = r;
diff --git a/lib/libcrypto/rsa/rsa_eay.c b/lib/libcrypto/rsa/rsa_eay.c
index 610889dc805..bb77d0f67e9 100644
--- a/lib/libcrypto/rsa/rsa_eay.c
+++ b/lib/libcrypto/rsa/rsa_eay.c
@@ -56,7 +56,7 @@
* [including the GNU Public Licence.]
*/
/* ====================================================================
- * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1998-2006 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
@@ -115,7 +115,7 @@
#include <openssl/rsa.h>
#include <openssl/rand.h>
-#if !defined(RSA_NULL) && !defined(OPENSSL_FIPS)
+#ifndef RSA_NULL
static int RSA_eay_public_encrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa,int padding);
@@ -125,7 +125,7 @@ static int RSA_eay_public_decrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa,int padding);
static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa,int padding);
-static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *i, RSA *rsa);
+static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *i, RSA *rsa, BN_CTX *ctx);
static int RSA_eay_init(RSA *rsa);
static int RSA_eay_finish(RSA *rsa);
static RSA_METHOD rsa_pkcs1_eay_meth={
@@ -141,7 +141,8 @@ static RSA_METHOD rsa_pkcs1_eay_meth={
0, /* flags */
NULL,
0, /* rsa_sign */
- 0 /* rsa_verify */
+ 0, /* rsa_verify */
+ NULL /* rsa_keygen */
};
const RSA_METHOD *RSA_PKCS1_SSLeay(void)
@@ -149,19 +150,53 @@ const RSA_METHOD *RSA_PKCS1_SSLeay(void)
return(&rsa_pkcs1_eay_meth);
}
+/* Usage example;
+ * MONT_HELPER(rsa->_method_mod_p, bn_ctx, rsa->p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err);
+ */
+#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, \
+ (m), (ctx))) \
+ err_instr
+
static int RSA_eay_public_encrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding)
{
- BIGNUM f,ret;
+ BIGNUM *f,*ret;
int i,j,k,num=0,r= -1;
unsigned char *buf=NULL;
BN_CTX *ctx=NULL;
- BN_init(&f);
- BN_init(&ret);
+ if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS)
+ {
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_MODULUS_TOO_LARGE);
+ return -1;
+ }
+
+ if (BN_ucmp(rsa->n, rsa->e) <= 0)
+ {
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE);
+ return -1;
+ }
+
+ /* for large moduli, enforce exponent limit */
+ if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS)
+ {
+ if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS)
+ {
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE);
+ return -1;
+ }
+ }
+
if ((ctx=BN_CTX_new()) == NULL) goto err;
+ BN_CTX_start(ctx);
+ f = BN_CTX_get(ctx);
+ ret = BN_CTX_get(ctx);
num=BN_num_bytes(rsa->n);
- if ((buf=(unsigned char *)OPENSSL_malloc(num)) == NULL)
+ buf = OPENSSL_malloc(num);
+ if (!f || !ret || !buf)
{
RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,ERR_R_MALLOC_FAILURE);
goto err;
@@ -189,37 +224,34 @@ static int RSA_eay_public_encrypt(int flen, const unsigned char *from,
}
if (i <= 0) goto err;
- if (BN_bin2bn(buf,num,&f) == NULL) goto err;
+ if (BN_bin2bn(buf,num,f) == NULL) goto err;
- if (BN_ucmp(&f, rsa->n) >= 0)
- {
+ 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;
}
- if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
- {
- if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n,
- CRYPTO_LOCK_RSA, rsa->n, ctx))
- 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,
+ if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx,
rsa->_method_mod_n)) goto err;
/* 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(ret);
+ i=BN_bn2bin(ret,&(to[num-j]));
for (k=0; k<(num-i); k++)
to[k]=0;
r=num;
err:
- if (ctx != NULL) BN_CTX_free(ctx);
- BN_clear_free(&f);
- BN_clear_free(&ret);
+ if (ctx != NULL)
+ {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
if (buf != NULL)
{
OPENSSL_cleanse(buf,num);
@@ -228,64 +260,101 @@ err:
return(r);
}
-static int rsa_eay_blinding(RSA *rsa, BN_CTX *ctx)
- {
- int ret = 1;
- CRYPTO_w_lock(CRYPTO_LOCK_RSA);
- /* Check again inside the lock - the macro's check is racey */
- if(rsa->blinding == NULL)
- ret = RSA_blinding_on(rsa, ctx);
- CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
- return ret;
- }
+static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx)
+{
+ BN_BLINDING *ret;
+ int got_write_lock = 0;
-#define BLINDING_HELPER(rsa, ctx, err_instr) \
- do { \
- if((!((rsa)->flags & RSA_FLAG_NO_BLINDING)) && \
- ((rsa)->blinding == NULL) && \
- !rsa_eay_blinding(rsa, ctx)) \
- err_instr \
- } while(0)
+ CRYPTO_r_lock(CRYPTO_LOCK_RSA);
-static BN_BLINDING *setup_blinding(RSA *rsa, BN_CTX *ctx)
- {
- BIGNUM *A, *Ai;
- BN_BLINDING *ret = NULL;
+ if (rsa->blinding == NULL)
+ {
+ CRYPTO_r_unlock(CRYPTO_LOCK_RSA);
+ CRYPTO_w_lock(CRYPTO_LOCK_RSA);
+ got_write_lock = 1;
- /* added in OpenSSL 0.9.6j and 0.9.7b */
+ if (rsa->blinding == NULL)
+ rsa->blinding = RSA_setup_blinding(rsa, ctx);
+ }
- /* NB: similar code appears in RSA_blinding_on (rsa_lib.c);
- * this should be placed in a new function of its own, but for reasons
- * of binary compatibility can't */
+ ret = rsa->blinding;
+ if (ret == NULL)
+ goto err;
- BN_CTX_start(ctx);
- A = BN_CTX_get(ctx);
- if ((RAND_status() == 0) && rsa->d != NULL && rsa->d->d != NULL)
+ if (BN_BLINDING_get_thread_id(ret) == CRYPTO_thread_id())
{
- /* if PRNG is not properly seeded, resort to secret exponent as unpredictable seed */
- RAND_add(rsa->d->d, rsa->d->dmax * sizeof rsa->d->d[0], 0);
- if (!BN_pseudo_rand_range(A,rsa->n)) goto err;
+ /* rsa->blinding is ours! */
+
+ *local = 1;
}
else
{
- if (!BN_rand_range(A,rsa->n)) goto err;
+ /* resort to rsa->mt_blinding instead */
+
+ *local = 0; /* instructs rsa_blinding_convert(), rsa_blinding_invert()
+ * that the BN_BLINDING is shared, meaning that accesses
+ * require locks, and that the blinding factor must be
+ * stored outside the BN_BLINDING
+ */
+
+ if (rsa->mt_blinding == NULL)
+ {
+ if (!got_write_lock)
+ {
+ CRYPTO_r_unlock(CRYPTO_LOCK_RSA);
+ CRYPTO_w_lock(CRYPTO_LOCK_RSA);
+ got_write_lock = 1;
+ }
+
+ if (rsa->mt_blinding == NULL)
+ rsa->mt_blinding = RSA_setup_blinding(rsa, ctx);
+ }
+ ret = rsa->mt_blinding;
}
- if ((Ai=BN_mod_inverse(NULL,A,rsa->n,ctx)) == NULL) goto err;
- if (!rsa->meth->bn_mod_exp(A,A,rsa->e,rsa->n,ctx,rsa->_method_mod_n))
- goto err;
- ret = BN_BLINDING_new(A,Ai,rsa->n);
- BN_free(Ai);
-err:
- BN_CTX_end(ctx);
+ err:
+ if (got_write_lock)
+ CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
+ else
+ CRYPTO_r_unlock(CRYPTO_LOCK_RSA);
return ret;
- }
+}
+
+static int rsa_blinding_convert(BN_BLINDING *b, int local, BIGNUM *f,
+ BIGNUM *r, BN_CTX *ctx)
+{
+ if (local)
+ return BN_BLINDING_convert_ex(f, NULL, b, ctx);
+ else
+ {
+ int ret;
+ CRYPTO_r_lock(CRYPTO_LOCK_RSA_BLINDING);
+ ret = BN_BLINDING_convert_ex(f, r, b, ctx);
+ CRYPTO_r_unlock(CRYPTO_LOCK_RSA_BLINDING);
+ return ret;
+ }
+}
+
+static int rsa_blinding_invert(BN_BLINDING *b, int local, BIGNUM *f,
+ BIGNUM *r, BN_CTX *ctx)
+{
+ if (local)
+ return BN_BLINDING_invert_ex(f, NULL, b, ctx);
+ else
+ {
+ int ret;
+ CRYPTO_w_lock(CRYPTO_LOCK_RSA_BLINDING);
+ ret = BN_BLINDING_invert_ex(f, r, b, ctx);
+ CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING);
+ return ret;
+ }
+}
/* signing */
static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding)
{
- BIGNUM f,ret, *res;
+ BIGNUM *f, *ret, *br, *res;
int i,j,k,num=0,r= -1;
unsigned char *buf=NULL;
BN_CTX *ctx=NULL;
@@ -318,8 +387,13 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
}
if ((ctx=BN_CTX_new()) == NULL) goto err;
- num=BN_num_bytes(rsa->n);
- if ((buf=(unsigned char *)OPENSSL_malloc(num)) == NULL)
+ BN_CTX_start(ctx);
+ f = BN_CTX_get(ctx);
+ br = BN_CTX_get(ctx);
+ ret = BN_CTX_get(ctx);
+ num = BN_num_bytes(rsa->n);
+ buf = OPENSSL_malloc(num);
+ if(!f || !ret || !buf)
{
RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,ERR_R_MALLOC_FAILURE);
goto err;
@@ -330,6 +404,9 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
case RSA_PKCS1_PADDING:
i=RSA_padding_add_PKCS1_type_1(buf,num,from,flen);
break;
+ case RSA_X931_PADDING:
+ i=RSA_padding_add_X931(buf,num,from,flen);
+ break;
case RSA_NO_PADDING:
i=RSA_padding_add_none(buf,num,from,flen);
break;
@@ -340,26 +417,18 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
}
if (i <= 0) goto err;
- if (BN_bin2bn(buf,num,&f) == NULL) goto err;
+ if (BN_bin2bn(buf,num,f) == NULL) goto err;
- if (BN_ucmp(&f, rsa->n) >= 0)
+ if (BN_ucmp(f, rsa->n) >= 0)
{
/* usually the padding functions would catch this */
RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
goto err;
}
- BLINDING_HELPER(rsa, ctx, goto err;);
- blinding = rsa->blinding;
-
- /* Now unless blinding is disabled, 'blinding' is non-NULL.
- * But the BN_BLINDING object may be owned by some other thread
- * (we don't want to keep it constant and we don't want to use
- * lots of locking to avoid race conditions, so only a single
- * thread can use it; other threads have to use local blinding
- * factors) */
if (!(rsa->flags & RSA_FLAG_NO_BLINDING))
{
+ blinding = rsa_get_blinding(rsa, &local_blinding, ctx);
if (blinding == NULL)
{
RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR);
@@ -368,20 +437,8 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
}
if (blinding != NULL)
- {
- if (blinding->thread_id != CRYPTO_thread_id())
- {
- /* we need a local one-time blinding factor */
-
- blinding = setup_blinding(rsa, ctx);
- if (blinding == NULL)
- goto err;
- local_blinding = 1;
- }
- }
-
- if (blinding)
- if (!BN_BLINDING_convert(&f, blinding, ctx)) goto err;
+ if (!rsa_blinding_convert(blinding, local_blinding, f, br, ctx))
+ goto err;
if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
((rsa->p != NULL) &&
@@ -390,37 +447,42 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
(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, ctx)) goto err;
}
else
{
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;
- if (!rsa->meth->bn_mod_exp(&ret,&f,d,rsa->n,ctx,NULL)) goto err;
+ d= rsa->d;
+
+ 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;
}
if (blinding)
- if (!BN_BLINDING_invert(&ret, blinding, ctx)) goto err;
+ if (!rsa_blinding_invert(blinding, local_blinding, ret, br, ctx))
+ goto err;
if (padding == RSA_X931_PADDING)
{
- BN_sub(&f, rsa->n, &ret);
- if (BN_cmp(&ret, &f))
- res = &f;
+ BN_sub(f, rsa->n, ret);
+ if (BN_cmp(ret, f))
+ res = f;
else
- res = &ret;
+ res = ret;
}
else
- res = &ret;
+ res = ret;
/* put in leading 0 bytes if the number is less than the
* length of the modulus */
@@ -431,11 +493,11 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
r=num;
err:
- if (ctx != NULL) BN_CTX_free(ctx);
- BN_clear_free(&ret);
- BN_clear_free(&f);
- if (local_blinding)
- BN_BLINDING_free(blinding);
+ if (ctx != NULL)
+ {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
if (buf != NULL)
{
OPENSSL_cleanse(buf,num);
@@ -447,7 +509,7 @@ err:
static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding)
{
- BIGNUM f,ret;
+ BIGNUM *f, *ret, *br;
int j,num=0,r= -1;
unsigned char *p;
unsigned char *buf=NULL;
@@ -455,14 +517,14 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
int local_blinding = 0;
BN_BLINDING *blinding = NULL;
- BN_init(&f);
- BN_init(&ret);
- ctx=BN_CTX_new();
- if (ctx == NULL) goto err;
-
- num=BN_num_bytes(rsa->n);
-
- if ((buf=(unsigned char *)OPENSSL_malloc(num)) == NULL)
+ if((ctx = BN_CTX_new()) == NULL) goto err;
+ BN_CTX_start(ctx);
+ f = BN_CTX_get(ctx);
+ br = BN_CTX_get(ctx);
+ ret = BN_CTX_get(ctx);
+ num = BN_num_bytes(rsa->n);
+ buf = OPENSSL_malloc(num);
+ if(!f || !ret || !buf)
{
RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,ERR_R_MALLOC_FAILURE);
goto err;
@@ -477,25 +539,17 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
}
/* make data into a big number */
- if (BN_bin2bn(from,(int)flen,&f) == NULL) goto err;
+ if (BN_bin2bn(from,(int)flen,f) == NULL) goto err;
- if (BN_ucmp(&f, rsa->n) >= 0)
+ if (BN_ucmp(f, rsa->n) >= 0)
{
RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
goto err;
}
- BLINDING_HELPER(rsa, ctx, goto err;);
- blinding = rsa->blinding;
-
- /* Now unless blinding is disabled, 'blinding' is non-NULL.
- * But the BN_BLINDING object may be owned by some other thread
- * (we don't want to keep it constant and we don't want to use
- * lots of locking to avoid race conditions, so only a single
- * thread can use it; other threads have to use local blinding
- * factors) */
if (!(rsa->flags & RSA_FLAG_NO_BLINDING))
{
+ blinding = rsa_get_blinding(rsa, &local_blinding, ctx);
if (blinding == NULL)
{
RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, ERR_R_INTERNAL_ERROR);
@@ -504,20 +558,8 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
}
if (blinding != NULL)
- {
- if (blinding->thread_id != CRYPTO_thread_id())
- {
- /* we need a local one-time blinding factor */
-
- blinding = setup_blinding(rsa, ctx);
- if (blinding == NULL)
- goto err;
- local_blinding = 1;
- }
- }
-
- if (blinding)
- if (!BN_BLINDING_convert(&f, blinding, ctx)) goto err;
+ if (!rsa_blinding_convert(blinding, local_blinding, f, br, ctx))
+ goto err;
/* do the decrypt */
if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
@@ -527,29 +569,33 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
(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, ctx)) goto err;
}
else
{
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;
- if (!rsa->meth->bn_mod_exp(&ret,&f,d,rsa->n,ctx,NULL))
- 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;
}
if (blinding)
- if (!BN_BLINDING_invert(&ret, blinding, ctx)) goto err;
+ if (!rsa_blinding_invert(blinding, local_blinding, ret, br, ctx))
+ goto err;
p=buf;
- j=BN_bn2bin(&ret,p); /* j is only used with no-padding mode */
+ j=BN_bn2bin(ret,p); /* j is only used with no-padding mode */
switch (padding)
{
@@ -575,11 +621,11 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_PADDING_CHECK_FAILED);
err:
- if (ctx != NULL) BN_CTX_free(ctx);
- BN_clear_free(&f);
- BN_clear_free(&ret);
- if (local_blinding)
- BN_BLINDING_free(blinding);
+ if (ctx != NULL)
+ {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
if (buf != NULL)
{
OPENSSL_cleanse(buf,num);
@@ -592,7 +638,7 @@ err:
static int RSA_eay_public_decrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding)
{
- BIGNUM f,ret;
+ BIGNUM *f,*ret;
int i,num=0,r= -1;
unsigned char *p;
unsigned char *buf=NULL;
@@ -619,15 +665,14 @@ static int RSA_eay_public_decrypt(int flen, const unsigned char *from,
return -1;
}
}
-
- BN_init(&f);
- BN_init(&ret);
- ctx=BN_CTX_new();
- if (ctx == NULL) goto err;
-
+
+ if((ctx = BN_CTX_new()) == NULL) goto err;
+ BN_CTX_start(ctx);
+ f = BN_CTX_get(ctx);
+ ret = BN_CTX_get(ctx);
num=BN_num_bytes(rsa->n);
- buf=(unsigned char *)OPENSSL_malloc(num);
- if (buf == NULL)
+ buf = OPENSSL_malloc(num);
+ if(!f || !ret || !buf)
{
RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,ERR_R_MALLOC_FAILURE);
goto err;
@@ -641,37 +686,33 @@ static int RSA_eay_public_decrypt(int flen, const unsigned char *from,
goto err;
}
- if (BN_bin2bn(from,flen,&f) == NULL) goto err;
+ if (BN_bin2bn(from,flen,f) == NULL) goto err;
- if (BN_ucmp(&f, rsa->n) >= 0)
+ if (BN_ucmp(f, rsa->n) >= 0)
{
RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
goto err;
}
- /* do the decrypt */
-
- if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
- {
- if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n,
- CRYPTO_LOCK_RSA, rsa->n, ctx))
- 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,
+ 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);
+ if ((padding == RSA_X931_PADDING) && ((ret->d[0] & 0xf) != 12))
+ BN_sub(ret, rsa->n, ret);
p=buf;
- i=BN_bn2bin(&ret,p);
+ i=BN_bn2bin(ret,p);
switch (padding)
{
case RSA_PKCS1_PADDING:
r=RSA_padding_check_PKCS1_type_1(to,num,buf,i,num);
break;
+ case RSA_X931_PADDING:
+ r=RSA_padding_check_X931(to,num,buf,i,num);
+ break;
case RSA_NO_PADDING:
r=RSA_padding_check_none(to,num,buf,i,num);
break;
@@ -683,9 +724,11 @@ static int RSA_eay_public_decrypt(int flen, const unsigned char *from,
RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_PADDING_CHECK_FAILED);
err:
- if (ctx != NULL) BN_CTX_free(ctx);
- BN_clear_free(&f);
- BN_clear_free(&ret);
+ if (ctx != NULL)
+ {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
if (buf != NULL)
{
OPENSSL_cleanse(buf,num);
@@ -694,59 +737,111 @@ err:
return(r);
}
-static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
+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 *r1,*m1,*vrfy;
+ BIGNUM local_dmp1,local_dmq1,local_c,local_r1;
+ BIGNUM *dmp1,*dmq1,*c,*pr1;
int ret=0;
- BN_CTX *ctx;
- BN_init(&m1);
- BN_init(&r1);
- BN_init(&vrfy);
- if ((ctx=BN_CTX_new()) == NULL) goto err;
+ BN_CTX_start(ctx);
+ r1 = BN_CTX_get(ctx);
+ m1 = BN_CTX_get(ctx);
+ vrfy = BN_CTX_get(ctx);
+
+ {
+ BIGNUM local_p, local_q;
+ BIGNUM *p = NULL, *q = NULL;
+
+ /* 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);
+ }
- if (rsa->flags & RSA_FLAG_CACHE_PRIVATE)
+ 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))
{
- 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;
+ 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;
}
- if (!BN_mod(&r1,I,rsa->q,ctx)) goto err;
- if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
+ /* 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,
+ 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;
- if (!rsa->meth->bn_mod_exp(r0,&r1,dmp1,rsa->p,ctx,
+ 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;
+ if (!BN_sub(r0,r0,m1)) goto err;
/* This will help stop the size of r0 increasing, which does
* affect the multiply if it optimised for a power of 2 size */
- if (r0->neg)
+ if (BN_is_negative(r0))
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;
+ if (!BN_mul(r1,r0,rsa->iqmp,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
@@ -754,23 +849,23 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
* This will *never* happen with OpenSSL generated keys because
* they ensure p > q [steve]
*/
- if (r0->neg)
+ if (BN_is_negative(r0))
if (!BN_add(r0,r0,rsa->p)) goto err;
- if (!BN_mul(&r1,r0,rsa->q,ctx)) goto err;
- if (!BN_add(r0,&r1,&m1)) goto err;
+ if (!BN_mul(r1,r0,rsa->q,ctx)) goto err;
+ if (!BN_add(r0,r1,m1)) goto err;
if (rsa->e && rsa->n)
{
- if (!rsa->meth->bn_mod_exp(&vrfy,r0,rsa->e,rsa->n,ctx,NULL)) goto err;
+ if (!rsa->meth->bn_mod_exp(vrfy,r0,rsa->e,rsa->n,ctx,rsa->_method_mod_n)) goto err;
/* If 'I' was greater than (or equal to) rsa->n, the operation
* will be equivalent to using 'I mod n'. However, the result of
* the verify will *always* be less than 'n' so we don't check
* for absolute equality, just congruency. */
- if (!BN_sub(&vrfy, &vrfy, I)) goto err;
- if (!BN_mod(&vrfy, &vrfy, rsa->n, ctx)) goto err;
- if (vrfy.neg)
- if (!BN_add(&vrfy, &vrfy, rsa->n)) goto err;
- if (!BN_is_zero(&vrfy))
+ if (!BN_sub(vrfy, vrfy, I)) goto err;
+ if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) goto err;
+ if (BN_is_negative(vrfy))
+ 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)
@@ -779,22 +874,20 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
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;
- if (!rsa->meth->bn_mod_exp(r0,I,d,rsa->n,ctx,NULL)) goto err;
+ if (!rsa->meth->bn_mod_exp(r0,I,d,rsa->n,ctx,
+ rsa->_method_mod_n)) goto err;
}
}
ret=1;
err:
- BN_clear_free(&m1);
- BN_clear_free(&r1);
- BN_clear_free(&vrfy);
- BN_CTX_free(ctx);
+ BN_CTX_end(ctx);
return(ret);
}
diff --git a/lib/libcrypto/rsa/rsa_err.c b/lib/libcrypto/rsa/rsa_err.c
index ddcb28e6630..fe3ba1b44bb 100644
--- a/lib/libcrypto/rsa/rsa_err.c
+++ b/lib/libcrypto/rsa/rsa_err.c
@@ -71,14 +71,21 @@
static ERR_STRING_DATA RSA_str_functs[]=
{
{ERR_FUNC(RSA_F_MEMORY_LOCK), "MEMORY_LOCK"},
+{ERR_FUNC(RSA_F_RSA_BUILTIN_KEYGEN), "RSA_BUILTIN_KEYGEN"},
{ERR_FUNC(RSA_F_RSA_CHECK_KEY), "RSA_check_key"},
{ERR_FUNC(RSA_F_RSA_EAY_PRIVATE_DECRYPT), "RSA_EAY_PRIVATE_DECRYPT"},
{ERR_FUNC(RSA_F_RSA_EAY_PRIVATE_ENCRYPT), "RSA_EAY_PRIVATE_ENCRYPT"},
{ERR_FUNC(RSA_F_RSA_EAY_PUBLIC_DECRYPT), "RSA_EAY_PUBLIC_DECRYPT"},
{ERR_FUNC(RSA_F_RSA_EAY_PUBLIC_ENCRYPT), "RSA_EAY_PUBLIC_ENCRYPT"},
{ERR_FUNC(RSA_F_RSA_GENERATE_KEY), "RSA_generate_key"},
+{ERR_FUNC(RSA_F_RSA_MEMORY_LOCK), "RSA_memory_lock"},
{ERR_FUNC(RSA_F_RSA_NEW_METHOD), "RSA_new_method"},
{ERR_FUNC(RSA_F_RSA_NULL), "RSA_NULL"},
+{ERR_FUNC(RSA_F_RSA_NULL_MOD_EXP), "RSA_NULL_MOD_EXP"},
+{ERR_FUNC(RSA_F_RSA_NULL_PRIVATE_DECRYPT), "RSA_NULL_PRIVATE_DECRYPT"},
+{ERR_FUNC(RSA_F_RSA_NULL_PRIVATE_ENCRYPT), "RSA_NULL_PRIVATE_ENCRYPT"},
+{ERR_FUNC(RSA_F_RSA_NULL_PUBLIC_DECRYPT), "RSA_NULL_PUBLIC_DECRYPT"},
+{ERR_FUNC(RSA_F_RSA_NULL_PUBLIC_ENCRYPT), "RSA_NULL_PUBLIC_ENCRYPT"},
{ERR_FUNC(RSA_F_RSA_PADDING_ADD_NONE), "RSA_padding_add_none"},
{ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP), "RSA_padding_add_PKCS1_OAEP"},
{ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_PSS), "RSA_padding_add_PKCS1_PSS"},
@@ -94,6 +101,7 @@ static ERR_STRING_DATA RSA_str_functs[]=
{ERR_FUNC(RSA_F_RSA_PADDING_CHECK_X931), "RSA_padding_check_X931"},
{ERR_FUNC(RSA_F_RSA_PRINT), "RSA_print"},
{ERR_FUNC(RSA_F_RSA_PRINT_FP), "RSA_print_fp"},
+{ERR_FUNC(RSA_F_RSA_SETUP_BLINDING), "RSA_setup_blinding"},
{ERR_FUNC(RSA_F_RSA_SIGN), "RSA_sign"},
{ERR_FUNC(RSA_F_RSA_SIGN_ASN1_OCTET_STRING), "RSA_sign_ASN1_OCTET_STRING"},
{ERR_FUNC(RSA_F_RSA_VERIFY), "RSA_verify"},
@@ -130,20 +138,21 @@ static ERR_STRING_DATA RSA_str_reasons[]=
{ERR_REASON(RSA_R_KEY_SIZE_TOO_SMALL) ,"key size too small"},
{ERR_REASON(RSA_R_LAST_OCTET_INVALID) ,"last octet invalid"},
{ERR_REASON(RSA_R_MODULUS_TOO_LARGE) ,"modulus too large"},
+{ERR_REASON(RSA_R_NO_PUBLIC_EXPONENT) ,"no public exponent"},
{ERR_REASON(RSA_R_NULL_BEFORE_BLOCK_MISSING),"null before block missing"},
{ERR_REASON(RSA_R_N_DOES_NOT_EQUAL_P_Q) ,"n does not equal p q"},
{ERR_REASON(RSA_R_OAEP_DECODING_ERROR) ,"oaep decoding error"},
-{ERR_REASON(RSA_R_SLEN_RECOVERY_FAILED) ,"salt length recovery failed"},
{ERR_REASON(RSA_R_PADDING_CHECK_FAILED) ,"padding check failed"},
{ERR_REASON(RSA_R_P_NOT_PRIME) ,"p not prime"},
{ERR_REASON(RSA_R_Q_NOT_PRIME) ,"q not prime"},
{ERR_REASON(RSA_R_RSA_OPERATIONS_NOT_SUPPORTED),"rsa operations not supported"},
+{ERR_REASON(RSA_R_SLEN_CHECK_FAILED) ,"salt length check failed"},
+{ERR_REASON(RSA_R_SLEN_RECOVERY_FAILED) ,"salt length recovery failed"},
{ERR_REASON(RSA_R_SSLV3_ROLLBACK_ATTACK) ,"sslv3 rollback attack"},
{ERR_REASON(RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD),"the asn1 object identifier is not known for this md"},
{ERR_REASON(RSA_R_UNKNOWN_ALGORITHM_TYPE),"unknown algorithm type"},
{ERR_REASON(RSA_R_UNKNOWN_PADDING_TYPE) ,"unknown padding type"},
{ERR_REASON(RSA_R_WRONG_SIGNATURE_LENGTH),"wrong signature length"},
-{ERR_REASON(RSA_R_SLEN_CHECK_FAILED) ,"salt length check failed"},
{0,NULL}
};
@@ -151,15 +160,12 @@ static ERR_STRING_DATA RSA_str_reasons[]=
void ERR_load_RSA_strings(void)
{
- static int init=1;
+#ifndef OPENSSL_NO_ERR
- if (init)
+ if (ERR_func_error_string(RSA_str_functs[0].error) == NULL)
{
- init=0;
-#ifndef OPENSSL_NO_ERR
ERR_load_strings(0,RSA_str_functs);
ERR_load_strings(0,RSA_str_reasons);
-#endif
-
}
+#endif
}
diff --git a/lib/libcrypto/rsa/rsa_gen.c b/lib/libcrypto/rsa/rsa_gen.c
index dd1422cc98b..767f7ab682a 100644
--- a/lib/libcrypto/rsa/rsa_gen.c
+++ b/lib/libcrypto/rsa/rsa_gen.c
@@ -56,26 +56,42 @@
* [including the GNU Public Licence.]
*/
+
+/* NB: these functions have been "upgraded", the deprecated versions (which are
+ * compatibility wrappers using these functions) are in rsa_depr.c.
+ * - Geoff
+ */
+
#include <stdio.h>
#include <time.h>
#include "cryptlib.h"
#include <openssl/bn.h>
#include <openssl/rsa.h>
-#ifndef OPENSSL_FIPS
+static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb);
-RSA *RSA_generate_key(int bits, unsigned long e_value,
- void (*callback)(int,int,void *), void *cb_arg)
+/* NB: this wrapper would normally be placed in rsa_lib.c and the static
+ * implementation would probably be in rsa_eay.c. Nonetheless, is kept here so
+ * that we don't introduce a new linker dependency. Eg. any application that
+ * wasn't previously linking object code related to key-generation won't have to
+ * now just because key-generation is part of RSA_METHOD. */
+int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
+ {
+ if(rsa->meth->rsa_keygen)
+ return rsa->meth->rsa_keygen(rsa, bits, e_value, cb);
+ return rsa_builtin_keygen(rsa, bits, e_value, cb);
+ }
+
+static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
{
- RSA *rsa=NULL;
BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL,*tmp;
- int bitsp,bitsq,ok= -1,n=0,i;
- BN_CTX *ctx=NULL,*ctx2=NULL;
+ BIGNUM local_r0,local_d,local_p;
+ BIGNUM *pr0,*d,*p;
+ int bitsp,bitsq,ok= -1,n=0;
+ BN_CTX *ctx=NULL;
ctx=BN_CTX_new();
if (ctx == NULL) goto err;
- ctx2=BN_CTX_new();
- if (ctx2 == NULL) goto err;
BN_CTX_start(ctx);
r0 = BN_CTX_get(ctx);
r1 = BN_CTX_get(ctx);
@@ -85,49 +101,58 @@ RSA *RSA_generate_key(int bits, unsigned long e_value,
bitsp=(bits+1)/2;
bitsq=bits-bitsp;
- rsa=RSA_new();
- if (rsa == NULL) goto err;
- /* set e */
- rsa->e=BN_new();
- if (rsa->e == NULL) goto err;
+ /* We need the RSA components non-NULL */
+ if(!rsa->n && ((rsa->n=BN_new()) == NULL)) goto err;
+ if(!rsa->d && ((rsa->d=BN_new()) == NULL)) goto err;
+ if(!rsa->e && ((rsa->e=BN_new()) == NULL)) goto err;
+ if(!rsa->p && ((rsa->p=BN_new()) == NULL)) goto err;
+ if(!rsa->q && ((rsa->q=BN_new()) == NULL)) goto err;
+ if(!rsa->dmp1 && ((rsa->dmp1=BN_new()) == NULL)) goto err;
+ if(!rsa->dmq1 && ((rsa->dmq1=BN_new()) == NULL)) goto err;
+ if(!rsa->iqmp && ((rsa->iqmp=BN_new()) == NULL)) goto err;
-#if 1
- /* The problem is when building with 8, 16, or 32 BN_ULONG,
- * unsigned long can be larger */
- for (i=0; i<sizeof(unsigned long)*8; i++)
- {
- if (e_value & (1UL<<i))
- BN_set_bit(rsa->e,i);
- }
-#else
- if (!BN_set_word(rsa->e,e_value)) goto err;
-#endif
+ BN_copy(rsa->e, e_value);
/* generate p and q */
for (;;)
{
- rsa->p=BN_generate_prime(NULL,bitsp,0,NULL,NULL,callback,cb_arg);
- if (rsa->p == NULL) goto err;
+ if(!BN_generate_prime_ex(rsa->p, bitsp, 0, NULL, NULL, cb))
+ goto err;
if (!BN_sub(r2,rsa->p,BN_value_one())) goto err;
if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err;
if (BN_is_one(r1)) break;
- if (callback != NULL) callback(2,n++,cb_arg);
- BN_free(rsa->p);
+ if(!BN_GENCB_call(cb, 2, n++))
+ goto err;
}
- if (callback != NULL) callback(3,0,cb_arg);
+ if(!BN_GENCB_call(cb, 3, 0))
+ goto err;
for (;;)
{
- rsa->q=BN_generate_prime(NULL,bitsq,0,NULL,NULL,callback,cb_arg);
- if (rsa->q == NULL) goto err;
+ /* When generating ridiculously small keys, we can get stuck
+ * continually regenerating the same prime values. Check for
+ * this and bail if it happens 3 times. */
+ unsigned int degenerate = 0;
+ do
+ {
+ if(!BN_generate_prime_ex(rsa->q, bitsq, 0, NULL, NULL, cb))
+ goto err;
+ } while((BN_cmp(rsa->p, rsa->q) == 0) && (++degenerate < 3));
+ if(degenerate == 3)
+ {
+ ok = 0; /* we set our own err */
+ RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,RSA_R_KEY_SIZE_TOO_SMALL);
+ goto err;
+ }
if (!BN_sub(r2,rsa->q,BN_value_one())) goto err;
if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err;
- if (BN_is_one(r1) && (BN_cmp(rsa->p,rsa->q) != 0))
+ if (BN_is_one(r1))
break;
- if (callback != NULL) callback(2,n++,cb_arg);
- BN_free(rsa->q);
+ if(!BN_GENCB_call(cb, 2, n++))
+ goto err;
}
- if (callback != NULL) callback(3,1,cb_arg);
+ if(!BN_GENCB_call(cb, 3, 1))
+ goto err;
if (BN_cmp(rsa->p,rsa->q) < 0)
{
tmp=rsa->p;
@@ -136,66 +161,59 @@ RSA *RSA_generate_key(int bits, unsigned long e_value,
}
/* calculate n */
- rsa->n=BN_new();
- if (rsa->n == NULL) goto err;
if (!BN_mul(rsa->n,rsa->p,rsa->q,ctx)) goto err;
/* calculate d */
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) */
-
-/* should not be needed, since gcd(p-1,e) == 1 and gcd(q-1,e) == 1 */
-/* for (;;)
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
{
- if (!BN_gcd(r3,r0,rsa->e,ctx)) goto err;
- if (BN_is_one(r3)) break;
+ 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 */
- if (1)
- {
- if (!BN_add_word(rsa->e,2L)) goto err;
- continue;
- }
- RSAerr(RSA_F_RSA_GENERATE_KEY,RSA_R_BAD_E_VALUE);
- goto err;
+ /* 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);
}
-*/
- rsa->d=BN_mod_inverse(NULL,rsa->e,r0,ctx2); /* d */
- if (rsa->d == NULL) goto err;
+ else
+ d = rsa->d;
/* calculate d mod (p-1) */
- rsa->dmp1=BN_new();
- if (rsa->dmp1 == NULL) goto err;
- 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) */
- rsa->dmq1=BN_new();
- if (rsa->dmq1 == NULL) goto err;
- 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 */
- rsa->iqmp=BN_mod_inverse(NULL,rsa->q,rsa->p,ctx2);
- if (rsa->iqmp == NULL) 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:
if (ok == -1)
{
- RSAerr(RSA_F_RSA_GENERATE_KEY,ERR_LIB_BN);
+ RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,ERR_LIB_BN);
ok=0;
}
if (ctx != NULL)
- BN_CTX_end(ctx);
- BN_CTX_free(ctx);
- BN_CTX_free(ctx2);
-
- if (!ok)
{
- if (rsa != NULL) RSA_free(rsa);
- return(NULL);
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
}
- else
- return(rsa);
+
+ return ok;
}
-#endif
diff --git a/lib/libcrypto/rsa/rsa_lib.c b/lib/libcrypto/rsa/rsa_lib.c
index e4d622851ee..104aa4c1f2d 100644
--- a/lib/libcrypto/rsa/rsa_lib.c
+++ b/lib/libcrypto/rsa/rsa_lib.c
@@ -67,7 +67,7 @@
#include <openssl/engine.h>
#endif
-const char *RSA_version="RSA" OPENSSL_VERSION_PTEXT;
+const char RSA_version[]="RSA" OPENSSL_VERSION_PTEXT;
static const RSA_METHOD *default_RSA_meth=NULL;
@@ -179,6 +179,7 @@ RSA *RSA_new_method(ENGINE *engine)
ret->_method_mod_p=NULL;
ret->_method_mod_q=NULL;
ret->blinding=NULL;
+ ret->mt_blinding=NULL;
ret->bignum_data=NULL;
ret->flags=ret->meth->flags;
CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data);
@@ -232,6 +233,7 @@ void RSA_free(RSA *r)
if (r->dmq1 != NULL) BN_clear_free(r->dmq1);
if (r->iqmp != NULL) BN_clear_free(r->iqmp);
if (r->blinding != NULL) BN_BLINDING_free(r->blinding);
+ if (r->mt_blinding != NULL) BN_BLINDING_free(r->mt_blinding);
if (r->bignum_data != NULL) OPENSSL_free_locked(r->bignum_data);
OPENSSL_free(r);
}
@@ -314,59 +316,117 @@ void RSA_blinding_off(RSA *rsa)
rsa->flags |= RSA_FLAG_NO_BLINDING;
}
-int RSA_blinding_on(RSA *rsa, BN_CTX *p_ctx)
+int RSA_blinding_on(RSA *rsa, BN_CTX *ctx)
{
- BIGNUM *A,*Ai = NULL;
- BN_CTX *ctx;
int ret=0;
- if (p_ctx == NULL)
+ if (rsa->blinding != NULL)
+ RSA_blinding_off(rsa);
+
+ rsa->blinding = RSA_setup_blinding(rsa, ctx);
+ if (rsa->blinding == NULL)
+ goto err;
+
+ rsa->flags |= RSA_FLAG_BLINDING;
+ rsa->flags &= ~RSA_FLAG_NO_BLINDING;
+ ret=1;
+err:
+ return(ret);
+ }
+
+static BIGNUM *rsa_get_public_exp(const BIGNUM *d, const BIGNUM *p,
+ const BIGNUM *q, BN_CTX *ctx)
+{
+ BIGNUM *ret = NULL, *r0, *r1, *r2;
+
+ if (d == NULL || p == NULL || q == NULL)
+ return NULL;
+
+ BN_CTX_start(ctx);
+ r0 = BN_CTX_get(ctx);
+ r1 = BN_CTX_get(ctx);
+ r2 = BN_CTX_get(ctx);
+ if (r2 == NULL)
+ goto err;
+
+ if (!BN_sub(r1, p, BN_value_one())) goto err;
+ if (!BN_sub(r2, q, BN_value_one())) goto err;
+ if (!BN_mul(r0, r1, r2, ctx)) goto err;
+
+ ret = BN_mod_inverse(NULL, d, r0, ctx);
+err:
+ BN_CTX_end(ctx);
+ return ret;
+}
+
+BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx)
+{
+ BIGNUM local_n;
+ BIGNUM *e,*n;
+ BN_CTX *ctx;
+ BN_BLINDING *ret = NULL;
+
+ if (in_ctx == NULL)
{
- if ((ctx=BN_CTX_new()) == NULL) goto err;
+ if ((ctx = BN_CTX_new()) == NULL) return 0;
}
else
- ctx=p_ctx;
+ ctx = in_ctx;
- /* XXXXX: Shouldn't this be RSA_blinding_off(rsa)? */
- if (rsa->blinding != NULL)
+ BN_CTX_start(ctx);
+ e = BN_CTX_get(ctx);
+ if (e == NULL)
{
- BN_BLINDING_free(rsa->blinding);
- rsa->blinding = NULL;
+ RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_MALLOC_FAILURE);
+ goto err;
}
- /* NB: similar code appears in setup_blinding (rsa_eay.c);
- * this should be placed in a new function of its own, but for reasons
- * of binary compatibility can't */
+ if (rsa->e == NULL)
+ {
+ e = rsa_get_public_exp(rsa->d, rsa->p, rsa->q, ctx);
+ if (e == NULL)
+ {
+ RSAerr(RSA_F_RSA_SETUP_BLINDING, RSA_R_NO_PUBLIC_EXPONENT);
+ goto err;
+ }
+ }
+ else
+ e = rsa->e;
- BN_CTX_start(ctx);
- A = BN_CTX_get(ctx);
+
if ((RAND_status() == 0) && rsa->d != NULL && rsa->d->d != NULL)
{
- /* if PRNG is not properly seeded, resort to secret exponent as unpredictable seed */
- RAND_add(rsa->d->d, rsa->d->dmax * sizeof rsa->d->d[0], 0);
- if (!BN_pseudo_rand_range(A,rsa->n)) goto err;
+ /* if PRNG is not properly seeded, resort to secret
+ * exponent as unpredictable seed */
+ RAND_add(rsa->d->d, rsa->d->dmax * sizeof rsa->d->d[0], 0.0);
}
- else
+
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
{
- if (!BN_rand_range(A,rsa->n)) goto err;
+ /* Set BN_FLG_CONSTTIME flag */
+ n = &local_n;
+ BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME);
}
- if ((Ai=BN_mod_inverse(NULL,A,rsa->n,ctx)) == NULL) goto err;
+ else
+ n = rsa->n;
- if (!rsa->meth->bn_mod_exp(A,A,rsa->e,rsa->n,ctx,rsa->_method_mod_n))
+ ret = BN_BLINDING_create_param(NULL, e, n, ctx,
+ rsa->meth->bn_mod_exp, rsa->_method_mod_n);
+ if (ret == NULL)
+ {
+ RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB);
goto err;
- if ((rsa->blinding=BN_BLINDING_new(A,Ai,rsa->n)) == NULL) goto err;
- /* to make things thread-safe without excessive locking,
- * rsa->blinding will be used just by the current thread: */
- rsa->blinding->thread_id = CRYPTO_thread_id();
- rsa->flags |= RSA_FLAG_BLINDING;
- rsa->flags &= ~RSA_FLAG_NO_BLINDING;
- ret=1;
+ }
+ BN_BLINDING_set_thread_id(ret, CRYPTO_thread_id());
err:
- if (Ai != NULL) BN_free(Ai);
BN_CTX_end(ctx);
- if (ctx != p_ctx) BN_CTX_free(ctx);
- return(ret);
- }
+ if (in_ctx == NULL)
+ BN_CTX_free(ctx);
+ if(rsa->e == NULL)
+ BN_free(e);
+
+ return ret;
+}
int RSA_memory_lock(RSA *r)
{
@@ -389,7 +449,7 @@ int RSA_memory_lock(RSA *r)
j+= (*t[i])->top;
if ((p=OPENSSL_malloc_locked((off+j)*sizeof(BN_ULONG))) == NULL)
{
- RSAerr(RSA_F_MEMORY_LOCK,ERR_R_MALLOC_FAILURE);
+ RSAerr(RSA_F_RSA_MEMORY_LOCK,ERR_R_MALLOC_FAILURE);
return(0);
}
bn=(BIGNUM *)p;
diff --git a/lib/libcrypto/rsa/rsa_null.c b/lib/libcrypto/rsa/rsa_null.c
index 64057fbdcf7..491572c82bd 100644
--- a/lib/libcrypto/rsa/rsa_null.c
+++ b/lib/libcrypto/rsa/rsa_null.c
@@ -94,6 +94,9 @@ static RSA_METHOD rsa_null_meth={
RSA_null_finish,
0,
NULL,
+ NULL,
+ NULL,
+ NULL
};
const RSA_METHOD *RSA_null_method(void)
@@ -104,35 +107,35 @@ const RSA_METHOD *RSA_null_method(void)
static int RSA_null_public_encrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding)
{
- RSAerr(RSA_F_RSA_NULL, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
+ RSAerr(RSA_F_RSA_NULL_PUBLIC_ENCRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
return -1;
}
static int RSA_null_private_encrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding)
{
- RSAerr(RSA_F_RSA_NULL, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
+ RSAerr(RSA_F_RSA_NULL_PRIVATE_ENCRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
return -1;
}
static int RSA_null_private_decrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding)
{
- RSAerr(RSA_F_RSA_NULL, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
+ RSAerr(RSA_F_RSA_NULL_PRIVATE_DECRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
return -1;
}
static int RSA_null_public_decrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding)
{
- RSAerr(RSA_F_RSA_NULL, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
+ RSAerr(RSA_F_RSA_NULL_PUBLIC_DECRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
return -1;
}
#if 0 /* not currently used */
static int RSA_null_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa)
{
- RSAerr(RSA_F_RSA_NULL, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
+ ...err(RSA_F_RSA_NULL_MOD_EXP, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
return -1;
}
#endif
@@ -146,5 +149,3 @@ static int RSA_null_finish(RSA *rsa)
{
return(1);
}
-
-
diff --git a/lib/libcrypto/rsa/rsa_oaep.c b/lib/libcrypto/rsa/rsa_oaep.c
index d43ecaca630..3652677a998 100644
--- a/lib/libcrypto/rsa/rsa_oaep.c
+++ b/lib/libcrypto/rsa/rsa_oaep.c
@@ -28,6 +28,9 @@
#include <openssl/rand.h>
#include <openssl/sha.h>
+int MGF1(unsigned char *mask, long len,
+ const unsigned char *seed, long seedlen);
+
int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
const unsigned char *from, int flen,
const unsigned char *param, int plen)
@@ -73,13 +76,11 @@ int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
20);
#endif
- PKCS1_MGF1(dbmask, emlen - SHA_DIGEST_LENGTH, seed, SHA_DIGEST_LENGTH,
- EVP_sha1());
+ MGF1(dbmask, emlen - SHA_DIGEST_LENGTH, seed, SHA_DIGEST_LENGTH);
for (i = 0; i < emlen - SHA_DIGEST_LENGTH; i++)
db[i] ^= dbmask[i];
- PKCS1_MGF1(seedmask, SHA_DIGEST_LENGTH, db, emlen - SHA_DIGEST_LENGTH,
- EVP_sha1());
+ MGF1(seedmask, SHA_DIGEST_LENGTH, db, emlen - SHA_DIGEST_LENGTH);
for (i = 0; i < SHA_DIGEST_LENGTH; i++)
seed[i] ^= seedmask[i];
@@ -95,6 +96,7 @@ int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
const unsigned char *maskeddb;
int lzero;
unsigned char *db = NULL, seed[SHA_DIGEST_LENGTH], phash[SHA_DIGEST_LENGTH];
+ unsigned char *padded_from;
int bad = 0;
if (--num < 2 * SHA_DIGEST_LENGTH + 1)
@@ -105,8 +107,6 @@ int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
lzero = num - flen;
if (lzero < 0)
{
- /* lzero == -1 */
-
/* signalling this error immediately after detection might allow
* for side-channel attacks (e.g. timing if 'plen' is huge
* -- cf. James H. Manger, "A Chosen Ciphertext Attack on RSA Optimal
@@ -114,22 +114,30 @@ int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
* so we use a 'bad' flag */
bad = 1;
lzero = 0;
+ flen = num; /* don't overflow the memcpy to padded_from */
}
- maskeddb = from - lzero + SHA_DIGEST_LENGTH;
dblen = num - SHA_DIGEST_LENGTH;
- db = OPENSSL_malloc(dblen);
+ db = OPENSSL_malloc(dblen + num);
if (db == NULL)
{
- RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, ERR_R_MALLOC_FAILURE);
+ RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, ERR_R_MALLOC_FAILURE);
return -1;
}
- PKCS1_MGF1(seed, SHA_DIGEST_LENGTH, maskeddb, dblen, EVP_sha1());
- for (i = lzero; i < SHA_DIGEST_LENGTH; i++)
- seed[i] ^= from[i - lzero];
+ /* Always do this zero-padding copy (even when lzero == 0)
+ * to avoid leaking timing info about the value of lzero. */
+ padded_from = db + dblen;
+ memset(padded_from, 0, lzero);
+ memcpy(padded_from + lzero, from, flen);
+
+ maskeddb = padded_from + SHA_DIGEST_LENGTH;
+
+ MGF1(seed, SHA_DIGEST_LENGTH, maskeddb, dblen);
+ for (i = 0; i < SHA_DIGEST_LENGTH; i++)
+ seed[i] ^= padded_from[i];
- PKCS1_MGF1(db, dblen, seed, SHA_DIGEST_LENGTH, EVP_sha1());
+ MGF1(db, dblen, seed, SHA_DIGEST_LENGTH);
for (i = 0; i < dblen; i++)
db[i] ^= maskeddb[i];
@@ -142,13 +150,13 @@ int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
for (i = SHA_DIGEST_LENGTH; i < dblen; i++)
if (db[i] != 0x00)
break;
- if (db[i] != 0x01 || i++ >= dblen)
+ if (i == dblen || db[i] != 0x01)
goto decoding_err;
else
{
/* everything looks OK */
- mlen = dblen - i;
+ mlen = dblen - ++i;
if (tlen < mlen)
{
RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, RSA_R_DATA_TOO_LARGE);
diff --git a/lib/libcrypto/rsa/rsa_saos.c b/lib/libcrypto/rsa/rsa_saos.c
index 24fc94835e2..f98e0a80a6c 100644
--- a/lib/libcrypto/rsa/rsa_saos.c
+++ b/lib/libcrypto/rsa/rsa_saos.c
@@ -107,7 +107,8 @@ int RSA_verify_ASN1_OCTET_STRING(int dtype,
RSA *rsa)
{
int i,ret=0;
- unsigned char *p,*s;
+ unsigned char *s;
+ const unsigned char *p;
ASN1_OCTET_STRING *sig=NULL;
if (siglen != (unsigned int)RSA_size(rsa))
diff --git a/lib/libcrypto/rsa/rsa_sign.c b/lib/libcrypto/rsa/rsa_sign.c
index db86f1ac581..71aabeea1bd 100644
--- a/lib/libcrypto/rsa/rsa_sign.c
+++ b/lib/libcrypto/rsa/rsa_sign.c
@@ -146,7 +146,7 @@ int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,
unsigned char *sigbuf, unsigned int siglen, RSA *rsa)
{
int i,ret=0,sigtype;
- unsigned char *p,*s;
+ unsigned char *s;
X509_SIG *sig=NULL;
if (siglen != (unsigned int)RSA_size(rsa))
@@ -181,7 +181,7 @@ int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,
RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
else ret = 1;
} else {
- p=s;
+ const unsigned char *p=s;
sig=d2i_X509_SIG(NULL,&p,(long)i);
if (sig == NULL) goto err;
diff --git a/lib/libcrypto/rsa/rsa_test.c b/lib/libcrypto/rsa/rsa_test.c
index 218bb2a39bb..4080de8bcf9 100644
--- a/lib/libcrypto/rsa/rsa_test.c
+++ b/lib/libcrypto/rsa/rsa_test.c
@@ -8,6 +8,7 @@
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/rand.h>
+#include <openssl/bn.h>
#ifdef OPENSSL_NO_RSA
int main(int argc, char *argv[])
{
@@ -218,6 +219,7 @@ int main(int argc, char *argv[])
int plen;
int clen = 0;
int num;
+ int n;
CRYPTO_malloc_debug_init();
CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
@@ -241,7 +243,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);
@@ -277,7 +279,7 @@ int main(int argc, char *argv[])
err=1;
goto next;
}
-
+
num = RSA_private_decrypt(num, ctext, ptext, key,
RSA_PKCS1_OAEP_PADDING);
if (num != plen || memcmp(ptext, ptext_ex, num) != 0)
@@ -286,10 +288,7 @@ int main(int argc, char *argv[])
err=1;
}
else if (memcmp(ctext, ctext_ex, num) == 0)
- {
printf("OAEP test vector %d passed!\n", v);
- goto next;
- }
/* Different ciphertexts (rsa_oaep.c without -DPKCS_TESTVECT).
Try decrypting ctext_ex */
@@ -304,6 +303,26 @@ int main(int argc, char *argv[])
}
else
printf("OAEP encryption/decryption ok\n");
+
+ /* Try decrypting corrupted ciphertexts */
+ for(n = 0 ; n < clen ; ++n)
+ {
+ int b;
+ unsigned char saved = ctext[n];
+ for(b = 0 ; b < 256 ; ++b)
+ {
+ if(b == saved)
+ continue;
+ ctext[n] = b;
+ num = RSA_private_decrypt(num, ctext, ptext, key,
+ RSA_PKCS1_OAEP_PADDING);
+ if(num > 0)
+ {
+ printf("Corrupt data decrypted!\n");
+ err = 1;
+ }
+ }
+ }
next:
RSA_free(key);
}
@@ -313,6 +332,9 @@ int main(int argc, char *argv[])
CRYPTO_mem_leaks_fp(stderr);
+#ifdef OPENSSL_SYS_NETWARE
+ if (err) printf("ERROR: %d\n", err);
+#endif
return err;
}
#endif