Add ACVP fips module tests

For FIPS validation purposes - Automated Cryptographic Validation Protocol (ACVP) tests need to be
performed. (See https://github.com/usnistgov/ACVP). These tests are very similiar to the old CAVS tests.

This PR uses a hardwired subset of these test vectors to perform similiar operations,
to show the usage and prove that the API's are able to perform the required operations.
It may also help with communication with the lab (i.e- The lab could add a test here to show
a unworking use case - which we can then address).

The EVP layer performs these tests instead of calling lower level API's
as was done in the old FOM.
Some of these tests require access to internals that are not normally allowed/required.

The config option 'acvp_tests' (enabled by default) has been added so that this
access may be removed.

The mechanism has been implemented as additional OSSL_PARAM values that can be set and get.
A callback mechanism did not seem to add any additional benefit.
These params will not be added to the gettables lists.

Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/11572)
master
Shane Lontis 3 years ago
parent 5a147abd79
commit 4f2271d58a

@ -360,6 +360,7 @@ my @dtls = qw(dtls1 dtls1_2);
# For developers: keep it sorted alphabetically
my @disablables = (
"acvp_tests",
"afalgeng",
"aria",
"asan",

@ -501,6 +501,16 @@ never be used in production environments. It will only work when used with
gcc or clang and should be used in conjunction with the [no-shared](#no-shared)
option.
### no-acvp_tests
Do not build support for Automated Cryptographic Validation Protocol (ACVP)
tests.
This is required for FIPS validation purposes. Certain ACVP tests require
access to algorithm internals that are not normally accessible.
Additional information related to ACVP can be found at
<https://github.com/usnistgov/ACVP>.
### no-asm
Do not use assembler code.

@ -62,8 +62,8 @@ int DH_check_params(const DH *dh, int *ret)
* (2b) FFC domain params conform to FIPS-186-4 explicit domain param
* validity tests.
*/
return ffc_params_FIPS186_4_validate(&dh->params, FFC_PARAM_TYPE_DH, NULL,
FFC_PARAMS_VALIDATE_ALL, ret, NULL);
return ffc_params_FIPS186_4_validate(dh->libctx, &dh->params,
FFC_PARAM_TYPE_DH, ret, NULL);
}
#else
int DH_check_params(const DH *dh, int *ret)

@ -35,28 +35,21 @@ static int dh_builtin_genparams(DH *ret, int prime_len, int generator,
BN_GENCB *cb);
#endif /* FIPS_MODULE */
int dh_generate_ffc_parameters(DH *dh, int type, int pbits,
int qbits, EVP_MD *md, BN_GENCB *cb)
int dh_generate_ffc_parameters(DH *dh, int type, int pbits, int qbits,
BN_GENCB *cb)
{
int ret, res;
if (qbits <= 0) {
if (md != NULL)
qbits = EVP_MD_size(md) * 8;
else
qbits = (pbits >= 2048 ? SHA256_DIGEST_LENGTH :
SHA_DIGEST_LENGTH) * 8;
}
#ifndef FIPS_MODULE
if (type == DH_PARAMGEN_TYPE_FIPS_186_2)
ret = ffc_params_FIPS186_2_generate(dh->libctx, &dh->params,
FFC_PARAM_TYPE_DH,
pbits, qbits, md, &res, cb);
pbits, qbits, &res, cb);
else
#endif
ret = ffc_params_FIPS186_4_generate(dh->libctx, &dh->params,
FFC_PARAM_TYPE_DH,
pbits, qbits, md, &res, cb);
pbits, qbits, &res, cb);
if (ret > 0)
dh->dirty_cnt++;
return ret;

@ -286,7 +286,6 @@ static DH *ffc_params_generate(OPENSSL_CTX *libctx, DH_PKEY_CTX *dctx,
int res;
int prime_len = dctx->prime_len;
int subprime_len = dctx->subprime_len;
const EVP_MD *md = dctx->md;
if (dctx->paramgen_type > DH_PARAMGEN_TYPE_FIPS_186_4)
return NULL;
@ -300,26 +299,22 @@ static DH *ffc_params_generate(OPENSSL_CTX *libctx, DH_PKEY_CTX *dctx,
else
subprime_len = 160;
}
if (md == NULL) {
if (prime_len >= 2048)
md = EVP_sha256();
else
md = EVP_sha1();
}
if (dctx->md != NULL)
ffc_set_digest(&ret->params, EVP_MD_name(dctx->md), NULL);
# ifndef FIPS_MODULE
if (dctx->paramgen_type == DH_PARAMGEN_TYPE_FIPS_186_2)
rv = ffc_params_FIPS186_2_generate(libctx, &ret->params,
FFC_PARAM_TYPE_DH,
prime_len, subprime_len, md, &res,
pcb);
prime_len, subprime_len, &res, pcb);
else
# endif
/* For FIPS we always use the DH_PARAMGEN_TYPE_FIPS_186_4 generator */
if (dctx->paramgen_type >= DH_PARAMGEN_TYPE_FIPS_186_2)
rv = ffc_params_FIPS186_4_generate(libctx, &ret->params,
FFC_PARAM_TYPE_DH,
prime_len, subprime_len, md, &res,
pcb);
prime_len, subprime_len, &res, pcb);
if (rv <= 0) {
DH_free(ret);
return NULL;

@ -19,8 +19,8 @@ int dsa_check_params(const DSA *dsa, int *ret)
* (2b) FFC domain params conform to FIPS-186-4 explicit domain param
* validity tests.
*/
return ffc_params_FIPS186_4_validate(&dsa->params, FFC_PARAM_TYPE_DSA, NULL,
FFC_PARAMS_VALIDATE_ALL, ret, NULL);
return ffc_params_FIPS186_4_validate(dsa->libctx, &dsa->params,
FFC_PARAM_TYPE_DSA, ret, NULL);
}
/*

@ -23,29 +23,21 @@
#include "crypto/dsa.h"
#include "dsa_local.h"
int dsa_generate_ffc_parameters(DSA *dsa, int type,
int pbits, int qbits,
EVP_MD *md, BN_GENCB *cb)
int dsa_generate_ffc_parameters(DSA *dsa, int type, int pbits, int qbits,
BN_GENCB *cb)
{
int ret = 0, res;
if (qbits <= 0) {
if (md != NULL)
qbits = EVP_MD_size(md) * 8;
else
qbits = (pbits >= 2048 ? SHA256_DIGEST_LENGTH :
SHA_DIGEST_LENGTH) * 8;
}
#ifndef FIPS_MODULE
if (type == DSA_PARAMGEN_TYPE_FIPS_186_2)
ret = ffc_params_FIPS186_2_generate(dsa->libctx, &dsa->params,
FFC_PARAM_TYPE_DSA,
pbits, qbits, md, &res, cb);
pbits, qbits, &res, cb);
else
#endif
ret = ffc_params_FIPS186_4_generate(dsa->libctx, &dsa->params,
FFC_PARAM_TYPE_DSA,
pbits, qbits, md, &res, cb);
pbits, qbits, &res, cb);
if (ret > 0)
dsa->dirty_cnt++;
return ret;
@ -57,26 +49,21 @@ int DSA_generate_parameters_ex(DSA *dsa, int bits,
int *counter_ret, unsigned long *h_ret,
BN_GENCB *cb)
{
#ifndef FIPS_MODULE
if (dsa->meth->dsa_paramgen)
return dsa->meth->dsa_paramgen(dsa, bits, seed_in, seed_len,
counter_ret, h_ret, cb);
#endif
if (seed_in != NULL
&& !ffc_params_set_validate_params(&dsa->params, seed_in, seed_len, -1))
return 0;
#ifndef FIPS_MODULE
/* The old code used FIPS 186-2 DSA Parameter generation */
if (bits <= 1024 && seed_len == 20) {
if (!dsa_generate_ffc_parameters(dsa, DSA_PARAMGEN_TYPE_FIPS_186_2,
bits, 160, NULL, cb))
bits, 160, cb))
return 0;
} else
#endif
{
} else {
if (!dsa_generate_ffc_parameters(dsa, DSA_PARAMGEN_TYPE_FIPS_186_4,
bits, -1, NULL, cb))
bits, -1, cb))
return 0;
}

