Add EVP_KDF-X942 to the fips module
[openssl.git] / test / evp_test.c
index a1e205b20b5917a45d4db8bf9604ab6d7edace2b..d4d60694d428b38c740c2d7badc5b5d4cede5860 100644 (file)
@@ -11,6 +11,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <ctype.h>
+#include "../e_os.h" /* strcasecmp */
 #include <openssl/evp.h>
 #include <openssl/pem.h>
 #include <openssl/err.h>
 #include <openssl/kdf.h>
 #include <openssl/params.h>
 #include <openssl/core_names.h>
+#include <openssl/fips_names.h>
 #include "internal/numbers.h"
 #include "internal/nelem.h"
+#include "crypto/evp.h"
 #include "testutil.h"
-#include "evp_test.h"
 
-DEFINE_STACK_OF_STRING()
+typedef struct evp_test_buffer_st EVP_TEST_BUFFER;
+DEFINE_STACK_OF(EVP_TEST_BUFFER)
 
 #define AAD_NUM 4
 
 typedef struct evp_test_method_st EVP_TEST_METHOD;
 
-/*
- * Structure holding test information
- */
+/* Structure holding test information */
 typedef struct evp_test_st {
     STANZA s;                     /* Common test stanza */
     char *name;
@@ -45,9 +46,7 @@ typedef struct evp_test_st {
     void *data;                   /* test specific data */
 } EVP_TEST;
 
-/*
- * Test method structure
- */
+/* Test method structure */
 struct evp_test_method_st {
     /* Name of test as it appears in file */
     const char *name;
@@ -61,24 +60,34 @@ struct evp_test_method_st {
     int (*run_test) (EVP_TEST * t);
 };
 
-
-/*
- * Linked list of named keys.
- */
+/* Linked list of named keys. */
 typedef struct key_list_st {
     char *name;
     EVP_PKEY *key;
     struct key_list_st *next;
 } KEY_LIST;
 
-/*
- * List of public and private keys
- */
+typedef enum OPTION_choice {
+    OPT_ERR = -1,
+    OPT_EOF = 0,
+    OPT_CONFIG_FILE,
+    OPT_TEST_ENUM
+} OPTION_CHOICE;
+
+static OSSL_PROVIDER *prov_null = NULL;
+static OSSL_LIB_CTX *libctx = NULL;
+
+/* List of public and private keys */
 static KEY_LIST *private_keys;
 static KEY_LIST *public_keys;
-static int find_key(EVP_PKEY **ppk, const char *name, KEY_LIST *lst);
 
+static int find_key(EVP_PKEY **ppk, const char *name, KEY_LIST *lst);
 static int parse_bin(const char *value, unsigned char **buf, size_t *buflen);
+static int is_digest_disabled(const char *name);
+static int is_pkey_disabled(const char *name);
+static int is_mac_disabled(const char *name);
+static int is_cipher_disabled(const char *name);
+static int is_kdf_disabled(const char *name);
 
 /*
  * Compare two memory regions for equality, returning zero if they differ.
@@ -120,9 +129,7 @@ static void evp_test_buffer_free(EVP_TEST_BUFFER *db)
     }
 }
 
-/*
- * append buffer to a list
- */
+/* append buffer to a list */
 static int evp_test_buffer_append(const char *value,
                                   STACK_OF(EVP_TEST_BUFFER) **sk)
 {
@@ -148,9 +155,7 @@ err:
     return 0;
 }
 
-/*
- * replace last buffer in list with copies of itself
- */
+/* replace last buffer in list with copies of itself */
 static int evp_test_buffer_ncopy(const char *value,
                                  STACK_OF(EVP_TEST_BUFFER) *sk)
 {
@@ -178,9 +183,7 @@ static int evp_test_buffer_ncopy(const char *value,
     return 1;
 }
 
-/*
- * set repeat count for last buffer in list
- */
+/* set repeat count for last buffer in list */
 static int evp_test_buffer_set_count(const char *value,
                                      STACK_OF(EVP_TEST_BUFFER) *sk)
 {
@@ -202,9 +205,7 @@ static int evp_test_buffer_set_count(const char *value,
     return 1;
 }
 
-/*
- * call "fn" with each element of the list in turn
- */
+/* call "fn" with each element of the list in turn */
 static int evp_test_buffer_do(STACK_OF(EVP_TEST_BUFFER) *sk,
                               int (*fn)(void *ctx,
                                         const unsigned char *buf,
@@ -319,10 +320,9 @@ static int parse_bin(const char *value, unsigned char **buf, size_t *buflen)
     return 1;
 }
 
-
 /**
-***  MESSAGE DIGEST TESTS
-**/
+ **  MESSAGE DIGEST TESTS
+ **/
 
 typedef struct digest_data_st {
     /* Digest this test is for */
@@ -343,15 +343,15 @@ static int digest_test_init(EVP_TEST *t, const char *alg)
     const EVP_MD *digest;
     EVP_MD *fetched_digest;
 
-    if ((digest = fetched_digest = EVP_MD_fetch(NULL, alg, NULL)) == NULL
-        && (digest = EVP_get_digestbyname(alg)) == NULL) {
-        /* If alg has an OID assume disabled algorithm */
-        if (OBJ_sn2nid(alg) != NID_undef || OBJ_ln2nid(alg) != NID_undef) {
-            t->skip = 1;
-            return 1;
-        }
-        return 0;
+    if (is_digest_disabled(alg)) {
+        TEST_info("skipping, '%s' is disabled", alg);
+        t->skip = 1;
+        return 1;
     }
+
+    if ((digest = fetched_digest = EVP_MD_fetch(libctx, alg, NULL)) == NULL
+        && (digest = EVP_get_digestbyname(alg)) == NULL)
+        return 0;
     if (!TEST_ptr(mdat = OPENSSL_zalloc(sizeof(*mdat))))
         return 0;
     t->data = mdat;
@@ -369,7 +369,7 @@ static void digest_test_cleanup(EVP_TEST *t)
 
     sk_EVP_TEST_BUFFER_pop_free(mdat->input, evp_test_buffer_free);
     OPENSSL_free(mdat->output);
-    EVP_MD_meth_free(mdat->fetched_digest);
+    EVP_MD_free(mdat->fetched_digest);
 }
 
 static int digest_test_parse(EVP_TEST *t,
@@ -489,7 +489,6 @@ static const EVP_TEST_METHOD digest_test_method = {
     digest_test_run
 };
 
-
 /**
 ***  CIPHER TESTS
 **/
@@ -526,15 +525,16 @@ static int cipher_test_init(EVP_TEST *t, const char *alg)
     CIPHER_DATA *cdat;
     int m;
 
-    if ((cipher = fetched_cipher = EVP_CIPHER_fetch(NULL, alg, NULL)) == NULL
-        && (cipher = EVP_get_cipherbyname(alg)) == NULL) {
-        /* If alg has an OID assume disabled algorithm */
-        if (OBJ_sn2nid(alg) != NID_undef || OBJ_ln2nid(alg) != NID_undef) {
-            t->skip = 1;
-            return 1;
-        }
-        return 0;
+    if (is_cipher_disabled(alg)) {
+        t->skip = 1;
+        TEST_info("skipping, '%s' is disabled", alg);
+        return 1;
     }
+
+    if ((cipher = fetched_cipher = EVP_CIPHER_fetch(libctx, alg, NULL)) == NULL
+        && (cipher = EVP_get_cipherbyname(alg)) == NULL)
+        return 0;
+
     cdat = OPENSSL_zalloc(sizeof(*cdat));
     cdat->cipher = cipher;
     cdat->fetched_cipher = fetched_cipher;
@@ -568,7 +568,7 @@ static void cipher_test_cleanup(EVP_TEST *t)
     for (i = 0; i < AAD_NUM; i++)
         OPENSSL_free(cdat->aad[i]);
     OPENSSL_free(cdat->tag);
-    EVP_CIPHER_meth_free(cdat->fetched_cipher);
+    EVP_CIPHER_free(cdat->fetched_cipher);
 }
 
 static int cipher_test_parse(EVP_TEST *t, const char *keyword,
@@ -664,9 +664,7 @@ static int cipher_test_enc(EVP_TEST *t, int enc,
         out_len = expected->plaintext_len;
     }
     if (inp_misalign == (size_t)-1) {
-        /*
-         * Exercise in-place encryption
-         */
+        /* Exercise in-place encryption */
         tmp = OPENSSL_malloc(out_misalign + in_len + 2 * EVP_MAX_BLOCK_LENGTH);
         if (!tmp)
             goto err;
@@ -763,12 +761,16 @@ static int cipher_test_enc(EVP_TEST *t, int enc,
     }
 
     /* Check that we get the same IV back */
-    if (expected->iv != NULL
-        && (EVP_CIPHER_flags(expected->cipher) & EVP_CIPH_CUSTOM_IV) == 0
-        && !TEST_mem_eq(expected->iv, expected->iv_len,
-                        EVP_CIPHER_CTX_iv(ctx_base), expected->iv_len)) {
-        t->err = "INVALID_IV";
-        goto err;
+    if (expected->iv != NULL) {
+        /* Some (e.g., GCM) tests use IVs longer than EVP_MAX_IV_LENGTH. */
+        unsigned char iv[128];
+        if (!TEST_true(EVP_CIPHER_CTX_get_iv_state(ctx_base, iv, sizeof(iv)))
+                || ((EVP_CIPHER_flags(expected->cipher) & EVP_CIPH_CUSTOM_IV) == 0
+                    && !TEST_mem_eq(expected->iv, expected->iv_len, iv,
+                                    expected->iv_len))) {
+            t->err = "INVALID_IV";
+            goto err;
+        }
     }
 
     /* Test that the cipher dup functions correctly if it is supported */
@@ -982,8 +984,8 @@ static const EVP_TEST_METHOD cipher_test_method = {
 
 
 /**
-***  MAC TESTS
-**/
+ **  MAC TESTS
+ **/
 
 typedef struct mac_data_st {
     /* MAC type in one form or another */
@@ -1019,7 +1021,12 @@ static int mac_test_init(EVP_TEST *t, const char *alg)
     int type = NID_undef;
     MAC_DATA *mdat;
 
-    if ((mac = EVP_MAC_fetch(NULL, alg, NULL)) == NULL) {
+    if (is_mac_disabled(alg)) {
+        TEST_info("skipping, '%s' is disabled", alg);
+        t->skip = 1;
+        return 1;
+    }
+    if ((mac = EVP_MAC_fetch(libctx, alg, NULL)) == NULL) {
         /*
          * Since we didn't find an EVP_MAC, we check for known EVP_PKEY methods
          * For debugging purposes, we allow 'NNNN by EVP_PKEY' to force running
@@ -1032,41 +1039,16 @@ static int mac_test_init(EVP_TEST *t, const char *alg)
             && strcmp(alg + sz - (sizeof(epilogue) - 1), epilogue) == 0)
             sz -= sizeof(epilogue) - 1;
 
-        if (strncmp(alg, "HMAC", sz) == 0) {
+        if (strncmp(alg, "HMAC", sz) == 0)
             type = EVP_PKEY_HMAC;
-        } else if (strncmp(alg, "CMAC", sz) == 0) {
-#ifndef OPENSSL_NO_CMAC
+        else if (strncmp(alg, "CMAC", sz) == 0)
             type = EVP_PKEY_CMAC;
-#else
-            t->skip = 1;
-            return 1;
-#endif
-        } else if (strncmp(alg, "Poly1305", sz) == 0) {
-#ifndef OPENSSL_NO_POLY1305
+        else if (strncmp(alg, "Poly1305", sz) == 0)
             type = EVP_PKEY_POLY1305;
-#else
-            t->skip = 1;
-            return 1;
-#endif
-        } else if (strncmp(alg, "SipHash", sz) == 0) {
-#ifndef OPENSSL_NO_SIPHASH
+        else if (strncmp(alg, "SipHash", sz) == 0)
             type = EVP_PKEY_SIPHASH;
-#else
-            t->skip = 1;
-            return 1;
-#endif
-        } else {
-            /*
-             * Not a known EVP_PKEY method either.  If it's a known OID, then
-             * assume it's been disabled.
-             */
-            if (OBJ_sn2nid(alg) != NID_undef || OBJ_ln2nid(alg) != NID_undef) {
-                t->skip = 1;
-                return 1;
-            }
-
+        else
             return 0;
-        }
     }
 
     mdat = OPENSSL_zalloc(sizeof(*mdat));
@@ -1157,7 +1139,8 @@ static int mac_test_run_pkey(EVP_TEST *t)
     EVP_MD_CTX *mctx = NULL;
     EVP_PKEY_CTX *pctx = NULL, *genctx = NULL;
     EVP_PKEY *key = NULL;
-    const EVP_MD *md = NULL;
+    const char *mdname = NULL;
+    EVP_CIPHER *cipher = NULL;
     unsigned char *got = NULL;
     size_t got_len;
     int i;
@@ -1168,36 +1151,43 @@ static int mac_test_run_pkey(EVP_TEST *t)
         TEST_info("Trying the EVP_PKEY %s test with %s",
                   OBJ_nid2sn(expected->type), expected->alg);
 
-#ifdef OPENSSL_NO_DES
-    if (expected->alg != NULL && strstr(expected->alg, "DES") != NULL) {
-        /* Skip DES */
-        t->err = NULL;
-        goto err;
+    if (expected->type == EVP_PKEY_CMAC) {
+        if (expected->alg != NULL && is_cipher_disabled(expected->alg)) {
+            TEST_info("skipping, PKEY CMAC '%s' is disabled", expected->alg);
+            t->skip = 1;
+            t->err = NULL;
+            goto err;
+        }
+        if (!TEST_ptr(cipher = EVP_CIPHER_fetch(libctx, expected->alg, NULL))) {
+            t->err = "MAC_KEY_CREATE_ERROR";
+            goto err;
+        }
+        key = EVP_PKEY_new_CMAC_key_ex(expected->key, expected->key_len,
+                                       EVP_CIPHER_name(cipher), libctx, NULL);
+    } else {
+        key = EVP_PKEY_new_raw_private_key_ex(libctx,
+                                              OBJ_nid2sn(expected->type), NULL,
+                                              expected->key, expected->key_len);
     }
-#endif
-
-    if (expected->type == EVP_PKEY_CMAC)
-        key = EVP_PKEY_new_CMAC_key(NULL, expected->key, expected->key_len,
-                                    EVP_get_cipherbyname(expected->alg));
-    else
-        key = EVP_PKEY_new_raw_private_key(expected->type, NULL, expected->key,
-                                           expected->key_len);
     if (key == NULL) {
         t->err = "MAC_KEY_CREATE_ERROR";
         goto err;
     }
 
-    if (expected->type == EVP_PKEY_HMAC) {
-        if (!TEST_ptr(md = EVP_get_digestbyname(expected->alg))) {
-            t->err = "MAC_ALGORITHM_SET_ERROR";
+    if (expected->type == EVP_PKEY_HMAC && expected->alg != NULL) {
+        if (is_digest_disabled(expected->alg)) {
+            TEST_info("skipping, HMAC '%s' is disabled", expected->alg);
+            t->skip = 1;
+            t->err = NULL;
             goto err;
         }
+        mdname = expected->alg;
     }
     if (!TEST_ptr(mctx = EVP_MD_CTX_new())) {
         t->err = "INTERNAL_ERROR";
         goto err;
     }
-    if (!EVP_DigestSignInit(mctx, &pctx, md, NULL, key)) {
+    if (!EVP_DigestSignInit_ex(mctx, &pctx, mdname, libctx, NULL, key)) {
         t->err = "DIGESTSIGNINIT_ERROR";
         goto err;
     }
@@ -1229,6 +1219,7 @@ static int mac_test_run_pkey(EVP_TEST *t)
     }
     t->err = NULL;
  err:
+    EVP_CIPHER_free(cipher);
     EVP_MD_CTX_free(mctx);
     OPENSSL_free(got);
     EVP_PKEY_CTX_free(genctx);
@@ -1255,14 +1246,6 @@ static int mac_test_run_mac(EVP_TEST *t)
         TEST_info("Trying the EVP_MAC %s test with %s",
                   expected->mac_name, expected->alg);
 
-#ifdef OPENSSL_NO_DES
-    if (expected->alg != NULL && strstr(expected->alg, "DES") != NULL) {
-        /* Skip DES */
-        t->err = NULL;
-        goto err;
-    }
-#endif
-
     if (expected->alg != NULL) {
         /*
          * The underlying algorithm may be a cipher or a digest.
@@ -1305,9 +1288,7 @@ static int mac_test_run_mac(EVP_TEST *t)
                                               expected->iv,
                                               expected->iv_len);
 
-    /*
-     * Unknown controls.  They must match parameters that the MAC recognises
-     */
+    /* Unknown controls.  They must match parameters that the MAC recognizes */
     if (params_n + sk_OPENSSL_STRING_num(expected->controls)
         >= OSSL_NELEM(params)) {
         t->err = "MAC_TOO_MANY_PARAMETERS";
@@ -1402,9 +1383,9 @@ static const EVP_TEST_METHOD mac_test_method = {
 
 
 /**
-***  PUBLIC KEY TESTS
-***  These are all very similar and share much common code.
-**/
+ **  PUBLIC KEY TESTS
+ **  These are all very similar and share much common code.
+ **/
 
 typedef struct pkey_data_st {
     /* Context for this operation */
@@ -1442,6 +1423,7 @@ static int pkey_test_init(EVP_TEST *t, const char *name,
     if (rv == 0)
         rv = find_key(&pkey, name, private_keys);
     if (rv == 0 || pkey == NULL) {
+        TEST_info("skipping, key '%s' is disabled", name);
         t->skip = 1;
         return 1;
     }
@@ -1451,7 +1433,7 @@ static int pkey_test_init(EVP_TEST *t, const char *name,
         return 0;
     }
     kdata->keyop = keyop;
-    if (!TEST_ptr(kdata->ctx = EVP_PKEY_CTX_new(pkey, NULL))) {
+    if (!TEST_ptr(kdata->ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, NULL))) {
         EVP_PKEY_free(pkey);
         OPENSSL_free(kdata);
         return 0;
@@ -1487,14 +1469,8 @@ static int pkey_test_ctrl(EVP_TEST *t, EVP_PKEY_CTX *pctx,
         t->err = "PKEY_CTRL_INVALID";
         rv = 1;
     } else if (p != NULL && rv <= 0) {
-        /* If p has an OID and lookup fails assume disabled algorithm */
-        int nid = OBJ_sn2nid(p);
-
-        if (nid == NID_undef)
-             nid = OBJ_ln2nid(p);
-        if (nid != NID_undef
-                && EVP_get_digestbynid(nid) == NULL
-                && EVP_get_cipherbynid(nid) == NULL) {
+        if (is_digest_disabled(p) || is_cipher_disabled(p)) {
+            TEST_info("skipping, '%s' is disabled", p);
             t->skip = 1;
             rv = 1;
         } else {
@@ -1637,7 +1613,6 @@ static const EVP_TEST_METHOD pverify_test_method = {
     verify_test_run
 };
 
-
 static int pderive_test_init(EVP_TEST *t, const char *name)
 {
     return pkey_test_init(t, name, 0, EVP_PKEY_derive_init, 0);
@@ -1652,8 +1627,11 @@ static int pderive_test_parse(EVP_TEST *t,
         EVP_PKEY *peer;
         if (find_key(&peer, value, public_keys) == 0)
             return -1;
-        if (EVP_PKEY_derive_set_peer(kdata->ctx, peer) <= 0)
-            return -1;
+        if (EVP_PKEY_derive_set_peer(kdata->ctx, peer) <= 0) {
+            t->err = "DERIVE_SET_PEER_ERROR";
+            return 1;
+        }
+        t->err = NULL;
         return 1;
     }
     if (strcmp(keyword, "SharedSecret") == 0)
@@ -1702,8 +1680,8 @@ static const EVP_TEST_METHOD pderive_test_method = {
 
 
 /**
-***  PBE TESTS
-**/
+ **  PBE TESTS
+ **/
 
 typedef enum pbe_type_enum {
     PBE_TYPE_INVALID = 0,
@@ -1729,9 +1707,7 @@ typedef struct pbe_data_st {
 } PBE_DATA;
 
 #ifndef OPENSSL_NO_SCRYPT
-/*
- * Parse unsigned decimal 64 bit integer value
- */
+/* Parse unsigned decimal 64 bit integer value */
 static int parse_uint64(const char *value, uint64_t *pr)
 {
     const char *p = value;
@@ -1812,13 +1788,13 @@ static int pbe_test_init(EVP_TEST *t, const char *alg)
     PBE_DATA *pdat;
     PBE_TYPE pbe_type = PBE_TYPE_INVALID;
 
-    if (strcmp(alg, "scrypt") == 0) {
-#ifndef OPENSSL_NO_SCRYPT
-        pbe_type = PBE_TYPE_SCRYPT;
-#else
+    if (is_kdf_disabled(alg)) {
+        TEST_info("skipping, '%s' is disabled", alg);
         t->skip = 1;
         return 1;
-#endif
+    }
+    if (strcmp(alg, "scrypt") == 0) {
+        pbe_type = PBE_TYPE_SCRYPT;
     } else if (strcmp(alg, "pbkdf2") == 0) {
         pbe_type = PBE_TYPE_PBKDF2;
     } else if (strcmp(alg, "pkcs12") == 0) {
@@ -1867,6 +1843,10 @@ static int pbe_test_run(EVP_TEST *t)
 {
     PBE_DATA *expected = t->data;
     unsigned char *key;
+    EVP_MD *fetched_digest = NULL;
+    OSSL_LIB_CTX *save_libctx;
+
+    save_libctx = OSSL_LIB_CTX_set0_default(libctx);
 
     if (!TEST_ptr(key = OPENSSL_malloc(expected->key_len))) {
         t->err = "INTERNAL_ERROR";
@@ -1883,18 +1863,23 @@ static int pbe_test_run(EVP_TEST *t)
 #ifndef OPENSSL_NO_SCRYPT
     } else if (expected->pbe_type == PBE_TYPE_SCRYPT) {
         if (EVP_PBE_scrypt((const char *)expected->pass, expected->pass_len,
-                           expected->salt, expected->salt_len, expected->N,
-                           expected->r, expected->p, expected->maxmem,
-                           key, expected->key_len) == 0) {
+                            expected->salt, expected->salt_len,
+                            expected->N, expected->r, expected->p,
+                            expected->maxmem, key, expected->key_len) == 0) {
             t->err = "SCRYPT_ERROR";
             goto err;
         }
 #endif
     } else if (expected->pbe_type == PBE_TYPE_PKCS12) {
+        fetched_digest = EVP_MD_fetch(libctx, EVP_MD_name(expected->md), NULL);
+        if (fetched_digest == NULL) {
+            t->err = "PKCS12_ERROR";
+            goto err;
+        }
         if (PKCS12_key_gen_uni(expected->pass, expected->pass_len,
                                expected->salt, expected->salt_len,
                                expected->id, expected->iter, expected->key_len,
-                               key, expected->md) == 0) {
+                               key, fetched_digest) == 0) {
             t->err = "PKCS12_ERROR";
             goto err;
         }
@@ -1905,7 +1890,9 @@ static int pbe_test_run(EVP_TEST *t)
 
     t->err = NULL;
 err:
+    EVP_MD_free(fetched_digest);
     OPENSSL_free(key);
+    OSSL_LIB_CTX_set0_default(save_libctx);
     return 1;
 }
 
@@ -1919,8 +1906,8 @@ static const EVP_TEST_METHOD pbe_test_method = {
 
 
 /**
-***  BASE64 TESTS
-**/
+ **  BASE64 TESTS
+ **/
 
 typedef enum {
     BASE64_CANONICAL_ENCODING = 0,
@@ -2066,9 +2053,8 @@ static const EVP_TEST_METHOD encode_test_method = {
 
 
 /**
-***  RAND TESTS
-**/
-
+ **  RAND TESTS
+ **/
 #define MAX_RAND_REPEATS    15
 
 typedef struct rand_data_pass_st {
@@ -2112,7 +2098,8 @@ static int rand_test_init(EVP_TEST *t, const char *name)
     if (!TEST_ptr(rdata = OPENSSL_zalloc(sizeof(*rdata))))
         return 0;
 
-    rand = EVP_RAND_fetch(NULL, "TEST-RAND", NULL);
+    /* TEST-RAND is available in the FIPS provider but not with "fips=yes" */
+    rand = EVP_RAND_fetch(libctx, "TEST-RAND", "-fips");
     if (rand == NULL)
         goto err;
     rdata->parent = EVP_RAND_CTX_new(rand, NULL);
@@ -2124,7 +2111,7 @@ static int rand_test_init(EVP_TEST *t, const char *name)
     if (!EVP_RAND_set_ctx_params(rdata->parent, params))
         goto err;
 
-    rand = EVP_RAND_fetch(NULL, name, NULL);
+    rand = EVP_RAND_fetch(libctx, name, NULL);
     if (rand == NULL)
         goto err;
     rdata->ctx = EVP_RAND_CTX_new(rand, rdata->parent);
@@ -2351,9 +2338,8 @@ static const EVP_TEST_METHOD rand_test_method = {
 
 
 /**
-***  KDF TESTS
-**/
-
+ **  KDF TESTS
+ **/
 typedef struct kdf_data_st {
     /* Context for this operation */
     EVP_KDF_CTX *ctx;
@@ -2373,27 +2359,18 @@ static int kdf_test_init(EVP_TEST *t, const char *name)
     KDF_DATA *kdata;
     EVP_KDF *kdf;
 
-#ifdef OPENSSL_NO_SCRYPT
-    /* TODO(3.0) Replace with "scrypt" once aliases are supported */
-    if (strcmp(name, "id-scrypt") == 0) {
-        t->skip = 1;
-        return 1;
-    }
-#endif /* OPENSSL_NO_SCRYPT */
-
-#ifdef OPENSSL_NO_CMS
-    if (strcmp(name, "X942KDF") == 0) {
+    if (is_kdf_disabled(name)) {
+        TEST_info("skipping, '%s' is disabled", name);
         t->skip = 1;
         return 1;
     }
-#endif /* OPENSSL_NO_CMS */
 
     if (!TEST_ptr(kdata = OPENSSL_zalloc(sizeof(*kdata))))
         return 0;
     kdata->p = kdata->params;
     *kdata->p = OSSL_PARAM_construct_end();
 
-    kdf = EVP_KDF_fetch(NULL, name, NULL);
+    kdf = EVP_KDF_fetch(libctx, name, NULL);
     if (kdf == NULL) {
         OPENSSL_free(kdata);
         return 0;
@@ -2442,22 +2419,17 @@ static int kdf_test_ctrl(EVP_TEST *t, EVP_KDF_CTX *kctx,
         return 0;
     }
     if (p != NULL && strcmp(name, "digest") == 0) {
-        /* If p has an OID and lookup fails assume disabled algorithm */
-        int nid = OBJ_sn2nid(p);
-
-        if (nid == NID_undef)
-             nid = OBJ_ln2nid(p);
-        if (nid != NID_undef && EVP_get_digestbynid(nid) == NULL)
+        if (is_digest_disabled(p)) {
+            TEST_info("skipping, '%s' is disabled", p);
             t->skip = 1;
+        }
     }
-    if (p != NULL && strcmp(name, "cipher") == 0) {
-        /* If p has an OID and lookup fails assume disabled algorithm */
-        int nid = OBJ_sn2nid(p);
-
-        if (nid == NID_undef)
-             nid = OBJ_ln2nid(p);
-        if (nid != NID_undef && EVP_get_cipherbynid(nid) == NULL)
-            t->skip = 1;
+    if (p != NULL
+        && (strcmp(name, "cipher") == 0
+            || strcmp(name, "cekalg") == 0)
+        && is_cipher_disabled(p)) {
+        TEST_info("skipping, '%s' is disabled", p);
+        t->skip = 1;
     }
     OPENSSL_free(name);
     return 1;
@@ -2513,10 +2485,9 @@ static const EVP_TEST_METHOD kdf_test_method = {
     kdf_test_run
 };
 
-
 /**
-***  PKEY KDF TESTS
-**/
+ **  PKEY KDF TESTS
+ **/
 
 typedef struct pkey_kdf_data_st {
     /* Context for this operation */
@@ -2532,40 +2503,28 @@ typedef struct pkey_kdf_data_st {
  */
 static int pkey_kdf_test_init(EVP_TEST *t, const char *name)
 {
-    PKEY_KDF_DATA *kdata;
-    int kdf_nid = OBJ_sn2nid(name);
-
-#ifdef OPENSSL_NO_SCRYPT
-    if (strcmp(name, "scrypt") == 0) {
-        t->skip = 1;
-        return 1;
-    }
-#endif /* OPENSSL_NO_SCRYPT */
+    PKEY_KDF_DATA *kdata = NULL;
 
-#ifdef OPENSSL_NO_CMS
-    if (strcmp(name, "X942KDF") == 0) {
+    if (is_kdf_disabled(name)) {
+        TEST_info("skipping, '%s' is disabled", name);
         t->skip = 1;
         return 1;
     }
-#endif /* OPENSSL_NO_CMS */
-
-    if (kdf_nid == NID_undef)
-        kdf_nid = OBJ_ln2nid(name);
 
     if (!TEST_ptr(kdata = OPENSSL_zalloc(sizeof(*kdata))))
         return 0;
-    kdata->ctx = EVP_PKEY_CTX_new_id(kdf_nid, NULL);
-    if (kdata->ctx == NULL) {
-        OPENSSL_free(kdata);
-        return 0;
-    }
-    if (EVP_PKEY_derive_init(kdata->ctx) <= 0) {
-        EVP_PKEY_CTX_free(kdata->ctx);
-        OPENSSL_free(kdata);
-        return 0;
-    }
+
+    kdata->ctx = EVP_PKEY_CTX_new_from_name(libctx, name, NULL);
+    if (kdata->ctx == NULL
+        || EVP_PKEY_derive_init(kdata->ctx) <= 0)
+        goto err;
+
     t->data = kdata;
     return 1;
+err:
+    EVP_PKEY_CTX_free(kdata->ctx);
+    OPENSSL_free(kdata);
+    return 0;
 }
 
 static void pkey_kdf_test_cleanup(EVP_TEST *t)
@@ -2621,10 +2580,9 @@ static const EVP_TEST_METHOD pkey_kdf_test_method = {
     pkey_kdf_test_run
 };
 
-
 /**
-***  KEYPAIR TESTS
-**/
+ **  KEYPAIR TESTS
+ **/
 
 typedef struct keypair_test_data_st {
     EVP_PKEY *privk;
@@ -2739,8 +2697,8 @@ static const EVP_TEST_METHOD keypair_test_method = {
 };
 
 /**
-***  KEYGEN TEST
-**/
+ **  KEYGEN TEST
+ **/
 
 typedef struct keygen_test_data_st {
     EVP_PKEY_CTX *genctx; /* Keygen context to use */
@@ -2759,11 +2717,12 @@ static int keygen_test_init(EVP_TEST *t, const char *alg)
             return 0;
     }
 
-    if (!TEST_ptr(genctx = EVP_PKEY_CTX_new_id(nid, NULL))) {
-        /* assume algorithm disabled */
+    if (is_pkey_disabled(alg)) {
         t->skip = 1;
         return 1;
     }
+    if (!TEST_ptr(genctx = EVP_PKEY_CTX_new_from_name(libctx, alg, NULL)))
+        goto err;
 
     if (EVP_PKEY_keygen_init(genctx) <= 0) {
         t->err = "KEYGEN_INIT_ERROR";
@@ -2816,6 +2775,10 @@ static int keygen_test_run(EVP_TEST *t)
         goto err;
     }
 
+    if (!evp_pkey_is_provided(pkey)) {
+        TEST_info("Warning: legacy key generated %s", keygen->keyname);
+        goto err;
+    }
     if (keygen->keyname != NULL) {
         KEY_LIST *key;
 
@@ -2852,8 +2815,8 @@ static const EVP_TEST_METHOD keygen_test_method = {
 };
 
 /**
-***  DIGEST SIGN+VERIFY TESTS
-**/
+ **  DIGEST SIGN+VERIFY TESTS
+ **/
 
 typedef struct {
     int is_verify; /* Set to 1 if verifying */
@@ -2875,14 +2838,13 @@ static int digestsigver_test_init(EVP_TEST *t, const char *alg, int is_verify,
     DIGESTSIGN_DATA *mdat;
 
     if (strcmp(alg, "NULL") != 0) {
-        if ((md = EVP_get_digestbyname(alg)) == NULL) {
-            /* If alg has an OID assume disabled algorithm */
-            if (OBJ_sn2nid(alg) != NID_undef || OBJ_ln2nid(alg) != NID_undef) {
-                t->skip = 1;
-                return 1;
-            }
-            return 0;
+        if (is_digest_disabled(alg)) {
+            t->skip = 1;
+            return 1;
         }
+        md = EVP_get_digestbyname(alg);
+        if (md == NULL)
+            return 0;
     }
     if (!TEST_ptr(mdat = OPENSSL_zalloc(sizeof(*mdat))))
         return 0;
@@ -2922,6 +2884,7 @@ static int digestsigver_test_parse(EVP_TEST *t,
     if (strcmp(keyword, "Key") == 0) {
         EVP_PKEY *pkey = NULL;
         int rv = 0;
+        const char *name = mdata->md == NULL ? NULL : EVP_MD_name(mdata->md);
 
         if (mdata->is_verify)
             rv = find_key(&pkey, value, public_keys);
@@ -2932,13 +2895,13 @@ static int digestsigver_test_parse(EVP_TEST *t,
             return 1;
         }
         if (mdata->is_verify) {
-            if (!EVP_DigestVerifyInit(mdata->ctx, &mdata->pctx, mdata->md,
-                                      NULL, pkey))
+            if (!EVP_DigestVerifyInit_ex(mdata->ctx, &mdata->pctx, name, libctx,
+                                         NULL, pkey))
                 t->err = "DIGESTVERIFYINIT_ERROR";
             return 1;
         }
-        if (!EVP_DigestSignInit(mdata->ctx, &mdata->pctx, mdata->md, NULL,
-                                pkey))
+        if (!EVP_DigestSignInit_ex(mdata->ctx, &mdata->pctx, name, libctx, NULL,
+                                   pkey))
             t->err = "DIGESTSIGNINIT_ERROR";
         return 1;
     }
@@ -3117,8 +3080,8 @@ static const EVP_TEST_METHOD oneshot_digestverify_test_method = {
 
 
 /**
-***  PARSING AND DISPATCH
-**/
+ **  PARSING AND DISPATCH
+ **/
 
 static const EVP_TEST_METHOD *evp_test_list[] = {
     &rand_test_method,
@@ -3175,9 +3138,7 @@ static void clear_test(EVP_TEST *t)
     t->meth = NULL;
 }
 
-/*
- * Check for errors in the test structure; return 1 if okay, else 0.
- */
+/* Check for errors in the test structure; return 1 if okay, else 0. */
 static int check_test_error(EVP_TEST *t)
 {
     unsigned long err;
@@ -3240,9 +3201,7 @@ static int check_test_error(EVP_TEST *t)
     return 0;
 }
 
-/*
- * Run a parsed test. Log a message and return 0 on error.
- */
+/* Run a parsed test. Log a message and return 0 on error. */
 static int run_test(EVP_TEST *t)
 {
     if (t->meth == NULL)
@@ -3296,11 +3255,10 @@ static void free_key_list(KEY_LIST *lst)
  */
 static int key_unsupported(void)
 {
-    long err = ERR_peek_error();
+    long err = ERR_peek_last_error();
 
     if (ERR_GET_LIB(err) == ERR_LIB_EVP
-            && (ERR_GET_REASON(err) == EVP_R_UNSUPPORTED_ALGORITHM
-                || ERR_GET_REASON(err) == EVP_R_FETCH_FAILED)) {
+            && (ERR_GET_REASON(err) == EVP_R_UNSUPPORTED_ALGORITHM)) {
         ERR_clear_error();
         return 1;
     }
@@ -3311,7 +3269,8 @@ static int key_unsupported(void)
      * disabled).
      */
     if (ERR_GET_LIB(err) == ERR_LIB_EC
-        && ERR_GET_REASON(err) == EC_R_UNKNOWN_GROUP) {
+        && (ERR_GET_REASON(err) == EC_R_UNKNOWN_GROUP
+            || ERR_GET_REASON(err) == EC_R_INVALID_CURVE)) {
         ERR_clear_error();
         return 1;
     }
@@ -3319,9 +3278,7 @@ static int key_unsupported(void)
     return 0;
 }
 
-/*
- * NULL out the value from |pp| but return it.  This "steals" a pointer.
- */
+/* NULL out the value from |pp| but return it.  This "steals" a pointer. */
 static char *take_value(PAIR *pp)
 {
     char *p = pp->value;
@@ -3330,6 +3287,35 @@ static char *take_value(PAIR *pp)
     return p;
 }
 
+#if !defined(OPENSSL_NO_FIPS_SECURITYCHECKS)
+static int securitycheck_enabled(void)
+{
+    static int enabled = -1;
+
+    if (enabled == -1) {
+        if (OSSL_PROVIDER_available(libctx, "fips")) {
+            OSSL_PARAM params[2];
+            OSSL_PROVIDER *prov = NULL;
+            int check = 1;
+
+            prov = OSSL_PROVIDER_load(libctx, "fips");
+            if (prov != NULL) {
+                params[0] =
+                    OSSL_PARAM_construct_int(OSSL_PROV_PARAM_SECURITY_CHECKS,
+                                             &check);
+                params[1] = OSSL_PARAM_construct_end();
+                OSSL_PROVIDER_get_params(prov, params);
+                OSSL_PROVIDER_unload(prov);
+            }
+            enabled = check;
+            return enabled;
+        }
+        enabled = 0;
+    }
+    return enabled;
+}
+#endif
+
 /*
  * Return 1 if one of the providers named in the string is available.
  * The provider names are separated with whitespace.
@@ -3351,21 +3337,19 @@ static int prov_available(char *providers)
             more = 0;
         else
             *p = '\0';
-        if (OSSL_PROVIDER_available(NULL, providers))
+        if (OSSL_PROVIDER_available(libctx, providers))
             return 1;            /* Found one */
     }
     return 0;
 }
 
-/*
- * 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)
 {
     KEY_LIST *key, **klist;
     EVP_PKEY *pkey;
     PAIR *pp;
-    int i;
+    int i, skip_availablein = 0;
 
 top:
     do {
@@ -3380,8 +3364,9 @@ top:
     /* Are we adding a key? */
     klist = NULL;
     pkey = NULL;
+start:
     if (strcmp(pp->key, "PrivateKey") == 0) {
-        pkey = PEM_read_bio_PrivateKey(t->s.key, NULL, 0, NULL);
+        pkey = PEM_read_bio_PrivateKey_ex(t->s.key, NULL, 0, NULL, libctx, NULL);
         if (pkey == NULL && !key_unsupported()) {
             EVP_PKEY_free(pkey);
             TEST_info("Can't read private key %s", pp->value);
@@ -3390,7 +3375,7 @@ top:
         }
         klist = &private_keys;
     } else if (strcmp(pp->key, "PublicKey") == 0) {
-        pkey = PEM_read_bio_PUBKEY(t->s.key, NULL, 0, NULL);
+        pkey = PEM_read_bio_PUBKEY_ex(t->s.key, NULL, 0, NULL, libctx, NULL);
         if (pkey == NULL && !key_unsupported()) {
             EVP_PKEY_free(pkey);
             TEST_info("Can't read public key %s", pp->value);
@@ -3424,7 +3409,7 @@ top:
 
         nid = OBJ_txt2nid(strnid);
         if (nid == NID_undef) {
-            TEST_info("Uncrecognised algorithm NID");
+            TEST_info("Unrecognised algorithm NID");
             return 0;
         }
         if (!parse_bin(keydata, &keybin, &keylen)) {
@@ -3432,9 +3417,11 @@ top:
             return 0;
         }
         if (klist == &private_keys)
-            pkey = EVP_PKEY_new_raw_private_key(nid, NULL, keybin, keylen);
+            pkey = EVP_PKEY_new_raw_private_key_ex(libctx, strnid, NULL, keybin,
+                                                   keylen);
         else
-            pkey = EVP_PKEY_new_raw_public_key(nid, NULL, keybin, keylen);
+            pkey = EVP_PKEY_new_raw_public_key_ex(libctx, strnid, NULL, keybin,
+                                                  keylen);
         if (pkey == NULL && !key_unsupported()) {
             TEST_info("Can't read %s data", pp->key);
             OPENSSL_free(keybin);
@@ -3442,6 +3429,16 @@ top:
             return 0;
         }
         OPENSSL_free(keybin);
+    } else if (strcmp(pp->key, "Availablein") == 0) {
+        if (!prov_available(pp->value)) {
+            TEST_info("skipping, '%s' provider not available: %s:%d",
+                      pp->value, t->s.test_file, t->s.start);
+                t->skip = 1;
+                return 0;
+        }
+        skip_availablein++;
+        pp++;
+        goto start;
     }
 
     /* If we have a key add to list */
@@ -3458,7 +3455,7 @@ top:
         *klist = key;
 
         /* Go back and start a new stanza. */
-        if (t->s.numpairs != 1)
+        if ((t->s.numpairs - skip_availablein) != 1)
             TEST_info("Line %d: missing blank line\n", t->s.curr);
         goto top;
     }
@@ -3475,14 +3472,22 @@ top:
         return 0;
     }
 
-    for (pp++, i = 1; i < t->s.numpairs; pp++, i++) {
-        if (strcmp(pp->key, "Availablein") == 0) {
-            if (!prov_available(pp->value)) {
-                TEST_info("skipping, providers not available: %s:%d",
+    for (pp++, i = 1; i < (t->s.numpairs - skip_availablein); pp++, i++) {
+        if (strcmp(pp->key, "Securitycheck") == 0) {
+#if defined(OPENSSL_NO_FIPS_SECURITYCHECKS)
+#else
+            if (!securitycheck_enabled())
+#endif
+            {
+                TEST_info("skipping, Securitycheck is disabled: %s:%d",
                           t->s.test_file, t->s.start);
                 t->skip = 1;
                 return 0;
             }
+        } else if (strcmp(pp->key, "Availablein") == 0) {
+            TEST_info("Line %d: 'Availablein' should be the first option",
+                      t->s.curr);
+            return 0;
         } else if (strcmp(pp->key, "Result") == 0) {
             if (t->expected_err != NULL) {
                 TEST_info("Line %d: multiple result lines", t->s.curr);
@@ -3551,14 +3556,54 @@ static int run_file_tests(int i)
     return c == 0;
 }
 
-OPT_TEST_DECLARE_USAGE("file...\n")
+const OPTIONS *test_get_options(void)
+{
+    static const OPTIONS test_options[] = {
+        OPT_TEST_OPTIONS_WITH_EXTRA_USAGE("[file...]\n"),
+        { "config", OPT_CONFIG_FILE, '<',
+          "The configuration file to use for the libctx" },
+        { OPT_HELP_STR, 1, '-',
+          "file\tFile to run tests on.\n" },
+        { NULL }
+    };
+    return test_options;
+}
 
 int setup_tests(void)
 {
     size_t n;
+    char *config_file = NULL;
+
+    OPTION_CHOICE o;
 
-    if (!test_skip_common_options()) {
-        TEST_error("Error parsing test options\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;
+        }
+    }
+
+    /*
+     * Load the 'null' provider into the default library context to ensure that
+     * the the tests do not fallback to using the default provider.
+     */
+    prov_null = OSSL_PROVIDER_load(NULL, "null");
+    if (prov_null == NULL) {
+        opt_printf_stderr("Failed to load null provider into default libctx\n");
+        return 0;
+    }
+
+    /* load the provider via configuration into the created library context */
+    libctx = OSSL_LIB_CTX_new();
+    if (libctx == NULL
+        || !OSSL_LIB_CTX_load_config(libctx, config_file)) {
+        TEST_error("Failed to load config %s\n", config_file);
         return 0;
     }
 
@@ -3569,3 +3614,168 @@ int setup_tests(void)
     ADD_ALL_TESTS(run_file_tests, n);
     return 1;
 }
+
+void cleanup_tests(void)
+{
+    OSSL_PROVIDER_unload(prov_null);
+    OSSL_LIB_CTX_free(libctx);
+}
+
+#define STR_STARTS_WITH(str, pre) strncasecmp(pre, str, strlen(pre)) == 0
+#define STR_ENDS_WITH(str, pre)                                                \
+strlen(str) < strlen(pre) ? 0 : (strcasecmp(pre, str + strlen(str) - strlen(pre)) == 0)
+
+static int is_digest_disabled(const char *name)
+{
+#ifdef OPENSSL_NO_BLAKE2
+    if (STR_STARTS_WITH(name, "BLAKE"))
+        return 1;
+#endif
+#ifdef OPENSSL_NO_MD2
+    if (strcasecmp(name, "MD2") == 0)
+        return 1;
+#endif
+#ifdef OPENSSL_NO_MDC2
+    if (strcasecmp(name, "MDC2") == 0)
+        return 1;
+#endif
+#ifdef OPENSSL_NO_MD4
+    if (strcasecmp(name, "MD4") == 0)
+        return 1;
+#endif
+#ifdef OPENSSL_NO_MD5
+    if (strcasecmp(name, "MD5") == 0)
+        return 1;
+#endif
+#ifdef OPENSSL_NO_RMD160
+    if (strcasecmp(name, "RIPEMD160") == 0)
+        return 1;
+#endif
+#ifdef OPENSSL_NO_SM3
+    if (strcasecmp(name, "SM3") == 0)
+        return 1;
+#endif
+#ifdef OPENSSL_NO_WHIRLPOOL
+    if (strcasecmp(name, "WHIRLPOOL") == 0)
+        return 1;
+#endif
+    return 0;
+}
+
+static int is_pkey_disabled(const char *name)
+{
+#ifdef OPENSSL_NO_RSA
+    if (STR_STARTS_WITH(name, "RSA"))
+        return 1;
+#endif
+#ifdef OPENSSL_NO_EC
+    if (STR_STARTS_WITH(name, "EC"))
+        return 1;
+#endif
+#ifdef OPENSSL_NO_DH
+    if (STR_STARTS_WITH(name, "DH"))
+        return 1;
+#endif
+#ifdef OPENSSL_NO_DSA
+    if (STR_STARTS_WITH(name, "DSA"))
+        return 1;
+#endif
+    return 0;
+}
+
+static int is_mac_disabled(const char *name)
+{
+#ifdef OPENSSL_NO_BLAKE2
+    if (STR_STARTS_WITH(name, "BLAKE2BMAC")
+        || STR_STARTS_WITH(name, "BLAKE2SMAC"))
+        return 1;
+#endif
+#ifdef OPENSSL_NO_CMAC
+    if (STR_STARTS_WITH(name, "CMAC"))
+        return 1;
+#endif
+#ifdef OPENSSL_NO_POLY1305
+    if (STR_STARTS_WITH(name, "Poly1305"))
+        return 1;
+#endif
+#ifdef OPENSSL_NO_SIPHASH
+    if (STR_STARTS_WITH(name, "SipHash"))
+        return 1;
+#endif
+    return 0;
+}
+static int is_kdf_disabled(const char *name)
+{
+#ifdef OPENSSL_NO_SCRYPT
+    if (STR_ENDS_WITH(name, "SCRYPT"))
+        return 1;
+#endif
+    return 0;
+}
+
+static int is_cipher_disabled(const char *name)
+{
+#ifdef OPENSSL_NO_ARIA
+    if (STR_STARTS_WITH(name, "ARIA"))
+        return 1;
+#endif
+#ifdef OPENSSL_NO_BF
+    if (STR_STARTS_WITH(name, "BF"))
+        return 1;
+#endif
+#ifdef OPENSSL_NO_CAMELLIA
+    if (STR_STARTS_WITH(name, "CAMELLIA"))
+        return 1;
+#endif
+#ifdef OPENSSL_NO_CAST
+    if (STR_STARTS_WITH(name, "CAST"))
+        return 1;
+#endif
+#ifdef OPENSSL_NO_CHACHA
+    if (STR_STARTS_WITH(name, "CHACHA"))
+        return 1;
+#endif
+#ifdef OPENSSL_NO_POLY1305
+    if (STR_ENDS_WITH(name, "Poly1305"))
+        return 1;
+#endif
+#ifdef OPENSSL_NO_DES
+    if (STR_STARTS_WITH(name, "DES"))
+        return 1;
+    if (STR_ENDS_WITH(name, "3DESwrap"))
+        return 1;
+#endif
+#ifdef OPENSSL_NO_OCB
+    if (STR_ENDS_WITH(name, "OCB"))
+        return 1;
+#endif
+#ifdef OPENSSL_NO_IDEA
+    if (STR_STARTS_WITH(name, "IDEA"))
+        return 1;
+#endif
+#ifdef OPENSSL_NO_RC2
+    if (STR_STARTS_WITH(name, "RC2"))
+        return 1;
+#endif
+#ifdef OPENSSL_NO_RC4
+    if (STR_STARTS_WITH(name, "RC4"))
+        return 1;
+#endif
+#ifdef OPENSSL_NO_RC5
+    if (STR_STARTS_WITH(name, "RC5"))
+        return 1;
+#endif
+#ifdef OPENSSL_NO_SEED
+    if (STR_STARTS_WITH(name, "SEED"))
+        return 1;
+#endif
+#ifdef OPENSSL_NO_SIV
+    if (STR_ENDS_WITH(name, "SIV"))
+        return 1;
+#endif
+#ifdef OPENSSL_NO_SM4
+    if (STR_STARTS_WITH(name, "SM4"))
+        return 1;
+#endif
+    return 0;
+}