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
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;
/*
* 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
#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)
}
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;
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;
}
}
#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;
}
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
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);
{
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);
if (ex_primes <= 0 || (ex_primes + 2) > rsa_multip_cap(bits))
return 0;
}
+#endif
return rsa_compute_security_bits(bits);
}
return 1;
}
+#ifndef FIPS_MODE
/*
* Is it better to export RSA_PRIME_INFO structure
* and related functions to let user pass a triplet?
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)
*q = r->q;
}
+#ifndef FIPS_MODE
int RSA_get_multi_prime_extra_count(const RSA *r)
{
int pnum;
return 1;
}
+#endif
void RSA_get0_crt_params(const RSA *r,
const BIGNUM **dmp1, const BIGNUM **dmq1,
*iqmp = r->iqmp;
}
+#ifndef FIPS_MODE
int RSA_get0_multi_prime_crt_params(const RSA *r, const BIGNUM *exps[],
const BIGNUM *coeffs[])
{
return 1;
}
+#endif
const BIGNUM *RSA_get0_n(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)
{
return r->version;
}
+#ifndef FIPS_MODE
ENGINE *RSA_get0_engine(const RSA *r)
{
return r->engine;
return -1;
return EVP_PKEY_CTX_ctrl(ctx, -1, optype, cmd, p1, p2);
}
+#endif
DEFINE_STACK_OF(BIGNUM)
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)
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);
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
*/
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)
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;
return (int)labellen;
}
+#endif
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
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
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;
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;
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);
}
}
- 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);
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;
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);
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);
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;
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);
}
}
- 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);
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();
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);
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));
}
BN_free(dmp1);
}
+#ifndef FIPS_MODE
/*
* calculate m_i in multi-prime case
*
BN_free(cc);
BN_free(di);
}
+#endif
if (!BN_sub(r0, r0, m1))
goto err;
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();
}
BN_free(pr2);
}
+#endif
tail:
if (rsa->e && rsa->n) {
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;
}
}
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);
}
return 0;
}
- ctx = BN_CTX_new();
+ ctx = BN_CTX_new_ex(rsa->libctx);
gcd = BN_new();
if (ctx == NULL || gcd == NULL)
goto err;
return 0;
}
- ctx = BN_CTX_new();
+ ctx = BN_CTX_new_ex(rsa->libctx);
if (ctx == NULL)
return 0;
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;
#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);
/*
* 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
{ 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 },
#ifndef OPENSSL_NO_DSA
{ "DSA", "fips=yes", dsa_keymgmt_functions },
#endif
+ { "RSA:rsaEncryption", "default=yes", rsa_keymgmt_functions },
{ NULL, NULL, NULL }
};
return fips_keyexch;
case OSSL_OP_SIGNATURE:
return fips_signature;
+ case OSSL_OP_ASYM_CIPHER:
+ return fips_asym_cipher;
}
return NULL;
}
-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
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,
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,
#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;
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)
&& !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) {
}
#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;
}