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)
This commit is contained in:
Shane Lontis 2020-06-17 11:33:16 +10:00
parent 5a147abd79
commit 4f2271d58a
39 changed files with 4235 additions and 506 deletions

View File

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

View File

@ -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.

View File

@ -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)

View File

@ -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;

View File

@ -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;

View File

@ -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);
}
/*

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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,

View File

@ -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;
Xp2 = test->Xp2;
Xq1 = test->Xq1;
Xq2 = test->Xq2;
Xp = test->Xp;
Xq = test->Xq;
p1 = test->p1;
p2 = test->p2;
q1 = test->q1;
q2 = test->q2;
}
#endif
/* (Step 1) Check key length
* NOTE: SP800-131A Rev1 Disallows key lengths of < 2048 bits for RSA
@ -294,6 +316,11 @@ int rsa_sp800_56b_generate_key(RSA *rsa, int nbits, const BIGNUM *efixed,
int ok;
BN_CTX *ctx = NULL;
BIGNUM *e = NULL;
RSA_ACVP_TEST *info = NULL;
#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
info = rsa->acvp_test;
#endif
/* (Steps 1a-1b) : Currently ignores the strength check */
if (!rsa_sp800_56b_validate_strength(nbits, -1))
@ -311,13 +338,12 @@ int rsa_sp800_56b_generate_key(RSA *rsa, int nbits, const BIGNUM *efixed,
} else {
e = (BIGNUM *)efixed;
}
/* (Step 1c) fixed exponent is checked later . */
/* (Step 1c) fixed exponent is checked later .*/
for (;;) {
/* (Step 2) Generate prime factors */
if (!rsa_fips186_4_gen_prob_primes(rsa, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL,
NULL, nbits, e, ctx, cb))
if (!rsa_fips186_4_gen_prob_primes(rsa, info, nbits, e, ctx,
cb))
goto err;
/* (Steps 3-5) Compute params d, n, dP, dQ, qInv */
ok = rsa_sp800_56b_derive_params_from_pq(rsa, nbits, e, ctx);

View File

@ -131,10 +131,63 @@ For legacy reasons a value of 3 is currently accepted but is deprecated.
=back
=head2 RSA key generation parameters for FIPS module testing
When generating RSA keys, the following additional key generation parameters may
be used for algorithm testing purposes only. Do not use these to generate
RSA keys for a production environment.
=over 4
=item "xp" (B<OSSL_PKEY_PARAM_RSA_TEST_XP>) <unsigned integer>
=item "xq" (B<OSSL_PKEY_PARAM_RSA_TEST_XQ>) <unsigned integer>
These 2 fields are normally randomly generated and are used to generate "p" and
"q".
=item "xp1" (B<OSSL_PKEY_PARAM_RSA_TEST_XP1>) <unsigned integer>
=item "xp2" (B<OSSL_PKEY_PARAM_RSA_TEST_XP2>) <unsigned integer>
=item "xq1" (B<OSSL_PKEY_PARAM_RSA_TEST_XQ1>) <unsigned integer>
=item "xq2" (B<OSSL_PKEY_PARAM_RSA_TEST_XQ2>) <unsigned integer>
These 4 fields are normally randomly generated. The prime factors "p1", "p2",
"q1" and "q2" are determined from these values.
=back
=head2 RSA key parameters for FIPS module testing
The following intermediate values can be retrieved only if the values
specified in L</"RSA key generation parameters for FIPS module testing"> are set.
These should not be accessed in a production environment.
=over 4
=item "p1" (B<OSSL_PKEY_PARAM_RSA_TEST_P1>) <unsigned integer>
=item "p2" (B<OSSL_PKEY_PARAM_RSA_TEST_P2>) <unsigned integer>
=item "q1" (B<OSSL_PKEY_PARAM_RSA_TEST_Q1>) <unsigned integer>
=item "q2" (B<OSSL_PKEY_PARAM_RSA_TEST_Q2>) <unsigned integer>
The auxiliary probable primes.
=back
=head1 CONFORMING TO
=over 4
=item FIPS186-4
Section B.3.6 Generation of Probable Primes with Conditions Based on
Auxiliary Probable Primes
=item RFC 8017, excluding RSA-PSS and RSA-OAEP
=for comment RSA-PSS, and probably also RSA-OAEP, need separate keytypes,

View File

@ -14,8 +14,8 @@
DH *dh_new_by_nid_with_libctx(OPENSSL_CTX *libctx, int nid);
DH *dh_new_with_libctx(OPENSSL_CTX *libctx);
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 dh_generate_public_key(BN_CTX *ctx, DH *dh, const BIGNUM *priv_key,
BIGNUM *pub_key);
int dh_get_named_group_uid_from_size(int pbits);

View File

@ -16,8 +16,8 @@
DSA *dsa_new_with_ctx(OPENSSL_CTX *libctx);
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 dsa_sign_int(int type, const unsigned char *dgst,
int dlen, unsigned char *sig, unsigned int *siglen, DSA *dsa);

View File

@ -10,8 +10,8 @@
#ifndef OSSL_INTERNAL_RSA_H
# define OSSL_INTERNAL_RSA_H
#include <openssl/core.h>
#include <openssl/rsa.h>
# include <openssl/core.h>
# include <openssl/rsa.h>
typedef struct rsa_pss_params_30_st {
int hash_algorithm_nid;
@ -93,4 +93,16 @@ extern const char *rsa_mp_factor_names[];
extern const char *rsa_mp_exp_names[];
extern const char *rsa_mp_coeff_names[];
# if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
int rsa_acvp_test_gen_params_new(OSSL_PARAM **dst, const OSSL_PARAM src[]);
void rsa_acvp_test_gen_params_free(OSSL_PARAM *dst);
int rsa_acvp_test_set_params(RSA *r, const OSSL_PARAM params[]);
int rsa_acvp_test_get_params(RSA *r, OSSL_PARAM params[]);
typedef struct rsa_acvp_test_st RSA_ACVP_TEST;
void rsa_acvp_test_free(RSA_ACVP_TEST *t);
# else
# define RSA_ACVP_TEST void
# endif
#endif

View File

@ -16,6 +16,7 @@
# include <openssl/dh.h> /* Uses Error codes from DH */
# include <openssl/params.h>
# include <openssl/param_build.h>
# include "internal/sizes.h"
/* Default value for gindex when canonical generation of g is not used */
# define FFC_UNVERIFIABLE_GINDEX -1
@ -24,17 +25,24 @@
# define FFC_PARAM_TYPE_DSA 0
# define FFC_PARAM_TYPE_DH 1
/*
* The mode used by functions that share code for both generation and
* verification. See ffc_params_FIPS186_4_gen_verify().
*/
#define FFC_PARAM_MODE_VERIFY 0
#define FFC_PARAM_MODE_GENERATE 1
/* Return codes for generation and validation of FFC parameters */
#define FFC_PARAMS_RET_STATUS_FAILED 0
#define FFC_PARAMS_RET_STATUS_SUCCESS 1
#define FFC_PARAM_RET_STATUS_FAILED 0
#define FFC_PARAM_RET_STATUS_SUCCESS 1
/* Returned if validating and g is only partially verifiable */
#define FFC_PARAMS_RET_STATUS_UNVERIFIABLE_G 2
#define FFC_PARAM_RET_STATUS_UNVERIFIABLE_G 2
/* Validation flags */
# define FFC_PARAMS_GENERATE 0x00
# define FFC_PARAMS_VALIDATE_PQ 0x01
# define FFC_PARAMS_VALIDATE_G 0x02
# define FFC_PARAMS_VALIDATE_ALL (FFC_PARAMS_VALIDATE_PQ | FFC_PARAMS_VALIDATE_G)
# define FFC_PARAM_FLAG_VALIDATE_PQ 0x01
# define FFC_PARAM_FLAG_VALIDATE_G 0x02
# define FFC_PARAM_FLAG_VALIDATE_ALL \
(FFC_PARAM_FLAG_VALIDATE_PQ | FFC_PARAM_FLAG_VALIDATE_G)
/*
* NB: These values must align with the equivalently named macros in
@ -94,6 +102,14 @@ typedef struct ffc_params_st {
*/
int gindex;
int h; /* loop counter for unverifiable g */
unsigned int flags; /* See FFC_PARAM_FLAG_VALIDATE_ALL */
/*
* The digest to use for generation or validation. If this value is NULL,
* then the digest is chosen using the value of N.
*/
const char *mdname;
const char *mdprops;
} FFC_PARAMS;
void ffc_params_init(FFC_PARAMS *params);
@ -107,6 +123,8 @@ int ffc_params_set_seed(FFC_PARAMS *params,
void ffc_params_set_gindex(FFC_PARAMS *params, int index);
void ffc_params_set_pcounter(FFC_PARAMS *params, int index);
void ffc_params_set_h(FFC_PARAMS *params, int index);
void ffc_params_set_flags(FFC_PARAMS *params, unsigned int flags);
int ffc_set_digest(FFC_PARAMS *params, const char *alg, const char *props);
int ffc_params_set_validate_params(FFC_PARAMS *params,
const unsigned char *seed, size_t seedlen,
@ -125,27 +143,22 @@ int ffc_params_print(BIO *bp, const FFC_PARAMS *ffc, int indent);
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);
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);
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 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 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_2_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);
int ffc_params_FIPS186_2_validate(OPENSSL_CTX *libctx, const FFC_PARAMS *params,
int type, int *res, BN_GENCB *cb);
int ffc_generate_private_key(BN_CTX *ctx, const FFC_PARAMS *params,
int N, int s, BIGNUM *priv);
@ -168,5 +181,7 @@ int ffc_set_group_pqg(FFC_PARAMS *ffc, const char *group_name);
int ffc_named_group_to_uid(const char *name);
const char *ffc_named_group_from_uid(int nid);
int ffc_set_group_pqg(FFC_PARAMS *ffc, const char *group_name);
const char *ffc_params_flags_to_name(int flags);
int ffc_params_flags_from_name(const char *name);
#endif /* OSSL_INTERNAL_FFC_H */