@ -217,9 +217,11 @@ static int pkey_dsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
BN_GENCB_free(pcb);
return 0;
}
if (dctx->md != NULL)
ffc_set_digest(&dsa->params, EVP_MD_name(dctx->md), NULL);
ret = ffc_params_FIPS186_4_generate(NULL, &dsa->params, FFC_PARAM_TYPE_DSA,
dctx->nbits, dctx->qbits, dctx->pmd,
&res, pcb);
dctx->nbits, dctx->qbits, &res, pcb);
BN_GENCB_free(pcb);
if (ret > 0)
EVP_PKEY_assign_DSA(pkey, dsa);

@ -78,6 +78,28 @@ int ffc_params_fromdata(FFC_PARAMS *ffc, const OSSL_PARAM params[])
if (!ffc_params_set_seed(ffc, prm->data, prm->data_size))
goto err;
}
prm = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_VALIDATE_TYPE);
if (prm != NULL) {
if (prm->data_type != OSSL_PARAM_UTF8_STRING)
goto err;
ffc_params_set_flags(ffc, ffc_params_flags_from_name(prm->data));
}
prm = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_DIGEST);
if (prm != NULL) {
const OSSL_PARAM *p1;
const char *props = NULL;
if (prm->data_type != OSSL_PARAM_UTF8_STRING)
goto err;
p1 = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_DIGEST_PROPS);
if (p1 != NULL) {
if (p1->data_type != OSSL_PARAM_UTF8_STRING)
goto err;
}
if (!ffc_set_digest(ffc, prm->data, props))
goto err;
}
ffc_params_set0_pqg(ffc, p, q, g);
ffc_params_set0_j(ffc, j);
return 1;

@ -11,6 +11,8 @@
#include <openssl/core_names.h>
#include "internal/ffc.h"
#include "internal/param_build_set.h"
#include "internal/nelem.h"
#include "e_os.h" /* strcasecmp */
#ifndef FIPS_MODULE
# include <openssl/asn1.h> /* ffc_params_print */
@ -21,6 +23,7 @@ void ffc_params_init(FFC_PARAMS *params)
memset(params, 0, sizeof(*params));
params->pcounter = -1;
params->gindex = FFC_UNVERIFIABLE_GINDEX;
params->flags = FFC_PARAM_FLAG_VALIDATE_ALL;
}
void ffc_params_cleanup(FFC_PARAMS *params)
@ -109,6 +112,18 @@ void ffc_params_set_h(FFC_PARAMS *params, int index)
params->h = index;
}
void ffc_params_set_flags(FFC_PARAMS *params, unsigned int flags)
{
params->flags = flags;
}
int ffc_set_digest(FFC_PARAMS *params, const char *alg, const char *props)
{
params->mdname = alg;
params->mdprops = props;
return 1;
}
int ffc_params_set_validate_params(FFC_PARAMS *params,
const unsigned char *seed, size_t seedlen,
int counter)
@ -182,6 +197,36 @@ int ffc_params_cmp(const FFC_PARAMS *a, const FFC_PARAMS *b, int ignore_q)
&& (ignore_q || BN_cmp(a->q, b->q) == 0); /* Note: q may be NULL */
}
static const OSSL_ITEM flag_map[] = {
{ FFC_PARAM_FLAG_VALIDATE_PQ, OSSL_FFC_PARAM_VALIDATE_PQ },
{ FFC_PARAM_FLAG_VALIDATE_G, OSSL_FFC_PARAM_VALIDATE_G },
{ FFC_PARAM_FLAG_VALIDATE_ALL, OSSL_FFC_PARAM_VALIDATE_PQG },
{ 0, "" }
};
int ffc_params_flags_from_name(const char *name)
{
size_t i;
for (i = 0; i < OSSL_NELEM(flag_map); ++i) {
if (strcasecmp(flag_map[i].ptr, name) == 0)
return flag_map[i].id;
}
return NID_undef;
}
const char *ffc_params_flags_to_name(int flags)
{
size_t i;
flags &= FFC_PARAM_FLAG_VALIDATE_ALL;
for (i = 0; i < OSSL_NELEM(flag_map); ++i) {
if ((int)flag_map[i].id == flags)
return flag_map[i].ptr;
}
return "";
}
int ffc_params_todata(const FFC_PARAMS *ffc, OSSL_PARAM_BLD *bld,
OSSL_PARAM params[])
{
@ -228,6 +273,20 @@ int ffc_params_todata(const FFC_PARAMS *ffc, OSSL_PARAM_BLD *bld,
return 0;
#endif
}
if (!ossl_param_build_set_utf8_string(bld, params,
OSSL_PKEY_PARAM_FFC_VALIDATE_TYPE,
ffc_params_flags_to_name(ffc->flags)))
return 0;
if (ffc->mdname != NULL
&& !ossl_param_build_set_utf8_string(bld, params,
OSSL_PKEY_PARAM_FFC_DIGEST,
ffc->mdname))
return 0;
if (ffc->mdprops != NULL
&& !ossl_param_build_set_utf8_string(bld, params,
OSSL_PKEY_PARAM_FFC_DIGEST_PROPS,
ffc->mdprops))
return 0;
return 1;
}

