diff options
Diffstat (limited to 'Cryptlib/OpenSSL/crypto/rsa/rsa_pmeth.c')
-rw-r--r-- | Cryptlib/OpenSSL/crypto/rsa/rsa_pmeth.c | 261 |
1 files changed, 189 insertions, 72 deletions
diff --git a/Cryptlib/OpenSSL/crypto/rsa/rsa_pmeth.c b/Cryptlib/OpenSSL/crypto/rsa/rsa_pmeth.c index db4fb0fb..ac583bf6 100644 --- a/Cryptlib/OpenSSL/crypto/rsa/rsa_pmeth.c +++ b/Cryptlib/OpenSSL/crypto/rsa/rsa_pmeth.c @@ -1,22 +1,77 @@ +/* crypto/rsa/rsa_pmeth.c */ /* - * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved. + * 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). * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html */ #include <stdio.h> -#include "internal/cryptlib.h" +#include "cryptlib.h" #include <openssl/asn1t.h> #include <openssl/x509.h> #include <openssl/rsa.h> #include <openssl/bn.h> #include <openssl/evp.h> #include <openssl/x509v3.h> -#include <openssl/cms.h> -#include "internal/evp_int.h" +#ifndef OPENSSL_NO_CMS +# include <openssl/cms.h> +#endif +#ifdef OPENSSL_FIPS +# include <openssl/fips.h> +#endif +#include "evp_locl.h" #include "rsa_locl.h" /* RSA pkey context structure */ @@ -45,12 +100,21 @@ typedef struct { static int pkey_rsa_init(EVP_PKEY_CTX *ctx) { RSA_PKEY_CTX *rctx; - rctx = OPENSSL_zalloc(sizeof(*rctx)); - if (rctx == NULL) + 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->mgf1md = NULL; + rctx->tbuf = NULL; + rctx->saltlen = -2; + + rctx->oaep_label = NULL; + rctx->oaep_labellen = 0; + ctx->data = rctx; ctx->keygen_info = rctx->gentmp; ctx->keygen_info_count = 2; @@ -75,8 +139,9 @@ static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) dctx->md = sctx->md; dctx->mgf1md = sctx->mgf1md; if (sctx->oaep_label) { - OPENSSL_free(dctx->oaep_label); - dctx->oaep_label = OPENSSL_memdup(sctx->oaep_label, sctx->oaep_labellen); + if (dctx->oaep_label) + OPENSSL_free(dctx->oaep_label); + dctx->oaep_label = BUF_memdup(sctx->oaep_label, sctx->oaep_labellen); if (!dctx->oaep_label) return 0; dctx->oaep_labellen = sctx->oaep_labellen; @@ -89,7 +154,7 @@ 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 == NULL) + if (!ctx->tbuf) return 0; return 1; } @@ -98,13 +163,50 @@ static void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx) { RSA_PKEY_CTX *rctx = ctx->data; if (rctx) { - BN_free(rctx->pub_exp); - OPENSSL_free(rctx->tbuf); - OPENSSL_free(rctx->oaep_label); + if (rctx->pub_exp) + BN_free(rctx->pub_exp); + if (rctx->tbuf) + OPENSSL_free(rctx->tbuf); + if (rctx->oaep_label) + OPENSSL_free(rctx->oaep_label); OPENSSL_free(rctx); } } +#ifdef OPENSSL_FIPS +/* + * FIP checker. Return value indicates status of context parameters: 1 : + * redirect to FIPS. 0 : don't redirect to FIPS. -1 : illegal operation in + * FIPS mode. + */ + +static int pkey_fips_check_ctx(EVP_PKEY_CTX *ctx) +{ + RSA_PKEY_CTX *rctx = ctx->data; + RSA *rsa = ctx->pkey->pkey.rsa; + int rv = -1; + if (!FIPS_mode()) + return 0; + if (rsa->flags & RSA_FLAG_NON_FIPS_ALLOW) + rv = 0; + if (!(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) && rv) + return -1; + if (rctx->md) { + const EVP_MD *fmd; + fmd = FIPS_get_digestbynid(EVP_MD_type(rctx->md)); + if (!fmd || !(fmd->flags & EVP_MD_FLAG_FIPS)) + return rv; + } + if (rctx->mgf1md && !(rctx->mgf1md->flags & EVP_MD_FLAG_FIPS)) { + const EVP_MD *fmd; + fmd = FIPS_get_digestbynid(EVP_MD_type(rctx->mgf1md)); + if (!fmd || !(fmd->flags & EVP_MD_FLAG_FIPS)) + return rv; + } + return 1; +} +#endif + static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, const unsigned char *tbs, size_t tbslen) @@ -113,17 +215,39 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, RSA_PKEY_CTX *rctx = ctx->data; RSA *rsa = ctx->pkey->pkey.rsa; +#ifdef OPENSSL_FIPS + ret = pkey_fips_check_ctx(ctx); + if (ret < 0) { + RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); + return -1; + } +#endif + 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; } +#ifdef OPENSSL_FIPS + if (ret > 0) { + unsigned int slen; + ret = FIPS_rsa_sign_digest(rsa, tbs, tbslen, rctx->md, + rctx->pad_mode, + rctx->saltlen, + rctx->mgf1md, sig, &slen); + if (ret > 0) + *siglen = slen; + else + *siglen = 0; + return ret; + } +#endif if (EVP_MD_type(rctx->md) == NID_mdc2) { unsigned int sltmp; if (rctx->pad_mode != RSA_PKCS1_PADDING) return -1; - ret = RSA_sign_ASN1_OCTET_STRING(0, + ret = RSA_sign_ASN1_OCTET_STRING(NID_mdc2, tbs, tbslen, sig, &sltmp, rsa); if (ret <= 0) @@ -225,7 +349,27 @@ static int pkey_rsa_verify(EVP_PKEY_CTX *ctx, RSA_PKEY_CTX *rctx = ctx->data; RSA *rsa = ctx->pkey->pkey.rsa; size_t rslen; +#ifdef OPENSSL_FIPS + int rv; + rv = pkey_fips_check_ctx(ctx); + if (rv < 0) { + RSAerr(RSA_F_PKEY_RSA_VERIFY, + RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); + return -1; + } +#endif if (rctx->md) { +#ifdef OPENSSL_FIPS + if (rv > 0) { + return FIPS_rsa_verify_digest(rsa, + tbs, tbslen, + rctx->md, + rctx->pad_mode, + rctx->saltlen, + rctx->mgf1md, sig, siglen); + + } +#endif if (rctx->pad_mode == RSA_PKCS1_PADDING) return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen, sig, siglen, rsa); @@ -329,43 +473,20 @@ static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, static int check_padding_md(const EVP_MD *md, int padding) { - int mdnid; if (!md) return 1; - mdnid = EVP_MD_type(md); - 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(mdnid) == -1) { + if (RSA_X931_hash_id(EVP_MD_type(md)) == -1) { RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_X931_DIGEST); return 0; } - } else { - switch(mdnid) { - /* List of all supported RSA digests */ - case NID_sha1: - case NID_sha224: - case NID_sha256: - case NID_sha384: - case NID_sha512: - case NID_md5: - case NID_md5_sha1: - case NID_md2: - case NID_md4: - case NID_mdc2: - case NID_ripemd160: - return 1; - - default: - RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_DIGEST); - return 0; - - } + return 1; } return 1; @@ -420,8 +541,8 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) return 1; case EVP_PKEY_CTRL_RSA_KEYGEN_BITS: - if (p1 < 512) { - RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_KEY_SIZE_TOO_SMALL); + if (p1 < 256) { + RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_KEYBITS); return -2; } rctx->nbits = p1; @@ -479,7 +600,8 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PADDING_MODE); return -2; } - OPENSSL_free(rctx->oaep_label); + if (rctx->oaep_label) + OPENSSL_free(rctx->oaep_label); if (p2 && p1 > 0) { rctx->oaep_label = p2; rctx->oaep_labellen = p1; @@ -526,21 +648,21 @@ static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx, RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_VALUE_MISSING); return 0; } - if (strcmp(type, "rsa_padding_mode") == 0) { + if (!strcmp(type, "rsa_padding_mode")) { int pm; - if (strcmp(value, "pkcs1") == 0) + if (!strcmp(value, "pkcs1")) pm = RSA_PKCS1_PADDING; - else if (strcmp(value, "sslv23") == 0) + else if (!strcmp(value, "sslv23")) pm = RSA_SSLV23_PADDING; - else if (strcmp(value, "none") == 0) + else if (!strcmp(value, "none")) pm = RSA_NO_PADDING; - else if (strcmp(value, "oeap") == 0) + else if (!strcmp(value, "oeap")) pm = RSA_PKCS1_OAEP_PADDING; - else if (strcmp(value, "oaep") == 0) + else if (!strcmp(value, "oaep")) pm = RSA_PKCS1_OAEP_PADDING; - else if (strcmp(value, "x931") == 0) + else if (!strcmp(value, "x931")) pm = RSA_X931_PADDING; - else if (strcmp(value, "pss") == 0) + else if (!strcmp(value, "pss")) pm = RSA_PKCS1_PSS_PADDING; else { RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_UNKNOWN_PADDING_TYPE); @@ -549,19 +671,19 @@ static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx, return EVP_PKEY_CTX_set_rsa_padding(ctx, pm); } - if (strcmp(type, "rsa_pss_saltlen") == 0) { + 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") == 0) { + 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") == 0) { + if (!strcmp(type, "rsa_keygen_pubexp")) { int ret; BIGNUM *pubexp = NULL; if (!BN_asc2bn(&pubexp, value)) @@ -572,28 +694,28 @@ static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx, return ret; } - if (strcmp(type, "rsa_mgf1_md") == 0) { + if (!strcmp(type, "rsa_mgf1_md")) { const EVP_MD *md; - if ((md = EVP_get_digestbyname(value)) == NULL) { + if (!(md = EVP_get_digestbyname(value))) { RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_INVALID_DIGEST); return 0; } return EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, md); } - if (strcmp(type, "rsa_oaep_md") == 0) { + if (!strcmp(type, "rsa_oaep_md")) { const EVP_MD *md; - if ((md = EVP_get_digestbyname(value)) == NULL) { + if (!(md = EVP_get_digestbyname(value))) { RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_INVALID_DIGEST); return 0; } return EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md); } - if (strcmp(type, "rsa_oaep_label") == 0) { + if (!strcmp(type, "rsa_oaep_label")) { unsigned char *lab; long lablen; int ret; - lab = OPENSSL_hexstr2buf(value, &lablen); + lab = string_to_hex(value, &lablen); if (!lab) return 0; ret = EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, lab, lablen); @@ -609,27 +731,22 @@ static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { RSA *rsa = NULL; RSA_PKEY_CTX *rctx = ctx->data; - BN_GENCB *pcb; + BN_GENCB *pcb, cb; int ret; - if (rctx->pub_exp == NULL) { + if (!rctx->pub_exp) { rctx->pub_exp = BN_new(); - if (rctx->pub_exp == NULL || !BN_set_word(rctx->pub_exp, RSA_F4)) + if (!rctx->pub_exp || !BN_set_word(rctx->pub_exp, RSA_F4)) return 0; } rsa = RSA_new(); - if (rsa == NULL) + if (!rsa) return 0; if (ctx->pkey_gencb) { - pcb = BN_GENCB_new(); - if (pcb == NULL) { - RSA_free(rsa); - return 0; - } + pcb = &cb; evp_pkey_set_cb_translate(pcb, ctx); } else pcb = NULL; ret = RSA_generate_key_ex(rsa, rctx->nbits, rctx->pub_exp, pcb); - BN_GENCB_free(pcb); if (ret > 0) EVP_PKEY_assign_RSA(pkey, rsa); else |