Explicitly fetch ciphers and digests in libssl

We modify libssl to use explicitly fetched ciphers, digests and other
algorithms as required based on the configured library context and
property query string for the SSL_CTX that is being used.

Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/10854)
diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c
index ea0fb75..76bea32 100644
--- a/ssl/s3_enc.c
+++ b/ssl/s3_enc.c
@@ -86,7 +86,7 @@
  err:
     EVP_MD_CTX_free(m5);
     EVP_MD_CTX_free(s1);
-    EVP_MD_free(md5);
+    ssl_evp_md_free(md5);
     return ret;
 }
 
@@ -257,13 +257,16 @@
     if (s->s3.tmp.key_block_length != 0)
         return 1;
 
-    if (!ssl_cipher_get_evp(s->session, &c, &hash, NULL, NULL, &comp, 0)) {
+    if (!ssl_cipher_get_evp(s->ctx, s->session, &c, &hash, NULL, NULL, &comp,
+                            0)) {
         SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_SETUP_KEY_BLOCK,
                  SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
         return 0;
     }
 
+    ssl_evp_cipher_free(s->s3.tmp.new_sym_enc);
     s->s3.tmp.new_sym_enc = c;
+    ssl_evp_md_free(s->s3.tmp.new_hash);
     s->s3.tmp.new_hash = hash;
 #ifdef OPENSSL_NO_COMP
     s->s3.tmp.new_compression = NULL;
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index a1a61cf..f5e313b 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -3317,6 +3317,9 @@
     s->s3.tmp.pkey = NULL;
 #endif
 
+    ssl_evp_cipher_free(s->s3.tmp.new_sym_enc);
+    ssl_evp_md_free(s->s3.tmp.new_hash);
+
     OPENSSL_free(s->s3.tmp.ctype);
     sk_X509_NAME_pop_free(s->s3.tmp.peer_ca_names, X509_NAME_free);
     OPENSSL_free(s->s3.tmp.ciphers_raw);
@@ -4136,7 +4139,6 @@
     STACK_OF(SSL_CIPHER) *prio, *allow;
     int i, ii, ok, prefer_sha256 = 0;
     unsigned long alg_k = 0, alg_a = 0, mask_k = 0, mask_a = 0;
-    const EVP_MD *mdsha256 = EVP_sha256();
 #ifndef OPENSSL_NO_CHACHA
     STACK_OF(SSL_CIPHER) *prio_chacha = NULL;
 #endif
@@ -4310,7 +4312,12 @@
             if (prefer_sha256) {
                 const SSL_CIPHER *tmp = sk_SSL_CIPHER_value(allow, ii);
 
-                if (ssl_md(tmp->algorithm2) == mdsha256) {
+                /*
+                 * TODO: When there are no more legacy digests we can just use
+                 * OSSL_DIGEST_NAME_SHA2_256 instead of calling OBJ_nid2sn
+                 */
+                if (EVP_MD_is_a(ssl_md(s->ctx, tmp->algorithm2),
+                                       OBJ_nid2sn(NID_sha256))) {
                     ret = tmp;
                     break;
                 }
diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c
index f9fbc59..64c7916 100644
--- a/ssl/ssl_ciph.c
+++ b/ssl/ssl_ciph.c
@@ -22,30 +22,6 @@
 #include "internal/thread_once.h"
 #include "internal/cryptlib.h"
 
-#define SSL_ENC_DES_IDX         0
-#define SSL_ENC_3DES_IDX        1
-#define SSL_ENC_RC4_IDX         2
-#define SSL_ENC_RC2_IDX         3
-#define SSL_ENC_IDEA_IDX        4
-#define SSL_ENC_NULL_IDX        5
-#define SSL_ENC_AES128_IDX      6
-#define SSL_ENC_AES256_IDX      7
-#define SSL_ENC_CAMELLIA128_IDX 8
-#define SSL_ENC_CAMELLIA256_IDX 9
-#define SSL_ENC_GOST89_IDX      10
-#define SSL_ENC_SEED_IDX        11
-#define SSL_ENC_AES128GCM_IDX   12
-#define SSL_ENC_AES256GCM_IDX   13
-#define SSL_ENC_AES128CCM_IDX   14
-#define SSL_ENC_AES256CCM_IDX   15
-#define SSL_ENC_AES128CCM8_IDX  16
-#define SSL_ENC_AES256CCM8_IDX  17
-#define SSL_ENC_GOST8912_IDX    18
-#define SSL_ENC_CHACHA_IDX      19
-#define SSL_ENC_ARIA128GCM_IDX  20
-#define SSL_ENC_ARIA256GCM_IDX  21
-#define SSL_ENC_NUM_IDX         22
-
 /* NB: make sure indices in these tables match values above */
 
 typedef struct {
@@ -79,8 +55,6 @@
     {SSL_ARIA256GCM, NID_aria_256_gcm}, /* SSL_ENC_ARIA256GCM_IDX 21 */
 };
 
-static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX];
-
 #define SSL_COMP_NULL_IDX       0
 #define SSL_COMP_ZLIB_IDX       1
 #define SSL_COMP_NUM_IDX        2
@@ -91,13 +65,6 @@
 static CRYPTO_ONCE ssl_load_builtin_comp_once = CRYPTO_ONCE_STATIC_INIT;
 #endif
 
-/*
- * Constant SSL_MAX_DIGEST equal to size of digests array should be defined
- * in the ssl_local.h
- */
-
-#define SSL_MD_NUM_IDX  SSL_MAX_DIGEST
-
 /* NB: make sure indices in this table matches values above */
 static const ssl_cipher_table ssl_cipher_table_mac[SSL_MD_NUM_IDX] = {
     {SSL_MD5, NID_md5},         /* SSL_MD_MD5_IDX 0 */
@@ -114,10 +81,6 @@
     {0, NID_sha512}             /* SSL_MD_SHA512_IDX 11 */
 };
 
-static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX] = {
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
-};
-
 /* *INDENT-OFF* */
 static const ssl_cipher_table ssl_cipher_table_kx[] = {
     {SSL_kRSA,      NID_kx_rsa},
@@ -176,8 +139,6 @@
     NID_undef, NID_undef, NID_undef
 };
 
-static size_t ssl_mac_secret_size[SSL_MD_NUM_IDX];
-
 #define CIPHER_ADD      1
 #define CIPHER_KILL     2
 #define CIPHER_DEL      3
@@ -355,41 +316,37 @@
 static uint32_t disabled_mkey_mask;
 static uint32_t disabled_auth_mask;
 
-int ssl_load_ciphers(void)
+int ssl_load_ciphers(SSL_CTX *ctx)
 {
     size_t i;
     const ssl_cipher_table *t;
 
     disabled_enc_mask = 0;
-    ssl_sort_cipher_list();
     for (i = 0, t = ssl_cipher_table_cipher; i < SSL_ENC_NUM_IDX; i++, t++) {
-        if (t->nid == NID_undef) {
-            ssl_cipher_methods[i] = NULL;
-        } else {
-            const EVP_CIPHER *cipher = EVP_get_cipherbynid(t->nid);
-            ssl_cipher_methods[i] = cipher;
+        if (t->nid != NID_undef) {
+            const EVP_CIPHER *cipher
+                = ssl_evp_cipher_fetch(ctx->libctx, t->nid, ctx->propq);
+
+            ctx->ssl_cipher_methods[i] = cipher;
             if (cipher == NULL)
                 disabled_enc_mask |= t->mask;
         }
     }
     disabled_mac_mask = 0;
     for (i = 0, t = ssl_cipher_table_mac; i < SSL_MD_NUM_IDX; i++, t++) {
-        const EVP_MD *md = EVP_get_digestbynid(t->nid);
-        ssl_digest_methods[i] = md;
+        const EVP_MD *md
+            = ssl_evp_md_fetch(ctx->libctx, t->nid, ctx->propq);
+
+        ctx->ssl_digest_methods[i] = md;
         if (md == NULL) {
             disabled_mac_mask |= t->mask;
         } else {
             int tmpsize = EVP_MD_size(md);
             if (!ossl_assert(tmpsize >= 0))
                 return 0;
-            ssl_mac_secret_size[i] = tmpsize;
+            ctx->ssl_mac_secret_size[i] = tmpsize;
         }
     }
-    /* Make sure we can access MD5 and SHA1 */
-    if (!ossl_assert(ssl_digest_methods[SSL_MD_MD5_IDX] != NULL))
-        return 0;
-    if (!ossl_assert(ssl_digest_methods[SSL_MD_SHA1_IDX] != NULL))
-        return 0;
 
     disabled_mkey_mask = 0;
     disabled_auth_mask = 0;
@@ -422,14 +379,14 @@
      */
     ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX] = get_optional_pkey_id("gost-mac");
     if (ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX])
-        ssl_mac_secret_size[SSL_MD_GOST89MAC_IDX] = 32;
+        ctx->ssl_mac_secret_size[SSL_MD_GOST89MAC_IDX] = 32;
     else
         disabled_mac_mask |= SSL_GOST89MAC;
 
     ssl_mac_pkey_id[SSL_MD_GOST89MAC12_IDX] =
         get_optional_pkey_id("gost-mac-12");
     if (ssl_mac_pkey_id[SSL_MD_GOST89MAC12_IDX])
-        ssl_mac_secret_size[SSL_MD_GOST89MAC12_IDX] = 32;
+        ctx->ssl_mac_secret_size[SSL_MD_GOST89MAC12_IDX] = 32;
     else
         disabled_mac_mask |= SSL_GOST89MAC12;
 
@@ -482,9 +439,10 @@
 }
 #endif
 