@ -413,18 +413,15 @@ err:
return ret;
}
static EVP_MD *fetch_default_md(OPENSSL_CTX *libctx, size_t N)
static const char *default_mdname(size_t N)
{
char *name = NULL;
if (N == 160)
name = "SHA1";
return "SHA1";
else if (N == 224)
name = "SHA-224";
return "SHA-224";
else if (N == 256)
name = "SHA-256";
return name != NULL ? EVP_MD_fetch(libctx, name, "") : NULL;
return "SHA-256";
return NULL;
}
/*
@ -446,6 +443,13 @@ static EVP_MD *fetch_default_md(OPENSSL_CTX *libctx, size_t N)
* the seed and index used during generation as input.
*
* params: used to pass in values for generation and validation.
* params->md: is the digest to use, If this value is NULL, then the digest is
* chosen using the value of N.
* params->flags:
* For validation one of:
* -FFC_PARAM_FLAG_VALIDATE_PQ
* -FFC_PARAM_FLAG_VALIDATE_G
* -FFC_PARAM_FLAG_VALIDATE_ALL
* For generation of p & q:
* - This is skipped if p & q are passed in.
* - If the seed is passed in then generation of p & q uses this seed (and if
@ -462,48 +466,58 @@ static EVP_MD *fetch_default_md(OPENSSL_CTX *libctx, size_t N)
* - For a partial validation : p, q and g are required.
* - For a canonical validation : the gindex and seed used for generation are
* also required.
* mode: The mode - either FFC_PARAM_MODE_GENERATE or FFC_PARAM_MODE_VERIFY.
* type: The key type - FFC_PARAM_TYPE_DSA or FFC_PARAM_TYPE_DH.
* L: is the size of the prime p in bits (e.g 2048)
* N: is the size of the prime q in bits (e.g 256)
* evpmd: is the digest to use, If this value is NULL, then the digest is chosen
* using the value of N.
* validate_flags:
* or generation: FFC_PARAMS_GENERATE.
* For validation one of:
* -FFC_PARAMS_VALIDATE_PQ
* -FFC_PARAMS_VALIDATE_G
* -FFC_PARAMS_VALIDATE_ALL
* res: A returned failure reason (One of FFC_CHECK_XXXX),
* or 0 for general failures.
* cb: A callback (can be NULL) that is called during different phases
*
* Returns:
* - FFC_PARAMS_RET_STATUS_FAILED: if there was an error, or validation failed.
* - FFC_PARAMS_RET_STATUS_SUCCESS if the generation or validation succeeded.
* - FFC_PARAMS_RET_STATUS_UNVERIFIABLE_G if the validation of G succeeded,
* - FFC_PARAM_RET_STATUS_FAILED: if there was an error, or validation failed.
* - FFC_PARAM_RET_STATUS_SUCCESS if the generation or validation succeeded.
* - FFC_PARAM_RET_STATUS_UNVERIFIABLE_G if the validation of G succeeded,
* but G is unverifiable.
*/
int ffc_params_FIPS186_4_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
int type, size_t L, size_t N,
const EVP_MD *evpmd, int validate_flags,
int mode, int type, size_t L, size_t N,
int *res, BN_GENCB *cb)
{
int ok = FFC_PARAMS_RET_STATUS_FAILED;
int ok = FFC_PARAM_RET_STATUS_FAILED;
unsigned char *seed = NULL, *seed_tmp = NULL;
int mdsize, counter = 0, pcounter = 0, r = 0;
size_t seedlen = 0;
BIGNUM *tmp, *pm1, *e, *test;
BIGNUM *g = NULL, *q = NULL, *p = NULL;
BN_MONT_CTX *mont = NULL;
int n = 0, m = 0, qsize = N >> 3;
int n = 0, m = 0, qsize;
int canonical_g = 0, hret = 0;
BN_CTX *ctx = NULL;
EVP_MD_CTX *mctx = NULL;
int generate = (validate_flags == 0);
EVP_MD *evpmd_fetch = NULL;
EVP_MD *md = NULL;
int verify = (mode == FFC_PARAM_MODE_VERIFY);
unsigned int flags = verify ? params->flags : 0;
*res = 0;
if (params->mdname != NULL) {
md = EVP_MD_fetch(libctx, params->mdname, params->mdprops);
} else {
if (N <= 0)
N = (L >= 2048 ? SHA256_DIGEST_LENGTH : SHA_DIGEST_LENGTH) * 8;
md = EVP_MD_fetch(libctx, default_mdname(N), NULL);
}
if (md == NULL)
goto err;
mdsize = EVP_MD_size(md);
if (mdsize <= 0)
goto err;
if (N <= 0)
N = mdsize * 8;
qsize = N >> 3;
/*
* A.1.1.2 Step (1) AND
* A.1.1.3 Step (3)
@ -518,15 +532,6 @@ int ffc_params_FIPS186_4_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
if (mctx == NULL)
goto err;
if (evpmd == NULL) {
evpmd_fetch = fetch_default_md(libctx, N);
evpmd = evpmd_fetch;
}
mdsize = EVP_MD_size(evpmd);
if (mdsize <= 0)
goto err;
if ((ctx = BN_CTX_new_ex(libctx)) == NULL)
goto err;
@ -546,7 +551,7 @@ int ffc_params_FIPS186_4_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
if (params->seed != NULL)
seed = params->seed;
if (generate) {
if (!verify) {
/* For generation: p & q must both be NULL or NON-NULL */
if ((params->p == NULL) != (params->q == NULL)) {
*res = FFC_CHECK_INVALID_PQ;
@ -554,13 +559,13 @@ int ffc_params_FIPS186_4_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
}
} else {
/* Validation of p,q requires seed and counter to be valid */
if ((validate_flags & FFC_PARAMS_VALIDATE_PQ) != 0) {
if ((flags & FFC_PARAM_FLAG_VALIDATE_PQ) != 0) {
if (seed == NULL || params->pcounter < 0) {
*res = FFC_CHECK_MISSING_SEED_OR_COUNTER;
goto err;
}
}
if ((validate_flags & FFC_PARAMS_VALIDATE_G) != 0) {
if ((flags & FFC_PARAM_FLAG_VALIDATE_G) != 0) {
/* validation of g also requires g to be set */
if (params->g == NULL) {
*res = FFC_CHECK_INVALID_G;
@ -574,7 +579,7 @@ int ffc_params_FIPS186_4_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
* validate_flags = 0 then skip the generation of PQ.
* validate_flags = VALIDATE_G then also skip the validation of PQ.
*/
if (params->p != NULL && ((validate_flags & FFC_PARAMS_VALIDATE_PQ) == 0)) {
if (params->p != NULL && ((flags & FFC_PARAM_FLAG_VALIDATE_PQ) == 0)) {
/* p and q already exists so only generate g */
p = params->p;
q = params->q;
@ -604,7 +609,7 @@ int ffc_params_FIPS186_4_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
if (seed == NULL) {
/* Validation requires the seed to be supplied */
if (validate_flags) {
if (verify) {
*res = FFC_CHECK_MISSING_SEED_OR_COUNTER;
goto err;
}
@ -617,7 +622,7 @@ int ffc_params_FIPS186_4_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
/* A.1.1.2 Step (11): max loop count = 4L - 1 */
counter = 4 * L - 1;
/* Validation requires the counter to be supplied */
if (validate_flags) {
if (verify) {
/* A.1.1.3 Step (4) : if (counter > (4L -1)) return INVALID */
if (params->pcounter > counter) {
*res = FFC_CHECK_INVALID_COUNTER;
@ -638,11 +643,11 @@ int ffc_params_FIPS186_4_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
goto err;
for (;;) {
if (!generate_q_fips186_4(ctx, q, evpmd, qsize, seed, seedlen,
if (!generate_q_fips186_4(ctx, q, md, qsize, seed, seedlen,
seed != params->seed, &m, res, cb))
goto err;
/* A.1.1.3 Step (9): Verify that q matches the expected value */
if (validate_flags && (BN_cmp(q, params->q) != 0)) {
if (verify && (BN_cmp(q, params->q) != 0)) {
*res = FFC_CHECK_Q_MISMATCH;
goto err;
}
@ -652,8 +657,8 @@ int ffc_params_FIPS186_4_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
goto err;
memcpy(seed_tmp, seed, seedlen);
r = generate_p(ctx, evpmd, counter, n, seed_tmp, seedlen, q, p, L, cb,
&pcounter, res);
r = generate_p(ctx, md, counter, n, seed_tmp, seedlen, q, p, L,
cb, &pcounter, res);
if (r > 0)
break; /* found p */
if (r < 0)
@ -674,11 +679,11 @@ int ffc_params_FIPS186_4_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
* Gets here if we found p.
* A.1.1.3 Step (14): return error if i != counter OR computed_p != known_p.
*/
if (validate_flags && (pcounter != counter || (BN_cmp(p, params->p) != 0)))
if (verify && (pcounter != counter || (BN_cmp(p, params->p) != 0)))
goto err;
/* If validating p & q only then skip the g validation test */
if ((validate_flags & FFC_PARAMS_VALIDATE_ALL) == FFC_PARAMS_VALIDATE_PQ)
if ((flags & FFC_PARAM_FLAG_VALIDATE_ALL) == FFC_PARAM_FLAG_VALIDATE_PQ)
goto pass;
g_only:
if ((mont = BN_MONT_CTX_new()) == NULL)
@ -686,7 +691,7 @@ g_only:
if (!BN_MONT_CTX_set(mont, p, ctx))
goto err;
if (((validate_flags & FFC_PARAMS_VALIDATE_G) != 0)
if (((flags & FFC_PARAM_FLAG_VALIDATE_G) != 0)
&& !ffc_params_validate_unverifiable_g(ctx, mont, p, q, params->g,
tmp, res))
goto err;
@ -703,17 +708,17 @@ g_only:
/* Canonical g requires a seed and index to be set */
if ((seed != NULL) && (params->gindex != FFC_UNVERIFIABLE_GINDEX)) {
canonical_g = 1;
if (!generate_canonical_g(ctx, mont, evpmd, g, tmp, p, e,
if (!generate_canonical_g(ctx, mont, md, g, tmp, p, e,
params->gindex, seed, seedlen)) {
*res = FFC_CHECK_INVALID_G;
goto err;
}
/* A.2.4 Step (13): Return valid if computed_g == g */
if (validate_flags && BN_cmp(g, params->g) != 0) {
if (verify && BN_cmp(g, params->g) != 0) {
*res = FFC_CHECK_G_MISMATCH;
goto err;
}
} else if (generate) {
} else if (!verify) {
if (!generate_unverifiable_g(ctx, mont, g, tmp, p, e, pm1, &hret))
goto err;
}
@ -721,7 +726,7 @@ g_only:
if (!BN_GENCB_call(cb, 3, 1))
goto err;
if (generate) {
if (!verify) {
if (p != params->p) {
BN_free(params->p);
params->p = BN_dup(p);
@ -741,11 +746,11 @@ g_only:
params->h = hret;
}
pass:
if ((validate_flags & FFC_PARAMS_VALIDATE_G) != 0 && (canonical_g == 0))
if ((flags & FFC_PARAM_FLAG_VALIDATE_G) != 0 && (canonical_g == 0))
/* Return for the case where g is partially valid */
ok = FFC_PARAMS_RET_STATUS_UNVERIFIABLE_G;
ok = FFC_PARAM_RET_STATUS_UNVERIFIABLE_G;
else
ok = FFC_PARAMS_RET_STATUS_SUCCESS;
ok = FFC_PARAM_RET_STATUS_SUCCESS;
err:
if (seed != params->seed)
OPENSSL_free(seed);
@ -754,33 +759,47 @@ err:
BN_CTX_end(ctx);
BN_CTX_free(ctx);
BN_MONT_CTX_free(mont);
EVP_MD_free(evpmd_fetch);
EVP_MD_CTX_free(mctx);
EVP_MD_free(md);
return ok;
}
int ffc_params_FIPS186_2_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
int type, size_t L, size_t N,
const EVP_MD *evpmd, int validate_flags,
int mode, int type, size_t L, size_t N,
int *res, BN_GENCB *cb)
{
int ok = FFC_PARAMS_RET_STATUS_FAILED;
int ok = FFC_PARAM_RET_STATUS_FAILED;
unsigned char seed[SHA256_DIGEST_LENGTH];
unsigned char buf[SHA256_DIGEST_LENGTH];
BIGNUM *r0, *test, *tmp, *g = NULL, *q = NULL, *p = NULL;
BN_MONT_CTX *mont = NULL;
size_t qsize = N >> 3;
EVP_MD *md = NULL;
size_t qsize;
int n = 0, m = 0;
int counter = 0, pcounter = 0, use_random_seed;
int rv;
BN_CTX *ctx = NULL;
int hret = -1;
int generate = (validate_flags == 0);
unsigned char *seed_in = params->seed;
size_t seed_len = params->seedlen;
EVP_MD *evpmd_fetch = NULL;
int verify = (mode == FFC_PARAM_MODE_VERIFY);
unsigned int flags = verify ? params->flags : 0;
*res = 0;
if (params->mdname != NULL) {
md = EVP_MD_fetch(libctx, params->mdname, params->mdprops);
} else {
if (N <= 0)
N = (L >= 2048 ? SHA256_DIGEST_LENGTH : SHA_DIGEST_LENGTH) * 8;
md = EVP_MD_fetch(libctx, default_mdname(N), NULL);
}
if (md == NULL)
goto err;
if (N <= 0)
N = EVP_MD_size(md) * 8;
qsize = N >> 3;
#ifdef FIPS_MODULE
/*
* FIPS 186-4 states that validation can only be done for this pair.
@ -788,7 +807,7 @@ int ffc_params_FIPS186_2_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
*/
if (L != 1024 || N != 160) {
*res = FFC_CHECK_BAD_LN_PAIR;
return FFC_PARAMS_RET_STATUS_FAILED;
goto err;
}
#endif
if (qsize != SHA_DIGEST_LENGTH
@ -796,17 +815,7 @@ int ffc_params_FIPS186_2_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
&& qsize != SHA256_DIGEST_LENGTH) {
/* invalid q size */
*res = FFC_CHECK_INVALID_Q_VALUE;
return FFC_PARAMS_RET_STATUS_FAILED;
}
if (evpmd == NULL) {
evpmd_fetch = fetch_default_md(libctx, qsize * 8);
evpmd = evpmd_fetch;
} else {
rv = EVP_MD_size(evpmd);
if (rv <= 0)
return 0;
qsize = (size_t)rv;
goto err;
}
if (L < 512)
@ -817,12 +826,11 @@ int ffc_params_FIPS186_2_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
if (seed_in != NULL) {
if (seed_len < qsize) {
*res = FFC_CHECK_INVALID_SEED_SIZE;
return 0;
goto err;
}
if (seed_len > qsize) {
/* Only consume as much seed as is expected. */
/* Only consume as much seed as is expected. */
if (seed_len > qsize)
seed_len = qsize;
}
memcpy(seed, seed_in, seed_len);
}
@ -844,21 +852,21 @@ int ffc_params_FIPS186_2_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
if (!BN_lshift(test, BN_value_one(), L - 1))
goto err;
if (generate) {
if (!verify) {
/* For generation: p & q must both be NULL or NON-NULL */
if ((params->p != NULL) != (params->q != NULL)) {
*res = FFC_CHECK_INVALID_PQ;
goto err;
}
} else {
if ((validate_flags & FFC_PARAMS_VALIDATE_PQ) != 0) {
if ((flags & FFC_PARAM_FLAG_VALIDATE_PQ) != 0) {
/* Validation of p,q requires seed and counter to be valid */
if (seed_in == NULL || params->pcounter < 0) {
*res = FFC_CHECK_MISSING_SEED_OR_COUNTER;
goto err;
}
}
if ((validate_flags & FFC_PARAMS_VALIDATE_G) != 0) {
if ((flags & FFC_PARAM_FLAG_VALIDATE_G) != 0) {
/* validation of g also requires g to be set */
if (params->g == NULL) {
*res = FFC_CHECK_INVALID_G;
@ -867,7 +875,7 @@ int ffc_params_FIPS186_2_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
}
}
if (params->p != NULL && ((validate_flags & FFC_PARAMS_VALIDATE_PQ) == 0)) {
if (params->p != NULL && ((flags & FFC_PARAM_FLAG_VALIDATE_PQ) == 0)) {
/* p and q already exists so only generate g */
p = params->p;
q = params->q;
@ -877,7 +885,7 @@ int ffc_params_FIPS186_2_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
use_random_seed = (seed_in == NULL);
for (;;) {
if (!generate_q_fips186_2(ctx, q, evpmd, buf, seed, qsize,
if (!generate_q_fips186_2(ctx, q, md, buf, seed, qsize,
use_random_seed, &m, res, cb))
goto err;
@ -890,7 +898,7 @@ int ffc_params_FIPS186_2_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
n = (L - 1) / 160;
counter = 4 * L - 1; /* Was 4096 */
/* Validation requires the counter to be supplied */
if (validate_flags) {
if (verify) {
if (params->pcounter > counter) {
*res = FFC_CHECK_INVALID_COUNTER;
goto err;
@ -898,7 +906,7 @@ int ffc_params_FIPS186_2_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
counter = params->pcounter;
}
rv = generate_p(ctx, evpmd, counter, n, buf, qsize, q, p, L, cb,
rv = generate_p(ctx, md, counter, n, buf, qsize, q, p, L, cb,
&pcounter, res);
if (rv > 0)
break; /* found it */
@ -911,7 +919,7 @@ int ffc_params_FIPS186_2_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
if (!BN_GENCB_call(cb, 2, 1))
goto err;
if (validate_flags) {
if (verify) {
if (pcounter != counter) {
*res = FFC_CHECK_COUNTER_MISMATCH;
goto err;
@ -922,7 +930,7 @@ int ffc_params_FIPS186_2_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
}
}
/* If validating p & q only then skip the g validation test */
if ((validate_flags & FFC_PARAMS_VALIDATE_ALL) == FFC_PARAMS_VALIDATE_PQ)
if ((flags & FFC_PARAM_FLAG_VALIDATE_ALL) == FFC_PARAM_FLAG_VALIDATE_PQ)
goto pass;
g_only:
if ((mont = BN_MONT_CTX_new()) == NULL)
@ -930,7 +938,7 @@ g_only:
if (!BN_MONT_CTX_set(mont, p, ctx))
goto err;
if (generate) {
if (!verify) {
/* We now need to generate g */
/* set test = p - 1 */
if (!BN_sub(test, p, BN_value_one()))
@ -940,7 +948,7 @@ g_only:
goto err;
if (!generate_unverifiable_g(ctx, mont, g, tmp, p, r0, test, &hret))
goto err;
} else if (((validate_flags & FFC_PARAMS_VALIDATE_G) != 0)
} else if (((flags & FFC_PARAM_FLAG_VALIDATE_G) != 0)
&& !ffc_params_validate_unverifiable_g(ctx, mont, p, q,
params->g, tmp, res)) {
goto err;
@ -949,7 +957,7 @@ g_only:
if (!BN_GENCB_call(cb, 3, 1))
goto err;
if (generate) {
if (!verify) {
if (p != params->p) {
BN_free(params->p);
params->p = BN_dup(p);
@ -969,32 +977,34 @@ g_only:
params->h = hret;
}
pass:
if ((validate_flags & FFC_PARAMS_VALIDATE_G) != 0)
ok = FFC_PARAMS_RET_STATUS_UNVERIFIABLE_G;
if ((flags & FFC_PARAM_FLAG_VALIDATE_G) != 0)
ok = FFC_PARAM_RET_STATUS_UNVERIFIABLE_G;
else
ok = FFC_PARAMS_RET_STATUS_SUCCESS;
ok = FFC_PARAM_RET_STATUS_SUCCESS;
err:
if (ctx != NULL)
BN_CTX_end(ctx);
BN_CTX_free(ctx);
EVP_MD_free(evpmd_fetch);
BN_MONT_CTX_free(mont);
EVP_MD_free(md);
return ok;
}
int ffc_params_FIPS186_4_generate(OPENSSL_CTX *libctx, FFC_PARAMS *params,
int type, size_t L, size_t N,
const EVP_MD *evpmd, int *res, BN_GENCB *cb)
int *res, BN_GENCB *cb)
{
return ffc_params_FIPS186_4_gen_verify(libctx, params, type, L, N, evpmd, 0,
res, cb);
return ffc_params_FIPS186_4_gen_verify(libctx, params,
FFC_PARAM_MODE_GENERATE,
type, L, N, res, cb);
}
/* This should no longer be used in FIPS mode */
int ffc_params_FIPS186_2_generate(OPENSSL_CTX *libctx, FFC_PARAMS *params,
int type, size_t L, size_t N,
const EVP_MD *evpmd, int *res, BN_GENCB *cb)
int *res, BN_GENCB *cb)
{
return ffc_params_FIPS186_2_gen_verify(libctx, params, type, L, N, evpmd,
0, res, cb);
return ffc_params_FIPS186_2_gen_verify(libctx, params,
FFC_PARAM_MODE_GENERATE,
type, L, N, res, cb);
}

@ -44,37 +44,37 @@ int ffc_params_validate_unverifiable_g(BN_CTX *ctx, BN_MONT_CTX *mont,
return 1;
}
int ffc_params_FIPS186_4_validate(const FFC_PARAMS *params, int type,
const EVP_MD *evpmd, int validate_flags,
int *res, BN_GENCB *cb)
int ffc_params_FIPS186_4_validate(OPENSSL_CTX *libctx, const FFC_PARAMS *params,
int type, int *res, BN_GENCB *cb)
{
size_t L, N;
if (params == NULL || params->p == NULL || params->q == NULL)
return FFC_PARAMS_RET_STATUS_FAILED;
return FFC_PARAM_RET_STATUS_FAILED;
/* A.1.1.3 Step (1..2) : L = len(p), N = len(q) */
L = BN_num_bits(params->p);
N = BN_num_bits(params->q);
return ffc_params_FIPS186_4_gen_verify(NULL, (FFC_PARAMS *)params, type, L, N,
evpmd, validate_flags, res, cb);
return ffc_params_FIPS186_4_gen_verify(libctx, (FFC_PARAMS *)params,
FFC_PARAM_MODE_VERIFY, type,
L, N, res, cb);
}
/* This may be used in FIPS mode to validate deprecated FIPS-186-2 Params */
int ffc_params_FIPS186_2_validate(const FFC_PARAMS *params, int type,
const EVP_MD *evpmd, int validate_flags,
int *res, BN_GENCB *cb)
int ffc_params_FIPS186_2_validate(OPENSSL_CTX *libctx, const FFC_PARAMS *params,
int type, int *res, BN_GENCB *cb)
{
size_t L, N;
if (params->p == NULL || params->q == NULL) {
*res = FFC_CHECK_INVALID_PQ;
return FFC_PARAMS_RET_STATUS_FAILED;
return FFC_PARAM_RET_STATUS_FAILED;
}
/* A.1.1.3 Step (1..2) : L = len(p), N = len(q) */
L = BN_num_bits(params->p);
N = BN_num_bits(params->q);
return ffc_params_FIPS186_2_gen_verify(NULL, (FFC_PARAMS *)params, type, L, N,
evpmd, validate_flags, res, cb);
return ffc_params_FIPS186_2_gen_verify(libctx, (FFC_PARAMS *)params,
FFC_PARAM_MODE_VERIFY, type,
L, N, res, cb);
}

@ -13,3 +13,7 @@ IF[{- !$disabled{'deprecated-0.9.8'} -}]
ENDIF
SOURCE[../../providers/libfips.a]=$COMMON
IF[{- !$disabled{'acvp-tests'} -}]
SOURCE[../../providers/libfips.a]=rsa_acvp_test_params.c
ENDIF

@ -0,0 +1,167 @@
/*
* Copyright 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
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include <string.h> /* memcpy */
#include <openssl/core_names.h>
#include <openssl/param_build.h>
#include "crypto/rsa.h"
#include "rsa_local.h"
int rsa_acvp_test_gen_params_new(OSSL_PARAM **dst, const OSSL_PARAM src[])
{
const OSSL_PARAM *p, *s;
OSSL_PARAM *d, *alloc = NULL;
int ret = 1;
static const OSSL_PARAM settable[] = {
OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_TEST_XP, NULL, 0),
OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_TEST_XP1, NULL, 0),
OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_TEST_XP2, NULL, 0),
OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_TEST_XQ, NULL, 0),
OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_TEST_XQ1, NULL, 0),
OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_TEST_XQ2, NULL, 0),
OSSL_PARAM_END
};
/* Assume the first element is a required field if this feature is used */
p = OSSL_PARAM_locate_const(src, settable[0].key);
if (p == NULL)
return 1;
/* Zeroing here means the terminator is always set at the end */
alloc = OPENSSL_zalloc(sizeof(settable));
if (alloc == NULL)
return 0;
d = alloc;
for (s = settable; s->key != NULL; ++s) {
/* If src contains a key from settable then copy the src to the dest */
p = OSSL_PARAM_locate_const(src, s->key);
if (p != NULL) {
*d = *s; /* shallow copy from the static settable[] */
d->data_size = p->data_size;
d->data = OPENSSL_memdup(p->data, p->data_size);
if (d->data == NULL)
ret = 0;
++d;
}
}
if (ret == 0) {
rsa_acvp_test_gen_params_free(alloc);
alloc = NULL;
}
if (*dst != NULL)
rsa_acvp_test_gen_params_free(*dst);
*dst = alloc;
return ret;
}
void rsa_acvp_test_gen_params_free(OSSL_PARAM *dst)
{
OSSL_PARAM *p;
if (dst == NULL)
return;
for (p = dst; p->key != NULL; ++p) {
OPENSSL_free(p->data);
p->data = NULL;
}
OPENSSL_free(dst);
}
int rsa_acvp_test_set_params(RSA *r, const OSSL_PARAM params[])
{
RSA_ACVP_TEST *t;
const OSSL_PARAM *p;
if (r->acvp_test != NULL) {
rsa_acvp_test_free(r->acvp_test);
r->acvp_test = NULL;
}
t = OPENSSL_zalloc(sizeof(*t));
if (t == NULL)
return 0;
/* Set the input parameters */
if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_TEST_XP1)) != NULL
&& !OSSL_PARAM_get_BN(p, &t->Xp1))
goto err;
if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_TEST_XP2)) != NULL
&& !OSSL_PARAM_get_BN(p, &t->Xp2))
goto err;
if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_TEST_XP)) != NULL
&& !OSSL_PARAM_get_BN(p, &t->Xp))
goto err;
if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_TEST_XQ1)) != NULL
&& !OSSL_PARAM_get_BN(p, &t->Xq1))
goto err;
if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_TEST_XQ2)) != NULL
&& !OSSL_PARAM_get_BN(p, &t->Xq2))
goto err;
if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_TEST_XQ)) != NULL
&& !OSSL_PARAM_get_BN(p, &t->Xq))
goto err;
/* Setup the output parameters */
t->p1 = BN_new();
t->p2 = BN_new();
t->q1 = BN_new();
t->q2 = BN_new();
r->acvp_test = t;
return 1;
err:
rsa_acvp_test_free(t);
return 0;
}
int rsa_acvp_test_get_params(RSA *r, OSSL_PARAM params[])
{
RSA_ACVP_TEST *t;
OSSL_PARAM *p;
if (r == NULL)
return 0;
t = r->acvp_test;
if (t != NULL) {
if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_RSA_TEST_P1)) != NULL
&& !OSSL_PARAM_set_BN(p, t->p1))
return 0;
if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_RSA_TEST_P2)) != NULL
&& !OSSL_PARAM_set_BN(p, t->p2))
return 0;
if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_RSA_TEST_Q1)) != NULL
&& !OSSL_PARAM_set_BN(p, t->q1))
return 0;
if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_RSA_TEST_Q2)) != NULL
&& !OSSL_PARAM_set_BN(p, t->q2))
return 0;
}
return 1;
}
void rsa_acvp_test_free(RSA_ACVP_TEST *t)
{
if (t != NULL) {
BN_free(t->Xp1);
BN_free(t->Xp2);
BN_free(t->Xp);
BN_free(t->Xq1);
BN_free(t->Xq2);
BN_free(t->Xq);
BN_free(t->p1);
BN_free(t->p2);
BN_free(t->q1);
BN_free(t->q2);
OPENSSL_free(t);
}
}