View File

@ -201,22 +201,30 @@ extern "C" {
#define OSSL_PKEY_PARAM_PRIV_KEY "priv"
/* Diffie-Hellman/DSA Parameters */
#define OSSL_PKEY_PARAM_FFC_P "p"
#define OSSL_PKEY_PARAM_FFC_G "g"
#define OSSL_PKEY_PARAM_FFC_Q "q"
#define OSSL_PKEY_PARAM_FFC_GINDEX "gindex"
#define OSSL_PKEY_PARAM_FFC_PCOUNTER "pcounter"
#define OSSL_PKEY_PARAM_FFC_SEED "seed"
#define OSSL_PKEY_PARAM_FFC_COFACTOR "j"
#define OSSL_PKEY_PARAM_FFC_H "hindex"
#define OSSL_PKEY_PARAM_FFC_P "p"
#define OSSL_PKEY_PARAM_FFC_G "g"
#define OSSL_PKEY_PARAM_FFC_Q "q"
#define OSSL_PKEY_PARAM_FFC_GINDEX "gindex"
#define OSSL_PKEY_PARAM_FFC_PCOUNTER "pcounter"
#define OSSL_PKEY_PARAM_FFC_SEED "seed"
#define OSSL_PKEY_PARAM_FFC_COFACTOR "j"
#define OSSL_PKEY_PARAM_FFC_H "hindex"
#define OSSL_PKEY_PARAM_FFC_VALIDATE_TYPE "valid-type"
/* Diffie-Hellman/DSA Parameters parameter validation types */
#define OSSL_FFC_PARAM_VALIDATE_PQ "validate-pq"
#define OSSL_FFC_PARAM_VALIDATE_G "validate-g"
#define OSSL_FFC_PARAM_VALIDATE_PQG "validate-pqg"
/* Diffie-Hellman params */
#define OSSL_PKEY_PARAM_DH_GROUP "group"
#define OSSL_PKEY_PARAM_DH_GENERATOR "safeprime-generator"
#define OSSL_PKEY_PARAM_DH_PRIV_LEN "priv_len"
#define OSSL_PKEY_PARAM_DH_GROUP "group"
#define OSSL_PKEY_PARAM_DH_GENERATOR "safeprime-generator"
#define OSSL_PKEY_PARAM_DH_PRIV_LEN "priv_len"
/* Elliptic Curve Domain Parameters */
#define OSSL_PKEY_PARAM_EC_NAME "curve-name"
#define OSSL_PKEY_PARAM_EC_PUB_X "qx"
#define OSSL_PKEY_PARAM_EC_PUB_Y "qy"
/* Elliptic Curve Key Parameters */
#define OSSL_PKEY_PARAM_USE_COFACTOR_FLAG "use-cofactor-flag"
@ -334,7 +342,6 @@ extern "C" {
#define OSSL_SIGNATURE_PARAM_MGF1_PROPERTIES \
OSSL_PKEY_PARAM_MGF1_PROPERTIES
#define OSSL_SIGNATURE_PARAM_DIGEST_SIZE OSSL_PKEY_PARAM_DIGEST_SIZE
#define OSSL_SIGNATURE_PARAM_KAT "kat"
/* Asym cipher parameters */
#define OSSL_ASYM_CIPHER_PARAM_PAD_MODE OSSL_PKEY_PARAM_PAD_MODE
@ -364,6 +371,19 @@ extern "C" {
#define OSSL_GEN_PARAM_POTENTIAL "potential" /* integer */
#define OSSL_GEN_PARAM_ITERATION "iteration" /* integer */
/* ACVP Test parameters : These should not be used normally */
#define OSSL_PKEY_PARAM_RSA_TEST_XP1 "xp1"
#define OSSL_PKEY_PARAM_RSA_TEST_XP2 "xp2"
#define OSSL_PKEY_PARAM_RSA_TEST_XP "xp"
#define OSSL_PKEY_PARAM_RSA_TEST_XQ1 "xq1"
#define OSSL_PKEY_PARAM_RSA_TEST_XQ2 "xq2"
#define OSSL_PKEY_PARAM_RSA_TEST_XQ "xq"
#define OSSL_PKEY_PARAM_RSA_TEST_P1 "p1"
#define OSSL_PKEY_PARAM_RSA_TEST_P2 "p2"
#define OSSL_PKEY_PARAM_RSA_TEST_Q1 "q1"
#define OSSL_PKEY_PARAM_RSA_TEST_Q2 "q2"
#define OSSL_SIGNATURE_PARAM_KAT "kat"
# ifdef __cplusplus
}
# endif

View File

@ -59,7 +59,6 @@ struct dh_gen_ctx {
int group_nid;
size_t pbits;
size_t qbits;
EVP_MD *md;
unsigned char *seed; /* optional FIPS186-4 param for testing */
size_t seedlen;
int gindex; /* optional FIPS186-4 generator index (ignored if -1) */
@ -69,6 +68,8 @@ struct dh_gen_ctx {
int hindex;
int priv_len;
const char *mdname;
const char *mdprops;
OSSL_CALLBACK *cb;
void *cbarg;
};
@ -411,7 +412,7 @@ static void *dh_gen_init(void *provctx, int selection)
gctx->libctx = libctx;
gctx->pbits = 2048;
gctx->qbits = 224;
gctx->md = NULL;
gctx->mdname = NULL;
gctx->gen_type = DH_PARAMGEN_TYPE_FIPS_186_4;
gctx->gindex = -1;
gctx->hindex = 0;
@ -498,20 +499,15 @@ static int dh_gen_set_params(void *genctx, const OSSL_PARAM params[])
return 0;
p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_DIGEST);
if (p != NULL) {
const OSSL_PARAM *p1;
char mdprops[OSSL_MAX_PROPQUERY_SIZE] = { '\0' };
char *str = mdprops;
if (p->data_type != OSSL_PARAM_UTF8_STRING)
return 0;
p1 = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_DIGEST_PROPS);
if (p1 != NULL
&& !OSSL_PARAM_get_utf8_string(p1, &str, sizeof(mdprops)))
return 0;
EVP_MD_free(gctx->md);
gctx->md = EVP_MD_fetch(gctx->libctx, p->data, mdprops);
if (gctx->md == NULL)
gctx->mdname = p->data;
}
p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_DIGEST_PROPS);
if (p != NULL) {
if (p->data_type != OSSL_PARAM_UTF8_STRING)
return 0;
gctx->mdprops = p->data;
}
p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DH_PRIV_LEN);
if (p != NULL && !OSSL_PARAM_get_int(p, &gctx->priv_len))
@ -592,6 +588,10 @@ static void *dh_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
} else if (gctx->hindex != 0) {
ffc_params_set_h(ffc, gctx->hindex);
}
if (gctx->mdname != NULL) {
if (!ffc_set_digest(ffc, gctx->mdname, gctx->mdprops))
goto end;
}
gctx->cb = osslcb;
gctx->cbarg = cbarg;
gencb = BN_GENCB_new();
@ -609,7 +609,7 @@ static void *dh_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
gctx->generator, gencb);
else
ret = dh_generate_ffc_parameters(dh, gctx->gen_type, gctx->pbits,
gctx->qbits, gctx->md, gencb);
gctx->qbits, gencb);
if (ret <= 0)
goto end;
}
@ -641,7 +641,6 @@ static void dh_gen_cleanup(void *genctx)
return;
OPENSSL_clear_free(gctx->seed, gctx->seedlen);
EVP_MD_free(gctx->md);
OPENSSL_free(gctx);
}