-int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
-                       const EVP_MD **md, int *mac_pkey_type,
-                       size_t *mac_secret_size, SSL_COMP **comp, int use_etm)
+int ssl_cipher_get_evp(SSL_CTX *ctx, const SSL_SESSION *s,
+                       const EVP_CIPHER **enc, const EVP_MD **md,
+                       int *mac_pkey_type, size_t *mac_secret_size,
+                       SSL_COMP **comp, int use_etm)
 {
     int i;
     const SSL_CIPHER *c;
@@ -521,10 +479,18 @@
     if (i == -1) {
         *enc = NULL;
     } else {
-        if (i == SSL_ENC_NULL_IDX)
-            *enc = EVP_enc_null();
-        else
-            *enc = ssl_cipher_methods[i];
+        if (i == SSL_ENC_NULL_IDX) {
+            /*
+             * We assume we don't care about this coming from an ENGINE so
+             * just do a normal EVP_CIPHER_fetch instead of
+             * ssl_evp_cipher_fetch()
+             */
+            *enc = EVP_CIPHER_fetch(ctx->libctx, "NULL", ctx->propq);
+        } else {
+            if (!ssl_evp_cipher_up_ref(ctx->ssl_cipher_methods[i]))
+                return 0;
+            *enc = ctx->ssl_cipher_methods[i];
+        }
     }
 
     i = ssl_cipher_info_lookup(ssl_cipher_table_mac, c->algorithm_mac);
@@ -537,67 +503,80 @@
         if (c->algorithm_mac == SSL_AEAD)
             mac_pkey_type = NULL;
     } else {
-        *md = ssl_digest_methods[i];
+        if (!ssl_evp_md_up_ref(ctx->ssl_digest_methods[i])) {
+            ssl_evp_cipher_free(*enc);
+            return 0;
+        }
+        *md = ctx->ssl_digest_methods[i];
         if (mac_pkey_type != NULL)
             *mac_pkey_type = ssl_mac_pkey_id[i];
         if (mac_secret_size != NULL)
-            *mac_secret_size = ssl_mac_secret_size[i];
+            *mac_secret_size = ctx->ssl_mac_secret_size[i];
     }
 
     if ((*enc != NULL) &&
         (*md != NULL || (EVP_CIPHER_flags(*enc) & EVP_CIPH_FLAG_AEAD_CIPHER))
         && (!mac_pkey_type || *mac_pkey_type != NID_undef)) {
-        const EVP_CIPHER *evp;
+        const EVP_CIPHER *evp = NULL;
 
-        if (use_etm)
+        if (use_etm
+                || s->ssl_version >> 8 != TLS1_VERSION_MAJOR
+                || s->ssl_version < TLS1_VERSION)
             return 1;
 
-        if (s->ssl_version >> 8 != TLS1_VERSION_MAJOR ||
-            s->ssl_version < TLS1_VERSION)
-            return 1;
+        if (c->algorithm_enc == SSL_RC4
+                && c->algorithm_mac == SSL_MD5)
+            evp = ssl_evp_cipher_fetch(ctx->libctx, NID_rc4_hmac_md5,
+                                       ctx->propq);
+        else if (c->algorithm_enc == SSL_AES128
+                    && c->algorithm_mac == SSL_SHA1)
+            evp = ssl_evp_cipher_fetch(ctx->libctx,
+                                       NID_aes_128_cbc_hmac_sha1,
+                                       ctx->propq);
+        else if (c->algorithm_enc == SSL_AES256
+                    && c->algorithm_mac == SSL_SHA1)
+             evp = ssl_evp_cipher_fetch(ctx->libctx,
+                                        NID_aes_256_cbc_hmac_sha1,
+                                        ctx->propq);
+        else if (c->algorithm_enc == SSL_AES128
+                    && c->algorithm_mac == SSL_SHA256)
+            evp = ssl_evp_cipher_fetch(ctx->libctx,
+                                       NID_aes_128_cbc_hmac_sha256,
+                                       ctx->propq);
+        else if (c->algorithm_enc == SSL_AES256
+                    && c->algorithm_mac == SSL_SHA256)
+            evp = ssl_evp_cipher_fetch(ctx->libctx,
+                                       NID_aes_256_cbc_hmac_sha256,
+                                       ctx->propq);
 
-        if (c->algorithm_enc == SSL_RC4 &&
-            c->algorithm_mac == SSL_MD5 &&
-            (evp = EVP_get_cipherbyname("RC4-HMAC-MD5")))
-            *enc = evp, *md = NULL;
-        else if (c->algorithm_enc == SSL_AES128 &&
-                 c->algorithm_mac == SSL_SHA1 &&
-                 (evp = EVP_get_cipherbyname("AES-128-CBC-HMAC-SHA1")))
-            *enc = evp, *md = NULL;
-        else if (c->algorithm_enc == SSL_AES256 &&
-                 c->algorithm_mac == SSL_SHA1 &&
-                 (evp = EVP_get_cipherbyname("AES-256-CBC-HMAC-SHA1")))
-            *enc = evp, *md = NULL;
-        else if (c->algorithm_enc == SSL_AES128 &&
-                 c->algorithm_mac == SSL_SHA256 &&
-                 (evp = EVP_get_cipherbyname("AES-128-CBC-HMAC-SHA256")))
-            *enc = evp, *md = NULL;
-        else if (c->algorithm_enc == SSL_AES256 &&
-                 c->algorithm_mac == SSL_SHA256 &&
-                 (evp = EVP_get_cipherbyname("AES-256-CBC-HMAC-SHA256")))
-            *enc = evp, *md = NULL;
+        if (evp != NULL) {
+            ssl_evp_cipher_free(*enc);
+            ssl_evp_md_free(*md);
+            *enc = evp;
+            *md = NULL;
+        }
         return 1;
-    } else {
-        return 0;
     }