@ -88,6 +88,7 @@ int rsa_fromdata(RSA *rsa, const OSSL_PARAM params[])
goto err;
}
sk_BIGNUM_free(factors);
sk_BIGNUM_free(exps);
sk_BIGNUM_free(coeffs);
@ -126,7 +127,7 @@ int rsa_todata(RSA *rsa, OSSL_PARAM_BLD *bld, OSSL_PARAM params[])
int numcoeffs = sk_BIGNUM_const_num(coeffs);
/*
* It's permisssible to have zero primes, i.e. no CRT params.
* It's permissible to have zero primes, i.e. no CRT params.
* Otherwise, there must be at least two, as many exponents,
* and one coefficient less.
*/
@ -145,6 +146,11 @@ int rsa_todata(RSA *rsa, OSSL_PARAM_BLD *bld, OSSL_PARAM params[])
|| !ossl_param_build_set_multi_key_bn(bld, params, rsa_mp_coeff_names,
coeffs))
goto err;
#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
/* The acvp test results are not meant for export so check for bld == NULL */
if (bld == NULL)
rsa_acvp_test_get_params(rsa, params);
#endif
ret = 1;
err:
sk_BIGNUM_const_free(factors);

@ -66,8 +66,8 @@ int RSA_generate_multi_prime_key(RSA *rsa, int bits, int primes,
else
return 0;
}
#endif /* FIPS_MODULE */
return rsa_keygen(NULL, rsa, bits, primes, e_value, cb, 0);
#endif /* FIPS_MODUKE */
return rsa_keygen(rsa->libctx, rsa, bits, primes, e_value, cb, 0);
}
#ifndef FIPS_MODULE