View File

@ -56,13 +56,14 @@ struct dsa_gen_ctx {
/* All these parameters are used for parameter generation only */
size_t pbits;
size_t qbits;
EVP_MD *md;
unsigned char *seed; /* optional FIPS186-4 param for testing */
size_t seedlen;
int gindex; /* optional FIPS186-4 generator index (ignored if -1) */
int gen_type; /* DSA_PARAMGEN_TYPE_FIPS_186_2 or DSA_PARAMGEN_TYPE_FIPS_186_4 */
int pcounter;
int hindex;
const char *mdname;
const char *mdprops;
OSSL_CALLBACK *cb;
void *cbarg;
};
@ -364,7 +365,6 @@ static void *dsa_gen_init(void *provctx, int selection)
gctx->libctx = libctx;
gctx->pbits = 2048;
gctx->qbits = 224;
gctx->md = NULL;
gctx->gen_type = DSA_PARAMGEN_TYPE_FIPS_186_4;
gctx->gindex = -1;
gctx->pcounter = -1;
@ -440,21 +440,15 @@ static int dsa_gen_set_params(void *genctx, const OSSL_PARAM params[])
return 0;
p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_DIGEST);
if (p != NULL) {
const OSSL_PARAM *p1;
char mdprops[OSSL_MAX_PROPQUERY_SIZE] = { '\0' };
char *str = mdprops;
if (p->data_type != OSSL_PARAM_UTF8_STRING)
return 0;
p1 = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_DIGEST_PROPS);
if (p1 != NULL) {
if (!OSSL_PARAM_get_utf8_string(p1, &str, sizeof(mdprops)))
return 0;
}
EVP_MD_free(gctx->md);
gctx->md = EVP_MD_fetch(gctx->libctx, p->data, mdprops);
if (gctx->md == NULL)
gctx->mdname = p->data;
}
p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_DIGEST_PROPS);
if (p != NULL) {
if (p->data_type != OSSL_PARAM_UTF8_STRING)
return 0;
gctx->mdprops = p->data;
}
return 1;
}
@ -523,10 +517,14 @@ static void *dsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
} else if (gctx->hindex != 0) {
ffc_params_set_h(ffc, gctx->hindex);
}
if (gctx->mdname != NULL) {
if (!ffc_set_digest(ffc, gctx->mdname, gctx->mdprops))
goto end;
}
if ((gctx->selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) {
if (dsa_generate_ffc_parameters(dsa, gctx->gen_type,
gctx->pbits, gctx->qbits, gctx->md,
gctx->pbits, gctx->qbits,
gencb) <= 0)
goto end;
}
@ -556,7 +554,6 @@ static void dsa_gen_cleanup(void *genctx)
return;
OPENSSL_clear_free(gctx->seed, gctx->seedlen);
EVP_MD_free(gctx->md);
OPENSSL_free(gctx);
}

View File

