With fips provider 3.0.0 skip tests related to explicit curves handling

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/19201)
This commit is contained in:
Tomas Mraz 2022-09-13 22:38:30 +02:00 committed by Pauli
parent c342004e07
commit e1289d90d0
7 changed files with 178 additions and 77 deletions

View File

@ -63,7 +63,7 @@ IF[{- !$disabled{tests} -}]
keymgmt_internal_test hexstr_test provider_status_test defltfips_test \
bio_readbuffer_test user_property_test pkcs7_test upcallstest \
provfetchtest prov_config_test rand_test ca_internals_test \
bio_tfo_test membio_test list_test
bio_tfo_test membio_test list_test fips_version_test
IF[{- !$disabled{'deprecated-3.0'} -}]
PROGRAMS{noinst}=enginetest
@ -427,6 +427,10 @@ IF[{- !$disabled{tests} -}]
INCLUDE[defltfips_test]=../include ../apps/include
DEPEND[defltfips_test]=../libcrypto libtestutil.a
SOURCE[fips_version_test]=fips_version_test.c
INCLUDE[fips_version_test]=../include ../apps/include
DEPEND[fips_version_test]=../libcrypto libtestutil.a
SOURCE[ocspapitest]=ocspapitest.c
INCLUDE[ocspapitest]=../include ../apps/include
DEPEND[ocspapitest]=../libcrypto libtestutil.a

View File

