Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add tests for FIPS keygen self test failures.
During key generation RSA, EC and DSA have extra tests that run in FIPS mode All 3 algorithms have a pairwise test, EC & DSA also run a KAT test. This test uses the self test callback to force an error during each of the extra pairwise and KAT tests. Reviewed-by: Paul Dale <pauli@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from #20183)
- Loading branch information
Showing
4 changed files
with
257 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
/* | ||
* Copyright 2023 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 <openssl/pem.h> | ||
#include <openssl/core_names.h> | ||
#include <openssl/self_test.h> | ||
#include "testutil.h" | ||
|
||
typedef enum OPTION_choice { | ||
OPT_ERR = -1, | ||
OPT_EOF = 0, | ||
OPT_PROVIDER_NAME, | ||
OPT_CONFIG_FILE, | ||
OPT_PAIRWISETEST, | ||
OPT_DSAPARAM, | ||
OPT_TEST_ENUM | ||
} OPTION_CHOICE; | ||
|
||
struct self_test_arg { | ||
const char *type; | ||
}; | ||
|
||
static OSSL_LIB_CTX *libctx = NULL; | ||
static char *pairwise_name = NULL; | ||
static char *dsaparam_file = NULL; | ||
static struct self_test_arg self_test_args = { 0 }; | ||
|
||
const OPTIONS *test_get_options(void) | ||
{ | ||
static const OPTIONS test_options[] = { | ||
OPT_TEST_OPTIONS_DEFAULT_USAGE, | ||
{ "config", OPT_CONFIG_FILE, '<', | ||
"The configuration file to use for the libctx" }, | ||
{ "pairwise", OPT_PAIRWISETEST, 's', | ||
"Test keygen pairwise test failures" }, | ||
{ "dsaparam", OPT_DSAPARAM, 's', "DSA param file" }, | ||
{ NULL } | ||
}; | ||
return test_options; | ||
} | ||
|
||
static int self_test_on_pairwise_fail(const OSSL_PARAM params[], void *arg) | ||
{ | ||
struct self_test_arg *args = arg; | ||
const OSSL_PARAM *p = NULL; | ||
const char *type = NULL, *phase = NULL; | ||
|
||
p = OSSL_PARAM_locate_const(params, OSSL_PROV_PARAM_SELF_TEST_PHASE); | ||
if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) | ||
return 0; | ||
phase = (const char *)p->data; | ||
if (strcmp(phase, OSSL_SELF_TEST_PHASE_CORRUPT) == 0) { | ||
p = OSSL_PARAM_locate_const(params, OSSL_PROV_PARAM_SELF_TEST_TYPE); | ||
if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) | ||
return 0; | ||
type = (const char *)p->data; | ||
if (strcmp(type, args->type) == 0) | ||
return 0; | ||
} | ||
return 1; | ||
} | ||
|
||
static int setup_selftest_pairwise_failure(const char *type) | ||
{ | ||
int ret = 0; | ||
OSSL_PROVIDER *prov = NULL; | ||
|
||
if (!TEST_ptr(prov = OSSL_PROVIDER_load(libctx, "fips"))) | ||
goto err; | ||
|
||
/* Setup a callback that corrupts the pairwise self tests and causes failures */ | ||
self_test_args.type = type; | ||
OSSL_SELF_TEST_set_callback(libctx, self_test_on_pairwise_fail, &self_test_args); | ||
|
||
ret = 1; | ||
err: | ||
OSSL_PROVIDER_unload(prov); | ||
return ret; | ||
} | ||
|
||
static int test_keygen_pairwise_failure(void) | ||
{ | ||
BIO *bio = NULL; | ||
EVP_PKEY_CTX *ctx = NULL; | ||
EVP_PKEY *pParams = NULL; | ||
EVP_PKEY *pkey = NULL; | ||
const char *type = OSSL_SELF_TEST_TYPE_PCT; | ||
int ret = 0; | ||
|
||
if (strcmp(pairwise_name, "rsa") == 0) { | ||
if (!TEST_true(setup_selftest_pairwise_failure(type))) | ||
goto err; | ||
if (!TEST_ptr_null(pkey = EVP_PKEY_Q_keygen(libctx, NULL, "RSA", 2048))) | ||
goto err; | ||
} else if (strncmp(pairwise_name, "ec", 2) == 0) { | ||
if (strcmp(pairwise_name, "eckat") == 0) | ||
type = OSSL_SELF_TEST_TYPE_PCT_KAT; | ||
if (!TEST_true(setup_selftest_pairwise_failure(type))) | ||
goto err; | ||
if (!TEST_ptr_null(pkey = EVP_PKEY_Q_keygen(libctx, NULL, "EC", "P-256"))) | ||
goto err; | ||
} else if (strncmp(pairwise_name, "dsa", 3) == 0) { | ||
if (strcmp(pairwise_name, "dsakat") == 0) | ||
type = OSSL_SELF_TEST_TYPE_PCT_KAT; | ||
if (!TEST_true(setup_selftest_pairwise_failure(type))) | ||
goto err; | ||
if (!TEST_ptr(bio = BIO_new_file(dsaparam_file, "r"))) | ||
goto err; | ||
if (!TEST_ptr(pParams = PEM_read_bio_Parameters_ex(bio, NULL, libctx, NULL))) | ||
goto err; | ||
if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pParams, NULL))) | ||
goto err; | ||
if (!TEST_int_eq(EVP_PKEY_keygen_init(ctx), 1)) | ||
goto err; | ||
if (!TEST_int_le(EVP_PKEY_keygen(ctx, &pkey), 0)) | ||
goto err; | ||
if (!TEST_ptr_null(pkey)) | ||
goto err; | ||
} | ||
ret = 1; | ||
err: | ||
EVP_PKEY_free(pkey); | ||
EVP_PKEY_CTX_free(ctx); | ||
BIO_free(bio); | ||
EVP_PKEY_free(pParams); | ||
return ret; | ||
} | ||
|
||
int setup_tests(void) | ||
{ | ||
OPTION_CHOICE o; | ||
char *config_file = NULL; | ||
|
||
while ((o = opt_next()) != OPT_EOF) { | ||
switch (o) { | ||
case OPT_CONFIG_FILE: | ||
config_file = opt_arg(); | ||
break; | ||
case OPT_PAIRWISETEST: | ||
pairwise_name = opt_arg(); | ||
break; | ||
case OPT_DSAPARAM: | ||
dsaparam_file = opt_arg(); | ||
break; | ||
case OPT_TEST_CASES: | ||
break; | ||
default: | ||
case OPT_ERR: | ||
return 0; | ||
} | ||
} | ||
|
||
libctx = OSSL_LIB_CTX_new(); | ||
if (libctx == NULL) | ||
return 0; | ||
if (!OSSL_LIB_CTX_load_config(libctx, config_file)) { | ||
opt_printf_stderr("Failed to load config\n"); | ||
return 0; | ||
} | ||
ADD_TEST(test_keygen_pairwise_failure); | ||
return 1; | ||
} | ||
|
||
void cleanup_tests(void) | ||
{ | ||
OSSL_LIB_CTX_free(libctx); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
#! /usr/bin/env perl | ||
# Copyright 2023 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_file srctop_dir data_file); | ||
use OpenSSL::Test::Utils; | ||
|
||
BEGIN { | ||
setup("test_pairwise_fail"); | ||
} | ||
|
||
use lib srctop_dir('Configurations'); | ||
use lib bldtop_dir('.'); | ||
|
||
plan skip_all => "These tests are unsupported in a non fips build" | ||
if disabled("fips"); | ||
|
||
plan tests => 5; | ||
my $provconf = srctop_file("test", "fips-and-base.cnf"); | ||
|
||
run(test(["fips_version_test", "-config", $provconf, ">=3.1.0"]), | ||
capture => 1, statusvar => \my $fips_exit); | ||
|
||
SKIP: { | ||
skip "Skip RSA test because of no rsa in this build", 1 | ||
if disabled("rsa"); | ||
ok(run(test(["pairwise_fail_test", "-config", $provconf, | ||
"-pairwise", "rsa"])), | ||
"fips provider rsa keygen pairwise failure test"); | ||
} | ||
|
||
SKIP: { | ||
skip "Skip EC test because of no ec in this build", 2 | ||
if disabled("ec"); | ||
ok(run(test(["pairwise_fail_test", "-config", $provconf, | ||
"-pairwise", "ec"])), | ||
"fips provider ec keygen pairwise failure test"); | ||
|
||
skip "FIPS provider version is too old", 1 | ||
if !$fips_exit; | ||
ok(run(test(["pairwise_fail_test", "-config", $provconf, | ||
"-pairwise", "eckat"])), | ||
"fips provider ec keygen kat failure test"); | ||
} | ||
|
||
SKIP: { | ||
skip "Skip DSA tests because of no dsa in this build", 2 | ||
if disabled("dsa"); | ||
ok(run(test(["pairwise_fail_test", "-config", $provconf, | ||
"-pairwise", "dsa", "-dsaparam", data_file("dsaparam.pem")])), | ||
"fips provider dsa keygen pairwise failure test"); | ||
|
||
skip "FIPS provider version is too old", 1 | ||
if !$fips_exit; | ||
ok(run(test(["pairwise_fail_test", "-config", $provconf, | ||
"-pairwise", "dsakat", "-dsaparam", data_file("dsaparam.pem")])), | ||
"fips provider dsa keygen kat failure test"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
-----BEGIN DSA PARAMETERS----- | ||
MIICLQKCAQEA2Drds0DjRV8ht73dVp44MMtcjvSxugNuElrwheVB5Bm1wsmrEVnt | ||
MSGdZJ5FpndQD/ndqSctTssjW+cxjJ4mHjVTXpTZURQZW0MNkn7+qVw6oFrnd+qq | ||
tDkh0jnaTYTNiEp6qm5QmnEC/Ccvr3YZuY9EHurzVptJuoRIMgFGCz4CHj5q2vQ/ | ||
CPvBohUSvC9EmKGveWGFID+tmFWuHZ9d9pF/GWjA2rdW//uRiStssbN24jscsbZ6 | ||
XnNrJpgyGYYjugsl+catrMkodstrLsk7YvEYcE6YYN0TwZc9kjJ5f3ydQnI35Y/s | ||
EQPtP7DdA8aLaOC1ra2Nakm2ZW+pkygPMQIhAI2NF0GuR7NjD7lXx6gnVyk3p6gR | ||
l7u+BNIhHFVJP2/9AoIBAQCvGDoQ9S6So58RDz15ghYjpdNSzCBtA6ixYszesSJU | ||
DksnEDV34AEB2C8/uvzcSIca3314dDsE2R0ubTrh4J/2JNbNE9M5UYEaJh0oK7LW | ||
h7YZ2XI5j08/aAApRsR84kcZdE3r+QYFHTuEnoc0ADkC3J9uIuQwl/CgTkw56OBP | ||
MmA1GD79/MeYc/mvJujujWG0Y+tyuQCORzcYccEpYR8q6kf1r7+IUy1L8r4XFIwM | ||
oW9eB4XyTrA8wKtWQfEpSAo+PX59hfafuOG8wKUPbTANSFK2ePQRJO/6T81rofOF | ||
Bz9oeTjZV0f0EkJIcF14V2rksGVT0kAHndBw73w27ofj | ||
-----END DSA PARAMETERS----- |