+
+    return 0;
 }
 
-const EVP_MD *ssl_md(int idx)
+const EVP_MD *ssl_md(SSL_CTX *ctx, int idx)
 {
     idx &= SSL_HANDSHAKE_MAC_MASK;
     if (idx < 0 || idx >= SSL_MD_NUM_IDX)
         return NULL;
-    return ssl_digest_methods[idx];
+    return ctx->ssl_digest_methods[idx];
 }
 
 const EVP_MD *ssl_handshake_md(SSL *s)
 {
-    return ssl_md(ssl_get_algorithm2(s));
+    return ssl_md(s->ctx, ssl_get_algorithm2(s));
 }
 
 const EVP_MD *ssl_prf_md(SSL *s)
 {
-    return ssl_md(ssl_get_algorithm2(s) >> TLS1_PRF_DGST_SHIFT);
+    return ssl_md(s->ctx, ssl_get_algorithm2(s) >> TLS1_PRF_DGST_SHIFT);
 }
 
 #define ITEM_SEP(a) \
@@ -2094,7 +2073,7 @@
 
     if (idx < 0 || idx >= SSL_MD_NUM_IDX)
         return NULL;
-    return ssl_digest_methods[idx];
+    return EVP_get_digestbynid(ssl_cipher_table_mac[idx].nid);
 }
 
 int SSL_CIPHER_is_aead(const SSL_CIPHER *c)
diff --git a/ssl/ssl_init.c b/ssl/ssl_init.c
index 3e85426..2ccbda7 100644
--- a/ssl/ssl_init.c
+++ b/ssl/ssl_init.c
@@ -94,10 +94,7 @@
      */
     SSL_COMP_get_compression_methods();
 #endif
-    /* initialize cipher/digest methods table */
-    if (!ssl_load_ciphers())
-        return 0;
-
+    ssl_sort_cipher_list();
     OSSL_TRACE(INIT,"ossl_init_ssl_base: SSL_add_ssl_module()\n");
     /*
      * We ignore an error return here. Not much we can do - but not that bad
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index b5239d6..977b599 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -3146,6 +3146,10 @@
         goto err;
 #endif
 
+    /* initialize cipher/digest methods table */
+    if (!ssl_load_ciphers(ret))
+        return 0;
+
     if (!SSL_CTX_set_ciphersuites(ret, OSSL_default_ciphersuites()))
         goto err;
 
@@ -3162,14 +3166,12 @@
     if (ret->param == NULL)
         goto err;
 
