mirror of
https://github.com/openssl/openssl.git
synced 2025-02-17 14:32:04 +08:00
Add FIPS DSA Keygen tests
Adjust the existing tests to disable DSA keygen in FIPS mode. Allow evp_test to load DSA 'KeyParams' that can then be used to perform a DSA KeyGen. Reviewed-by: Paul Dale <ppzgs1@gmail.com> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/24978)
This commit is contained in:
parent
49a35f0f92
commit
f98e49b326
@ -347,7 +347,7 @@ static EVP_PKEY *dsa_paramgen(int L, int N)
|
||||
|| !TEST_true(EVP_PKEY_CTX_set_dsa_paramgen_bits(paramgen_ctx, L))
|
||||
|| !TEST_true(EVP_PKEY_CTX_set_dsa_paramgen_q_bits(paramgen_ctx, N))
|
||||
|| !TEST_true(EVP_PKEY_paramgen(paramgen_ctx, ¶m_key)))
|
||||
return NULL;
|
||||
TEST_info("dsa_paramgen failed");
|
||||
EVP_PKEY_CTX_free(paramgen_ctx);
|
||||
return param_key;
|
||||
}
|
||||
@ -378,6 +378,10 @@ static int dsa_keygen_test(int id)
|
||||
size_t priv_len = 0, pub_len = 0;
|
||||
const struct dsa_paramgen_st *tst = &dsa_keygen_data[id];
|
||||
|
||||
if (!dsasign_allowed) {
|
||||
TEST_info("DSA keygen test skipped: DSA signing is not allowed");
|
||||
return 1;
|
||||
}
|
||||
if (!TEST_ptr(param_key = dsa_paramgen(tst->L, tst->N))
|
||||
|| !TEST_ptr(keygen_ctx = EVP_PKEY_CTX_new_from_pkey(libctx, param_key,
|
||||
NULL))
|
||||
@ -421,23 +425,31 @@ static int dsa_paramgen_test(int id)
|
||||
if (!TEST_ptr(paramgen_ctx = EVP_PKEY_CTX_new_from_name(libctx, "DSA", NULL))
|
||||
|| !TEST_int_gt(EVP_PKEY_paramgen_init(paramgen_ctx), 0)
|
||||
|| !TEST_true(EVP_PKEY_CTX_set_dsa_paramgen_bits(paramgen_ctx, tst->L))
|
||||
|| !TEST_true(EVP_PKEY_CTX_set_dsa_paramgen_q_bits(paramgen_ctx, tst->N))
|
||||
|| !TEST_true(EVP_PKEY_paramgen(paramgen_ctx, ¶m_key))
|
||||
|| !TEST_true(pkey_get_bn_bytes(param_key, OSSL_PKEY_PARAM_FFC_P,
|
||||
&p, &plen))
|
||||
|| !TEST_true(pkey_get_bn_bytes(param_key, OSSL_PKEY_PARAM_FFC_Q,
|
||||
&q, &qlen))
|
||||
|| !TEST_true(pkey_get_octet_bytes(param_key, OSSL_PKEY_PARAM_FFC_SEED,
|
||||
&seed, &seedlen))
|
||||
|| !TEST_true(EVP_PKEY_get_int_param(param_key,
|
||||
OSSL_PKEY_PARAM_FFC_PCOUNTER,
|
||||
&counter)))
|
||||
|| !TEST_true(EVP_PKEY_CTX_set_dsa_paramgen_q_bits(paramgen_ctx,
|
||||
tst->N)))
|
||||
goto err;
|
||||
|
||||
test_output_memory("p", p, plen);
|
||||
test_output_memory("q", q, qlen);
|
||||
test_output_memory("domainSeed", seed, seedlen);
|
||||
test_printf_stderr("%s: %d\n", "counter", counter);
|
||||
if (!dsasign_allowed) {
|
||||
if (!TEST_false(EVP_PKEY_paramgen(paramgen_ctx, ¶m_key)))
|
||||
goto err;
|
||||
} else {
|
||||
if (!TEST_true(EVP_PKEY_paramgen(paramgen_ctx, ¶m_key))
|
||||
|| !TEST_true(pkey_get_bn_bytes(param_key, OSSL_PKEY_PARAM_FFC_P,
|
||||
&p, &plen))
|
||||
|| !TEST_true(pkey_get_bn_bytes(param_key, OSSL_PKEY_PARAM_FFC_Q,
|
||||
&q, &qlen))
|
||||
|| !TEST_true(pkey_get_octet_bytes(param_key,
|
||||
OSSL_PKEY_PARAM_FFC_SEED,
|
||||
&seed, &seedlen))
|
||||
|| !TEST_true(EVP_PKEY_get_int_param(param_key,
|
||||
OSSL_PKEY_PARAM_FFC_PCOUNTER,
|
||||
&counter)))
|
||||
goto err;
|
||||
test_output_memory("p", p, plen);
|
||||
test_output_memory("q", q, qlen);
|
||||
test_output_memory("domainSeed", seed, seedlen);
|
||||
test_printf_stderr("%s: %d\n", "counter", counter);
|
||||
}
|
||||
ret = 1;
|
||||
err:
|
||||
OPENSSL_free(p);
|
||||
@ -597,10 +609,12 @@ static int dsa_siggen_test(int id)
|
||||
size_t sig_len = 0, rlen = 0, slen = 0;
|
||||
const struct dsa_siggen_st *tst = &dsa_siggen_data[id];
|
||||
|
||||
if (!TEST_ptr(pkey = dsa_keygen(tst->L, tst->N)))
|
||||
goto err;
|
||||
|
||||
if (dsasign_allowed) {
|
||||
if (!dsasign_allowed) {
|
||||
if (!TEST_ptr_null(pkey = dsa_keygen(tst->L, tst->N)))
|
||||
goto err;
|
||||
} else {
|
||||
if (!TEST_ptr(pkey = dsa_keygen(tst->L, tst->N)))
|
||||
goto err;
|
||||
if (!TEST_true(sig_gen(pkey, NULL, tst->digest_alg, tst->msg, tst->msg_len,
|
||||
&sig, &sig_len))
|
||||
|| !TEST_true(get_dsa_sig_rs_bytes(sig, sig_len, &r, &s, &rlen, &slen)))
|
||||
|
@ -247,7 +247,7 @@ static int dsa_keygen_test(void)
|
||||
goto end;
|
||||
if (!TEST_ptr(pg_ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL))
|
||||
|| !TEST_int_gt(EVP_PKEY_paramgen_init(pg_ctx), 0)
|
||||
|| !TEST_ptr_null(EVP_PKEY_CTX_gettable_params(pg_ctx))
|
||||
|| !TEST_ptr(EVP_PKEY_CTX_gettable_params(pg_ctx))
|
||||
|| !TEST_ptr(settables = EVP_PKEY_CTX_settable_params(pg_ctx))
|
||||
|| !TEST_ptr(OSSL_PARAM_locate_const(settables,
|
||||
OSSL_PKEY_PARAM_FFC_PBITS))
|
||||
|
@ -781,7 +781,9 @@ int setup_tests(void)
|
||||
ADD_TEST(test_evp_cipher_api_safety);
|
||||
|
||||
#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DH)
|
||||
ADD_ALL_TESTS(test_dsa_param_keygen, 3 * 3 * 3);
|
||||
if (strcmp(prov_name, "fips") != 0
|
||||
|| fips_provider_version_lt(libctx, 3, 4, 0))
|
||||
ADD_ALL_TESTS(test_dsa_param_keygen, 3 * 3 * 3);
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DH
|
||||
ADD_ALL_TESTS(test_dh_safeprime_param_keygen, 3 * 3 * 3);
|
||||
|
@ -153,6 +153,13 @@ static int pkey_check_fips_approved(EVP_PKEY_CTX *ctx, EVP_TEST *t)
|
||||
* value of approved.
|
||||
*/
|
||||
int approved = 1;
|
||||
const OSSL_PARAM *gettables = EVP_PKEY_CTX_gettable_params(ctx);
|
||||
|
||||
if (gettables == NULL
|
||||
|| OSSL_PARAM_locate_const(gettables,
|
||||
OSSL_ALG_PARAM_FIPS_APPROVED_INDICATOR)
|
||||
== NULL)
|
||||
return 1;
|
||||
|
||||
/* Older providers dont have a gettable */
|
||||
if (EVP_PKEY_CTX_gettable_params(ctx) == NULL)
|
||||
@ -3879,14 +3886,15 @@ static const EVP_TEST_METHOD keypair_test_method = {
|
||||
**/
|
||||
|
||||
typedef struct keygen_test_data_st {
|
||||
EVP_PKEY_CTX *genctx; /* Keygen context to use */
|
||||
char *keyname; /* Key name to store key or NULL */
|
||||
char *paramname;
|
||||
char *alg;
|
||||
STACK_OF(OPENSSL_STRING) *controls; /* Collection of controls */
|
||||
} KEYGEN_TEST_DATA;
|
||||
|
||||
static int keygen_test_init(EVP_TEST *t, const char *alg)
|
||||
{
|
||||
KEYGEN_TEST_DATA *data;
|
||||
EVP_PKEY_CTX *genctx;
|
||||
int nid = OBJ_sn2nid(alg);
|
||||
|
||||
if (nid == NID_undef) {
|
||||
@ -3899,24 +3907,17 @@ static int keygen_test_init(EVP_TEST *t, const char *alg)
|
||||
t->skip = 1;
|
||||
return 1;
|
||||
}
|
||||
if (!TEST_ptr(genctx = EVP_PKEY_CTX_new_from_name(libctx, alg, propquery)))
|
||||
goto err;
|
||||
|
||||
if (EVP_PKEY_keygen_init(genctx) <= 0) {
|
||||
t->err = "KEYGEN_INIT_ERROR";
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!TEST_ptr(data = OPENSSL_malloc(sizeof(*data))))
|
||||
goto err;
|
||||
data->genctx = genctx;
|
||||
data->keyname = NULL;
|
||||
data->alg = OPENSSL_strdup(alg);
|
||||
data->paramname = NULL;
|
||||
data->controls = sk_OPENSSL_STRING_new_null();
|
||||
t->data = data;
|
||||
t->err = NULL;
|
||||
return 1;
|
||||
|
||||
err:
|
||||
EVP_PKEY_CTX_free(genctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -3924,7 +3925,9 @@ static void keygen_test_cleanup(EVP_TEST *t)
|
||||
{
|
||||
KEYGEN_TEST_DATA *keygen = t->data;
|
||||
|
||||
EVP_PKEY_CTX_free(keygen->genctx);
|
||||
ctrlfree(keygen->controls);
|
||||
OPENSSL_free(keygen->alg);
|
||||
OPENSSL_free(keygen->paramname);
|
||||
OPENSSL_free(keygen->keyname);
|
||||
OPENSSL_free(t->data);
|
||||
t->data = NULL;
|
||||
@ -3937,21 +3940,57 @@ static int keygen_test_parse(EVP_TEST *t,
|
||||
|
||||
if (strcmp(keyword, "KeyName") == 0)
|
||||
return TEST_ptr(keygen->keyname = OPENSSL_strdup(value));
|
||||
if (strcmp(keyword, "KeyParam") == 0)
|
||||
return TEST_ptr(keygen->paramname = OPENSSL_strdup(value));
|
||||
if (strcmp(keyword, "Ctrl") == 0)
|
||||
return pkey_test_ctrl(t, keygen->genctx, value);
|
||||
return ctrladd(keygen->controls, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int keygen_test_run(EVP_TEST *t)
|
||||
{
|
||||
KEYGEN_TEST_DATA *keygen = t->data;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
int rv = 1;
|
||||
EVP_PKEY *pkey = NULL, *keyparams = NULL;
|
||||
EVP_PKEY_CTX *genctx = NULL; /* Keygen context to use */
|
||||
int rv = 1, i;
|
||||
|
||||
if (EVP_PKEY_keygen(keygen->genctx, &pkey) <= 0) {
|
||||
if (keygen->paramname != NULL) {
|
||||
rv = find_key(&keyparams, keygen->paramname, public_keys);
|
||||
if (rv == 0 || keyparams == NULL) {
|
||||
TEST_info("skipping, key '%s' is disabled", keygen->paramname);
|
||||
t->skip = 1;
|
||||
return 1;
|
||||
}
|
||||
if (!TEST_ptr(genctx = EVP_PKEY_CTX_new_from_pkey(libctx, keyparams,
|
||||
propquery)))
|
||||
goto err;
|
||||
|
||||
} else {
|
||||
if (!TEST_ptr(genctx = EVP_PKEY_CTX_new_from_name(libctx, keygen->alg,
|
||||
propquery)))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (EVP_PKEY_keygen_init(genctx) <= 0) {
|
||||
t->err = "KEYGEN_INIT_ERROR";
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (i = 0; i < sk_OPENSSL_STRING_num(keygen->controls); ++i) {
|
||||
if (!pkey_test_ctrl(t, genctx,
|
||||
sk_OPENSSL_STRING_value(keygen->controls, i))
|
||||
|| t->err != NULL)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (EVP_PKEY_keygen(genctx, &pkey) <= 0) {
|
||||
t->err = "KEYGEN_GENERATE_ERROR";
|
||||
goto err;
|
||||
}
|
||||
if (!pkey_check_fips_approved(genctx, t)) {
|
||||
rv = 0;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!evp_pkey_is_provided(pkey)) {
|
||||
TEST_info("Warning: legacy key generated %s", keygen->keyname);
|
||||
@ -3979,8 +4018,8 @@ static int keygen_test_run(EVP_TEST *t)
|
||||
}
|
||||
|
||||
t->err = NULL;
|
||||
|
||||
err:
|
||||
EVP_PKEY_CTX_free(genctx);
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -4662,6 +4701,15 @@ start:
|
||||
return 0;
|
||||
}
|
||||
klist = &public_keys;
|
||||
} else if (strcmp(pp->key, "ParamKey") == 0) {
|
||||
pkey = PEM_read_bio_Parameters_ex(t->s.key, NULL, libctx, NULL);
|
||||
if (pkey == NULL && !key_unsupported()) {
|
||||
EVP_PKEY_free(pkey);
|
||||
TEST_info("Can't read params key %s", pp->value);
|
||||
TEST_openssl_errors();
|
||||
return 0;
|
||||
}
|
||||
klist = &public_keys;
|
||||
} else if (strcmp(pp->key, "PrivateKeyRaw") == 0
|
||||
|| strcmp(pp->key, "PublicKeyRaw") == 0) {
|
||||
char *strnid = NULL, *keydata = NULL;
|
||||
|
@ -1,5 +1,5 @@
|
||||
#! /usr/bin/env perl
|
||||
# Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved.
|
||||
# Copyright 2017-2024 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
|
||||
@ -160,22 +160,28 @@ unless ($no_fips) {
|
||||
|
||||
$ENV{OPENSSL_TEST_LIBCTX} = "1";
|
||||
|
||||
# DSA signing/keygen is not approved in FIPS 140-3
|
||||
run(test(["fips_version_test", "-config", $provconf, "<3.4.0"]),
|
||||
capture => 1, statusvar => \my $dsasignpass);
|
||||
|
||||
# Generate params
|
||||
ok(run(app(['openssl', 'genpkey',
|
||||
is(run(app(['openssl', 'genpkey',
|
||||
@prov,
|
||||
'-genparam',
|
||||
'-algorithm', 'DSA',
|
||||
'-pkeyopt', 'pbits:3072',
|
||||
'-pkeyopt', 'qbits:256',
|
||||
'-out', 'gendsatest3072params.pem'])),
|
||||
$dsasignpass,
|
||||
"Generating 3072-bit DSA params");
|
||||
|
||||
# Generate keypair
|
||||
ok(run(app(['openssl', 'genpkey',
|
||||
is(run(app(['openssl', 'genpkey',
|
||||
@prov,
|
||||
'-paramfile', 'gendsatest3072params.pem',
|
||||
'-text',
|
||||
'-out', 'gendsatest3072.pem'])),
|
||||
$dsasignpass,
|
||||
"Generating 3072-bit DSA keypair");
|
||||
|
||||
}
|
||||
|
@ -437,3 +437,43 @@ CtrlInit = sign-check:0
|
||||
Key = DSA-2048-256
|
||||
Input = "Hello"
|
||||
Result = DIGESTSIGNINIT_ERROR
|
||||
|
||||
Title = Test DSA keygen
|
||||
|
||||
# Load DSA Params to use in the DSA keygen tests
|
||||
ParamKey = DSA-2048-PARAMS
|
||||
-----BEGIN DSA PARAMETERS-----
|
||||
MIICKAKCAQEAgrJrFYjhhJ3NnIBSRNpVK5+gze+9fA4Ce0Yjbiz3KOU2TTtE1mbf
|
||||
lGVsjuAEX2c/cBUWFEjg77EoGCFCpfbzSh6nd2DgCiFaw91ak3GuQ+yKs55SyeQV
|
||||
ikUQaAILVm0SgIPhdCUtG5XdghJyNUTEHFowWXh3gaQDaRB6MqxbMj0a9LoRwYAw
|
||||
Mo/9bug6Uh/ITEKjoBertznRW8SflHhATvc6eCL6NXi3qhkQIgYDdwxUGGz1SnfH
|
||||
wUTYcvu2eogv+0WAnnxCJh51qv2gUynH4TLeL9g/jskcJfvYtejJ+k/G3Q6dsEn/
|
||||
an8pdKdH0MaplOZNB6nJSa1H0VZfg9V9VQIdALq9dtHaBpeXSal0qhn0P/nmR9ID
|
||||
I1Yn4K1l33cCggEAAulOaqN0hBs9DXQyljrKesD8zTLgIsabgyEauuyFfsZp5ezU
|
||||
762cnqDde20DPTHu1hbVmw68hvKDAWNpVzMMsopFPPWt8JwnEHSMZxwv08RxBET9
|
||||
HQXL4+YxA9hfAmtRkUK+QdZFRdXv4AjnxcLyNbIqT/uPm1c/+Dd7875rIzTcW3cc
|
||||
IvhlS7VgfwIg0IUuGF2uXt/6P7zInftR+nan4/DbNWind5308I7l4jchRjUDRlsK
|
||||
WbJpcH2m2K43Ue0MUKIki1dTlH07PiHUuY4wQ+jInWtnnRQlLGSw+LdrD7gwpFYY
|
||||
w/lWdpSTr0aHbSvxD9vcrUzKljFY6iSQF32wcg==
|
||||
-----END DSA PARAMETERS-----
|
||||
|
||||
# FIPS Key generation tests
|
||||
|
||||
# Test FIPS DSA keygen is not allowed
|
||||
Availablein = fips
|
||||
FIPSversion = >=3.4.0
|
||||
KeyGen = DSA
|
||||
KeyParam = DSA-2048-PARAMS
|
||||
KeyName = tmp1dsa
|
||||
Result = KEYGEN_GENERATE_ERROR
|
||||
|
||||
Title = Test DSA keygen FIPS indicator test
|
||||
|
||||
# Test DSA keygen is not approved
|
||||
Availablein = fips
|
||||
FIPSversion = >=3.4.0
|
||||
KeyGen = DSA
|
||||
KeyParam = DSA-2048-PARAMS
|
||||
KeyName = tmp2dsa
|
||||
Unapproved = 1
|
||||
Ctrl = sign-check:0
|
||||
|
@ -126,11 +126,9 @@ int test_readstanza(STANZA *s)
|
||||
if (s->numpairs == 0)
|
||||
s->start = s->curr;
|
||||
|
||||
if (strcmp(key, "PrivateKey") == 0) {
|
||||
if (!read_key(s))
|
||||
return 0;
|
||||
}
|
||||
if (strcmp(key, "PublicKey") == 0) {
|
||||
if (strcmp(key, "PrivateKey") == 0
|
||||
|| strcmp(key, "PublicKey") == 0
|
||||
|| strcmp(key, "ParamKey") == 0) {
|
||||
if (!read_key(s))
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user