diff --git a/test/acvp_test.c b/test/acvp_test.c index 82ecaf8b00..623fab028c 100644 --- a/test/acvp_test.c +++ b/test/acvp_test.c @@ -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))) diff --git a/test/dsatest.c b/test/dsatest.c index 73c6827bb0..e8839c7176 100644 --- a/test/dsatest.c +++ b/test/dsatest.c @@ -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)) diff --git a/test/evp_libctx_test.c b/test/evp_libctx_test.c index 35a1127193..65e63cffe8 100644 --- a/test/evp_libctx_test.c +++ b/test/evp_libctx_test.c @@ -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); diff --git a/test/evp_test.c b/test/evp_test.c index b817f72b00..c3d28cdf71 100644 --- a/test/evp_test.c +++ b/test/evp_test.c @@ -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; diff --git a/test/recipes/15-test_gendsa.t b/test/recipes/15-test_gendsa.t index 4bc460784b..cd331c4cfc 100644 --- a/test/recipes/15-test_gendsa.t +++ b/test/recipes/15-test_gendsa.t @@ -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"); } diff --git a/test/recipes/30-test_evp_data/evppkey_dsa.txt b/test/recipes/30-test_evp_data/evppkey_dsa.txt index 1109abb453..51c4405b15 100644 --- a/test/recipes/30-test_evp_data/evppkey_dsa.txt +++ b/test/recipes/30-test_evp_data/evppkey_dsa.txt @@ -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 diff --git a/test/testutil/stanza.c b/test/testutil/stanza.c index a3f833a543..69edfad668 100644 --- a/test/testutil/stanza.c +++ b/test/testutil/stanza.c @@ -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; }