-    if ((ret->md5 = EVP_get_digestbyname("ssl3-md5")) == NULL) {
-        SSLerr(0, SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES);
-        goto err2;
-    }
-    if ((ret->sha1 = EVP_get_digestbyname("ssl3-sha1")) == NULL) {
-        SSLerr(0, SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES);
-        goto err2;
-    }
+    /*
+     * If these aren't available from the provider we'll get NULL returns.
+     * That's fine but will cause errors later if SSLv3 is negotiated
+     */
+    ret->md5 = ssl_evp_md_fetch(libctx, NID_md5, propq);
+    ret->sha1 = ssl_evp_md_fetch(libctx, NID_sha1, propq);
 
     if ((ret->ca_names = sk_X509_NAME_new_null()) == NULL)
         goto err;
@@ -3359,6 +3361,14 @@
     OPENSSL_free(a->ext.alpn);
     OPENSSL_secure_free(a->ext.secure);
 
+    ssl_evp_md_free(a->md5);
+    ssl_evp_md_free(a->sha1);
+
+    for (i = 0; i < SSL_ENC_NUM_IDX; i++)
+        ssl_evp_cipher_free(a->ssl_cipher_methods[i]);
+    for (i = 0; i < SSL_MD_NUM_IDX; i++)
+        ssl_evp_md_free(a->ssl_digest_methods[i]);
+
     CRYPTO_THREAD_lock_free(a->lock);
 
     OPENSSL_free(a->propq);
@@ -5833,3 +5843,88 @@
     s->allow_early_data_cb = cb;
     s->allow_early_data_cb_data = arg;
 }
+
+const EVP_CIPHER *ssl_evp_cipher_fetch(OPENSSL_CTX *libctx,
+                                       int nid,
+                                       const char *properties)
+{
+    /*
+     * If there is an Engine available for this cipher we use the "implicit"
+     * form to ensure we use that engine later.
+     */
+    if (ENGINE_get_cipher_engine(nid) != NULL)
+        return EVP_get_cipherbynid(nid);
+
+    /* Otherwise we do an explicit fetch */
+    return EVP_CIPHER_fetch(libctx, OBJ_nid2sn(nid), properties);
+}
+
+
+int ssl_evp_cipher_up_ref(const EVP_CIPHER *cipher)
+{
+    /* Don't up-ref an implicit EVP_CIPHER */
+    if (EVP_CIPHER_provider(cipher) == NULL)
+        return 1;
+
+    /*
+     * The cipher was explicitly fetched and therefore it is safe to cast
+     * away the const
+     */
+    return EVP_CIPHER_up_ref((EVP_CIPHER *)cipher);
+}
+
+void ssl_evp_cipher_free(const EVP_CIPHER *cipher)
+{
+    if (cipher == NULL)
+        return;
+
+    if (EVP_CIPHER_provider(cipher) != NULL) {
+        /*
+         * The cipher was explicitly fetched and therefore it is safe to cast
+         * away the const
+         */
+        EVP_CIPHER_free((EVP_CIPHER *)cipher);
+    }
+}
+
+const EVP_MD *ssl_evp_md_fetch(OPENSSL_CTX *libctx,
+                               int nid,
+                               const char *properties)
+{
+    /*
+     * If there is an Engine available for this digest we use the "implicit"
+     * form to ensure we use that engine later.
+     */
+    if (ENGINE_get_digest_engine(nid) != NULL)
+        return EVP_get_digestbynid(nid);
+
+    /* Otherwise we do an explicit fetch */
+    return EVP_MD_fetch(libctx, OBJ_nid2sn(nid), properties);
+}
+
+int ssl_evp_md_up_ref(const EVP_MD *md)
+{
+    /* Don't up-ref an implicit EVP_MD */
+    if (EVP_MD_provider(md) == NULL)
+        return 1;
+
+    /*
+     * The digest was explicitly fetched and therefore it is safe to cast
+     * away the const
+     */
+    return EVP_MD_up_ref((EVP_MD *)md);
+}
+
+void ssl_evp_md_free(const EVP_MD *md)
+{
+    if (md == NULL)
+        return;
+
+    if (EVP_MD_provider(md) != NULL) {
+        /*
+         * The digest was explicitly fetched and therefore it is safe to cast
+         * away the const
+         */
+        EVP_MD_free((EVP_MD *)md);
+    }
+}
diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h
index 680afa0..eefc4ea 100644
--- a/ssl/ssl_local.h
+++ b/ssl/ssl_local.h
@@ -276,6 +276,8 @@
 # define SSL_MD_SHA512_IDX 11
 # define SSL_MAX_DIGEST 12
 
+#define SSL_MD_NUM_IDX  SSL_MAX_DIGEST
+
 /* Bits for algorithm2 (handshake digests and other extra flags) */
 
 /* Bits 0-7 are handshake MAC */
@@ -389,6 +391,30 @@
 # define SSL_PKEY_ED448          8
 # define SSL_PKEY_NUM            9
 
+# define SSL_ENC_DES_IDX         0
+# define SSL_ENC_3DES_IDX        1
+# define SSL_ENC_RC4_IDX         2
+# define SSL_ENC_RC2_IDX         3
+# define SSL_ENC_IDEA_IDX        4
+# define SSL_ENC_NULL_IDX        5
+# define SSL_ENC_AES128_IDX      6
+# define SSL_ENC_AES256_IDX      7
+# define SSL_ENC_CAMELLIA128_IDX 8
+# define SSL_ENC_CAMELLIA256_IDX 9
+# define SSL_ENC_GOST89_IDX      10
+# define SSL_ENC_SEED_IDX        11
+# define SSL_ENC_AES128GCM_IDX   12
+# define SSL_ENC_AES256GCM_IDX   13
+# define SSL_ENC_AES128CCM_IDX   14
+# define SSL_ENC_AES256CCM_IDX   15
+# define SSL_ENC_AES128CCM8_IDX  16
+# define SSL_ENC_AES256CCM8_IDX  17
+# define SSL_ENC_GOST8912_IDX    18
+# define SSL_ENC_CHACHA_IDX      19
+# define SSL_ENC_ARIA128GCM_IDX  20
+# define SSL_ENC_ARIA256GCM_IDX  21
+# define SSL_ENC_NUM_IDX         22
+
 /*-
  * SSL_kRSA <- RSA_ENC
  * SSL_kDH  <- DH_ENC & (RSA_ENC | RSA_SIGN | DSA_SIGN)
@@ -865,7 +891,7 @@
     CRYPTO_EX_DATA ex_data;
 
     const EVP_MD *md5;          /* For SSLv3/TLSv1 'ssl3-md5' */
