mirror of https://github.com/openssl/openssl.git
				
				
				
			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 \ | ||||
|           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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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 | ||||
| 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"], | ||||
|  |  | |||
|  | @ -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[] | ||||
|  |  | |||
|  | @ -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; | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue