summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShane Lontis <shane.lontis@oracle.com>2020-06-17 11:33:16 +1000
committerShane Lontis <shane.lontis@oracle.com>2020-06-17 11:33:16 +1000
commit4f2271d58a36b2aee125062ffb9626c6208fa394 (patch)
tree122e6de930647c37a35b5f457448a031e51969b8
parent5a147abd790075cdc97b36ff5084e2eb1d779b95 (diff)
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)
-rwxr-xr-xConfigure1
-rw-r--r--INSTALL.md10
-rw-r--r--crypto/dh/dh_check.c4
-rw-r--r--crypto/dh/dh_gen.c15
-rw-r--r--crypto/dh/dh_pmeth.c17
-rw-r--r--crypto/dsa/dsa_check.c4
-rw-r--r--crypto/dsa/dsa_gen.c27
-rw-r--r--crypto/dsa/dsa_pmeth.c6
-rw-r--r--crypto/ffc/ffc_backend.c22
-rw-r--r--crypto/ffc/ffc_params.c59
-rw-r--r--crypto/ffc/ffc_params_generate.c208
-rw-r--r--crypto/ffc/ffc_params_validate.c24
-rw-r--r--crypto/rsa/build.info4
-rw-r--r--crypto/rsa/rsa_acvp_test_params.c167
-rw-r--r--crypto/rsa/rsa_backend.c8
-rw-r--r--crypto/rsa/rsa_gen.c4
-rw-r--r--crypto/rsa/rsa_lib.c5
-rw-r--r--crypto/rsa/rsa_local.h38
-rw-r--r--crypto/rsa/rsa_sp800_56b_gen.c74
-rw-r--r--doc/man7/EVP_PKEY-RSA.pod53
-rw-r--r--include/crypto/dh.h4
-rw-r--r--include/crypto/dsa.h4
-rw-r--r--include/crypto/rsa.h16
-rw-r--r--include/internal/ffc.h55
-rw-r--r--include/openssl/core_names.h44
-rw-r--r--providers/implementations/keymgmt/dh_kmgmt.c29
-rw-r--r--providers/implementations/keymgmt/dsa_kmgmt.c29
-rw-r--r--providers/implementations/keymgmt/ec_kmgmt.c47
-rw-r--r--providers/implementations/keymgmt/rsa_kmgmt.c23
-rw-r--r--providers/implementations/signature/build.info4
-rw-r--r--providers/implementations/signature/dsa.c18
-rw-r--r--providers/implementations/signature/ecdsa.c25
-rw-r--r--providers/implementations/signature/rsa.c19
-rw-r--r--test/acvp_test.c1367
-rw-r--r--test/acvp_test.inc1984
-rw-r--r--test/build.info7
-rw-r--r--test/ffc_internal_test.c149
-rw-r--r--test/recipes/30-test_acvp.t41
-rw-r--r--test/rsa_sp800_56b_test.c128
39 files changed, 4236 insertions, 507 deletions
diff --git a/Configure b/Configure
index 1a22f47822..a0b9c22b6d 100755
--- a/Configure
+++ b/Configure
@@ -360,6 +360,7 @@ my @dtls = qw(dtls1 dtls1_2);
# For developers: keep it sorted alphabetically
my @disablables = (
+ "acvp_tests",
"afalgeng",
"aria",
"asan",
diff --git a/INSTALL.md b/INSTALL.md
index 88961aa74b..981a86af04 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -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.
diff --git a/crypto/dh/dh_check.c b/crypto/dh/dh_check.c
index 9dd595ae12..a223121cd0 100644
--- a/crypto/dh/dh_check.c
+++ b/crypto/dh/dh_check.c
@@ -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)
diff --git a/crypto/dh/dh_gen.c b/crypto/dh/dh_gen.c
index 8c1518ad9b..52f3151bc8 100644
--- a/crypto/dh/dh_gen.c
+++ b/crypto/dh/dh_gen.c
@@ -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;
diff --git a/crypto/dh/dh_pmeth.c b/crypto/dh/dh_pmeth.c
index 23527acf04..39b79ffb36 100644
--- a/crypto/dh/dh_pmeth.c
+++ b/crypto/dh/dh_pmeth.c
@@ -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;
diff --git a/crypto/dsa/dsa_check.c b/crypto/dsa/dsa_check.c
index dc42ec5f5f..01cf0f6341 100644
--- a/crypto/dsa/dsa_check.c
+++ b/crypto/dsa/dsa_check.c
@@ -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);
}
/*
diff --git a/crypto/dsa/dsa_gen.c b/crypto/dsa/dsa_gen.c
index acd088ee79..9d5e91de29 100644
--- a/crypto/dsa/dsa_gen.c
+++ b/crypto/dsa/dsa_gen.c
@@ -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;
}
diff --git a/crypto/dsa/dsa_pmeth.c b/crypto/dsa/dsa_pmeth.c
index 7f7f57f6d3..7b364059e7 100644
--- a/crypto/dsa/dsa_pmeth.c
+++ b/crypto/dsa/dsa_pmeth.c
@@ -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);
diff --git a/crypto/ffc/ffc_backend.c b/crypto/ffc/ffc_backend.c
index c34e79bf4f..49f42d70d0 100644
--- a/crypto/ffc/ffc_backend.c
+++ b/crypto/ffc/ffc_backend.c
@@ -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;
diff --git a/crypto/ffc/ffc_params.c b/crypto/ffc/ffc_params.c
index a95a2fa12b..0796d34337 100644
--- a/crypto/ffc/ffc_params.c
+++ b/crypto/ffc/ffc_params.c
@@ -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;
}
diff --git a/crypto/ffc/ffc_params_generate.c b/crypto/ffc/ffc_params_generate.c
index 624c24dd21..b3ab476f3f 100644
--- a/crypto/ffc/ffc_params_generate.c
+++ b/crypto/ffc/ffc_params_generate.c
@@ -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_VER