From: Pauli Date: Mon, 12 Sep 2022 22:49:05 +0000 (+1000) Subject: evp_test: allow FIPS provider version based escapes in evp_test X-Git-Tag: openssl-3.2.0-alpha1~2080 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=54a7bbedf43a1ade98c8f47eb8896d75f3db0165;p=thirdparty%2Fopenssl.git 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) --- diff --git a/test/evp_test.c b/test/evp_test.c index 403efb3e25c..e4350c39b4d 100644 --- a/test/evp_test.c +++ b/test/evp_test.c @@ -1596,7 +1596,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; @@ -2822,7 +2823,9 @@ static int kdf_test_run(EVP_TEST *t) t->err = "INTERNAL_ERROR"; goto err; } - if ((ctx = EVP_KDF_CTX_dup(expected->ctx)) != NULL) { + /* 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); expected->ctx = ctx; } @@ -2918,21 +2921,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"; @@ -3729,13 +3737,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 { @@ -3822,7 +3896,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; } @@ -3841,7 +3931,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; } @@ -3858,7 +3948,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