@ -47,6 +47,7 @@ OSSL_provider_init_fn ossl_legacy_provider_init;
static int default_libctx = 1;
static int is_fips = 0;
static int is_fips_3_0_0 = 0;
static OSSL_LIB_CTX *testctx = NULL;
static OSSL_LIB_CTX *keyctx = NULL;
@ -174,7 +175,7 @@ static int test_encode_decode(const char *file, const int line,
output_type, output_structure, pass, pcipher)))
goto end;
if ((flags & FLAG_FAIL_IF_FIPS) != 0 && is_fips) {
if ((flags & FLAG_FAIL_IF_FIPS) != 0 && is_fips && !is_fips_3_0_0) {
if (TEST_false(decode_cb(file, line, (void **)&pkey2, encoded,
encoded_len, output_type, output_structure,
(flags & FLAG_DECODE_WITH_TYPE ? type : NULL),
@ -1323,6 +1324,11 @@ int setup_tests(void)
return 0;
}
/* FIPS(3.0.0): provider imports explicit params but they won't work #17998 */
is_fips_3_0_0 = fips_provider_version_eq(testctx, 3, 0, 0);
if (is_fips_3_0_0 < 0)
return 0;
#ifdef STATIC_LEGACY
/*
* This test is always statically linked against libcrypto. We must not

View File

@ -1596,7 +1596,7 @@ static int mac_test_run_mac(EVP_TEST *t)
goto err;
}
}
/* FIPS 3.0.0 can't reinitialise MAC contexts #18100 */
/* FIPS(3.0.0): can't reinitialise MAC contexts #18100 */
if (reinit-- && fips_provider_version_gt(libctx, 3, 0, 0)) {
OSSL_PARAM ivparams[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
int ret;
@ -2823,7 +2823,7 @@ static int kdf_test_run(EVP_TEST *t)
t->err = "INTERNAL_ERROR";
goto err;
}
/* FIPS 3.0.0 can't dup KDF contexts #17572 */
/* FIPS(3.0.0): can't dup KDF contexts #17572 */
if (fips_provider_version_gt(libctx, 3, 0, 0)
&& (ctx = EVP_KDF_CTX_dup(expected->ctx)) != NULL) {
EVP_KDF_CTX_free(expected->ctx);
@ -2922,7 +2922,7 @@ static int pkey_kdf_test_run(EVP_TEST *t)
size_t got_len = 0;
if (fips_provider_version_eq(libctx, 3, 0, 0)) {
/* FIPS 3.0.0 can't deal with oversized output buffers #18533 */
/* FIPS(3.0.0): can't deal with oversized output buffers #18533 */
got_len = expected->output_len;
} else {
/* Find out the KDF output size */
@ -3737,72 +3737,6 @@ static int prov_available(char *providers)
return 0;
}
static int check_fips_versions(char *versions, const EVP_TEST *t)
{
char *p;
int major, minor, patch, r;
enum {
MODE_EQ, MODE_NE, MODE_LE, MODE_GT
} mode;
while (*versions != '\0') {
for (; isspace(*versions); versions++)
continue;
if (*versions == '\0')
break;
for (p = versions; *versions != '\0' && !isspace(*versions); versions++)
continue;
if (*versions != '\0')
*versions++ = '\0';
if (*p == '!') {
mode = MODE_NE;
p++;
} else if (*p == '=') {
mode = MODE_EQ;
p++;
} else if (*p == '<' && p[1] == '=') {
mode = MODE_LE;
p += 2;
} else if (*p == '>') {
mode = MODE_GT;
p++;
} else if (isdigit(*p)) {
mode = MODE_EQ;
} else {
TEST_info("Line %d: error matching FIPS version: mode %s\n",
t->s.curr, p);
return -1;
}
if (sscanf(p, "%d.%d.%d", &major, &minor, &patch) != 3) {
TEST_info("Line %d: error matching FIPS version: version %s\n",
t->s.curr, p);
return -1;
}
switch (mode) {
case MODE_EQ:
r = fips_provider_version_eq(libctx, major, minor, patch);
break;
case MODE_NE:
r = fips_provider_version_ne(libctx, major, minor, patch);
break;
case MODE_LE:
r = fips_provider_version_le(libctx, major, minor, patch);
break;
case MODE_GT:
r = fips_provider_version_gt(libctx, major, minor, patch);
break;
}
if (r < 0) {
TEST_info("Line %d: error matching FIPS version: internal error\n",
t->s.curr);
return -1;
}
if (r == 0)
return 0;
}
return 1;
}
/* Read and parse one test. Return 0 if failure, 1 if okay. */
static int parse(EVP_TEST *t)
{
@ -3901,7 +3835,7 @@ start:
goto start;
} else if (strcmp(pp->key, "FIPSversion") == 0) {
if (prov_available("fips")) {
j = check_fips_versions(pp->value, t);
j = fips_provider_version_match(libctx, pp->value);
if (j < 0) {
TEST_info("Line %d: error matching FIPS versions\n", t->s.curr);
return 0;

78
test/fips_version_test.c Normal file
View File

@ -0,0 +1,78 @@
/*
* Copyright 2022 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/evp.h>
#include <openssl/provider.h>
#include "testutil.h"
static OSSL_LIB_CTX *libctx = NULL;
static OSSL_PROVIDER *libprov = NULL;
typedef enum OPTION_choice {
OPT_ERR = -1,
OPT_EOF = 0,
OPT_CONFIG_FILE,
OPT_TEST_ENUM
} OPTION_CHOICE;
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" },
{ NULL }
};
return test_options;
}
static int test_fips_version(int n)
{
const char *version = test_get_argument(n);
if (!TEST_ptr(version))
return 0;
return TEST_int_eq(fips_provider_version_match(libctx, version), 1);
}
int setup_tests(void)
{
char *config_file = NULL;
OPTION_CHOICE o;
int n;
while ((o = opt_next()) != OPT_EOF) {
switch (o) {
case OPT_CONFIG_FILE:
config_file = opt_arg();
break;
case OPT_TEST_CASES:
break;
default:
case OPT_ERR:
return 0;
}
}
if (!test_get_libctx(&libctx, NULL, config_file, &libprov, NULL))
return 0;
n = test_get_argument_count();
if (n == 0)
return 0;
ADD_ALL_TESTS(test_fips_version, n);
return 1;
}
void cleanup_tests(void)
{
OSSL_PROVIDER_unload(libprov);
OSSL_LIB_CTX_free(libctx);
}

View File

@ -354,12 +354,18 @@ SKIP: {
# Same as above but with base provider used for decoding
SKIP: {
my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0);
skip "EC is not supported or FIPS is disabled", 3
if disabled("ec") || $no_fips;
my $provconf = srctop_file("test", "fips-and-base.cnf");
my $provpath = bldtop_dir("providers");
my @prov = ("-provider-path", $provpath);
skip "EC is not supported or FIPS is disabled", 3
if disabled("ec") || $no_fips;
run(test(["fips_version_test", "-config", $provconf, ">3.0.0"]),
capture => 1, statusvar => \my $exit);
skip "FIPS provider version is too old", 3
if !$exit;
$ENV{OPENSSL_CONF} = $provconf;
ok(!verify("ee-cert-ec-explicit", "", ["root-cert"],

View File

@ -240,7 +240,7 @@ void cleanup_tests(void);
/*
* Helper functions to detect specific versions of the FIPS provider being in use.
* Because of FIPS rules, code changes after a module has been validated are
* difficult and because we provide an hard guarantee of ABI and behavioural
* difficult and because we provide a hard guarantee of ABI and behavioural
* stability going forwards, it is a requirement to have tests be conditional
* on specific FIPS provider versions. Without this, bug fixes cannot be tested
* in later releases.
@ -259,6 +259,17 @@ int fips_provider_version_ne(OSSL_LIB_CTX *libctx, int major, int minor, int pat
int fips_provider_version_le(OSSL_LIB_CTX *libctx, int major, int minor, int patch);
int fips_provider_version_gt(OSSL_LIB_CTX *libctx, int major, int minor, int patch);
/*
* This function matches fips provider version with (potentially multiple)
* <operator>maj.min.patch version strings in versions.
* The operator can be one of = ! <= or > comparison symbols.
* If the fips provider matches all the version comparisons (or if there is no
* fips provider available) the function returns 1.
* If the fips provider does not match the version comparisons, it returns 0.
* On error the function returns -1.
*/
int fips_provider_version_match(OSSL_LIB_CTX *libctx, const char *versions);
/*
* Used to supply test specific command line options,
* If non optional parameters are used, then the first entry in the OPTIONS[]

View File

@ -8,6 +8,7 @@
*/
#include "../testutil.h"
#include <ctype.h>
#include <openssl/provider.h>
#include <openssl/core_names.h>
#include <string.h>
@ -88,7 +89,7 @@ static int fips_provider_version(OSSL_LIB_CTX *libctx, FIPS_VERSION *vers)
|| sscanf(vs, "%d.%d.%d", &vers->major, &vers->minor, &vers->patch) != 3)
goto err;
if (!OSSL_PROVIDER_unload(fips_prov))
return -1; /* WTF do we do here??? */
return -1;
return 1;
err:
OSSL_PROVIDER_unload(fips_prov);
@ -140,3 +141,64 @@ int fips_provider_version_gt(OSSL_LIB_CTX *libctx, int major, int minor, int pat
&& (prov.minor > minor
|| (prov.minor == minor && prov.patch > patch)));
}
int fips_provider_version_match(OSSL_LIB_CTX *libctx, const char *versions)
{
const char *p;
int major, minor, patch, r;
enum {
MODE_EQ, MODE_NE, MODE_LE, MODE_GT
} mode;
while (*versions != '\0') {
for (; isspace(*versions); versions++)
continue;
if (*versions == '\0')
break;
for (p = versions; *versions != '\0' && !isspace(*versions); versions++)
continue;
if (*p == '!') {
mode = MODE_NE;
p++;
} else if (*p == '=') {
mode = MODE_EQ;
p++;
} else if (*p == '<' && p[1] == '=') {
mode = MODE_LE;
p += 2;
} else if (*p == '>') {
mode = MODE_GT;
p++;
} else if (isdigit(*p)) {
mode = MODE_EQ;
} else {
TEST_info("Error matching FIPS version: mode %s\n", p);
return -1;
}
if (sscanf(p, "%d.%d.%d", &major, &minor, &patch) != 3) {
TEST_info("Error matching FIPS version: version %s\n", p);
return -1;
}
switch (mode) {
case MODE_EQ:
r = fips_provider_version_eq(libctx, major, minor, patch);
break;
case MODE_NE:
r = fips_provider_version_ne(libctx, major, minor, patch);
break;
case MODE_LE:
r = fips_provider_version_le(libctx, major, minor, patch);
break;
case MODE_GT:
r = fips_provider_version_gt(libctx, major, minor, patch);
break;
}
if (r < 0) {
TEST_info("Error matching FIPS version: internal error\n");
return -1;
}
if (r == 0)
return 0;
}
return 1;
}