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:
parent
c342004e07
commit
e1289d90d0
@ -63,7 +63,7 @@ IF[{- !$disabled{tests} -}]
|
|||||||
keymgmt_internal_test hexstr_test provider_status_test defltfips_test \
|
keymgmt_internal_test hexstr_test provider_status_test defltfips_test \
|
||||||
bio_readbuffer_test user_property_test pkcs7_test upcallstest \
|
bio_readbuffer_test user_property_test pkcs7_test upcallstest \
|
||||||
provfetchtest prov_config_test rand_test ca_internals_test \
|
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'} -}]
|
IF[{- !$disabled{'deprecated-3.0'} -}]
|
||||||
PROGRAMS{noinst}=enginetest
|
PROGRAMS{noinst}=enginetest
|
||||||
@ -427,6 +427,10 @@ IF[{- !$disabled{tests} -}]
|
|||||||
INCLUDE[defltfips_test]=../include ../apps/include
|
INCLUDE[defltfips_test]=../include ../apps/include
|
||||||
DEPEND[defltfips_test]=../libcrypto libtestutil.a
|
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
|
SOURCE[ocspapitest]=ocspapitest.c
|
||||||
INCLUDE[ocspapitest]=../include ../apps/include
|
INCLUDE[ocspapitest]=../include ../apps/include
|
||||||
DEPEND[ocspapitest]=../libcrypto libtestutil.a
|
DEPEND[ocspapitest]=../libcrypto libtestutil.a
|
||||||
|
@ -47,6 +47,7 @@ OSSL_provider_init_fn ossl_legacy_provider_init;
|
|||||||
|
|
||||||
static int default_libctx = 1;
|
static int default_libctx = 1;
|
||||||
static int is_fips = 0;
|
static int is_fips = 0;
|
||||||
|
static int is_fips_3_0_0 = 0;
|
||||||
|
|
||||||
static OSSL_LIB_CTX *testctx = NULL;
|
static OSSL_LIB_CTX *testctx = NULL;
|
||||||
static OSSL_LIB_CTX *keyctx = 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)))
|
output_type, output_structure, pass, pcipher)))
|
||||||
goto end;
|
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,
|
if (TEST_false(decode_cb(file, line, (void **)&pkey2, encoded,
|
||||||
encoded_len, output_type, output_structure,
|
encoded_len, output_type, output_structure,
|
||||||
(flags & FLAG_DECODE_WITH_TYPE ? type : NULL),
|
(flags & FLAG_DECODE_WITH_TYPE ? type : NULL),
|
||||||
@ -1323,6 +1324,11 @@ int setup_tests(void)
|
|||||||
return 0;
|
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
|
#ifdef STATIC_LEGACY
|
||||||
/*
|
/*
|
||||||
* This test is always statically linked against libcrypto. We must not
|
* This test is always statically linked against libcrypto. We must not
|
||||||
|
@ -1596,7 +1596,7 @@ static int mac_test_run_mac(EVP_TEST *t)
|
|||||||
goto err;
|
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)) {
|
if (reinit-- && fips_provider_version_gt(libctx, 3, 0, 0)) {
|
||||||
OSSL_PARAM ivparams[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
OSSL_PARAM ivparams[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||||
int ret;
|
int ret;
|
||||||
@ -2823,7 +2823,7 @@ static int kdf_test_run(EVP_TEST *t)
|
|||||||
t->err = "INTERNAL_ERROR";
|
t->err = "INTERNAL_ERROR";
|
||||||
goto err;
|
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)
|
if (fips_provider_version_gt(libctx, 3, 0, 0)
|
||||||
&& (ctx = EVP_KDF_CTX_dup(expected->ctx)) != NULL) {
|
&& (ctx = EVP_KDF_CTX_dup(expected->ctx)) != NULL) {
|
||||||
EVP_KDF_CTX_free(expected->ctx);
|
EVP_KDF_CTX_free(expected->ctx);
|
||||||
@ -2922,7 +2922,7 @@ static int pkey_kdf_test_run(EVP_TEST *t)
|
|||||||
size_t got_len = 0;
|
size_t got_len = 0;
|
||||||
|
|
||||||
if (fips_provider_version_eq(libctx, 3, 0, 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;
|
got_len = expected->output_len;
|
||||||
} else {
|
} else {
|
||||||
/* Find out the KDF output size */
|
/* Find out the KDF output size */
|
||||||
@ -3737,72 +3737,6 @@ static int prov_available(char *providers)
|
|||||||
return 0;
|
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. */
|
/* Read and parse one test. Return 0 if failure, 1 if okay. */
|
||||||
static int parse(EVP_TEST *t)
|
static int parse(EVP_TEST *t)
|
||||||
{
|
{
|
||||||
@ -3901,7 +3835,7 @@ start:
|
|||||||
goto start;
|
goto start;
|
||||||
} else if (strcmp(pp->key, "FIPSversion") == 0) {
|
} else if (strcmp(pp->key, "FIPSversion") == 0) {
|
||||||
if (prov_available("fips")) {
|
if (prov_available("fips")) {
|
||||||
j = check_fips_versions(pp->value, t);
|
j = fips_provider_version_match(libctx, pp->value);
|
||||||
if (j < 0) {
|
if (j < 0) {
|
||||||
TEST_info("Line %d: error matching FIPS versions\n", t->s.curr);
|
TEST_info("Line %d: error matching FIPS versions\n", t->s.curr);
|
||||||
return 0;
|
return 0;
|
||||||
|
78
test/fips_version_test.c
Normal file
78
test/fips_version_test.c
Normal 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);
|
||||||
|
}
|
@ -354,12 +354,18 @@ SKIP: {
|
|||||||
# Same as above but with base provider used for decoding
|
# Same as above but with base provider used for decoding
|
||||||
SKIP: {
|
SKIP: {
|
||||||
my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0);
|
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 $provconf = srctop_file("test", "fips-and-base.cnf");
|
||||||
my $provpath = bldtop_dir("providers");
|
my $provpath = bldtop_dir("providers");
|
||||||
my @prov = ("-provider-path", $provpath);
|
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;
|
$ENV{OPENSSL_CONF} = $provconf;
|
||||||
|
|
||||||
ok(!verify("ee-cert-ec-explicit", "", ["root-cert"],
|
ok(!verify("ee-cert-ec-explicit", "", ["root-cert"],
|
||||||
|
@ -240,7 +240,7 @@ void cleanup_tests(void);
|
|||||||
/*
|
/*
|
||||||
* Helper functions to detect specific versions of the FIPS provider being in use.
|
* 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
|
* 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
|
* stability going forwards, it is a requirement to have tests be conditional
|
||||||
* on specific FIPS provider versions. Without this, bug fixes cannot be tested
|
* on specific FIPS provider versions. Without this, bug fixes cannot be tested
|
||||||
* in later releases.
|
* 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_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);
|
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,
|
* Used to supply test specific command line options,
|
||||||
* If non optional parameters are used, then the first entry in the OPTIONS[]
|
* If non optional parameters are used, then the first entry in the OPTIONS[]
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "../testutil.h"
|
#include "../testutil.h"
|
||||||
|
#include <ctype.h>
|
||||||
#include <openssl/provider.h>
|
#include <openssl/provider.h>
|
||||||
#include <openssl/core_names.h>
|
#include <openssl/core_names.h>
|
||||||
#include <string.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)
|
|| sscanf(vs, "%d.%d.%d", &vers->major, &vers->minor, &vers->patch) != 3)
|
||||||
goto err;
|
goto err;
|
||||||
if (!OSSL_PROVIDER_unload(fips_prov))
|
if (!OSSL_PROVIDER_unload(fips_prov))
|
||||||
return -1; /* WTF do we do here??? */
|
return -1;
|
||||||
return 1;
|
return 1;
|
||||||
err:
|
err:
|
||||||
OSSL_PROVIDER_unload(fips_prov);
|
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.minor == minor && prov.patch > patch)));
|
|| (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;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user