From 8462f5d441a3d61810118bb1a548dc0a0152b188 Mon Sep 17 00:00:00 2001 From: Pauli Date: Tue, 13 Sep 2022 08:49:05 +1000 Subject: evp_test: allow FIPS provider version based escapes in evp_test Also fix a number of regressions when run against the 3.0.0 FIPS provider that result from bug fixes. Reviewed-by: Matt Caswell Reviewed-by: Tomas Mraz Reviewed-by: Shane Lontis (Merged from https://github.com/openssl/openssl/pull/19201) (cherry picked from commit 54a7bbedf43a1ade98c8f47eb8896d75f3db0165) --- test/evp_test.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 107 insertions(+), 19 deletions(-) diff --git a/test/evp_test.c b/test/evp_test.c index ce4c66ddcc..2be97e916e 100644 --- a/test/evp_test.c +++ b/test/evp_test.c @@ -1575,7 +1575,8 @@ static int mac_test_run_mac(EVP_TEST *t) goto err; } } - if (reinit--) { + /* 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; @@ -2882,21 +2883,26 @@ static int pkey_kdf_test_run(EVP_TEST *t) unsigned char *got = NULL; size_t got_len = 0; - /* Find out the KDF output size */ - if (EVP_PKEY_derive(expected->ctx, NULL, &got_len) <= 0) { - t->err = "INTERNAL_ERROR"; - goto err; - } - - /* - * We may get an absurd output size, which signals that anything goes. - * If not, we specify a too big buffer for the output, to test that - * EVP_PKEY_derive() can cope with it. - */ - if (got_len == SIZE_MAX || got_len == 0) + if (fips_provider_version_eq(libctx, 3, 0, 0)) { + /* FIPS 3.0.0 can't deal with oversized output buffers #18533 */ got_len = expected->output_len; - else - got_len = expected->output_len * 2; + } else { + /* Find out the KDF output size */ + if (EVP_PKEY_derive(expected->ctx, NULL, &got_len) <= 0) { + t->err = "INTERNAL_ERROR"; + goto err; + } + + /* + * We may get an absurd output size, which signals that anything goes. + * If not, we specify a too big buffer for the output, to test that + * EVP_PKEY_derive() can cope with it. + */ + if (got_len == SIZE_MAX || got_len == 0) + got_len = expected->output_len; + else + got_len = expected->output_len * 2; + } if (!TEST_ptr(got = OPENSSL_malloc(got_len == 0 ? 1 : got_len))) { t->err = "INTERNAL_ERROR"; @@ -3693,13 +3699,79 @@ 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) { KEY_LIST *key, **klist; EVP_PKEY *pkey; PAIR *pp; - int i, skip_availablein = 0; + int i, j, skipped = 0; top: do { @@ -3786,7 +3858,23 @@ start: t->skip = 1; return 0; } - skip_availablein++; + skipped++; + pp++; + goto start; + } else if (strcmp(pp->key, "FIPSversion") == 0) { + if (prov_available("fips")) { + j = check_fips_versions(pp->value, t); + if (j < 0) { + TEST_info("Line %d: error matching FIPS versions\n", t->s.curr); + return 0; + } else if (j == 0) { + TEST_info("skipping, FIPS provider incompatible version: %s:%d", + t->s.test_file, t->s.start); + t->skip = 1; + return 0; + } + } + skipped++; pp++; goto start; } @@ -3805,7 +3893,7 @@ start: *klist = key; /* Go back and start a new stanza. */ - if ((t->s.numpairs - skip_availablein) != 1) + if ((t->s.numpairs - skipped) != 1) TEST_info("Line %d: missing blank line\n", t->s.curr); goto top; } @@ -3822,7 +3910,7 @@ start: return 0; } - for (pp++, i = 1; i < (t->s.numpairs - skip_availablein); pp++, i++) { + for (pp++, i = 1; i < (t->s.numpairs - skipped); pp++, i++) { if (strcmp(pp->key, "Securitycheck") == 0) { #if defined(OPENSSL_NO_FIPS_SECURITYCHECKS) #else -- cgit v1.2.3