-    const EVP_MD *sha1;         /* For SSLv3/TLSv1 'ssl3->sha1' */
+    const EVP_MD *sha1;         /* For SSLv3/TLSv1 'ssl3-sha1' */
 
     STACK_OF(X509) *extra_certs;
     STACK_OF(SSL_COMP) *comp_methods; /* stack of SSL_COMP, SSLv3/TLSv1 */
@@ -1109,6 +1135,10 @@
     void *async_cb_arg;
 
     char *propq;
+
+    const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX];
+    const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX];
+    size_t ssl_mac_secret_size[SSL_MD_NUM_IDX];
 };
 
 typedef struct cert_pkey_st CERT_PKEY;
@@ -2333,10 +2363,10 @@
                                 STACK_OF(SSL_CIPHER) **scsvs, int sslv2format,
                                 int fatal);
 void ssl_update_cache(SSL *s, int mode);
-__owur int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
-                              const EVP_MD **md, int *mac_pkey_type,
-                              size_t *mac_secret_size, SSL_COMP **comp,
-                              int use_etm);
+__owur int ssl_cipher_get_evp(SSL_CTX *ctxc, const SSL_SESSION *s,
+                              const EVP_CIPHER **enc, const EVP_MD **md,
+                              int *mac_pkey_type, size_t *mac_secret_size,
+                              SSL_COMP **comp, int use_etm);
 __owur int ssl_cipher_get_overhead(const SSL_CIPHER *c, size_t *mac_overhead,
                                    size_t *int_overhead, size_t *blocksize,
                                    size_t *ext_overhead);
@@ -2376,7 +2406,7 @@
 __owur STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s);
 __owur int ssl_x509err2alert(int type);
 void ssl_sort_cipher_list(void);
-int ssl_load_ciphers(void);
+int ssl_load_ciphers(SSL_CTX *ctx);
 __owur int ssl_fill_hello_random(SSL *s, int server, unsigned char *field,
                                  size_t len, DOWNGRADE dgrd);
 __owur int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen,
@@ -2631,7 +2661,8 @@
 __owur int tls1_save_sigalgs(SSL *s, PACKET *pkt, int cert);
 __owur int tls1_process_sigalgs(SSL *s);
 __owur int tls1_set_peer_legacy_sigalg(SSL *s, const EVP_PKEY *pkey);
-__owur int tls1_lookup_md(const SIGALG_LOOKUP *lu, const EVP_MD **pmd);
+__owur int tls1_lookup_md(SSL_CTX *ctx, const SIGALG_LOOKUP *lu,
+                          const EVP_MD **pmd);
 __owur size_t tls12_get_psigalgs(SSL *s, int sent, const uint16_t **psigs);
 #  ifndef OPENSSL_NO_EC
 __owur int tls_check_sigalg_curve(const SSL *s, int curve);
@@ -2642,7 +2673,7 @@
 
 __owur int ssl_handshake_hash(SSL *s, unsigned char *out, size_t outlen,
                                  size_t *hashlen);
-__owur const EVP_MD *ssl_md(int idx);
+__owur const EVP_MD *ssl_md(SSL_CTX *ctx, int idx);
 __owur const EVP_MD *ssl_handshake_md(SSL *s);
 __owur const EVP_MD *ssl_prf_md(SSL *s);
 
@@ -2720,6 +2751,18 @@
 /* ssl_mcnf.c */
 void ssl_ctx_system_config(SSL_CTX *ctx);
 
+const EVP_CIPHER *ssl_evp_cipher_fetch(OPENSSL_CTX *libctx,
+                                       int nid,
+                                       const char *properties);
+int ssl_evp_cipher_up_ref(const EVP_CIPHER *cipher);
+void ssl_evp_cipher_free(const EVP_CIPHER *cipher);
+const EVP_MD *ssl_evp_md_fetch(OPENSSL_CTX *libctx,
+                               int nid,
+                               const char *properties);
+int ssl_evp_md_up_ref(const EVP_MD *md);
+void ssl_evp_md_free(const EVP_MD *md);
+
+
 # else /* OPENSSL_UNIT_TEST */
 
 #  define ssl_init_wbio_buffer SSL_test_functions()->p_ssl_init_wbio_buffer
