From: Matt Caswell Date: Fri, 17 Jan 2020 14:47:18 +0000 (+0000) Subject: Make the RSA ASYM_CIPHER implementation available inside the FIPS module X-Git-Tag: openssl-3.0.0-alpha1~479 X-Git-Url: https://git.openssl.org/?p=openssl.git;a=commitdiff_plain;h=afb638f137958205b6b089da8967f4775b4c9bb6 Make the RSA ASYM_CIPHER implementation available inside the FIPS module RSA ASYM_CIPHER was already available within the default provider. We now make it also available from inside the FIPS module. Reviewed-by: Richard Levitte Reviewed-by: Shane Lontis (Merged from https://github.com/openssl/openssl/pull/10881) --- diff --git a/crypto/rsa/build.info b/crypto/rsa/build.info index 70864170ed..274f376979 100644 --- a/crypto/rsa/build.info +++ b/crypto/rsa/build.info @@ -1,7 +1,10 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]=\ - rsa_ossl.c rsa_gen.c rsa_lib.c rsa_sign.c rsa_saos.c rsa_err.c \ - rsa_pk1.c rsa_ssl.c rsa_none.c rsa_oaep.c rsa_chk.c \ - rsa_pss.c rsa_x931.c rsa_asn1.c rsa_depr.c rsa_ameth.c rsa_prn.c \ - rsa_pmeth.c rsa_crpt.c rsa_x931g.c rsa_meth.c rsa_mp.c \ - rsa_sp800_56b_gen.c rsa_sp800_56b_check.c + +$COMMON=rsa_ossl.c rsa_gen.c rsa_lib.c rsa_sign.c rsa_pk1.c \ + rsa_none.c rsa_oaep.c rsa_chk.c rsa_pss.c rsa_x931.c rsa_crpt.c \ + rsa_x931g.c rsa_sp800_56b_gen.c rsa_sp800_56b_check.c + +SOURCE[../../libcrypto]=$COMMON\ + rsa_saos.c rsa_err.c rsa_asn1.c rsa_depr.c rsa_ameth.c rsa_prn.c \ + rsa_pmeth.c rsa_meth.c rsa_mp.c rsa_ssl.c +SOURCE[../../providers/libfips.a]=$COMMON diff --git a/crypto/rsa/rsa_crpt.c b/crypto/rsa/rsa_crpt.c index 6a408e907b..6abee298c6 100644 --- a/crypto/rsa/rsa_crpt.c +++ b/crypto/rsa/rsa_crpt.c @@ -114,7 +114,7 @@ BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx) BN_BLINDING *ret = NULL; if (in_ctx == NULL) { - if ((ctx = BN_CTX_new()) == NULL) + if ((ctx = BN_CTX_new_ex(rsa->libctx)) == NULL) return 0; } else { ctx = in_ctx; diff --git a/crypto/rsa/rsa_err.c b/crypto/rsa/rsa_err.c index 692b1a1bd3..382b8cb7d1 100644 --- a/crypto/rsa/rsa_err.c +++ b/crypto/rsa/rsa_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/rsa/rsa_lib.c b/crypto/rsa/rsa_lib.c index 634c251efe..d6c5da752b 100644 --- a/crypto/rsa/rsa_lib.c +++ b/crypto/rsa/rsa_lib.c @@ -19,9 +19,12 @@ #include "crypto/rsa.h" #include "rsa_local.h" +static RSA *rsa_new_intern(ENGINE *engine, OPENSSL_CTX *libctx); + +#ifndef FIPS_MODE RSA *RSA_new(void) { - return RSA_new_method(NULL); + return rsa_new_intern(NULL, NULL); } const RSA_METHOD *RSA_get_method(const RSA *rsa) @@ -50,28 +53,40 @@ int RSA_set_method(RSA *rsa, const RSA_METHOD *meth) } RSA *RSA_new_method(ENGINE *engine) +{ + return rsa_new_intern(engine, NULL); +} +#endif + +RSA *rsa_new_with_ctx(OPENSSL_CTX *libctx) +{ + return rsa_new_intern(NULL, libctx); +} + +static RSA *rsa_new_intern(ENGINE *engine, OPENSSL_CTX *libctx) { RSA *ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) { - RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_MALLOC_FAILURE); + RSAerr(0, ERR_R_MALLOC_FAILURE); return NULL; } ret->references = 1; ret->lock = CRYPTO_THREAD_lock_new(); if (ret->lock == NULL) { - RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_MALLOC_FAILURE); + RSAerr(0, ERR_R_MALLOC_FAILURE); OPENSSL_free(ret); return NULL; } + ret->libctx = libctx; ret->meth = RSA_get_default_method(); -#ifndef OPENSSL_NO_ENGINE +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE) ret->flags = ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW; if (engine) { if (!ENGINE_init(engine)) { - RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB); + RSAerr(0, ERR_R_ENGINE_LIB); goto err; } ret->engine = engine; @@ -81,7 +96,7 @@ RSA *RSA_new_method(ENGINE *engine) if (ret->engine) { ret->meth = ENGINE_get_RSA(ret->engine); if (ret->meth == NULL) { - RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB); + RSAerr(0, ERR_R_ENGINE_LIB); goto err; } } @@ -95,7 +110,7 @@ RSA *RSA_new_method(ENGINE *engine) #endif if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { - RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_INIT_FAIL); + RSAerr(0, ERR_R_INIT_FAIL); goto err; } @@ -121,7 +136,7 @@ void RSA_free(RSA *r) if (r->meth != NULL && r->meth->finish != NULL) r->meth->finish(r); -#ifndef OPENSSL_NO_ENGINE +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE) ENGINE_finish(r->engine); #endif @@ -139,8 +154,11 @@ void RSA_free(RSA *r) BN_clear_free(r->dmp1); BN_clear_free(r->dmq1); BN_clear_free(r->iqmp); + /* TODO(3.0): Support PSS in FIPS_MODE */ +#ifndef FIPS_MODE RSA_PSS_PARAMS_free(r->pss); sk_RSA_PRIME_INFO_pop_free(r->prime_infos, rsa_multip_info_free); +#endif BN_BLINDING_free(r->blinding); BN_BLINDING_free(r->mt_blinding); OPENSSL_free(r->bignum_data); @@ -302,6 +320,7 @@ int RSA_security_bits(const RSA *rsa) { int bits = BN_num_bits(rsa->n); +#ifndef FIPS_MODE if (rsa->version == RSA_ASN1_VERSION_MULTI) { /* This ought to mean that we have private key at hand. */ int ex_primes = sk_RSA_PRIME_INFO_num(rsa->prime_infos); @@ -309,6 +328,7 @@ int RSA_security_bits(const RSA *rsa) if (ex_primes <= 0 || (ex_primes + 2) > rsa_multip_cap(bits)) return 0; } +#endif return rsa_compute_security_bits(bits); } @@ -394,6 +414,7 @@ int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) return 1; } +#ifndef FIPS_MODE /* * Is it better to export RSA_PRIME_INFO structure * and related functions to let user pass a triplet? @@ -462,6 +483,7 @@ int RSA_set0_multi_prime_params(RSA *r, BIGNUM *primes[], BIGNUM *exps[], sk_RSA_PRIME_INFO_pop_free(prime_infos, rsa_multip_info_free_ex); return 0; } +#endif void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) @@ -482,6 +504,7 @@ void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q) *q = r->q; } +#ifndef FIPS_MODE int RSA_get_multi_prime_extra_count(const RSA *r) { int pnum; @@ -511,6 +534,7 @@ int RSA_get0_multi_prime_factors(const RSA *r, const BIGNUM *primes[]) return 1; } +#endif void RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, const BIGNUM **dmq1, @@ -524,6 +548,7 @@ void RSA_get0_crt_params(const RSA *r, *iqmp = r->iqmp; } +#ifndef FIPS_MODE int RSA_get0_multi_prime_crt_params(const RSA *r, const BIGNUM *exps[], const BIGNUM *coeffs[]) { @@ -549,6 +574,7 @@ int RSA_get0_multi_prime_crt_params(const RSA *r, const BIGNUM *exps[], return 1; } +#endif const BIGNUM *RSA_get0_n(const RSA *r) { @@ -590,10 +616,13 @@ const BIGNUM *RSA_get0_iqmp(const RSA *r) return r->iqmp; } +/* TODO(3.0): Temporary until we move PSS support into the FIPS module */ +#ifndef FIPS_MODE const RSA_PSS_PARAMS *RSA_get0_pss_params(const RSA *r) { return r->pss; } +#endif void RSA_clear_flags(RSA *r, int flags) { @@ -616,6 +645,7 @@ int RSA_get_version(RSA *r) return r->version; } +#ifndef FIPS_MODE ENGINE *RSA_get0_engine(const RSA *r) { return r->engine; @@ -630,6 +660,7 @@ int RSA_pkey_ctx_ctrl(EVP_PKEY_CTX *ctx, int optype, int cmd, int p1, void *p2) return -1; return EVP_PKEY_CTX_ctrl(ctx, -1, optype, cmd, p1, p2); } +#endif DEFINE_STACK_OF(BIGNUM) @@ -637,7 +668,9 @@ int rsa_set0_all_params(RSA *r, const STACK_OF(BIGNUM) *primes, const STACK_OF(BIGNUM) *exps, const STACK_OF(BIGNUM) *coeffs) { +#ifndef FIPS_MODE STACK_OF(RSA_PRIME_INFO) *prime_infos, *old_infos = NULL; +#endif int pnum; if (primes == NULL || exps == NULL || coeffs == NULL) @@ -656,9 +689,12 @@ int rsa_set0_all_params(RSA *r, const STACK_OF(BIGNUM) *primes, sk_BIGNUM_value(coeffs, 0))) return 0; +#ifndef FIPS_MODE old_infos = r->prime_infos; +#endif if (pnum > 2) { +#ifndef FIPS_MODE int i; prime_infos = sk_RSA_PRIME_INFO_new_reserve(NULL, pnum); @@ -695,8 +731,12 @@ int rsa_set0_all_params(RSA *r, const STACK_OF(BIGNUM) *primes, r->prime_infos = old_infos; goto err; } +#else + return 0; +#endif } +#ifndef FIPS_MODE if (old_infos != NULL) { /* * This is hard to deal with, since the old infos could @@ -706,15 +746,18 @@ int rsa_set0_all_params(RSA *r, const STACK_OF(BIGNUM) *primes, */ sk_RSA_PRIME_INFO_pop_free(old_infos, rsa_multip_info_free); } +#endif r->version = pnum > 2 ? RSA_ASN1_VERSION_MULTI : RSA_ASN1_VERSION_DEFAULT; r->dirty_cnt++; return 1; +#ifndef FIPS_MODE err: /* r, d, t should not be freed */ sk_RSA_PRIME_INFO_pop_free(prime_infos, rsa_multip_info_free_ex); return 0; +#endif } DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM) @@ -723,29 +766,34 @@ int rsa_get0_all_params(RSA *r, STACK_OF(BIGNUM_const) *primes, STACK_OF(BIGNUM_const) *exps, STACK_OF(BIGNUM_const) *coeffs) { +#ifndef FIPS_MODE RSA_PRIME_INFO *pinfo; int i, pnum; +#endif if (r == NULL) return 0; - pnum = RSA_get_multi_prime_extra_count(r); - sk_BIGNUM_const_push(primes, RSA_get0_p(r)); sk_BIGNUM_const_push(primes, RSA_get0_q(r)); sk_BIGNUM_const_push(exps, RSA_get0_dmp1(r)); sk_BIGNUM_const_push(exps, RSA_get0_dmq1(r)); sk_BIGNUM_const_push(coeffs, RSA_get0_iqmp(r)); + +#ifndef FIPS_MODE + pnum = RSA_get_multi_prime_extra_count(r); for (i = 0; i < pnum; i++) { pinfo = sk_RSA_PRIME_INFO_value(r->prime_infos, i); sk_BIGNUM_const_push(primes, pinfo->r); sk_BIGNUM_const_push(exps, pinfo->d); sk_BIGNUM_const_push(coeffs, pinfo->t); } +#endif return 1; } +#ifndef FIPS_MODE int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int pad_mode) { OSSL_PARAM pad_params[2], *p = pad_params; @@ -1129,3 +1177,4 @@ int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx, unsigned char **label) return (int)labellen; } +#endif diff --git a/crypto/rsa/rsa_local.h b/crypto/rsa/rsa_local.h index 9b55115e47..e15c1ae3d5 100644 --- a/crypto/rsa/rsa_local.h +++ b/crypto/rsa/rsa_local.h @@ -29,6 +29,8 @@ DECLARE_ASN1_ITEM(RSA_PRIME_INFO) DEFINE_STACK_OF(RSA_PRIME_INFO) struct rsa_st { + OPENSSL_CTX *libctx; + /* * The first parameter is used to pickup errors where this is passed * instead of an EVP_PKEY, it is set to 0 @@ -46,11 +48,12 @@ struct rsa_st { BIGNUM *dmp1; BIGNUM *dmq1; BIGNUM *iqmp; + /* TODO(3.0): Support PSS in FIPS_MODE */ +#ifndef FIPS_MODE /* for multi-prime RSA, defined in RFC 8017 */ STACK_OF(RSA_PRIME_INFO) *prime_infos; /* If a PSS only key this contains the parameter restrictions */ RSA_PSS_PARAMS *pss; -#ifndef FIPS_MODE /* be careful using this if the RSA structure is shared */ CRYPTO_EX_DATA ex_data; #endif diff --git a/crypto/rsa/rsa_oaep.c b/crypto/rsa/rsa_oaep.c index 1ae7ed287f..d1150f09a8 100644 --- a/crypto/rsa/rsa_oaep.c +++ b/crypto/rsa/rsa_oaep.c @@ -57,8 +57,14 @@ int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, unsigned char seedmask[EVP_MAX_MD_SIZE]; int mdlen, dbmask_len = 0; +#ifndef FIPS_MODE if (md == NULL) md = EVP_sha1(); +#else + RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1, + ERR_R_PASSED_NULL_PARAMETER); + return 0; +#endif if (mgf1md == NULL) mgf1md = md; @@ -147,8 +153,15 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, phash[EVP_MAX_MD_SIZE]; int mdlen; - if (md == NULL) + if (md == NULL) { +#ifndef FIPS_MODE md = EVP_sha1(); +#else + RSAerr(0, ERR_R_PASSED_NULL_PARAMETER); + return -1; +#endif + } + if (mgf1md == NULL) mgf1md = md; @@ -272,13 +285,19 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, to[i] = constant_time_select_8(mask, db[i + mdlen + 1], to[i]); } +#ifndef FIPS_MODE /* * To avoid chosen ciphertext attacks, the error message should not * reveal which kind of decoding error happened. + * + * This trick doesn't work in the FIPS provider because libcrypto manages + * the error stack. Instead we opt not to put an error on the stack at all + * in case of padding failure in the FIPS provider. */ RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, RSA_R_OAEP_DECODING_ERROR); err_clear_last_constant_time(1 & good); +#endif cleanup: OPENSSL_cleanse(seed, sizeof(seed)); OPENSSL_clear_free(db, dblen); diff --git a/crypto/rsa/rsa_ossl.c b/crypto/rsa/rsa_ossl.c index 39d17cf38c..6332a5a411 100644 --- a/crypto/rsa/rsa_ossl.c +++ b/crypto/rsa/rsa_ossl.c @@ -91,7 +91,7 @@ static int rsa_ossl_public_encrypt(int flen, const unsigned char *from, } } - if ((ctx = BN_CTX_new()) == NULL) + if ((ctx = BN_CTX_new_ex(rsa->libctx)) == NULL) goto err; BN_CTX_start(ctx); f = BN_CTX_get(ctx); @@ -110,9 +110,11 @@ static int rsa_ossl_public_encrypt(int flen, const unsigned char *from, case RSA_PKCS1_OAEP_PADDING: i = RSA_padding_add_PKCS1_OAEP(buf, num, from, flen, NULL, 0); break; +#ifndef FIPS_MODE case RSA_SSLV23_PADDING: i = RSA_padding_add_SSLv23(buf, num, from, flen); break; +#endif case RSA_NO_PADDING: i = RSA_padding_add_none(buf, num, from, flen); break; @@ -246,7 +248,7 @@ static int rsa_ossl_private_encrypt(int flen, const unsigned char *from, BIGNUM *unblind = NULL; BN_BLINDING *blinding = NULL; - if ((ctx = BN_CTX_new()) == NULL) + if ((ctx = BN_CTX_new_ex(rsa->libctx)) == NULL) goto err; BN_CTX_start(ctx); f = BN_CTX_get(ctx); @@ -380,7 +382,7 @@ static int rsa_ossl_private_decrypt(int flen, const unsigned char *from, BIGNUM *unblind = NULL; BN_BLINDING *blinding = NULL; - if ((ctx = BN_CTX_new()) == NULL) + if ((ctx = BN_CTX_new_ex(rsa->libctx)) == NULL) goto err; BN_CTX_start(ctx); f = BN_CTX_get(ctx); @@ -480,9 +482,11 @@ static int rsa_ossl_private_decrypt(int flen, const unsigned char *from, case RSA_PKCS1_OAEP_PADDING: r = RSA_padding_check_PKCS1_OAEP(to, num, buf, j, num, NULL, 0); break; +#ifndef FIPS_MODE case RSA_SSLV23_PADDING: r = RSA_padding_check_SSLv23(to, num, buf, j, num); break; +#endif case RSA_NO_PADDING: memcpy(to, buf, (r = j)); break; @@ -490,8 +494,15 @@ static int rsa_ossl_private_decrypt(int flen, const unsigned char *from, RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_UNKNOWN_PADDING_TYPE); goto err; } +#ifndef FIPS_MODE + /* + * This trick doesn't work in the FIPS provider because libcrypto manages + * the error stack. Instead we opt not to put an error on the stack at all + * in case of padding failure in the FIPS provider. + */ RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_PADDING_CHECK_FAILED); err_clear_last_constant_time(1 & ~constant_time_msb(r)); +#endif err: BN_CTX_end(ctx); @@ -527,7 +538,7 @@ static int rsa_ossl_public_decrypt(int flen, const unsigned char *from, } } - if ((ctx = BN_CTX_new()) == NULL) + if ((ctx = BN_CTX_new_ex(rsa->libctx)) == NULL) goto err; BN_CTX_start(ctx); f = BN_CTX_get(ctx); @@ -600,23 +611,31 @@ static int rsa_ossl_public_decrypt(int flen, const unsigned char *from, static int rsa_ossl_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) { - BIGNUM *r1, *m1, *vrfy, *r2, *m[RSA_MAX_PRIME_NUM - 2]; - int ret = 0, i, ex_primes = 0, smooth = 0; + BIGNUM *r1, *m1, *vrfy; + int ret = 0, smooth = 0; +#ifndef FIPS_MODE + BIGNUM *r2, *m[RSA_MAX_PRIME_NUM - 2]; + int i, ex_primes = 0; RSA_PRIME_INFO *pinfo; +#endif BN_CTX_start(ctx); r1 = BN_CTX_get(ctx); +#ifndef FIPS_MODE r2 = BN_CTX_get(ctx); +#endif m1 = BN_CTX_get(ctx); vrfy = BN_CTX_get(ctx); if (vrfy == NULL) goto err; +#ifndef FIPS_MODE if (rsa->version == RSA_ASN1_VERSION_MULTI && ((ex_primes = sk_RSA_PRIME_INFO_num(rsa->prime_infos)) <= 0 || ex_primes > RSA_MAX_PRIME_NUM - 2)) goto err; +#endif if (rsa->flags & RSA_FLAG_CACHE_PRIVATE) { BIGNUM *factor = BN_new(); @@ -637,6 +656,7 @@ static int rsa_ossl_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) BN_free(factor); goto err; } +#ifndef FIPS_MODE for (i = 0; i < ex_primes; i++) { pinfo = sk_RSA_PRIME_INFO_value(rsa->prime_infos, i); BN_with_flags(factor, pinfo->r, BN_FLG_CONSTTIME); @@ -645,13 +665,16 @@ static int rsa_ossl_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) goto err; } } +#endif /* * We MUST free |factor| before any further use of the prime factors */ BN_free(factor); - smooth = (ex_primes == 0) - && (rsa->meth->bn_mod_exp == BN_mod_exp_mont) + smooth = (rsa->meth->bn_mod_exp == BN_mod_exp_mont) +#ifndef FIPS_MODE + && (ex_primes == 0) +#endif && (BN_num_bits(rsa->q) == BN_num_bits(rsa->p)); } @@ -757,6 +780,7 @@ static int rsa_ossl_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) BN_free(dmp1); } +#ifndef FIPS_MODE /* * calculate m_i in multi-prime case * @@ -806,6 +830,7 @@ static int rsa_ossl_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) BN_free(cc); BN_free(di); } +#endif if (!BN_sub(r0, r0, m1)) goto err; @@ -849,6 +874,7 @@ static int rsa_ossl_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) if (!BN_add(r0, r1, m1)) goto err; +#ifndef FIPS_MODE /* add m_i to m in multi-prime case */ if (ex_primes > 0) { BIGNUM *pr2 = BN_new(); @@ -891,6 +917,7 @@ static int rsa_ossl_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) } BN_free(pr2); } +#endif tail: if (rsa->e && rsa->n) { @@ -966,15 +993,18 @@ static int rsa_ossl_init(RSA *rsa) static int rsa_ossl_finish(RSA *rsa) { +#ifndef FIPS_MODE int i; RSA_PRIME_INFO *pinfo; - BN_MONT_CTX_free(rsa->_method_mod_n); - BN_MONT_CTX_free(rsa->_method_mod_p); - BN_MONT_CTX_free(rsa->_method_mod_q); for (i = 0; i < sk_RSA_PRIME_INFO_num(rsa->prime_infos); i++) { pinfo = sk_RSA_PRIME_INFO_value(rsa->prime_infos, i); BN_MONT_CTX_free(pinfo->m); } +#endif + + BN_MONT_CTX_free(rsa->_method_mod_n); + BN_MONT_CTX_free(rsa->_method_mod_p); + BN_MONT_CTX_free(rsa->_method_mod_q); return 1; } diff --git a/crypto/rsa/rsa_pk1.c b/crypto/rsa/rsa_pk1.c index 007e9b8cd5..eedc558e3f 100644 --- a/crypto/rsa/rsa_pk1.c +++ b/crypto/rsa/rsa_pk1.c @@ -251,8 +251,15 @@ int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, } OPENSSL_clear_free(em, num); +#ifndef FIPS_MODE + /* + * This trick doesn't work in the FIPS provider because libcrypto manages + * the error stack. Instead we opt not to put an error on the stack at all + * in case of padding failure in the FIPS provider. + */ RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, RSA_R_PKCS_DECODING_ERROR); err_clear_last_constant_time(1 & good); +#endif return constant_time_select_int(good, mlen, -1); } diff --git a/crypto/rsa/rsa_sp800_56b_check.c b/crypto/rsa/rsa_sp800_56b_check.c index 93d3103a18..e272840777 100644 --- a/crypto/rsa/rsa_sp800_56b_check.c +++ b/crypto/rsa/rsa_sp800_56b_check.c @@ -269,7 +269,7 @@ int rsa_sp800_56b_check_public(const RSA *rsa) return 0; } - ctx = BN_CTX_new(); + ctx = BN_CTX_new_ex(rsa->libctx); gcd = BN_new(); if (ctx == NULL || gcd == NULL) goto err; @@ -358,7 +358,7 @@ int rsa_sp800_56b_check_keypair(const RSA *rsa, const BIGNUM *efixed, return 0; } - ctx = BN_CTX_new(); + ctx = BN_CTX_new_ex(rsa->libctx); if (ctx == NULL) return 0; diff --git a/crypto/rsa/rsa_sp800_56b_gen.c b/crypto/rsa/rsa_sp800_56b_gen.c index 5474aaa4b5..1f8d01d477 100644 --- a/crypto/rsa/rsa_sp800_56b_gen.c +++ b/crypto/rsa/rsa_sp800_56b_gen.c @@ -297,7 +297,7 @@ int rsa_sp800_56b_generate_key(RSA *rsa, int nbits, const BIGNUM *efixed, if (!rsa_sp800_56b_validate_strength(nbits, -1)) return 0; - ctx = BN_CTX_new(); + ctx = BN_CTX_new_ex(rsa->libctx); if (ctx == NULL) return 0; diff --git a/include/crypto/rsa.h b/include/crypto/rsa.h index c3763d1e1f..97fd0f7aad 100644 --- a/include/crypto/rsa.h +++ b/include/crypto/rsa.h @@ -12,6 +12,8 @@ #include +RSA *rsa_new_with_ctx(OPENSSL_CTX *libctx); + int rsa_set0_all_params(RSA *r, const STACK_OF(BIGNUM) *primes, const STACK_OF(BIGNUM) *exps, const STACK_OF(BIGNUM) *coeffs); diff --git a/include/openssl/rsaerr.h b/include/openssl/rsaerr.h index 91fcc1cf8e..ef72bc744e 100644 --- a/include/openssl/rsaerr.h +++ b/include/openssl/rsaerr.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c index acc7edfa0d..596ece5235 100644 --- a/providers/fips/fipsprov.c +++ b/providers/fips/fipsprov.c @@ -805,6 +805,11 @@ static const OSSL_ALGORITHM fips_signature[] = { { NULL, NULL, NULL } }; +static const OSSL_ALGORITHM fips_asym_cipher[] = { + { "RSA:rsaEncryption", "fips=yes", rsa_asym_cipher_functions }, + { NULL, NULL, NULL } +}; + static const OSSL_ALGORITHM fips_keymgmt[] = { #ifndef OPENSSL_NO_DH { "DH:dhKeyAgreement", "fips=yes", dh_keymgmt_functions }, @@ -812,6 +817,7 @@ static const OSSL_ALGORITHM fips_keymgmt[] = { #ifndef OPENSSL_NO_DSA { "DSA", "fips=yes", dsa_keymgmt_functions }, #endif + { "RSA:rsaEncryption", "default=yes", rsa_keymgmt_functions }, { NULL, NULL, NULL } }; @@ -836,6 +842,8 @@ static const OSSL_ALGORITHM *fips_query(OSSL_PROVIDER *prov, return fips_keyexch; case OSSL_OP_SIGNATURE: return fips_signature; + case OSSL_OP_ASYM_CIPHER: + return fips_asym_cipher; } return NULL; } diff --git a/providers/implementations/asymciphers/build.info b/providers/implementations/asymciphers/build.info index aa050803d4..b4033d8a7d 100644 --- a/providers/implementations/asymciphers/build.info +++ b/providers/implementations/asymciphers/build.info @@ -1,4 +1,6 @@ -LIBS=../../../libcrypto -SOURCE[../../../libcrypto]=rsa_enc.c +# We make separate GOAL variables for each algorithm, to make it easy to +# switch each to the Legacy provider when needed. +$RSA_GOAL=../../libimplementations.a +SOURCE[$RSA_GOAL]=rsa_enc.c diff --git a/providers/implementations/asymciphers/rsa_enc.c b/providers/implementations/asymciphers/rsa_enc.c index c72571d6bb..2cce8474cd 100644 --- a/providers/implementations/asymciphers/rsa_enc.c +++ b/providers/implementations/asymciphers/rsa_enc.c @@ -118,6 +118,11 @@ static int rsa_encrypt(void *vprsactx, unsigned char *out, size_t *outlen, PROVerr(0, ERR_R_MALLOC_FAILURE); return 0; } + if (prsactx->oaep_md == NULL) { + prsactx->oaep_md = EVP_MD_fetch(prsactx->libctx, "SHA-1", NULL); + PROVerr(0, ERR_R_INTERNAL_ERROR); + return 0; + } ret = RSA_padding_add_PKCS1_OAEP_mgf1(tbuf, rsasize, in, inlen, prsactx->oaep_label, prsactx->oaep_labellen, @@ -194,6 +199,13 @@ static int rsa_decrypt(void *vprsactx, unsigned char *out, size_t *outlen, return 0; } if (prsactx->pad_mode == RSA_PKCS1_OAEP_PADDING) { + if (prsactx->oaep_md == NULL) { + prsactx->oaep_md = EVP_MD_fetch(prsactx->libctx, "SHA-1", NULL); + if (prsactx->oaep_md == NULL) { + PROVerr(0, ERR_R_INTERNAL_ERROR); + return 0; + } + } ret = RSA_padding_check_PKCS1_OAEP_mgf1(out, outsize, tbuf, len, len, prsactx->oaep_label, diff --git a/providers/implementations/keymgmt/rsa_kmgmt.c b/providers/implementations/keymgmt/rsa_kmgmt.c index 6ab695ea7b..f43520f857 100644 --- a/providers/implementations/keymgmt/rsa_kmgmt.c +++ b/providers/implementations/keymgmt/rsa_kmgmt.c @@ -18,6 +18,7 @@ #include "internal/param_build.h" #include "prov/implementations.h" #include "prov/providercommon.h" +#include "prov/provider_ctx.h" #include "crypto/rsa.h" static OSSL_OP_keymgmt_new_fn rsa_newdata; @@ -170,7 +171,9 @@ static int key_to_params(RSA *rsa, OSSL_PARAM_BLD *tmpl) static void *rsa_newdata(void *provctx) { - return RSA_new(); + OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(provctx); + + return rsa_new_with_ctx(libctx); } static void rsa_freedata(void *keydata) @@ -321,7 +324,7 @@ static int rsa_get_params(void *key, OSSL_PARAM params[]) && !OSSL_PARAM_set_int(p, RSA_size(rsa))) return 0; -# if 0 /* PSS support pending */ +# if 0 /* TODO(3.0): PSS support pending */ if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MANDATORY_DIGEST)) != NULL && RSA_get0_pss_params(rsa) != NULL) { @@ -338,9 +341,14 @@ static int rsa_get_params(void *key, OSSL_PARAM params[]) } #endif if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_DEFAULT_DIGEST)) != NULL - && RSA_get0_pss_params(rsa) == NULL) +/* TODO(3.0): PSS support pending */ +#if 0 + && RSA_get0_pss_params(rsa) == NULL +#endif + ) { if (!OSSL_PARAM_set_utf8_string(p, RSA_DEFAULT_MD)) return 0; + } return 1; }