@ -110,6 +110,7 @@ int key_to_params(const EC_KEY *eckey, OSSL_PARAM_BLD *tmpl,
OSSL_PARAM params[], int include_private,
unsigned char **pub_key)
{
BIGNUM *x = NULL, *y = NULL;
const BIGNUM *priv_key = NULL;
const EC_POINT *pub_point = NULL;
const EC_GROUP *ecg = NULL;
@ -125,6 +126,7 @@ int key_to_params(const EC_KEY *eckey, OSSL_PARAM_BLD *tmpl,
pub_point = EC_KEY_get0_public_key(eckey);
if (pub_point != NULL) {
OSSL_PARAM *p = NULL, *px = NULL, *py = NULL;
/*
* EC_POINT_point2buf() can generate random numbers in some
* implementations so we need to ensure we use the correct libctx.
@ -133,14 +135,41 @@ int key_to_params(const EC_KEY *eckey, OSSL_PARAM_BLD *tmpl,
if (bnctx == NULL)
goto err;
/* convert pub_point to a octet string according to the SECG standard */
if ((pub_key_len = EC_POINT_point2buf(ecg, pub_point,
POINT_CONVERSION_COMPRESSED,
pub_key, bnctx)) == 0
|| !ossl_param_build_set_octet_string(tmpl, params,
OSSL_PKEY_PARAM_PUB_KEY,
*pub_key, pub_key_len))
goto err;
/* If we are doing a get then check first before decoding the point */
if (tmpl == NULL) {
p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_PUB_KEY);
px = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_EC_PUB_X);
py = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_EC_PUB_Y);
}
if (p != NULL || tmpl != NULL) {
/* convert pub_point to a octet string according to the SECG standard */
if ((pub_key_len = EC_POINT_point2buf(ecg, pub_point,
POINT_CONVERSION_COMPRESSED,
pub_key, bnctx)) == 0
|| !ossl_param_build_set_octet_string(tmpl, p,
OSSL_PKEY_PARAM_PUB_KEY,
*pub_key, pub_key_len))
goto err;
}
if (px != NULL || py != NULL) {
if (px != NULL)
x = BN_CTX_get(bnctx);
if (py != NULL)
y = BN_CTX_get(bnctx);
if (!EC_POINT_get_affine_coordinates(ecg, pub_point, x, y, bnctx))
goto err;
if (px != NULL
&& !ossl_param_build_set_bn(tmpl, px,
OSSL_PKEY_PARAM_EC_PUB_X, x))
goto err;
if (py != NULL
&& !ossl_param_build_set_bn(tmpl, py,
OSSL_PKEY_PARAM_EC_PUB_Y, y))
goto err;
}
}
if (priv_key != NULL && include_private) {
@ -532,6 +561,8 @@ static const OSSL_PARAM ec_known_gettable_params[] = {
OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, NULL, 0),
EC_IMEXPORTABLE_DOM_PARAMETERS,
EC_IMEXPORTABLE_PUBLIC_KEY,
OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_PUB_X, NULL, 0),
OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_PUB_Y, NULL, 0),
EC_IMEXPORTABLE_PRIVATE_KEY,
EC_IMEXPORTABLE_OTHER_PARAMETERS,
OSSL_PARAM_END

View File

@ -380,6 +380,11 @@ struct rsa_gen_ctx {
/* For generation callback */
OSSL_CALLBACK *cb;
void *cbarg;
#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
/* ACVP test parameters */
OSSL_PARAM *acvp_test_params;
#endif
};
static int rsa_gencb(int p, int n, BN_GENCB *cb)
@ -389,7 +394,6 @@ static int rsa_gencb(int p, int n, BN_GENCB *cb)
params[0] = OSSL_PARAM_construct_int(OSSL_GEN_PARAM_POTENTIAL, &p);
params[1] = OSSL_PARAM_construct_int(OSSL_GEN_PARAM_ITERATION, &n);
return gctx->cb(params, gctx->cbarg);
}
@ -451,6 +455,11 @@ static int rsa_gen_set_params(void *genctx, const OSSL_PARAM params[])
&& !pss_params_fromdata(&gctx->pss_params, params, gctx->rsa_type,
gctx->libctx))
return 0;
#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
/* Any ACVP test related parameters are copied into a params[] */
if (!rsa_acvp_test_gen_params_new(&gctx->acvp_test_params, params))
return 0;
#endif
return 1;
}
@ -525,6 +534,13 @@ static void *rsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
if (gencb != NULL)
BN_GENCB_set(gencb, rsa_gencb, genctx);
#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
if (gctx->acvp_test_params != NULL) {
if (!rsa_acvp_test_set_params(rsa_tmp, gctx->acvp_test_params))
goto err;
}
#endif
if (!RSA_generate_multi_prime_key(rsa_tmp,
(int)gctx->nbits, (int)gctx->primes,
gctx->pub_exp, gencb))
@ -551,7 +567,10 @@ static void rsa_gen_cleanup(void *genctx)
if (gctx == NULL)
return;
#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
rsa_acvp_test_gen_params_free(gctx->acvp_test_params);
gctx->acvp_test_params = NULL;
#endif
BN_clear_free(gctx->pub_exp);
OPENSSL_free(gctx);
}

View File

@ -3,7 +3,6 @@
$DSA_GOAL=../../libimplementations.a
$EC_GOAL=../../libimplementations.a
$ECDSA_GOAL=../../libimplementations.a
IF[{- !$disabled{dsa} -}]
SOURCE[$DSA_GOAL]=dsa.c
@ -11,7 +10,8 @@ ENDIF
IF[{- !$disabled{ec} -}]
SOURCE[$EC_GOAL]=eddsa.c
SOURCE[$ECDSA_GOAL]=ecdsa.c
SOURCE[../../libfips.a]=ecdsa.c
SOURCE[../../libnonfips.a]=ecdsa.c
ENDIF
SOURCE[../../libfips.a]=rsa.c

View File