diff --git a/ssl/ssl_txt.c b/ssl/ssl_txt.c
index bc3fcfb..09d00ba 100644
--- a/ssl/ssl_txt.c
+++ b/ssl/ssl_txt.c
@@ -117,7 +117,7 @@
     if (x->compress_meth != 0) {
         SSL_COMP *comp = NULL;
 
-        if (!ssl_cipher_get_evp(x, NULL, NULL, NULL, NULL, &comp, 0))
+        if (!ssl_cipher_get_evp(NULL, x, NULL, NULL, NULL, NULL, &comp, 0))
             goto err;
         if (comp == NULL) {
             if (BIO_printf(bp, "\n    Compression: %d", x->compress_meth) <= 0)
diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c
index 75fecde..776473e 100644
--- a/ssl/statem/extensions_clnt.c
+++ b/ssl/statem/extensions_clnt.c
@@ -981,7 +981,7 @@
     if (s->session->ssl_version == TLS1_3_VERSION
             && s->session->ext.ticklen != 0
             && s->session->cipher != NULL) {
-        const EVP_MD *md = ssl_md(s->session->cipher->algorithm2);
+        const EVP_MD *md = ssl_md(s->ctx, s->session->cipher->algorithm2);
 
         if (md != NULL) {
             /*
@@ -1059,7 +1059,7 @@
                      ERR_R_INTERNAL_ERROR);
             return EXT_RETURN_FAIL;
         }
-        mdres = ssl_md(s->session->cipher->algorithm2);
+        mdres = ssl_md(s->ctx, s->session->cipher->algorithm2);
         if (mdres == NULL) {
             /*
              * Don't recognize this cipher so we can't use the session.
@@ -1132,7 +1132,7 @@
         return EXT_RETURN_NOT_SENT;
 
     if (s->psksession != NULL) {
-        mdpsk = ssl_md(s->psksession->cipher->algorithm2);
+        mdpsk = ssl_md(s->ctx, s->psksession->cipher->algorithm2);
         if (mdpsk == NULL) {
             /*
              * Don't recognize this cipher so we can't use the session.
diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c
index a2a4ae8..999e1cd 100644
--- a/ssl/statem/extensions_srvr.c
+++ b/ssl/statem/extensions_srvr.c
@@ -1238,8 +1238,9 @@
             }
         }
 
-        md = ssl_md(sess->cipher->algorithm2);
-        if (md != ssl_md(s->s3.tmp.new_cipher->algorithm2)) {
+        md = ssl_md(s->ctx, sess->cipher->algorithm2);
+        if (!EVP_MD_is_a(md,
+                EVP_MD_name(ssl_md(s->ctx, s->s3.tmp.new_cipher->algorithm2)))) {
             /* The ciphersuite is not compatible with this session. */
             SSL_SESSION_free(sess);
             sess = NULL;
diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c
index ef53fe7..e524e62 100644
--- a/ssl/statem/statem_clnt.c
+++ b/ssl/statem/statem_clnt.c
@@ -1376,8 +1376,8 @@
              * In TLSv1.3 it is valid for the server to select a different
              * ciphersuite as long as the hash is the same.
              */
-            if (ssl_md(c->algorithm2)
-                    != ssl_md(s->session->cipher->algorithm2)) {
+            if (ssl_md(s->ctx, c->algorithm2)
+                    != ssl_md(s->ctx, s->session->cipher->algorithm2)) {
                 SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER,
                          SSL_F_SET_CLIENT_CIPHERSUITE,
                          SSL_R_CIPHERSUITE_DIGEST_HAS_CHANGED);
@@ -2337,7 +2337,7 @@
             goto err;
         }
 
-        if (!tls1_lookup_md(s->s3.tmp.peer_sigalg, &md)) {
+        if (!tls1_lookup_md(s->ctx, s->s3.tmp.peer_sigalg, &md)) {
             SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_KEY_EXCHANGE,
                      ERR_R_INTERNAL_ERROR);
             goto err;
diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c
index c478bb4..c5956ea 100644
--- a/ssl/statem/statem_lib.c
+++ b/ssl/statem/statem_lib.c
@@ -247,7 +247,7 @@
     }
     pkey = s->s3.tmp.cert->privatekey;
 
-    if (pkey == NULL || !tls1_lookup_md(lu, &md)) {
+    if (pkey == NULL || !tls1_lookup_md(s->ctx, lu, &md)) {
         SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CERT_VERIFY,
                  ERR_R_INTERNAL_ERROR);
         goto err;
@@ -420,7 +420,7 @@
             goto err;
     }
 
-    if (!tls1_lookup_md(s->s3.tmp.peer_sigalg, &md)) {
+    if (!tls1_lookup_md(s->ctx, s->s3.tmp.peer_sigalg, &md)) {
         SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CERT_VERIFY,
                  ERR_R_INTERNAL_ERROR);
         goto err;
diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c
index 50eaf69..256575f 100644
--- a/ssl/statem/statem_srvr.c
+++ b/ssl/statem/statem_srvr.c
@@ -2763,7 +2763,7 @@
         unsigned char *sigbytes1, *sigbytes2, *tbs;
         size_t siglen = 0, tbslen;
 
-        if (pkey == NULL || !tls1_lookup_md(lu, &md)) {
+        if (pkey == NULL || !tls1_lookup_md(s->ctx, lu, &md)) {
             /* Should never happen */
             SSLfatal(s, SSL_AD_INTERNAL_ERROR,
                      SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
index 59bf789..6ce5235 100644
--- a/ssl/t1_enc.c
+++ b/ssl/t1_enc.c
@@ -538,14 +538,16 @@
     if (s->s3.tmp.key_block_length != 0)
         return 1;
 
-    if (!ssl_cipher_get_evp(s->session, &c, &hash, &mac_type, &mac_secret_size,
-                            &comp, s->ext.use_etm)) {
+    if (!ssl_cipher_get_evp(s->ctx, s->session, &c, &hash, &mac_type,
+                            &mac_secret_size, &comp, s->ext.use_etm)) {
         SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_SETUP_KEY_BLOCK,
                  SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
         return 0;
     }
 
+    ssl_evp_cipher_free(s->s3.tmp.new_sym_enc);
     s->s3.tmp.new_sym_enc = c;
+    ssl_evp_md_free(s->s3.tmp.new_hash);
     s->s3.tmp.new_hash = hash;
     s->s3.tmp.new_mac_pkey_type = mac_type;
     s->s3.tmp.new_mac_secret_size = mac_secret_size;
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index fa2d6e0..103a8f1 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -893,7 +893,7 @@
     return NULL;
 }
 /* Lookup hash: return 0 if invalid or not enabled */
-int tls1_lookup_md(const SIGALG_LOOKUP *lu, const EVP_MD **pmd)
+int tls1_lookup_md(SSL_CTX *ctx, const SIGALG_LOOKUP *lu, const EVP_MD **pmd)
 {
     const EVP_MD *md;
     if (lu == NULL)
@@ -902,7 +902,7 @@
     if (lu->hash == NID_undef) {
         md = NULL;
     } else {
-        md = ssl_md(lu->hash_idx);
+        md = ssl_md(ctx, lu->hash_idx);
         if (md == NULL)
             return 0;
     }
@@ -919,13 +919,14 @@
  * with a 128 byte (1024 bit) key.
  */
 #define RSA_PSS_MINIMUM_KEY_SIZE(md) (2 * EVP_MD_size(md) + 2)
-static int rsa_pss_check_min_key_size(const RSA *rsa, const SIGALG_LOOKUP *lu)
+static int rsa_pss_check_min_key_size(SSL_CTX *ctx, const RSA *rsa,
+                                      const SIGALG_LOOKUP *lu)
 {
     const EVP_MD *md;
 
     if (rsa == NULL)
         return 0;
-    if (!tls1_lookup_md(lu, &md) || md == NULL)
+    if (!tls1_lookup_md(ctx, lu, &md) || md == NULL)
         return 0;
     if (RSA_size(rsa) < RSA_PSS_MINIMUM_KEY_SIZE(md))
         return 0;
@@ -978,7 +979,7 @@
     if (SSL_USE_SIGALGS(s) || idx != SSL_PKEY_RSA) {
         const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(tls_default_sigalg[idx]);
 
-        if (!tls1_lookup_md(lu, NULL))
+        if (!tls1_lookup_md(s->ctx, lu, NULL))
             return NULL;
         if (!tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SUPPORTED, lu))
             return NULL;
@@ -1183,7 +1184,7 @@
                  SSL_R_WRONG_SIGNATURE_TYPE);
         return 0;
     }
-    if (!tls1_lookup_md(lu, &md)) {
+    if (!tls1_lookup_md(s->ctx, lu, &md)) {
         SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS12_CHECK_PEER_SIGALG,
                  SSL_R_UNKNOWN_DIGEST);
         return 0;
@@ -1670,7 +1671,7 @@
     int secbits;
 
     /* See if sigalgs is recognised and if hash is enabled */
-    if (!tls1_lookup_md(lu, NULL))
+    if (!tls1_lookup_md(s->ctx, lu, NULL))
         return 0;
     /* DSA is not allowed in TLS 1.3 */
     if (SSL_IS_TLS13(s) && lu->sig == EVP_PKEY_DSA)
@@ -1728,7 +1729,7 @@
     if (lu->hash == NID_undef)
         return 1;
     /* Security bits: half digest bits */
-    secbits = EVP_MD_size(ssl_md(lu->hash_idx)) * 4;
+    secbits = EVP_MD_size(ssl_md(s->ctx, lu->hash_idx)) * 4;
     /* Finally see if security callback allows it */
     sigalgstr[0] = (lu->sigalg >> 8) & 0xff;
     sigalgstr[1] = lu->sigalg & 0xff;
@@ -2777,7 +2778,7 @@
             || lu->sig == EVP_PKEY_RSA)
             continue;
         /* Check that we have a cert, and signature_algorithms_cert */
-        if (!tls1_lookup_md(lu, NULL))
+        if (!tls1_lookup_md(s->ctx, lu, NULL))
             continue;
         if ((pkey == NULL && !has_usable_cert(s, lu, -1))
                 || (pkey != NULL && !is_cert_usable(s, lu, x, pkey)))
@@ -2799,7 +2800,7 @@
 #endif
         } else if (lu->sig == EVP_PKEY_RSA_PSS) {
             /* validate that key is large enough for the signature algorithm */
-            if (!rsa_pss_check_min_key_size(EVP_PKEY_get0(tmppkey), lu))
+            if (!rsa_pss_check_min_key_size(s->ctx, EVP_PKEY_get0(tmppkey), lu))
                 continue;
         }
         break;
@@ -2885,7 +2886,9 @@
                         /* validate that key is large enough for the signature algorithm */
                         EVP_PKEY *pkey = s->cert->pkeys[sig_idx].privatekey;
 
-                        if (!rsa_pss_check_min_key_size(EVP_PKEY_get0(pkey), lu))
+                        if (!rsa_pss_check_min_key_size(s->ctx,
+                                                        EVP_PKEY_get0(pkey),
+                                                        lu))
                             continue;
                     }
 #ifndef OPENSSL_NO_EC
diff --git a/ssl/tls13_enc.c b/ssl/tls13_enc.c
index 181f392..9ca63b7 100644
--- a/ssl/tls13_enc.c
+++ b/ssl/tls13_enc.c
@@ -36,7 +36,8 @@
 #else
     static const unsigned char label_prefix[] = "tls13 ";
 #endif
-    EVP_KDF *kdf = EVP_KDF_fetch(NULL, OSSL_KDF_NAME_HKDF, NULL);
+    EVP_KDF *kdf = EVP_KDF_fetch(s->ctx->libctx, OSSL_KDF_NAME_HKDF,
+                                 s->ctx->propq);
     EVP_KDF_CTX *kctx;
     OSSL_PARAM params[5], *p = params;
     int mode = EVP_PKEY_HKDEF_MODE_EXPAND_ONLY;
@@ -194,7 +195,7 @@
 #endif
     unsigned char preextractsec[EVP_MAX_MD_SIZE];
 
-    kdf = EVP_KDF_fetch(NULL, OSSL_KDF_NAME_HKDF, NULL);
+    kdf = EVP_KDF_fetch(s->ctx->libctx, OSSL_KDF_NAME_HKDF, s->ctx->propq);
     kctx = EVP_KDF_CTX_new(kdf);
     EVP_KDF_free(kdf);
     if (kctx == NULL) {
@@ -311,11 +312,27 @@
 size_t tls13_final_finish_mac(SSL *s, const char *str, size_t slen,
                              unsigned char *out)
 {
-    const EVP_MD *md = ssl_handshake_md(s);
+    const char *mdname = EVP_MD_name(ssl_handshake_md(s));
+    EVP_MAC *hmac = EVP_MAC_fetch(s->ctx->libctx, "HMAC", s->ctx->propq);
     unsigned char hash[EVP_MAX_MD_SIZE];
+    unsigned char finsecret[EVP_MAX_MD_SIZE];
     size_t hashlen, ret = 0;
-    EVP_PKEY *key = NULL;
-    EVP_MD_CTX *ctx = EVP_MD_CTX_new();
+    EVP_MAC_CTX *ctx = NULL;
+    OSSL_PARAM params[4], *p = params;
+
+    if (hmac == NULL) {
+        SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_FINAL_FINISH_MAC,
+                 ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+
+    /* Safe to cast away const here since we're not "getting" any data */
+    *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_DIGEST,
+                                            (char *)mdname, 0);
+    if (s->ctx->propq != NULL)
+        *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_PROPERTIES,
+                                                (char *)s->ctx->propq,
+                                                0);
 
     if (!ssl_handshake_hash(s, hash, sizeof(hash), &hashlen)) {
         /* SSLfatal() already called */
@@ -323,29 +340,31 @@
     }
 
     if (str == s->method->ssl3_enc->server_finished_label) {
-        key = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL,
-                                           s->server_finished_secret, hashlen);
+        *p++ = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
+                                                 s->server_finished_secret,
+                                                 hashlen);
     } else if (SSL_IS_FIRST_HANDSHAKE(s)) {
-        key = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL,
-                                           s->client_finished_secret, hashlen);
+        *p++ = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
+                                                 s->client_finished_secret,
+                                                 hashlen);
     } else {
-        unsigned char finsecret[EVP_MAX_MD_SIZE];
-
         if (!tls13_derive_finishedkey(s, ssl_handshake_md(s),
                                       s->client_app_traffic_secret,
                                       finsecret, hashlen))
             goto err;
 
-        key = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL, finsecret,
-                                           hashlen);
-        OPENSSL_cleanse(finsecret, sizeof(finsecret));
+        *p++ = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, finsecret,
+                                                 hashlen);
     }
+    *p++ = OSSL_PARAM_construct_end();
 
-    if (key == NULL
-            || ctx == NULL
-            || EVP_DigestSignInit(ctx, NULL, md, NULL, key) <= 0
-            || EVP_DigestSignUpdate(ctx, hash, hashlen) <= 0
-            || EVP_DigestSignFinal(ctx, out, &hashlen) <= 0) {
+    ctx = EVP_MAC_CTX_new(hmac);
+    if (ctx == NULL
+            || !EVP_MAC_CTX_set_params(ctx, params)
+            || !EVP_MAC_init(ctx)
+            || !EVP_MAC_update(ctx, hash, hashlen)
+               /* outsize as per sizeof(peer_finish_md) */
+            || !EVP_MAC_final(ctx, out, &hashlen, EVP_MAX_MD_SIZE * 2)) {
         SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_FINAL_FINISH_MAC,
                  ERR_R_INTERNAL_ERROR);
         goto err;
@@ -353,8 +372,9 @@
 
     ret = hashlen;
  err:
-    EVP_PKEY_free(key);
-    EVP_MD_CTX_free(ctx);
+    OPENSSL_cleanse(finsecret, sizeof(finsecret));
+    EVP_MAC_CTX_free(ctx);
+    EVP_MAC_free(hmac);
     return ret;
 }
 
@@ -368,13 +388,16 @@
     const EVP_MD *hash;
 
     s->session->cipher = s->s3.tmp.new_cipher;
-    if (!ssl_cipher_get_evp(s->session, &c, &hash, NULL, NULL, NULL, 0)) {
+    if (!ssl_cipher_get_evp(s->ctx, s->session, &c, &hash, NULL, NULL, NULL,
+                            0)) {
         SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_SETUP_KEY_BLOCK,
                  SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
         return 0;
     }
 
+    ssl_evp_cipher_free(s->s3.tmp.new_sym_enc);
     s->s3.tmp.new_sym_enc = c;
+    ssl_evp_md_free(s->s3.tmp.new_hash);
     s->s3.tmp.new_hash = hash;
 
     return 1;
@@ -577,7 +600,7 @@
                 goto err;
             }
             cipher = EVP_get_cipherbynid(SSL_CIPHER_get_cipher_nid(sslcipher));
-            md = ssl_md(sslcipher->algorithm2);
+            md = ssl_md(s->ctx, sslcipher->algorithm2);
             if (md == NULL || !EVP_DigestInit_ex(mdctx, md, NULL)
                     || !EVP_DigestUpdate(mdctx, hdata, handlen)
                     || !EVP_DigestFinal_ex(mdctx, hashval, &hashlenui)) {
@@ -862,7 +885,7 @@
     else
         sslcipher = SSL_SESSION_get0_cipher(s->session);
 
-    md = ssl_md(sslcipher->algorithm2);
+    md = ssl_md(s->ctx, sslcipher->algorithm2);
 
     /*
      * Calculate the hash value and store it in |data|. The reason why
diff --git a/test/tls13secretstest.c b/test/tls13secretstest.c
index def78b9..5d61476 100644
--- a/test/tls13secretstest.c
+++ b/test/tls13secretstest.c
@@ -165,9 +165,10 @@
 {
 }
 
-int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
-                       const EVP_MD **md, int *mac_pkey_type,
-                       size_t *mac_secret_size, SSL_COMP **comp, int use_etm)
+int ssl_cipher_get_evp(SSL_CTX *ctx, const SSL_SESSION *s,
+                       const EVP_CIPHER **enc, const EVP_MD **md,
+                       int *mac_pkey_type, size_t *mac_secret_size,
+                       SSL_COMP **comp, int use_etm)
 
 {
     return 0;
@@ -186,7 +187,7 @@
     return 1;
 }
 
-const EVP_MD *ssl_md(int idx)
+const EVP_MD *ssl_md(SSL_CTX *ctx, int idx)
 {
     return EVP_sha256();
 }
@@ -206,6 +207,14 @@
     return 1;
 }
 
+void ssl_evp_cipher_free(const EVP_CIPHER *cipher)
+{
+}
+
+void ssl_evp_md_free(const EVP_MD *md)
+{
+}
+
 /* End of mocked out code */
 
 static int test_secret(SSL *s, unsigned char *prk,