Make the RSA ASYM_CIPHER implementation available inside the FIPS module
authorMatt Caswell <matt@openssl.org>
Fri, 17 Jan 2020 14:47:18 +0000 (14:47 +0000)
committerMatt Caswell <matt@openssl.org>
Thu, 13 Feb 2020 14:14:30 +0000 (14:14 +0000)
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 <levitte@openssl.org>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/10881)

16 files changed:
crypto/rsa/build.info
crypto/rsa/rsa_crpt.c
crypto/rsa/rsa_err.c
crypto/rsa/rsa_lib.c
crypto/rsa/rsa_local.h
crypto/rsa/rsa_oaep.c
crypto/rsa/rsa_ossl.c
crypto/rsa/rsa_pk1.c
crypto/rsa/rsa_sp800_56b_check.c
crypto/rsa/rsa_sp800_56b_gen.c
include/crypto/rsa.h
include/openssl/rsaerr.h
providers/fips/fipsprov.c
providers/implementations/asymciphers/build.info
providers/implementations/asymciphers/rsa_enc.c
providers/implementations/keymgmt/rsa_kmgmt.c

index 7086417..274f376 100644 (file)
@@ -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
index 6a408e9..6abee29 100644 (file)
@@ -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;
index 692b1a1..382b8cb 100644 (file)
@@ -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
index 634c251..d6c5da7 100644 (file)
 #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
index 9b55115..e15c1ae 100644 (file)
@@ -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
index 1ae7ed2..d1150f0 100644 (file)
@@ -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);
index 39d17cf..6332a5a 100644 (file)
@@ -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;
 }
index 007e9b8..eedc558 100644 (file)
@@ -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);
 }
index 93d3103..e272840 100644 (file)
@@ -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;
 
index 5474aaa..1f8d01d 100644 (file)
@@ -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;
 
index c3763d1..97fd0f7 100644 (file)
@@ -12,6 +12,8 @@
 
 #include <openssl/rsa.h>
 
+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);
index 91fcc1c..ef72bc7 100644 (file)
@@ -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
index acc7edf..596ece5 100644 (file)
@@ -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;
 }
index aa05080..b4033d8 100644 (file)
@@ -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
index c72571d..2cce847 100644 (file)
@@ -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,
index 6ab695e..f43520f 100644 (file)
@@ -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;
 }