@ -162,6 +162,11 @@ void RSA_free(RSA *r)
BN_clear_free(r->dmp1);
BN_clear_free(r->dmq1);
BN_clear_free(r->iqmp);
#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
rsa_acvp_test_free(r->acvp_test);
#endif
#ifndef FIPS_MODULE
RSA_PSS_PARAMS_free(r->pss);
sk_RSA_PRIME_INFO_pop_free(r->prime_infos, rsa_multip_info_free);

@ -10,7 +10,7 @@
#ifndef OSSL_CRYPTO_RSA_LOCAL_H
#define OSSL_CRYPTO_RSA_LOCAL_H
#include <openssl/rsa.h>
#include "crypto/rsa.h"
#include "internal/refcount.h"
#include "crypto/rsa.h"
@ -29,6 +29,24 @@ typedef struct rsa_prime_info_st {
DECLARE_ASN1_ITEM(RSA_PRIME_INFO)
DEFINE_STACK_OF(RSA_PRIME_INFO)
#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
struct rsa_acvp_test_st {
/* optional inputs */
BIGNUM *Xp1;
BIGNUM *Xp2;
BIGNUM *Xq1;
BIGNUM *Xq2;
BIGNUM *Xp;
BIGNUM *Xq;
/* optional outputs */
BIGNUM *p1;
BIGNUM *p2;
BIGNUM *q1;
BIGNUM *q2;
};
#endif
struct rsa_st {
/*
* #legacy
@ -58,12 +76,14 @@ struct rsa_st {
*/
/* This is used uniquely by OpenSSL provider implementations. */
RSA_PSS_PARAMS_30 pss_params;
#ifndef FIPS_MODULE
/* This is used uniquely by rsa_ameth.c and rsa_pmeth.c. */
RSA_PSS_PARAMS *pss;
#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
RSA_ACVP_TEST *acvp_test;
#endif
#ifndef FIPS_MODULE
/* This is used uniquely by rsa_ameth.c and rsa_pmeth.c. */
RSA_PSS_PARAMS *pss;
/* for multi-prime RSA, defined in RFC 8017 */
STACK_OF(RSA_PRIME_INFO) *prime_infos;
/* Be careful using this if the RSA structure is shared */
@ -172,13 +192,9 @@ int rsa_sp800_56b_generate_key(RSA *rsa, int nbits, const BIGNUM *efixed,
int rsa_sp800_56b_derive_params_from_pq(RSA *rsa, int nbits,
const BIGNUM *e, BN_CTX *ctx);
int rsa_fips186_4_gen_prob_primes(RSA *rsa, BIGNUM *p1, BIGNUM *p2,
BIGNUM *Xpout, const BIGNUM *Xp,
const BIGNUM *Xp1, const BIGNUM *Xp2,
BIGNUM *q1, BIGNUM *q2, BIGNUM *Xqout,
const BIGNUM *Xq, const BIGNUM *Xq1,
const BIGNUM *Xq2, int nbits,
const BIGNUM *e, BN_CTX *ctx, BN_GENCB *cb);
int rsa_fips186_4_gen_prob_primes(RSA *rsa, RSA_ACVP_TEST *test,
int nbits, const BIGNUM *e, BN_CTX *ctx,
BN_GENCB *cb);
int rsa_padding_add_SSLv23_with_libctx(OPENSSL_CTX *libctx, unsigned char *to,
int tlen, const unsigned char *from,

@ -10,6 +10,7 @@
#include <openssl/err.h>
#include <openssl/bn.h>
#include <openssl/core.h>
#include "crypto/bn.h"
#include "crypto/security_bits.h"
#include "rsa_local.h"
@ -25,20 +26,23 @@
*
* Params:
* rsa Object used to store primes p & q.
* p1, p2 The returned auxiliary primes for p. If NULL they are not returned.
* Xpout An optionally returned random number used during generation of p.
* Xp An optional passed in value (that is random number used during
* generation of p).
* Xp1, Xp2 Optionally passed in randomly generated numbers from which
* auxiliary primes p1 & p2 are calculated. If NULL these values
* are generated internally.
* q1, q2 The returned auxiliary primes for q. If NULL they are not returned.
* Xqout An optionally returned random number used during generation of q.
* Xq An optional passed in value (that is random number used during
* generation of q).
* Xq1, Xq2 Optionally passed in randomly generated numbers from which
* auxiliary primes q1 & q2 are calculated. If NULL these values
* are generated internally.
* test Object used for CAVS testing only.that contains..
* p1, p2 The returned auxiliary primes for p.
* If NULL they are not returned.
* Xpout An optionally returned random number used during generation of p.
* Xp An optional passed in value (that is random number used during
* generation of p).
* Xp1, Xp2 Optionally passed in randomly generated numbers from which
* auxiliary primes p1 & p2 are calculated. If NULL these values
* are generated internally.
* q1, q2 The returned auxiliary primes for q.
* If NULL they are not returned.
* Xqout An optionally returned random number used during generation of q.
* Xq An optional passed in value (that is random number used during
* generation of q).
* Xq1, Xq2 Optionally passed in randomly generated numbers from which
* auxiliary primes q1 & q2 are calculated. If NULL these values
* are generated internally.
* nbits The key size in bits (The size of the modulus n).
* e The public exponent.
* ctx A BN_CTX object.
@ -49,16 +53,34 @@
* Xp, Xp1, Xp2, Xq, Xq1, Xq2 are optionally passed in.
* (Required for CAVS testing).
*/
int rsa_fips186_4_gen_prob_primes(RSA *rsa, BIGNUM *p1, BIGNUM *p2,
BIGNUM *Xpout, const BIGNUM *Xp,
const BIGNUM *Xp1, const BIGNUM *Xp2,
BIGNUM *q1, BIGNUM *q2, BIGNUM *Xqout,
const BIGNUM *Xq, const BIGNUM *Xq1,
const BIGNUM *Xq2, int nbits,
int rsa_fips186_4_gen_prob_primes(RSA *rsa, RSA_ACVP_TEST *test, int nbits,
const BIGNUM *e, BN_CTX *ctx, BN_GENCB *cb)
{
int ret = 0, ok;
/* Temp allocated BIGNUMS */
BIGNUM *Xpo = NULL, *Xqo = NULL, *tmp = NULL;
/* Intermediate BIGNUMS that can be returned for testing */
BIGNUM *p1 = NULL, *p2 = NULL;
BIGNUM *q1 = NULL, *q2 = NULL;
/* Intermediate BIGNUMS that can be input for testing */
BIGNUM *Xpout = NULL, *Xqout = NULL;
BIGNUM *Xp = NULL, *Xp1 = NULL, *Xp2 = NULL;
BIGNUM *Xq = NULL, *Xq1 = NULL, *Xq2 = NULL;
#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
if (test != NULL) {
Xp1 = test->Xp1;