]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
evp_test: allow FIPS provider version based escapes in evp_test
authorPauli <pauli@openssl.org>
Mon, 12 Sep 2022 22:49:05 +0000 (08:49 +1000)
committerPauli <pauli@openssl.org>
Thu, 15 Sep 2022 22:34:52 +0000 (08:34 +1000)
Also fix a number of regressions when run against the 3.0.0 FIPS provider
that result from bug fixes.

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/19201)

test/evp_test.c

index 403efb3e25cf2a8b15967581c8e7d338e2a2310e..e4350c39b4d37778fdd50caea99112047b7d2168 100644 (file)
@@ -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