@ -338,13 +338,17 @@ int dsa_digest_verify_final(void *vpdsactx, const unsigned char *sig,
static void dsa_freectx(void *vpdsactx)
{
PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
PROV_DSA_CTX *ctx = (PROV_DSA_CTX *)vpdsactx;
DSA_free(pdsactx->dsa);
EVP_MD_CTX_free(pdsactx->mdctx);
EVP_MD_free(pdsactx->md);
OPENSSL_free(pdsactx);
OPENSSL_free(ctx->propq);
EVP_MD_CTX_free(ctx->mdctx);
EVP_MD_free(ctx->md);
ctx->propq = NULL;
ctx->mdctx = NULL;
ctx->md = NULL;
ctx->mdsize = 0;
DSA_free(ctx->dsa);
OPENSSL_free(ctx);
}
static void *dsa_dupctx(void *vpdsactx)

View File

@ -72,14 +72,6 @@ typedef struct {
EVP_MD *md;
EVP_MD_CTX *mdctx;
/*
* This indicates that KAT (CAVS) test is running. Externally an app will
* override the random callback such that the generated private key and k
* are known.
* Normal operation will loop to choose a new k if the signature is not
* valid - but for this mode of operation it forces a failure instead.
*/
unsigned int kattest;
/*
* Internally used to cache the results of calling the EC group
* sign_setup() methods which are then passed to the sign operation.
@ -89,6 +81,16 @@ typedef struct {
*/
BIGNUM *kinv;
BIGNUM *r;
#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
/*
* This indicates that KAT (CAVS) test is running. Externally an app will
* override the random callback such that the generated private key and k
* are known.
* Normal operation will loop to choose a new k if the signature is not
* valid - but for this mode of operation it forces a failure instead.
*/
unsigned int kattest;
#endif
} PROV_ECDSA_CTX;
static void *ecdsa_newctx(void *provctx, const char *propq)
@ -131,8 +133,10 @@ static int ecdsa_sign(void *vctx, unsigned char *sig, size_t *siglen,
return 1;
}
#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
if (ctx->kattest && !ECDSA_sign_setup(ctx->ec, NULL, &ctx->kinv, &ctx->r))
return 0;
#endif
if (sigsize < (size_t)ecsize)
return 0;
@ -201,8 +205,10 @@ static int get_md_nid(const EVP_MD *md)
static void free_md(PROV_ECDSA_CTX *ctx)
{
OPENSSL_free(ctx->propq);
EVP_MD_CTX_free(ctx->mdctx);
EVP_MD_free(ctx->md);
ctx->propq = NULL;
ctx->mdctx = NULL;
ctx->md = NULL;
ctx->mdsize = 0;
@ -414,10 +420,11 @@ static int ecdsa_set_ctx_params(void *vctx, const OSSL_PARAM params[])
*/
return 1;
}
#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_KAT);
if (p != NULL && !OSSL_PARAM_get_uint(p, &ctx->kattest))
return 0;
#endif
p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE);
if (p != NULL && !OSSL_PARAM_get_size_t(p, &ctx->mdsize))

View File

