From 829fd51d4f8dde4a7f3bf54754f3c1d1a502f5e2 Mon Sep 17 00:00:00 2001 From: djm <> Date: Fri, 1 Oct 2010 22:54:21 +0000 Subject: import OpenSSL-1.0.0a --- src/lib/libcrypto/rsa/rsa.h | 89 +++--- src/lib/libcrypto/rsa/rsa_ameth.c | 349 ++++++++++++++++++++++ src/lib/libcrypto/rsa/rsa_asn1.c | 16 +- src/lib/libcrypto/rsa/rsa_eay.c | 6 +- src/lib/libcrypto/rsa/rsa_err.c | 29 +- src/lib/libcrypto/rsa/rsa_gen.c | 3 - src/lib/libcrypto/rsa/rsa_lib.c | 283 ++++++++++++++++-- src/lib/libcrypto/rsa/rsa_locl.h | 4 + src/lib/libcrypto/rsa/rsa_oaep.c | 35 ++- src/lib/libcrypto/rsa/rsa_pmeth.c | 587 ++++++++++++++++++++++++++++++++++++++ src/lib/libcrypto/rsa/rsa_prn.c | 93 ++++++ src/lib/libcrypto/rsa/rsa_pss.c | 16 +- src/lib/libcrypto/rsa/rsa_sign.c | 88 +++--- 13 files changed, 1458 insertions(+), 140 deletions(-) create mode 100644 src/lib/libcrypto/rsa/rsa_ameth.c create mode 100644 src/lib/libcrypto/rsa/rsa_locl.h create mode 100644 src/lib/libcrypto/rsa/rsa_pmeth.c create mode 100644 src/lib/libcrypto/rsa/rsa_prn.c (limited to 'src/lib/libcrypto/rsa') diff --git a/src/lib/libcrypto/rsa/rsa.h b/src/lib/libcrypto/rsa/rsa.h index 5bb932ae15..cf74343657 100644 --- a/src/lib/libcrypto/rsa/rsa.h +++ b/src/lib/libcrypto/rsa/rsa.h @@ -74,25 +74,6 @@ #error RSA is disabled. #endif -/* If this flag is set the RSA method is FIPS compliant and can be used - * in FIPS mode. This is set in the validated module method. If an - * application sets this flag in its own methods it is its reposibility - * to ensure the result is compliant. - */ - -#define RSA_FLAG_FIPS_METHOD 0x0400 - -/* If this flag is set the operations normally disabled in FIPS mode are - * permitted it is then the applications responsibility to ensure that the - * usage is compliant. - */ - -#define RSA_FLAG_NON_FIPS_ALLOW 0x0400 - -#ifdef OPENSSL_FIPS -#define FIPS_RSA_SIZE_T int -#endif - #ifdef __cplusplus extern "C" { #endif @@ -136,7 +117,8 @@ struct rsa_meth_st unsigned char *sigret, unsigned int *siglen, const RSA *rsa); int (*rsa_verify)(int dtype, const unsigned char *m, unsigned int m_length, - unsigned char *sigbuf, unsigned int siglen, const RSA *rsa); + const unsigned char *sigbuf, unsigned int siglen, + const RSA *rsa); /* 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" @@ -182,8 +164,6 @@ struct rsa_st # define OPENSSL_RSA_MAX_MODULUS_BITS 16384 #endif -#define OPENSSL_RSA_FIPS_MIN_MODULUS_BITS 1024 - #ifndef OPENSSL_RSA_SMALL_MODULUS_BITS # define OPENSSL_RSA_SMALL_MODULUS_BITS 3072 #endif @@ -238,11 +218,37 @@ struct rsa_st #endif +#define EVP_PKEY_CTX_set_rsa_padding(ctx, pad) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, \ + pad, NULL) + +#define EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \ + (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \ + EVP_PKEY_CTRL_RSA_PSS_SALTLEN, \ + len, NULL) + +#define EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL) + +#define EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pubexp) + +#define EVP_PKEY_CTRL_RSA_PADDING (EVP_PKEY_ALG_CTRL + 1) +#define EVP_PKEY_CTRL_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 2) + +#define EVP_PKEY_CTRL_RSA_KEYGEN_BITS (EVP_PKEY_ALG_CTRL + 3) +#define EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP (EVP_PKEY_ALG_CTRL + 4) + #define RSA_PKCS1_PADDING 1 #define RSA_SSLV23_PADDING 2 #define RSA_NO_PADDING 3 #define RSA_PKCS1_OAEP_PADDING 4 #define RSA_X931_PADDING 5 +/* EVP_PKEY_ only */ +#define RSA_PKCS1_PSS_PADDING 6 #define RSA_PKCS1_PADDING_SIZE 11 @@ -261,11 +267,6 @@ RSA * RSA_generate_key(int bits, unsigned long e,void /* New version */ int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); -int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1, BIGNUM *q2, - const BIGNUM *Xp1, const BIGNUM *Xp2, const BIGNUM *Xp, - const BIGNUM *Xq1, const BIGNUM *Xq2, const BIGNUM *Xq, - const BIGNUM *e, BN_GENCB *cb); -int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e, BN_GENCB *cb); int RSA_check_key(const RSA *); /* next 4 return -1 on error */ @@ -283,11 +284,6 @@ int RSA_up_ref(RSA *r); int RSA_flags(const RSA *r); -#ifdef OPENSSL_FIPS -RSA *FIPS_rsa_new(void); -void FIPS_rsa_free(RSA *r); -#endif - void RSA_set_default_method(const RSA_METHOD *meth); const RSA_METHOD *RSA_get_default_method(void); const RSA_METHOD *RSA_get_method(const RSA *rsa); @@ -333,7 +329,7 @@ RSA *d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length, int RSA_sign(int type, const unsigned char *m, unsigned int m_length, unsigned char *sigret, unsigned int *siglen, RSA *rsa); int RSA_verify(int type, const unsigned char *m, unsigned int m_length, - unsigned char *sigbuf, unsigned int siglen, RSA *rsa); + const unsigned char *sigbuf, unsigned int siglen, RSA *rsa); /* The following 2 function sign and verify a ASN1_OCTET_STRING * object inside PKCS#1 padded RSA encryption */ @@ -401,9 +397,15 @@ void ERR_load_RSA_strings(void); /* Error codes for the RSA functions. */ /* Function codes. */ -#define RSA_F_FIPS_RSA_SIGN 140 -#define RSA_F_FIPS_RSA_VERIFY 141 +#define RSA_F_CHECK_PADDING_MD 140 +#define RSA_F_DO_RSA_PRINT 146 +#define RSA_F_INT_RSA_VERIFY 145 #define RSA_F_MEMORY_LOCK 100 +#define RSA_F_OLD_RSA_PRIV_DECODE 147 +#define RSA_F_PKEY_RSA_CTRL 143 +#define RSA_F_PKEY_RSA_CTRL_STR 144 +#define RSA_F_PKEY_RSA_SIGN 142 +#define RSA_F_PKEY_RSA_VERIFYRECOVER 141 #define RSA_F_RSA_BUILTIN_KEYGEN 129 #define RSA_F_RSA_CHECK_KEY 123 #define RSA_F_RSA_EAY_PRIVATE_DECRYPT 101 @@ -434,11 +436,10 @@ 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_PRIVATE_ENCRYPT 137 -#define RSA_F_RSA_PUBLIC_DECRYPT 138 +#define RSA_F_RSA_PRIV_DECODE 137 +#define RSA_F_RSA_PRIV_ENCODE 138 +#define RSA_F_RSA_PUB_DECODE 139 #define RSA_F_RSA_SETUP_BLINDING 136 -#define RSA_F_RSA_SET_DEFAULT_METHOD 139 -#define RSA_F_RSA_SET_METHOD 142 #define RSA_F_RSA_SIGN 117 #define RSA_F_RSA_SIGN_ASN1_OCTET_STRING 118 #define RSA_F_RSA_VERIFY 119 @@ -464,20 +465,25 @@ void ERR_load_RSA_strings(void); #define RSA_R_DMQ1_NOT_CONGRUENT_TO_D 125 #define RSA_R_D_E_NOT_CONGRUENT_TO_1 123 #define RSA_R_FIRST_OCTET_INVALID 133 +#define RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE 144 +#define RSA_R_INVALID_DIGEST_LENGTH 143 #define RSA_R_INVALID_HEADER 137 +#define RSA_R_INVALID_KEYBITS 145 #define RSA_R_INVALID_MESSAGE_LENGTH 131 #define RSA_R_INVALID_PADDING 138 +#define RSA_R_INVALID_PADDING_MODE 141 +#define RSA_R_INVALID_PSS_SALTLEN 146 #define RSA_R_INVALID_TRAILER 139 +#define RSA_R_INVALID_X931_DIGEST 142 #define RSA_R_IQMP_NOT_INVERSE_OF_Q 126 #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_NON_FIPS_METHOD 141 #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 -#define RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE 142 +#define RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 148 #define RSA_R_PADDING_CHECK_FAILED 114 #define RSA_R_P_NOT_PRIME 128 #define RSA_R_Q_NOT_PRIME 129 @@ -488,6 +494,7 @@ void ERR_load_RSA_strings(void); #define RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 116 #define RSA_R_UNKNOWN_ALGORITHM_TYPE 117 #define RSA_R_UNKNOWN_PADDING_TYPE 118 +#define RSA_R_VALUE_MISSING 147 #define RSA_R_WRONG_SIGNATURE_LENGTH 119 #ifdef __cplusplus diff --git a/src/lib/libcrypto/rsa/rsa_ameth.c b/src/lib/libcrypto/rsa/rsa_ameth.c new file mode 100644 index 0000000000..8c3209885e --- /dev/null +++ b/src/lib/libcrypto/rsa/rsa_ameth.c @@ -0,0 +1,349 @@ +/* crypto/rsa/rsa_ameth.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 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 + * 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 + * licensing@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 +#include "cryptlib.h" +#include +#include +#include +#include +#ifndef OPENSSL_NO_CMS +#include +#endif +#include "asn1_locl.h" + +static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) + { + unsigned char *penc = NULL; + int penclen; + penclen = i2d_RSAPublicKey(pkey->pkey.rsa, &penc); + if (penclen <= 0) + return 0; + if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_RSA), + V_ASN1_NULL, NULL, penc, penclen)) + return 1; + + OPENSSL_free(penc); + return 0; + } + +static int rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) + { + const unsigned char *p; + int pklen; + RSA *rsa = NULL; + if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, NULL, pubkey)) + return 0; + if (!(rsa = d2i_RSAPublicKey(NULL, &p, pklen))) + { + RSAerr(RSA_F_RSA_PUB_DECODE, ERR_R_RSA_LIB); + return 0; + } + EVP_PKEY_assign_RSA (pkey, rsa); + return 1; + } + +static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) + { + if (BN_cmp(b->pkey.rsa->n,a->pkey.rsa->n) != 0 + || BN_cmp(b->pkey.rsa->e,a->pkey.rsa->e) != 0) + return 0; + return 1; + } + +static int old_rsa_priv_decode(EVP_PKEY *pkey, + const unsigned char **pder, int derlen) + { + RSA *rsa; + if (!(rsa = d2i_RSAPrivateKey (NULL, pder, derlen))) + { + RSAerr(RSA_F_OLD_RSA_PRIV_DECODE, ERR_R_RSA_LIB); + return 0; + } + EVP_PKEY_assign_RSA(pkey, rsa); + return 1; + } + +static int old_rsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) + { + return i2d_RSAPrivateKey(pkey->pkey.rsa, pder); + } + +static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) + { + unsigned char *rk = NULL; + int rklen; + rklen = i2d_RSAPrivateKey(pkey->pkey.rsa, &rk); + + if (rklen <= 0) + { + RSAerr(RSA_F_RSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE); + return 0; + } + + if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_rsaEncryption), 0, + V_ASN1_NULL, NULL, rk, rklen)) + { + RSAerr(RSA_F_RSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE); + return 0; + } + + return 1; + } + +static int rsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) + { + const unsigned char *p; + int pklen; + if (!PKCS8_pkey_get0(NULL, &p, &pklen, NULL, p8)) + return 0; + return old_rsa_priv_decode(pkey, &p, pklen); + } + +static int int_rsa_size(const EVP_PKEY *pkey) + { + return RSA_size(pkey->pkey.rsa); + } + +static int rsa_bits(const EVP_PKEY *pkey) + { + return BN_num_bits(pkey->pkey.rsa->n); + } + +static void int_rsa_free(EVP_PKEY *pkey) + { + RSA_free(pkey->pkey.rsa); + } + + +static void update_buflen(const BIGNUM *b, size_t *pbuflen) + { + size_t i; + if (!b) + return; + if (*pbuflen < (i = (size_t)BN_num_bytes(b))) + *pbuflen = i; + } + +static int do_rsa_print(BIO *bp, const RSA *x, int off, int priv) + { + char *str; + const char *s; + unsigned char *m=NULL; + int ret=0, mod_len = 0; + size_t buf_len=0; + + update_buflen(x->n, &buf_len); + update_buflen(x->e, &buf_len); + + if (priv) + { + update_buflen(x->d, &buf_len); + update_buflen(x->p, &buf_len); + update_buflen(x->q, &buf_len); + update_buflen(x->dmp1, &buf_len); + update_buflen(x->dmq1, &buf_len); + update_buflen(x->iqmp, &buf_len); + } + + m=(unsigned char *)OPENSSL_malloc(buf_len+10); + if (m == NULL) + { + RSAerr(RSA_F_DO_RSA_PRINT,ERR_R_MALLOC_FAILURE); + goto err; + } + + if (x->n != NULL) + mod_len = BN_num_bits(x->n); + + if(!BIO_indent(bp,off,128)) + goto err; + + if (priv && x->d) + { + if (BIO_printf(bp,"Private-Key: (%d bit)\n", mod_len) + <= 0) goto err; + str = "modulus:"; + s = "publicExponent:"; + } + else + { + if (BIO_printf(bp,"Public-Key: (%d bit)\n", mod_len) + <= 0) goto err; + str = "Modulus:"; + s= "Exponent:"; + } + if (!ASN1_bn_print(bp,str,x->n,m,off)) goto err; + if (!ASN1_bn_print(bp,s,x->e,m,off)) + goto err; + if (priv) + { + if (!ASN1_bn_print(bp,"privateExponent:",x->d,m,off)) + goto err; + if (!ASN1_bn_print(bp,"prime1:",x->p,m,off)) + goto err; + if (!ASN1_bn_print(bp,"prime2:",x->q,m,off)) + goto err; + if (!ASN1_bn_print(bp,"exponent1:",x->dmp1,m,off)) + goto err; + if (!ASN1_bn_print(bp,"exponent2:",x->dmq1,m,off)) + goto err; + if (!ASN1_bn_print(bp,"coefficient:",x->iqmp,m,off)) + goto err; + } + ret=1; +err: + if (m != NULL) OPENSSL_free(m); + return(ret); + } + +static int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) + { + return do_rsa_print(bp, pkey->pkey.rsa, indent, 0); + } + + +static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) + { + return do_rsa_print(bp, pkey->pkey.rsa, indent, 1); + } + + +static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) + { + X509_ALGOR *alg = NULL; + switch (op) + { + + case ASN1_PKEY_CTRL_PKCS7_SIGN: + if (arg1 == 0) + PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, NULL, &alg); + break; + + case ASN1_PKEY_CTRL_PKCS7_ENCRYPT: + if (arg1 == 0) + PKCS7_RECIP_INFO_get0_alg(arg2, &alg); + break; +#ifndef OPENSSL_NO_CMS + case ASN1_PKEY_CTRL_CMS_SIGN: + if (arg1 == 0) + CMS_SignerInfo_get0_algs(arg2, NULL, NULL, NULL, &alg); + break; + + case ASN1_PKEY_CTRL_CMS_ENVELOPE: + if (arg1 == 0) + CMS_RecipientInfo_ktri_get0_algs(arg2, NULL, NULL, &alg); + break; +#endif + + case ASN1_PKEY_CTRL_DEFAULT_MD_NID: + *(int *)arg2 = NID_sha1; + return 1; + + default: + return -2; + + } + + if (alg) + X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), + V_ASN1_NULL, 0); + + return 1; + + } + + +const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] = + { + { + EVP_PKEY_RSA, + EVP_PKEY_RSA, + ASN1_PKEY_SIGPARAM_NULL, + + "RSA", + "OpenSSL RSA method", + + rsa_pub_decode, + rsa_pub_encode, + rsa_pub_cmp, + rsa_pub_print, + + rsa_priv_decode, + rsa_priv_encode, + rsa_priv_print, + + int_rsa_size, + rsa_bits, + + 0,0,0,0,0,0, + + int_rsa_free, + rsa_pkey_ctrl, + old_rsa_priv_decode, + old_rsa_priv_encode + }, + + { + EVP_PKEY_RSA2, + EVP_PKEY_RSA, + ASN1_PKEY_ALIAS + } + }; diff --git a/src/lib/libcrypto/rsa/rsa_asn1.c b/src/lib/libcrypto/rsa/rsa_asn1.c index 6e8a803e81..4efca8cdc8 100644 --- a/src/lib/libcrypto/rsa/rsa_asn1.c +++ b/src/lib/libcrypto/rsa/rsa_asn1.c @@ -3,7 +3,7 @@ * project 2000. */ /* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * Copyright (c) 2000-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 @@ -62,19 +62,9 @@ #include #include -static ASN1_METHOD method={ - (I2D_OF(void)) i2d_RSAPrivateKey, - (D2I_OF(void)) d2i_RSAPrivateKey, - (void *(*)(void)) RSA_new, - (void (*)(void *)) RSA_free}; - -ASN1_METHOD *RSAPrivateKey_asn1_meth(void) - { - return(&method); - } - /* Override the default free and new methods */ -static int rsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) +static int rsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) { if(operation == ASN1_OP_NEW_PRE) { *pval = (ASN1_VALUE *)RSA_new(); diff --git a/src/lib/libcrypto/rsa/rsa_eay.c b/src/lib/libcrypto/rsa/rsa_eay.c index 0ac6418449..c5eaeeae6b 100644 --- a/src/lib/libcrypto/rsa/rsa_eay.c +++ b/src/lib/libcrypto/rsa/rsa_eay.c @@ -115,7 +115,7 @@ #include #include -#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); @@ -256,6 +256,7 @@ static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx) { BN_BLINDING *ret; int got_write_lock = 0; + CRYPTO_THREADID cur; CRYPTO_r_lock(CRYPTO_LOCK_RSA); @@ -273,7 +274,8 @@ static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx) if (ret == NULL) goto err; - if (BN_BLINDING_get_thread_id(ret) == CRYPTO_thread_id()) + CRYPTO_THREADID_current(&cur); + if (!CRYPTO_THREADID_cmp(&cur, BN_BLINDING_thread_id(ret))) { /* rsa->blinding is ours! */ diff --git a/src/lib/libcrypto/rsa/rsa_err.c b/src/lib/libcrypto/rsa/rsa_err.c index 501f5ea389..cf9f1106b0 100644 --- a/src/lib/libcrypto/rsa/rsa_err.c +++ b/src/lib/libcrypto/rsa/rsa_err.c @@ -1,6 +1,6 @@ /* crypto/rsa/rsa_err.c */ /* ==================================================================== - * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2008 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 @@ -70,9 +70,15 @@ static ERR_STRING_DATA RSA_str_functs[]= { -{ERR_FUNC(RSA_F_FIPS_RSA_SIGN), "FIPS_RSA_SIGN"}, -{ERR_FUNC(RSA_F_FIPS_RSA_VERIFY), "FIPS_RSA_VERIFY"}, +{ERR_FUNC(RSA_F_CHECK_PADDING_MD), "CHECK_PADDING_MD"}, +{ERR_FUNC(RSA_F_DO_RSA_PRINT), "DO_RSA_PRINT"}, +{ERR_FUNC(RSA_F_INT_RSA_VERIFY), "INT_RSA_VERIFY"}, {ERR_FUNC(RSA_F_MEMORY_LOCK), "MEMORY_LOCK"}, +{ERR_FUNC(RSA_F_OLD_RSA_PRIV_DECODE), "OLD_RSA_PRIV_DECODE"}, +{ERR_FUNC(RSA_F_PKEY_RSA_CTRL), "PKEY_RSA_CTRL"}, +{ERR_FUNC(RSA_F_PKEY_RSA_CTRL_STR), "PKEY_RSA_CTRL_STR"}, +{ERR_FUNC(RSA_F_PKEY_RSA_SIGN), "PKEY_RSA_SIGN"}, +{ERR_FUNC(RSA_F_PKEY_RSA_VERIFYRECOVER), "PKEY_RSA_VERIFYRECOVER"}, {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"}, @@ -103,11 +109,10 @@ 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_PRIVATE_ENCRYPT), "RSA_private_encrypt"}, -{ERR_FUNC(RSA_F_RSA_PUBLIC_DECRYPT), "RSA_public_decrypt"}, +{ERR_FUNC(RSA_F_RSA_PRIV_DECODE), "RSA_PRIV_DECODE"}, +{ERR_FUNC(RSA_F_RSA_PRIV_ENCODE), "RSA_PRIV_ENCODE"}, +{ERR_FUNC(RSA_F_RSA_PUB_DECODE), "RSA_PUB_DECODE"}, {ERR_FUNC(RSA_F_RSA_SETUP_BLINDING), "RSA_setup_blinding"}, -{ERR_FUNC(RSA_F_RSA_SET_DEFAULT_METHOD), "RSA_set_default_method"}, -{ERR_FUNC(RSA_F_RSA_SET_METHOD), "RSA_set_method"}, {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"}, @@ -136,20 +141,25 @@ static ERR_STRING_DATA RSA_str_reasons[]= {ERR_REASON(RSA_R_DMQ1_NOT_CONGRUENT_TO_D),"dmq1 not congruent to d"}, {ERR_REASON(RSA_R_D_E_NOT_CONGRUENT_TO_1),"d e not congruent to 1"}, {ERR_REASON(RSA_R_FIRST_OCTET_INVALID) ,"first octet invalid"}, +{ERR_REASON(RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE),"illegal or unsupported padding mode"}, +{ERR_REASON(RSA_R_INVALID_DIGEST_LENGTH) ,"invalid digest length"}, {ERR_REASON(RSA_R_INVALID_HEADER) ,"invalid header"}, +{ERR_REASON(RSA_R_INVALID_KEYBITS) ,"invalid keybits"}, {ERR_REASON(RSA_R_INVALID_MESSAGE_LENGTH),"invalid message length"}, {ERR_REASON(RSA_R_INVALID_PADDING) ,"invalid padding"}, +{ERR_REASON(RSA_R_INVALID_PADDING_MODE) ,"invalid padding mode"}, +{ERR_REASON(RSA_R_INVALID_PSS_SALTLEN) ,"invalid pss saltlen"}, {ERR_REASON(RSA_R_INVALID_TRAILER) ,"invalid trailer"}, +{ERR_REASON(RSA_R_INVALID_X931_DIGEST) ,"invalid x931 digest"}, {ERR_REASON(RSA_R_IQMP_NOT_INVERSE_OF_Q) ,"iqmp not inverse of q"}, {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_NON_FIPS_METHOD) ,"non fips method"}, {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_OPERATION_NOT_ALLOWED_IN_FIPS_MODE),"operation not allowed in fips mode"}, +{ERR_REASON(RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE),"operation not supported for this keytype"}, {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"}, @@ -160,6 +170,7 @@ static ERR_STRING_DATA RSA_str_reasons[]= {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_VALUE_MISSING) ,"value missing"}, {ERR_REASON(RSA_R_WRONG_SIGNATURE_LENGTH),"wrong signature length"}, {0,NULL} }; diff --git a/src/lib/libcrypto/rsa/rsa_gen.c b/src/lib/libcrypto/rsa/rsa_gen.c index 41278f83c6..767f7ab682 100644 --- a/src/lib/libcrypto/rsa/rsa_gen.c +++ b/src/lib/libcrypto/rsa/rsa_gen.c @@ -68,8 +68,6 @@ #include #include -#ifndef OPENSSL_FIPS - static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb); /* NB: this wrapper would normally be placed in rsa_lib.c and the static @@ -219,4 +217,3 @@ err: return ok; } -#endif diff --git a/src/lib/libcrypto/rsa/rsa_lib.c b/src/lib/libcrypto/rsa/rsa_lib.c index 5714841f4c..de45088d76 100644 --- a/src/lib/libcrypto/rsa/rsa_lib.c +++ b/src/lib/libcrypto/rsa/rsa_lib.c @@ -67,6 +67,224 @@ #include #endif +const char RSA_version[]="RSA" OPENSSL_VERSION_PTEXT; + +static const RSA_METHOD *default_RSA_meth=NULL; + +RSA *RSA_new(void) + { + RSA *r=RSA_new_method(NULL); + + return r; + } + +void RSA_set_default_method(const RSA_METHOD *meth) + { + default_RSA_meth = meth; + } + +const RSA_METHOD *RSA_get_default_method(void) + { + if (default_RSA_meth == NULL) + { +#ifdef RSA_NULL + default_RSA_meth=RSA_null_method(); +#else +#if 0 /* was: #ifdef RSAref */ + default_RSA_meth=RSA_PKCS1_RSAref(); +#else + default_RSA_meth=RSA_PKCS1_SSLeay(); +#endif +#endif + } + + return default_RSA_meth; + } + +const RSA_METHOD *RSA_get_method(const RSA *rsa) + { + return rsa->meth; + } + +int RSA_set_method(RSA *rsa, const RSA_METHOD *meth) + { + /* NB: The caller is specifically setting a method, so it's not up to us + * to deal with which ENGINE it comes from. */ + const RSA_METHOD *mtmp; + mtmp = rsa->meth; + if (mtmp->finish) mtmp->finish(rsa); +#ifndef OPENSSL_NO_ENGINE + if (rsa->engine) + { + ENGINE_finish(rsa->engine); + rsa->engine = NULL; + } +#endif + rsa->meth = meth; + if (meth->init) meth->init(rsa); + return 1; + } + +RSA *RSA_new_method(ENGINE *engine) + { + RSA *ret; + + ret=(RSA *)OPENSSL_malloc(sizeof(RSA)); + if (ret == NULL) + { + RSAerr(RSA_F_RSA_NEW_METHOD,ERR_R_MALLOC_FAILURE); + return NULL; + } + + ret->meth = RSA_get_default_method(); +#ifndef OPENSSL_NO_ENGINE + if (engine) + { + if (!ENGINE_init(engine)) + { + RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB); + OPENSSL_free(ret); + return NULL; + } + ret->engine = engine; + } + else + ret->engine = ENGINE_get_default_RSA(); + if(ret->engine) + { + ret->meth = ENGINE_get_RSA(ret->engine); + if(!ret->meth) + { + RSAerr(RSA_F_RSA_NEW_METHOD, + ERR_R_ENGINE_LIB); + ENGINE_finish(ret->engine); + OPENSSL_free(ret); + return NULL; + } + } +#endif + + ret->pad=0; + ret->version=0; + ret->n=NULL; + ret->e=NULL; + ret->d=NULL; + ret->p=NULL; + ret->q=NULL; + ret->dmp1=NULL; + ret->dmq1=NULL; + ret->iqmp=NULL; + ret->references=1; + ret->_method_mod_n=NULL; + 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; + if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data)) + { +#ifndef OPENSSL_NO_ENGINE + if (ret->engine) + ENGINE_finish(ret->engine); +#endif + OPENSSL_free(ret); + return(NULL); + } + + if ((ret->meth->init != NULL) && !ret->meth->init(ret)) + { +#ifndef OPENSSL_NO_ENGINE + if (ret->engine) + ENGINE_finish(ret->engine); +#endif + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data); + OPENSSL_free(ret); + ret=NULL; + } + return(ret); + } + +void RSA_free(RSA *r) + { + int i; + + if (r == NULL) return; + + i=CRYPTO_add(&r->references,-1,CRYPTO_LOCK_RSA); +#ifdef REF_PRINT + REF_PRINT("RSA",r); +#endif + if (i > 0) return; +#ifdef REF_CHECK + if (i < 0) + { + fprintf(stderr,"RSA_free, bad reference count\n"); + abort(); + } +#endif + + if (r->meth->finish) + r->meth->finish(r); +#ifndef OPENSSL_NO_ENGINE + if (r->engine) + ENGINE_finish(r->engine); +#endif + + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, r, &r->ex_data); + + if (r->n != NULL) BN_clear_free(r->n); + if (r->e != NULL) BN_clear_free(r->e); + if (r->d != NULL) BN_clear_free(r->d); + if (r->p != NULL) BN_clear_free(r->p); + if (r->q != NULL) BN_clear_free(r->q); + if (r->dmp1 != NULL) BN_clear_free(r->dmp1); + 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); + } + +int RSA_up_ref(RSA *r) + { + int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_RSA); +#ifdef REF_PRINT + REF_PRINT("RSA",r); +#endif +#ifdef REF_CHECK + if (i < 2) + { + fprintf(stderr, "RSA_up_ref, bad reference count\n"); + abort(); + } +#endif + return ((i > 1) ? 1 : 0); + } + +int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) + { + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_RSA, argl, argp, + new_func, dup_func, free_func); + } + +int RSA_set_ex_data(RSA *r, int idx, void *arg) + { + return(CRYPTO_set_ex_data(&r->ex_data,idx,arg)); + } + +void *RSA_get_ex_data(const RSA *r, int idx) + { + return(CRYPTO_get_ex_data(&r->ex_data,idx)); + } + +int RSA_size(const RSA *r) + { + return(BN_num_bytes(r->n)); + } + int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { @@ -76,13 +294,6 @@ int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to, int RSA_private_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { -#ifdef OPENSSL_FIPS - if(FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) - { - RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); - return 0; - } -#endif return(rsa->meth->rsa_priv_enc(flen, from, to, rsa, padding)); } @@ -95,19 +306,12 @@ int RSA_private_decrypt(int flen, const unsigned char *from, unsigned char *to, int RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { -#ifdef OPENSSL_FIPS - if(FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) - { - RSAerr(RSA_F_RSA_PUBLIC_DECRYPT, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); - return 0; - } -#endif return(rsa->meth->rsa_pub_dec(flen, from, to, rsa, padding)); } -int RSA_size(const RSA *r) +int RSA_flags(const RSA *r) { - return(BN_num_bytes(r->n)); + return((r == NULL)?0:r->meth->flags); } void RSA_blinding_off(RSA *rsa) @@ -222,7 +426,7 @@ BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx) RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB); goto err; } - BN_BLINDING_set_thread_id(ret, CRYPTO_thread_id()); + CRYPTO_THREADID_current(BN_BLINDING_thread_id(ret)); err: BN_CTX_end(ctx); if (in_ctx == NULL) @@ -232,3 +436,48 @@ err: return ret; } + +int RSA_memory_lock(RSA *r) + { + int i,j,k,off; + char *p; + BIGNUM *bn,**t[6],*b; + BN_ULONG *ul; + + if (r->d == NULL) return(1); + t[0]= &r->d; + t[1]= &r->p; + t[2]= &r->q; + t[3]= &r->dmp1; + t[4]= &r->dmq1; + t[5]= &r->iqmp; + k=sizeof(BIGNUM)*6; + off=k/sizeof(BN_ULONG)+1; + j=1; + for (i=0; i<6; i++) + j+= (*t[i])->top; + if ((p=OPENSSL_malloc_locked((off+j)*sizeof(BN_ULONG))) == NULL) + { + RSAerr(RSA_F_RSA_MEMORY_LOCK,ERR_R_MALLOC_FAILURE); + return(0); + } + bn=(BIGNUM *)p; + ul=(BN_ULONG *)&(p[off]); + for (i=0; i<6; i++) + { + b= *(t[i]); + *(t[i])= &(bn[i]); + memcpy((char *)&(bn[i]),(char *)b,sizeof(BIGNUM)); + bn[i].flags=BN_FLG_STATIC_DATA; + bn[i].d=ul; + memcpy((char *)ul,b->d,sizeof(BN_ULONG)*b->top); + ul+=b->top; + BN_clear_free(b); + } + + /* I should fix this so it can still be done */ + r->flags&= ~(RSA_FLAG_CACHE_PRIVATE|RSA_FLAG_CACHE_PUBLIC); + + r->bignum_data=p; + return(1); + } diff --git a/src/lib/libcrypto/rsa/rsa_locl.h b/src/lib/libcrypto/rsa/rsa_locl.h new file mode 100644 index 0000000000..f5d2d56628 --- /dev/null +++ b/src/lib/libcrypto/rsa/rsa_locl.h @@ -0,0 +1,4 @@ +extern int int_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len, + unsigned char *rm, size_t *prm_len, + const unsigned char *sigbuf, size_t siglen, + RSA *rsa); diff --git a/src/lib/libcrypto/rsa/rsa_oaep.c b/src/lib/libcrypto/rsa/rsa_oaep.c index 4d30c9d2d3..e238d10e5c 100644 --- a/src/lib/libcrypto/rsa/rsa_oaep.c +++ b/src/lib/libcrypto/rsa/rsa_oaep.c @@ -28,7 +28,7 @@ #include #include -int MGF1(unsigned char *mask, long len, +static int MGF1(unsigned char *mask, long len, const unsigned char *seed, long seedlen); int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen, @@ -52,13 +52,6 @@ int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen, return 0; } - dbmask = OPENSSL_malloc(emlen - SHA_DIGEST_LENGTH); - if (dbmask == NULL) - { - RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, ERR_R_MALLOC_FAILURE); - return 0; - } - to[0] = 0; seed = to + 1; db = to + SHA_DIGEST_LENGTH + 1; @@ -76,11 +69,20 @@ int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen, 20); #endif - MGF1(dbmask, emlen - SHA_DIGEST_LENGTH, seed, SHA_DIGEST_LENGTH); + dbmask = OPENSSL_malloc(emlen - SHA_DIGEST_LENGTH); + if (dbmask == NULL) + { + RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (MGF1(dbmask, emlen - SHA_DIGEST_LENGTH, seed, SHA_DIGEST_LENGTH) < 0) + return 0; for (i = 0; i < emlen - SHA_DIGEST_LENGTH; i++) db[i] ^= dbmask[i]; - MGF1(seedmask, SHA_DIGEST_LENGTH, db, emlen - SHA_DIGEST_LENGTH); + if (MGF1(seedmask, SHA_DIGEST_LENGTH, db, emlen - SHA_DIGEST_LENGTH) < 0) + return 0; for (i = 0; i < SHA_DIGEST_LENGTH; i++) seed[i] ^= seedmask[i]; @@ -133,11 +135,13 @@ int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen, maskeddb = padded_from + SHA_DIGEST_LENGTH; - MGF1(seed, SHA_DIGEST_LENGTH, maskeddb, dblen); + if (MGF1(seed, SHA_DIGEST_LENGTH, maskeddb, dblen)) + return -1; for (i = 0; i < SHA_DIGEST_LENGTH; i++) seed[i] ^= padded_from[i]; - MGF1(db, dblen, seed, SHA_DIGEST_LENGTH); + if (MGF1(db, dblen, seed, SHA_DIGEST_LENGTH)) + return -1; for (i = 0; i < dblen; i++) db[i] ^= maskeddb[i]; @@ -187,7 +191,9 @@ int PKCS1_MGF1(unsigned char *mask, long len, int mdlen; EVP_MD_CTX_init(&c); - mdlen = M_EVP_MD_size(dgst); + mdlen = EVP_MD_size(dgst); + if (mdlen < 0) + return -1; for (i = 0; outlen < len; i++) { cnt[0] = (unsigned char)((i >> 24) & 255); @@ -213,7 +219,8 @@ int PKCS1_MGF1(unsigned char *mask, long len, return 0; } -int MGF1(unsigned char *mask, long len, const unsigned char *seed, long seedlen) +static int MGF1(unsigned char *mask, long len, const unsigned char *seed, + long seedlen) { return PKCS1_MGF1(mask, len, seed, seedlen, EVP_sha1()); } diff --git a/src/lib/libcrypto/rsa/rsa_pmeth.c b/src/lib/libcrypto/rsa/rsa_pmeth.c new file mode 100644 index 0000000000..c6892ecd09 --- /dev/null +++ b/src/lib/libcrypto/rsa/rsa_pmeth.c @@ -0,0 +1,587 @@ +/* crypto/rsa/rsa_pmeth.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 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 + * 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 + * licensing@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 +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include "evp_locl.h" +#include "rsa_locl.h" + +/* RSA pkey context structure */ + +typedef struct + { + /* Key gen parameters */ + int nbits; + BIGNUM *pub_exp; + /* Keygen callback info */ + int gentmp[2]; + /* RSA padding mode */ + int pad_mode; + /* message digest */ + const EVP_MD *md; + /* PSS/OAEP salt length */ + int saltlen; + /* Temp buffer */ + unsigned char *tbuf; + } RSA_PKEY_CTX; + +static int pkey_rsa_init(EVP_PKEY_CTX *ctx) + { + RSA_PKEY_CTX *rctx; + rctx = OPENSSL_malloc(sizeof(RSA_PKEY_CTX)); + if (!rctx) + return 0; + rctx->nbits = 1024; + rctx->pub_exp = NULL; + rctx->pad_mode = RSA_PKCS1_PADDING; + rctx->md = NULL; + rctx->tbuf = NULL; + + rctx->saltlen = -2; + + ctx->data = rctx; + ctx->keygen_info = rctx->gentmp; + ctx->keygen_info_count = 2; + + return 1; + } + +static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) + { + RSA_PKEY_CTX *dctx, *sctx; + if (!pkey_rsa_init(dst)) + return 0; + sctx = src->data; + dctx = dst->data; + dctx->nbits = sctx->nbits; + if (sctx->pub_exp) + { + dctx->pub_exp = BN_dup(sctx->pub_exp); + if (!dctx->pub_exp) + return 0; + } + dctx->pad_mode = sctx->pad_mode; + dctx->md = sctx->md; + return 1; + } + +static int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk) + { + if (ctx->tbuf) + return 1; + ctx->tbuf = OPENSSL_malloc(EVP_PKEY_size(pk->pkey)); + if (!ctx->tbuf) + return 0; + return 1; + } + +static void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx) + { + RSA_PKEY_CTX *rctx = ctx->data; + if (rctx) + { + if (rctx->pub_exp) + BN_free(rctx->pub_exp); + if (rctx->tbuf) + OPENSSL_free(rctx->tbuf); + OPENSSL_free(rctx); + } + } + +static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen) + { + int ret; + RSA_PKEY_CTX *rctx = ctx->data; + RSA *rsa = ctx->pkey->pkey.rsa; + + if (rctx->md) + { + if (tbslen != (size_t)EVP_MD_size(rctx->md)) + { + RSAerr(RSA_F_PKEY_RSA_SIGN, + RSA_R_INVALID_DIGEST_LENGTH); + return -1; + } + if (rctx->pad_mode == RSA_X931_PADDING) + { + if (!setup_tbuf(rctx, ctx)) + return -1; + memcpy(rctx->tbuf, tbs, tbslen); + rctx->tbuf[tbslen] = + RSA_X931_hash_id(EVP_MD_type(rctx->md)); + ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf, + sig, rsa, RSA_X931_PADDING); + } + else if (rctx->pad_mode == RSA_PKCS1_PADDING) + { + unsigned int sltmp; + ret = RSA_sign(EVP_MD_type(rctx->md), + tbs, tbslen, sig, &sltmp, rsa); + if (ret <= 0) + return ret; + ret = sltmp; + } + else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) + { + if (!setup_tbuf(rctx, ctx)) + return -1; + if (!RSA_padding_add_PKCS1_PSS(rsa, rctx->tbuf, tbs, + rctx->md, rctx->saltlen)) + return -1; + ret = RSA_private_encrypt(RSA_size(rsa), rctx->tbuf, + sig, rsa, RSA_NO_PADDING); + } + else + return -1; + } + else + ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa, + rctx->pad_mode); + if (ret < 0) + return ret; + *siglen = ret; + return 1; + } + + +static int pkey_rsa_verifyrecover(EVP_PKEY_CTX *ctx, + unsigned char *rout, size_t *routlen, + const unsigned char *sig, size_t siglen) + { + int ret; + RSA_PKEY_CTX *rctx = ctx->data; + + if (rctx->md) + { + if (rctx->pad_mode == RSA_X931_PADDING) + { + if (!setup_tbuf(rctx, ctx)) + return -1; + ret = RSA_public_decrypt(siglen, sig, + rctx->tbuf, ctx->pkey->pkey.rsa, + RSA_X931_PADDING); + if (ret < 1) + return 0; + ret--; + if (rctx->tbuf[ret] != + RSA_X931_hash_id(EVP_MD_type(rctx->md))) + { + RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER, + RSA_R_ALGORITHM_MISMATCH); + return 0; + } + if (ret != EVP_MD_size(rctx->md)) + { + RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER, + RSA_R_INVALID_DIGEST_LENGTH); + return 0; + } + if (rout) + memcpy(rout, rctx->tbuf, ret); + } + else if (rctx->pad_mode == RSA_PKCS1_PADDING) + { + size_t sltmp; + ret = int_rsa_verify(EVP_MD_type(rctx->md), + NULL, 0, rout, &sltmp, + sig, siglen, ctx->pkey->pkey.rsa); + if (ret <= 0) + return 0; + ret = sltmp; + } + else + return -1; + } + else + ret = RSA_public_decrypt(siglen, sig, rout, ctx->pkey->pkey.rsa, + rctx->pad_mode); + if (ret < 0) + return ret; + *routlen = ret; + return 1; + } + +static int pkey_rsa_verify(EVP_PKEY_CTX *ctx, + const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen) + { + RSA_PKEY_CTX *rctx = ctx->data; + RSA *rsa = ctx->pkey->pkey.rsa; + size_t rslen; + if (rctx->md) + { + if (rctx->pad_mode == RSA_PKCS1_PADDING) + return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen, + sig, siglen, rsa); + if (rctx->pad_mode == RSA_X931_PADDING) + { + if (pkey_rsa_verifyrecover(ctx, NULL, &rslen, + sig, siglen) <= 0) + return 0; + } + else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) + { + int ret; + if (!setup_tbuf(rctx, ctx)) + return -1; + ret = RSA_public_decrypt(siglen, sig, rctx->tbuf, + rsa, RSA_NO_PADDING); + if (ret <= 0) + return 0; + ret = RSA_verify_PKCS1_PSS(rsa, tbs, rctx->md, + rctx->tbuf, rctx->saltlen); + if (ret <= 0) + return 0; + return 1; + } + else + return -1; + } + else + { + if (!setup_tbuf(rctx, ctx)) + return -1; + rslen = RSA_public_decrypt(siglen, sig, rctx->tbuf, + rsa, rctx->pad_mode); + if (rslen == 0) + return 0; + } + + if ((rslen != tbslen) || memcmp(tbs, rctx->tbuf, rslen)) + return 0; + + return 1; + + } + + +static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen) + { + int ret; + RSA_PKEY_CTX *rctx = ctx->data; + ret = RSA_public_encrypt(inlen, in, out, ctx->pkey->pkey.rsa, + rctx->pad_mode); + if (ret < 0) + return ret; + *outlen = ret; + return 1; + } + +static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen) + { + int ret; + RSA_PKEY_CTX *rctx = ctx->data; + ret = RSA_private_decrypt(inlen, in, out, ctx->pkey->pkey.rsa, + rctx->pad_mode); + if (ret < 0) + return ret; + *outlen = ret; + return 1; + } + +static int check_padding_md(const EVP_MD *md, int padding) + { + if (!md) + return 1; + + if (padding == RSA_NO_PADDING) + { + RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_PADDING_MODE); + return 0; + } + + if (padding == RSA_X931_PADDING) + { + if (RSA_X931_hash_id(EVP_MD_type(md)) == -1) + { + RSAerr(RSA_F_CHECK_PADDING_MD, + RSA_R_INVALID_X931_DIGEST); + return 0; + } + return 1; + } + + return 1; + } + + +static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) + { + RSA_PKEY_CTX *rctx = ctx->data; + switch (type) + { + case EVP_PKEY_CTRL_RSA_PADDING: + if ((p1 >= RSA_PKCS1_PADDING) && (p1 <= RSA_PKCS1_PSS_PADDING)) + { + if (!check_padding_md(rctx->md, p1)) + return 0; + if (p1 == RSA_PKCS1_PSS_PADDING) + { + if (!(ctx->operation & + (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY))) + goto bad_pad; + if (!rctx->md) + rctx->md = EVP_sha1(); + } + if (p1 == RSA_PKCS1_OAEP_PADDING) + { + if (!(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT)) + goto bad_pad; + if (!rctx->md) + rctx->md = EVP_sha1(); + } + rctx->pad_mode = p1; + return 1; + } + bad_pad: + RSAerr(RSA_F_PKEY_RSA_CTRL, + RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); + return -2; + + case EVP_PKEY_CTRL_RSA_PSS_SALTLEN: + if (p1 < -2) + return -2; + if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) + { + RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PSS_SALTLEN); + return -2; + } + rctx->saltlen = p1; + return 1; + + case EVP_PKEY_CTRL_RSA_KEYGEN_BITS: + if (p1 < 256) + { + RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_KEYBITS); + return -2; + } + rctx->nbits = p1; + return 1; + + case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP: + if (!p2) + return -2; + rctx->pub_exp = p2; + return 1; + + case EVP_PKEY_CTRL_MD: + if (!check_padding_md(p2, rctx->pad_mode)) + return 0; + rctx->md = p2; + return 1; + + case EVP_PKEY_CTRL_DIGESTINIT: + case EVP_PKEY_CTRL_PKCS7_ENCRYPT: + case EVP_PKEY_CTRL_PKCS7_DECRYPT: + case EVP_PKEY_CTRL_PKCS7_SIGN: +#ifndef OPENSSL_NO_CMS + case EVP_PKEY_CTRL_CMS_ENCRYPT: + case EVP_PKEY_CTRL_CMS_DECRYPT: + case EVP_PKEY_CTRL_CMS_SIGN: +#endif + return 1; + case EVP_PKEY_CTRL_PEER_KEY: + RSAerr(RSA_F_PKEY_RSA_CTRL, + RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + + default: + return -2; + + } + } + +static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx, + const char *type, const char *value) + { + if (!value) + { + RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_VALUE_MISSING); + return 0; + } + if (!strcmp(type, "rsa_padding_mode")) + { + int pm; + if (!strcmp(value, "pkcs1")) + pm = RSA_PKCS1_PADDING; + else if (!strcmp(value, "sslv23")) + pm = RSA_SSLV23_PADDING; + else if (!strcmp(value, "none")) + pm = RSA_NO_PADDING; + else if (!strcmp(value, "oeap")) + pm = RSA_PKCS1_OAEP_PADDING; + else if (!strcmp(value, "x931")) + pm = RSA_X931_PADDING; + else if (!strcmp(value, "pss")) + pm = RSA_PKCS1_PSS_PADDING; + else + { + RSAerr(RSA_F_PKEY_RSA_CTRL_STR, + RSA_R_UNKNOWN_PADDING_TYPE); + return -2; + } + return EVP_PKEY_CTX_set_rsa_padding(ctx, pm); + } + + if (!strcmp(type, "rsa_pss_saltlen")) + { + int saltlen; + saltlen = atoi(value); + return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltlen); + } + + if (!strcmp(type, "rsa_keygen_bits")) + { + int nbits; + nbits = atoi(value); + return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, nbits); + } + + if (!strcmp(type, "rsa_keygen_pubexp")) + { + int ret; + BIGNUM *pubexp = NULL; + if (!BN_asc2bn(&pubexp, value)) + return 0; + ret = EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp); + if (ret <= 0) + BN_free(pubexp); + return ret; + } + + return -2; + } + +static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) + { + RSA *rsa = NULL; + RSA_PKEY_CTX *rctx = ctx->data; + BN_GENCB *pcb, cb; + int ret; + if (!rctx->pub_exp) + { + rctx->pub_exp = BN_new(); + if (!rctx->pub_exp || !BN_set_word(rctx->pub_exp, RSA_F4)) + return 0; + } + rsa = RSA_new(); + if (!rsa) + return 0; + if (ctx->pkey_gencb) + { + pcb = &cb; + evp_pkey_set_cb_translate(pcb, ctx); + } + else + pcb = NULL; + ret = RSA_generate_key_ex(rsa, rctx->nbits, rctx->pub_exp, pcb); + if (ret > 0) + EVP_PKEY_assign_RSA(pkey, rsa); + else + RSA_free(rsa); + return ret; + } + +const EVP_PKEY_METHOD rsa_pkey_meth = + { + EVP_PKEY_RSA, + EVP_PKEY_FLAG_AUTOARGLEN, + pkey_rsa_init, + pkey_rsa_copy, + pkey_rsa_cleanup, + + 0,0, + + 0, + pkey_rsa_keygen, + + 0, + pkey_rsa_sign, + + 0, + pkey_rsa_verify, + + 0, + pkey_rsa_verifyrecover, + + + 0,0,0,0, + + 0, + pkey_rsa_encrypt, + + 0, + pkey_rsa_decrypt, + + 0,0, + + pkey_rsa_ctrl, + pkey_rsa_ctrl_str + + + }; diff --git a/src/lib/libcrypto/rsa/rsa_prn.c b/src/lib/libcrypto/rsa/rsa_prn.c new file mode 100644 index 0000000000..224db0fae5 --- /dev/null +++ b/src/lib/libcrypto/rsa/rsa_prn.c @@ -0,0 +1,93 @@ +/* crypto/rsa/rsa_prn.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2006. + */ +/* ==================================================================== + * Copyright (c) 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 + * 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 + * licensing@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 +#include "cryptlib.h" +#include +#include + +#ifndef OPENSSL_NO_FP_API +int RSA_print_fp(FILE *fp, const RSA *x, int off) + { + BIO *b; + int ret; + + if ((b=BIO_new(BIO_s_file())) == NULL) + { + RSAerr(RSA_F_RSA_PRINT_FP,ERR_R_BUF_LIB); + return(0); + } + BIO_set_fp(b,fp,BIO_NOCLOSE); + ret=RSA_print(b,x,off); + BIO_free(b); + return(ret); + } +#endif + +int RSA_print(BIO *bp, const RSA *x, int off) + { + EVP_PKEY *pk; + int ret; + pk = EVP_PKEY_new(); + if (!pk || !EVP_PKEY_set1_RSA(pk, (RSA *)x)) + return 0; + ret = EVP_PKEY_print_private(bp, pk, off, NULL); + EVP_PKEY_free(pk); + return ret; + } + diff --git a/src/lib/libcrypto/rsa/rsa_pss.c b/src/lib/libcrypto/rsa/rsa_pss.c index 9b993aca49..ac211e2ffe 100644 --- a/src/lib/libcrypto/rsa/rsa_pss.c +++ b/src/lib/libcrypto/rsa/rsa_pss.c @@ -81,7 +81,9 @@ int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash, EVP_MD_CTX ctx; unsigned char H_[EVP_MAX_MD_SIZE]; - hLen = M_EVP_MD_size(Hash); + hLen = EVP_MD_size(Hash); + if (hLen < 0) + goto err; /* * Negative sLen has special meanings: * -1 sLen == hLen @@ -126,7 +128,8 @@ int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash, RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, ERR_R_MALLOC_FAILURE); goto err; } - PKCS1_MGF1(DB, maskedDBLen, H, hLen, Hash); + if (PKCS1_MGF1(DB, maskedDBLen, H, hLen, Hash) < 0) + goto err; for (i = 0; i < maskedDBLen; i++) DB[i] ^= EM[i]; if (MSBits) @@ -176,7 +179,9 @@ int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM, unsigned char *H, *salt = NULL, *p; EVP_MD_CTX ctx; - hLen = M_EVP_MD_size(Hash); + hLen = EVP_MD_size(Hash); + if (hLen < 0) + goto err; /* * Negative sLen has special meanings: * -1 sLen == hLen @@ -217,7 +222,7 @@ int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM, ERR_R_MALLOC_FAILURE); goto err; } - if (!RAND_bytes(salt, sLen)) + if (RAND_bytes(salt, sLen) <= 0) goto err; } maskedDBLen = emLen - hLen - 1; @@ -232,7 +237,8 @@ int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM, EVP_MD_CTX_cleanup(&ctx); /* Generate dbMask in place then perform XOR on it */ - PKCS1_MGF1(EM, maskedDBLen, H, hLen, Hash); + if (PKCS1_MGF1(EM, maskedDBLen, H, hLen, Hash)) + goto err; p = EM; diff --git a/src/lib/libcrypto/rsa/rsa_sign.c b/src/lib/libcrypto/rsa/rsa_sign.c index 5488c06f6d..0be4ec7fb0 100644 --- a/src/lib/libcrypto/rsa/rsa_sign.c +++ b/src/lib/libcrypto/rsa/rsa_sign.c @@ -62,6 +62,7 @@ #include #include #include +#include "rsa_locl.h" /* Size of an SSL signature: MD5+SHA1 */ #define SSL_SIG_LENGTH 36 @@ -90,14 +91,6 @@ int RSA_sign(int type, const unsigned char *m, unsigned int m_len, i = SSL_SIG_LENGTH; s = m; } else { - /* NB: in FIPS mode block anything that isn't a TLS signature */ -#ifdef OPENSSL_FIPS - if(FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) - { - RSAerr(RSA_F_RSA_SIGN, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); - return 0; - } -#endif sig.algor= &algor; sig.algor->algorithm=OBJ_nid2obj(type); if (sig.algor->algorithm == NULL) @@ -150,8 +143,11 @@ int RSA_sign(int type, const unsigned char *m, unsigned int m_len, return(ret); } -int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len, - unsigned char *sigbuf, unsigned int siglen, RSA *rsa) +int int_rsa_verify(int dtype, const unsigned char *m, + unsigned int m_len, + unsigned char *rm, size_t *prm_len, + const unsigned char *sigbuf, size_t siglen, + RSA *rsa) { int i,ret=0,sigtype; unsigned char *s; @@ -159,38 +155,30 @@ int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len, if (siglen != (unsigned int)RSA_size(rsa)) { - RSAerr(RSA_F_RSA_VERIFY,RSA_R_WRONG_SIGNATURE_LENGTH); + RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_WRONG_SIGNATURE_LENGTH); return(0); } - if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify) + if((dtype == NID_md5_sha1) && rm) { - return rsa->meth->rsa_verify(dtype, m, m_len, - sigbuf, siglen, rsa); + i = RSA_public_decrypt((int)siglen, + sigbuf,rm,rsa,RSA_PKCS1_PADDING); + if (i <= 0) + return 0; + *prm_len = i; + return 1; } s=(unsigned char *)OPENSSL_malloc((unsigned int)siglen); if (s == NULL) { - RSAerr(RSA_F_RSA_VERIFY,ERR_R_MALLOC_FAILURE); + RSAerr(RSA_F_INT_RSA_VERIFY,ERR_R_MALLOC_FAILURE); goto err; } - if(dtype == NID_md5_sha1) - { - if (m_len != SSL_SIG_LENGTH) - { - RSAerr(RSA_F_RSA_VERIFY,RSA_R_INVALID_MESSAGE_LENGTH); + if((dtype == NID_md5_sha1) && (m_len != SSL_SIG_LENGTH) ) { + RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_INVALID_MESSAGE_LENGTH); goto err; - } - } - /* NB: in FIPS mode block anything that isn't a TLS signature */ -#ifdef OPENSSL_FIPS - else if(FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) - { - RSAerr(RSA_F_RSA_VERIFY, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); - return 0; - } -#endif + } i=RSA_public_decrypt((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING); if (i <= 0) goto err; @@ -198,7 +186,7 @@ int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len, /* Special case: SSL signature */ if(dtype == NID_md5_sha1) { if((i != SSL_SIG_LENGTH) || memcmp(s, m, SSL_SIG_LENGTH)) - RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE); + RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE); else ret = 1; } else { const unsigned char *p=s; @@ -209,7 +197,7 @@ int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len, /* Excess data can be used to create forgeries */ if(p != s+i) { - RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE); + RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE); goto err; } @@ -218,7 +206,7 @@ int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len, if(sig->algor->parameter && ASN1_TYPE_get(sig->algor->parameter) != V_ASN1_NULL) { - RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE); + RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE); goto err; } @@ -244,15 +232,30 @@ int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len, } else { - RSAerr(RSA_F_RSA_VERIFY, + RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_ALGORITHM_MISMATCH); goto err; } } - if ( ((unsigned int)sig->digest->length != m_len) || + if (rm) + { + const EVP_MD *md; + md = EVP_get_digestbynid(dtype); + if (md && (EVP_MD_size(md) != sig->digest->length)) + RSAerr(RSA_F_INT_RSA_VERIFY, + RSA_R_INVALID_DIGEST_LENGTH); + else + { + memcpy(rm, sig->digest->data, + sig->digest->length); + *prm_len = sig->digest->length; + ret = 1; + } + } + else if (((unsigned int)sig->digest->length != m_len) || (memcmp(m,sig->digest->data,m_len) != 0)) { - RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE); + RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE); } else ret=1; @@ -267,3 +270,16 @@ err: return(ret); } +int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len, + const unsigned char *sigbuf, unsigned int siglen, + RSA *rsa) + { + + if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify) + { + return rsa->meth->rsa_verify(dtype, m, m_len, + sigbuf, siglen, rsa); + } + + return int_rsa_verify(dtype, m, m_len, NULL, NULL, sigbuf, siglen, rsa); + } -- cgit v1.2.3-55-g6feb