@ -594,13 +594,15 @@ static int rsa_verify_recover(void *vprsactx,
}
*routlen = ret;
if (routsize < (size_t)ret) {
ERR_raise_data(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL,
"buffer size is %d, should be %d",
routsize, ret);
return 0;
if (rout != prsactx->tbuf) {
if (routsize < (size_t)ret) {
ERR_raise_data(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL,
"buffer size is %d, should be %d",
routsize, ret);
return 0;
}
memcpy(rout, prsactx->tbuf, ret);
}
memcpy(rout, prsactx->tbuf, ret);
break;
case RSA_PKCS1_PADDING:
@ -655,7 +657,10 @@ static int rsa_verify(void *vprsactx, const unsigned char *sig, size_t siglen,
}
return 1;
case RSA_X931_PADDING:
if (rsa_verify_recover(prsactx, NULL, &rslen, 0, sig, siglen) <= 0)
if (!setup_tbuf(prsactx))
return 0;
if (rsa_verify_recover(prsactx, prsactx->tbuf, &rslen, 0,
sig, siglen) <= 0)
return 0;
break;
case RSA_PKCS1_PSS_PADDING:

1367
test/acvp_test.c Normal file

File diff suppressed because it is too large Load Diff

1984
test/acvp_test.inc Normal file

File diff suppressed because it is too large Load Diff

View File

@ -36,6 +36,7 @@ IF[{- !$disabled{tests} -}]
destest mdc2test \
enginetest exptest \
evp_pkey_provided_test evp_test evp_extra_test evp_fetch_prov_test \
acvp_test \
v3nametest v3ext \
crltest danetest bad_dtls_test lhash_test sparse_array_test \
conf_include_test params_api_test params_conversion_test \
@ -145,6 +146,12 @@ IF[{- !$disabled{tests} -}]
INCLUDE[evp_pkey_provided_test]=../include ../apps/include
DEPEND[evp_pkey_provided_test]=../libcrypto.a libtestutil.a
IF[{- !$disabled{acvp-tests} -}]
SOURCE[acvp_test]=acvp_test.c
INCLUDE[acvp_test]=../include ../apps/include
DEPEND[acvp_test]=../libcrypto.a libtestutil.a
ENDIF
IF[{- !$disabled{'deprecated-3.0'} -}]
PROGRAMS{noinst}=igetest bftest casttest

View File

@ -189,42 +189,40 @@ static int ffc_params_validate_g_unverified_test(void)
ffc_params_set0_pqg(&params, p, q, NULL);
p = NULL;
q = NULL;
if (!TEST_false(ffc_params_FIPS186_4_validate(&params, FFC_PARAM_TYPE_DSA,
EVP_sha256(),
FFC_PARAMS_VALIDATE_G, &res,
NULL)))
ffc_params_set_flags(&params, FFC_PARAM_FLAG_VALIDATE_G);
ffc_set_digest(&params, "SHA256", NULL);
if (!TEST_false(ffc_params_FIPS186_4_validate(NULL, &params,
FFC_PARAM_TYPE_DSA,
&res, NULL)))
goto err;
ffc_params_set0_pqg(&params, p, q, g);
g = NULL;
if (!TEST_true(ffc_params_FIPS186_4_validate(&params, FFC_PARAM_TYPE_DSA,
EVP_sha256(),
FFC_PARAMS_VALIDATE_G, &res,
NULL)))
if (!TEST_true(ffc_params_FIPS186_4_validate(NULL, &params,
FFC_PARAM_TYPE_DSA,
&res, NULL)))
goto err;
/* incorrect g */
BN_add_word(g1, 1);
if (!TEST_false(ffc_params_FIPS186_4_validate(&params, FFC_PARAM_TYPE_DSA,
EVP_sha256(),
FFC_PARAMS_VALIDATE_G, &res,
NULL)))
if (!TEST_false(ffc_params_FIPS186_4_validate(NULL, &params,
FFC_PARAM_TYPE_DSA,
&res, NULL)))
goto err;
/* fail if g < 2 */
BN_set_word(g1, 1);
if (!TEST_false(ffc_params_FIPS186_4_validate(&params, FFC_PARAM_TYPE_DSA,
EVP_sha256(),
FFC_PARAMS_VALIDATE_G, &res,
NULL)))
if (!TEST_false(ffc_params_FIPS186_4_validate(NULL, &params,
FFC_PARAM_TYPE_DSA,
&res, NULL)))
goto err;
BN_copy(g1, p1);
/* Fail if g >= p */
if (!TEST_false(ffc_params_FIPS186_4_validate(&params, FFC_PARAM_TYPE_DSA,
EVP_sha256(),
FFC_PARAMS_VALIDATE_G, &res,
NULL)))
if (!TEST_false(ffc_params_FIPS186_4_validate(NULL, &params,
FFC_PARAM_TYPE_DSA,
&res, NULL)))
goto err;
ret = 1;
@ -255,10 +253,12 @@ static int ffc_params_validate_pq_test(void)
/* No p */
ffc_params_set0_pqg(&params, NULL, q, NULL);
q = NULL;
if (!TEST_false(ffc_params_FIPS186_4_validate(&params, FFC_PARAM_TYPE_DSA,
EVP_sha224(),
FFC_PARAMS_VALIDATE_PQ, &res,
NULL)))
ffc_params_set_flags(&params, FFC_PARAM_FLAG_VALIDATE_PQ);
ffc_set_digest(&params, "SHA224", NULL);
if (!TEST_false(ffc_params_FIPS186_4_validate(NULL, &params,
FFC_PARAM_TYPE_DSA,
&res, NULL)))
goto err;
/* Test valid case */
@ -267,40 +267,36 @@ static int ffc_params_validate_pq_test(void)
ffc_params_set_validate_params(&params, dsa_2048_224_sha224_seed,
sizeof(dsa_2048_224_sha224_seed),
dsa_2048_224_sha224_counter);
if (!TEST_true(ffc_params_FIPS186_4_validate(&params, FFC_PARAM_TYPE_DSA,
EVP_sha224(),
FFC_PARAMS_VALIDATE_PQ, &res,
NULL)))
if (!TEST_true(ffc_params_FIPS186_4_validate(NULL, &params,
FFC_PARAM_TYPE_DSA,
&res, NULL)))
goto err;
/* Bad counter - so p is not prime */
ffc_params_set_validate_params(&params, dsa_2048_224_sha224_seed,
sizeof(dsa_2048_224_sha224_seed),
1);
if (!TEST_false(ffc_params_FIPS186_4_validate(&params, FFC_PARAM_TYPE_DSA,
EVP_sha224(),
FFC_PARAMS_VALIDATE_PQ, &res,
NULL)))
if (!TEST_false(ffc_params_FIPS186_4_validate(NULL, &params,
FFC_PARAM_TYPE_DSA,
&res, NULL)))
goto err;
/* seedlen smaller than N */
ffc_params_set_validate_params(&params, dsa_2048_224_sha224_seed,
sizeof(dsa_2048_224_sha224_seed)-1,
dsa_2048_224_sha224_counter);
if (!TEST_false(ffc_params_FIPS186_4_validate(&params, FFC_PARAM_TYPE_DSA,
EVP_sha224(),
FFC_PARAMS_VALIDATE_PQ, &res,
NULL)))
if (!TEST_false(ffc_params_FIPS186_4_validate(NULL, &params,
FFC_PARAM_TYPE_DSA,
&res, NULL)))
goto err;
/* Provided seed doesnt produce a valid prime q */
ffc_params_set_validate_params(&params, dsa_2048_224_sha224_bad_seed,
sizeof(dsa_2048_224_sha224_bad_seed),
dsa_2048_224_sha224_counter);
if (!TEST_false(ffc_params_FIPS186_4_validate(&params, FFC_PARAM_TYPE_DSA,
EVP_sha224(),
FFC_PARAMS_VALIDATE_PQ, &res,
NULL)))
if (!TEST_false(ffc_params_FIPS186_4_validate(NULL, &params,
FFC_PARAM_TYPE_DSA,
&res, NULL)))
goto err;
if (!TEST_ptr(p = BN_bin2bn(dsa_3072_256_sha512_p,
@ -314,21 +310,20 @@ static int ffc_params_validate_pq_test(void)
ffc_params_set0_pqg(&params, p, q, NULL);
p = q = NULL;
ffc_set_digest(&params, "SHA512", NULL);
ffc_params_set_validate_params(&params, dsa_3072_256_sha512_seed,
sizeof(dsa_3072_256_sha512_seed),
dsa_3072_256_sha512_counter);
/* Q doesn't div P-1 */
if (!TEST_false(ffc_params_FIPS186_4_validate(&params, FFC_PARAM_TYPE_DSA,
EVP_sha512(),
FFC_PARAMS_VALIDATE_PQ, &res,
NULL)))
if (!TEST_false(ffc_params_FIPS186_4_validate(NULL, &params,
FFC_PARAM_TYPE_DSA,
&res, NULL)))
goto err;
/* Bad L/N for FIPS DH */
if (!TEST_false(ffc_params_FIPS186_4_validate(&params, FFC_PARAM_TYPE_DH,
EVP_sha512(),
FFC_PARAMS_VALIDATE_PQ, &res,
NULL)))
if (!TEST_false(ffc_params_FIPS186_4_validate(NULL, &params,
FFC_PARAM_TYPE_DH,
&res, NULL)))
goto err;
ret = 1;
@ -347,13 +342,13 @@ static int ffc_params_gen_test(void)
FFC_PARAMS params;
ffc_params_init(&params);
if (!TEST_true(ffc_params_FIPS186_4_generate(NULL, &params, FFC_PARAM_TYPE_DH,
2048, 256, NULL, &res, NULL)))
if (!TEST_true(ffc_params_FIPS186_4_generate(NULL, &params,
FFC_PARAM_TYPE_DH,
2048, 256, &res, NULL)))
goto err;
if (!TEST_true(ffc_params_FIPS186_4_validate(&params, FFC_PARAM_TYPE_DH,
NULL,
FFC_PARAMS_VALIDATE_ALL, &res,
NULL)))
if (!TEST_true(ffc_params_FIPS186_4_validate(NULL, &params,
FFC_PARAM_TYPE_DH,
&res, NULL)))
goto err;
ret = 1;
@ -369,13 +364,13 @@ static int ffc_params_gen_canonicalg_test(void)
ffc_params_init(&params);
params.gindex = 1;
if (!TEST_true(ffc_params_FIPS186_4_generate(NULL, &params, FFC_PARAM_TYPE_DH,
2048, 256, NULL, &res, NULL)))
if (!TEST_true(ffc_params_FIPS186_4_generate(NULL, &params,
FFC_PARAM_TYPE_DH,
2048, 256, &res, NULL)))
goto err;
if (!TEST_true(ffc_params_FIPS186_4_validate(&params, FFC_PARAM_TYPE_DH,
NULL,
FFC_PARAMS_VALIDATE_ALL, &res,
NULL)))
if (!TEST_true(ffc_params_FIPS186_4_validate(NULL, &params,
FFC_PARAM_TYPE_DH,
&res, NULL)))
goto err;
if (!TEST_true(ffc_params_print(bio_out, &params, 4)))
@ -396,19 +391,18 @@ static int ffc_params_fips186_2_gen_validate_test(void)
ffc_params_init(&params);
if (!TEST_ptr(bn = BN_new()))
goto err;
if (!TEST_true(ffc_params_FIPS186_2_generate(NULL, &params, FFC_PARAM_TYPE_DH,
1024, 160, NULL, &res, NULL)))
if (!TEST_true(ffc_params_FIPS186_2_generate(NULL, &params,
FFC_PARAM_TYPE_DH,
1024, 160, &res, NULL)))
goto err;
if (!TEST_true(ffc_params_FIPS186_2_validate(&params, FFC_PARAM_TYPE_DH,
NULL,
FFC_PARAMS_VALIDATE_ALL, &res,
NULL)))
if (!TEST_true(ffc_params_FIPS186_2_validate(NULL, &params,
FFC_PARAM_TYPE_DH,
&res, NULL)))
goto err;
/* FIPS 186-4 L,N pair test will fail for DH */
if (!TEST_false(ffc_params_FIPS186_4_validate(&params, FFC_PARAM_TYPE_DH,
NULL,
FFC_PARAMS_VALIDATE_ALL, &res,
NULL)))
if (!TEST_false(ffc_params_FIPS186_4_validate(NULL, &params,
FFC_PARAM_TYPE_DH,
&res, NULL)))
goto err;
if (!TEST_int_eq(res, FFC_CHECK_BAD_LN_PAIR))
goto err;
@ -417,20 +411,19 @@ static int ffc_params_fips186_2_gen_validate_test(void)
* The fips186-2 generation should produce a different q compared to
* fips 186-4 given the same seed value. So validation of q will fail.
*/
if (!TEST_false(ffc_params_FIPS186_4_validate(&params, FFC_PARAM_TYPE_DSA,
NULL,
FFC_PARAMS_VALIDATE_ALL, &res,
NULL)))
if (!TEST_false(ffc_params_FIPS186_4_validate(NULL, &params,
FFC_PARAM_TYPE_DSA,
&res, NULL)))
goto err;
/* As the params are randomly generated the error is one of the following */
if (!TEST_true(res == FFC_CHECK_Q_MISMATCH || res == FFC_CHECK_Q_NOT_PRIME))
goto err;
ffc_params_set_flags(&params, FFC_PARAM_FLAG_VALIDATE_G);
/* Partially valid g test will still pass */
if (!TEST_int_eq(ffc_params_FIPS186_4_validate(&params, FFC_PARAM_TYPE_DSA,
NULL,
FFC_PARAMS_VALIDATE_G, &res,
NULL), 2))
if (!TEST_int_eq(ffc_params_FIPS186_4_validate(NULL, &params,
FFC_PARAM_TYPE_DSA,
&res, NULL), 2))
goto err;
if (!TEST_true(ffc_params_print(bio_out, &params, 4)))

View File

@ -0,0 +1,41 @@
#! /usr/bin/env perl
# 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
use strict;
use warnings;
use OpenSSL::Test qw(:DEFAULT bldtop_dir srctop_dir srctop_file bldtop_file);
use OpenSSL::Test::Utils;
BEGIN {
setup("test_acvp");
}
my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0);
plan skip_all => "ACVP is not supported by this test"
if $no_fips || disabled("acvp_tests");
use lib srctop_dir('Configurations');
use lib bldtop_dir('.');
use platform;
my $infile = bldtop_file('providers', platform->dso('fips'));
plan tests => 2;
ok(run(app(['openssl', 'fipsinstall',
'-out', bldtop_file('providers', 'fipsmodule.cnf'),
'-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
'-macopt', 'digest:SHA256', '-macopt', 'hexkey:00',
'-section_name', 'fips_sect'])),
"fipsinstall");
ok(run(test(["acvp_test", "-config", srctop_file("test","fips.cnf")])),
"running acvp_test");

View File

@ -33,63 +33,6 @@ int setup_tests(void)
static const unsigned char cav_e[] = {
0x01,0x00,0x01
};
static const unsigned char cav_Xp[] = {
0xcf,0x72,0x1b,0x9a,0xfd,0x0d,0x22,0x1a,0x74,0x50,0x97,0x22,0x76,0xd8,0xc0,
0xc2,0xfd,0x08,0x81,0x05,0xdd,0x18,0x21,0x99,0x96,0xd6,0x5c,0x79,0xe3,0x02,
0x81,0xd7,0x0e,0x3f,0x3b,0x34,0xda,0x61,0xc9,0x2d,0x84,0x86,0x62,0x1e,0x3d,
0x5d,0xbf,0x92,0x2e,0xcd,0x35,0x3d,0x6e,0xb9,0x59,0x16,0xc9,0x82,0x50,0x41,
0x30,0x45,0x67,0xaa,0xb7,0xbe,0xec,0xea,0x4b,0x9e,0xa0,0xc3,0x05,0xb3,0x88,
0xd4,0x4c,0xac,0xeb,0xe4,0x03,0xc6,0xca,0xcb,0xd9,0xd3,0x4e,0xf6,0x7f,0x2c,
0x27,0x1e,0x08,0x6c,0xc2,0xd6,0x45,0x1f,0x84,0xe4,0x3c,0x97,0x19,0xde,0xb8,
0x55,0xaf,0x0e,0xcf,0x9e,0xb0,0x9c,0x20,0xd3,0x1f,0xa8,0xd7,0x52,0xc2,0x95,
0x1c,0x80,0x15,0x42,0x4d,0x4f,0x19,0x16
};
static const unsigned char cav_Xp1[] = {
0xac,0x5f,0x7f,0x6e,0x33,0x3e,0x97,0x3a,0xb3,0x17,0x44,0xa9,0x0f,0x7a,0x54,
0x70,0x27,0x06,0x93,0xd5,0x49,0xde,0x91,0x83,0xbc,0x8a,0x7b,0x95
};
static const unsigned char cav_Xp2[] = {
0x0b,0xf6,0xe8,0x79,0x5a,0x81,0xae,0x90,0x1d,0xa4,0x38,0x74,0x9c,0x0e,0x6f,
0xe0,0x03,0xcf,0xc4,0x53,0x16,0x32,0x17,0xf7,0x09,0x5f,0xd9
};
static const unsigned char cav_Xq[] = {
0xfe,0xab,0xf2,0x7c,0x16,0x4a,0xf0,0x8d,0x31,0xc6,0x0a,0x82,0xe2,0xae,0xbb,
0x03,0x7e,0x7b,0x20,0x4e,0x64,0xb0,0x16,0xad,0x3c,0x01,0x1a,0xd3,0x54,0xbf,
0x2b,0xa4,0x02,0x9e,0xc3,0x0d,0x60,0x3d,0x1f,0xb9,0xc0,0x0d,0xe6,0x97,0x68,
0xbb,0x8c,0x81,0xd5,0xc1,0x54,0x96,0x0f,0x99,0xf0,0xa8,0xa2,0xf3,0xc6,0x8e,
0xec,0xbc,0x31,0x17,0x70,0x98,0x24,0xa3,0x36,0x51,0xa8,0x54,0xbd,0x9a,0x89,
0x99,0x6e,0x57,0x5e,0xd0,0x39,0x86,0xc3,0xa3,0x1b,0xc7,0xcf,0xc4,0x4f,0x47,
0x25,0x9e,0x2c,0x79,0xe1,0x2c,0xcc,0xe4,0x63,0xf4,0x02,0x84,0xf8,0xf6,0xa1,
0x5c,0x93,0x14,0xf2,0x68,0x5f,0x3a,0x90,0x2f,0x4e,0x5e,0xf9,0x16,0x05,0xcf,
0x21,0x63,0xca,0xfa,0xb0,0x08,0x02,0xc0
};
static const unsigned char cav_Xq1[] = {
0x9b,0x02,0xd4,0xba,0xf0,0xaa,0x14,0x99,0x6d,0xc0,0xb7,0xa5,0xe1,0xd3,0x70,
0xb6,0x5a,0xa2,0x9b,0x59,0xd5,0x8c,0x1e,0x9f,0x3f,0x9a,0xde,0xeb,0x9e,0x9c,
0x61,0xd6,0x5a,0xe1
};
static const unsigned char cav_Xq2[] = {
0x06,0x81,0x53,0xfd,0xa8,0x7b,0xa3,0x85,0x90,0x15,0x2c,0x97,0xb2,0xa0,0x17,
0x48,0xb0,0x7f,0x0a,0x01,0x6d
};
/* expected values */
static const unsigned char cav_p1[] = {
0xac,0x5f,0x7f,0x6e,0x33,0x3e,0x97,0x3a,0xb3,0x17,0x44,0xa9,0x0f,0x7a,0x54,
0x70,0x27,0x06,0x93,0xd5,0x49,0xde,0x91,0x83,0xbc,0x8a,0x7b,0xc3
};
static const unsigned char cav_p2[] = {
0x0b,0xf6,0xe8,0x79,0x5a,0x81,0xae,0x90,0x1d,0xa4,0x38,0x74,0x9c,0x0e,0x6f,
0xe0,0x03,0xcf,0xc4,0x53,0x16,0x32,0x17,0xf7,0x09,0x5f,0xd9
};
static const unsigned char cav_q1[] = {
0x9b,0x02,0xd4,0xba,0xf0,0xaa,0x14,0x99,0x6d,0xc0,0xb7,0xa5,0xe1,0xd3,0x70,
0xb6,0x5a,0xa2,0x9b,0x59,0xd5,0x8c,0x1e,0x9f,0x3f,0x9a,0xde,0xeb,0x9e,0x9c,
0x61,0xd6,0x5d,0x47
};
static const unsigned char cav_q2[] = {
0x06,0x81,0x53,0xfd,0xa8,0x7b,0xa3,0x85,0x90,0x15,0x2c,0x97,0xb2,0xa0,0x17,
0x48,0xb0,0x7f,0x0a,0x01,0x8f
};
static const unsigned char cav_p[] = {
0xcf,0x72,0x1b,0x9a,0xfd,0x0d,0x22,0x1a,0x74,0x50,0x97,0x22,0x76,0xd8,0xc0,
0xc2,0xfd,0x08,0x81,0x05,0xdd,0x18,0x21,0x99,0x96,0xd6,0x5c,0x79,0xe3,0x02,
@ -162,15 +105,6 @@ static BIGNUM *bn_load_new(const unsigned char *data, int sz)
return ret;
}
/* helper function */
static BIGNUM *bn_load(BN_CTX *ctx, const unsigned char *data, int sz)
{
BIGNUM *ret = BN_CTX_get(ctx);
if (ret != NULL)
BN_bin2bn(data, sz, ret);
return ret;
}
static int test_check_public_exponent(void)
{
int ret = 0;
@ -502,67 +436,6 @@ end:
return ret;
}
static int test_fips1864_keygen_kat(void)
{
int ret = 0;
RSA *key = NULL;
BN_CTX *ctx = NULL;
BIGNUM *e, *Xp, *Xp1, *Xp2, *Xq, *Xq1, *Xq2;
BIGNUM *p1, *p2, *q1, *q2;
BIGNUM *p1_exp, *p2_exp, *q1_exp, *q2_exp;
BIGNUM *p_exp, *q_exp, *n_exp, *d_exp;
const BIGNUM *p, *q, *n, *d, *e2;
if (!(TEST_ptr(key = RSA_new()) && TEST_ptr(ctx = BN_CTX_new())))
goto err;
BN_CTX_start(ctx);
e = bn_load(ctx, cav_e, sizeof(cav_e));
Xp = bn_load(ctx, cav_Xp, sizeof(cav_Xp));
Xp1 = bn_load(ctx, cav_Xp1, sizeof(cav_Xp1));
Xp2 = bn_load(ctx, cav_Xp2, sizeof(cav_Xp2));
Xq = bn_load(ctx, cav_Xq, sizeof(cav_Xq));
Xq1 = bn_load(ctx, cav_Xq1, sizeof(cav_Xq1));
Xq2 = bn_load(ctx, cav_Xq2, sizeof(cav_Xq2));
p1_exp = bn_load(ctx, cav_p1, sizeof(cav_p1));
p2_exp = bn_load(ctx, cav_p2, sizeof(cav_p2));
q1_exp = bn_load(ctx, cav_q1, sizeof(cav_q1));
q2_exp = bn_load(ctx, cav_q2, sizeof(cav_q2));
p_exp = bn_load(ctx, cav_p, sizeof(cav_p));
q_exp = bn_load(ctx, cav_q, sizeof(cav_q));
n_exp = bn_load(ctx, cav_n, sizeof(cav_n));
d_exp = bn_load(ctx, cav_d, sizeof(cav_d));
p1 = BN_CTX_get(ctx);
p2 = BN_CTX_get(ctx);
q1 = BN_CTX_get(ctx);
q2 = BN_CTX_get(ctx);
ret = TEST_ptr(q2)
&& TEST_true(rsa_fips186_4_gen_prob_primes(key, p1, p2, NULL, Xp, Xp1,
Xp2, q1, q2, NULL, Xq, Xq1,
Xq2, 2048, e, ctx, NULL))
&& TEST_true(rsa_sp800_56b_derive_params_from_pq(key, 2048, e, ctx))
&& TEST_BN_eq(p1_exp, p1)
&& TEST_BN_eq(p2_exp, p2)
&& TEST_BN_eq(q1_exp, q1)
&& TEST_BN_eq(q2_exp, q2);
if (!ret)
goto err;
RSA_get0_key(key, &n, &e2, &d);
RSA_get0_factors(key, &p, &q);
ret = TEST_BN_eq(e, e2)
&& TEST_BN_eq(p_exp, p)
&& TEST_BN_eq(q_exp, q)
&& TEST_BN_eq(n_exp, n)
&& TEST_BN_eq(d_exp, d);
err:
RSA_free(key);
BN_CTX_end(ctx);
BN_CTX_free(ctx);
return ret;
}
static int keygen_size[] =
{
2048, 3072
@ -668,7 +541,6 @@ int setup_tests(void)
ADD_TEST(test_check_public_key);
ADD_TEST(test_invalid_keypair);
ADD_TEST(test_pq_diff);
ADD_TEST(test_fips1864_keygen_kat);
ADD_ALL_TESTS(test_sp80056b_keygen, (int)OSSL_NELEM(keygen_size));
return 1;
}