-static void *evp_md_from_dispatch(const char *name, const OSSL_DISPATCH *fns,
- OSSL_PROVIDER *prov, void *unused)
+EVP_MD *evp_md_new(void)
+{
+ EVP_MD *md = OPENSSL_zalloc(sizeof(*md));
+
+ if (md != NULL) {
+ md->lock = CRYPTO_THREAD_lock_new();
+ if (md->lock == NULL) {
+ OPENSSL_free(md);
+ return NULL;
+ }
+ md->refcnt = 1;
+ }
+ return md;
+}
+
+/*
+ * FIPS module note: since internal fetches will be entirely
+ * provider based, we know that none of its code depends on legacy
+ * NIDs or any functionality that use them.
+ */
+#ifndef FIPS_MODE
+/* TODO(3.x) get rid of the need for legacy NIDs */
+static void set_legacy_nid(const char *name, void *vlegacy_nid)
+{
+ int nid;
+ int *legacy_nid = vlegacy_nid;
+ /*
+ * We use lowest level function to get the associated method, because
+ * higher level functions such as EVP_get_digestbyname() have changed
+ * to look at providers too.
+ */
+ const void *legacy_method = OBJ_NAME_get(name, OBJ_NAME_TYPE_MD_METH);
+
+ if (*legacy_nid == -1) /* We found a clash already */
+ return;
+
+ if (legacy_method == NULL)
+ return;
+ nid = EVP_MD_nid(legacy_method);
+ if (*legacy_nid != NID_undef && *legacy_nid != nid) {
+ *legacy_nid = -1;
+ return;
+ }
+ *legacy_nid = nid;
+}
+#endif
+
+static void *evp_md_from_dispatch(int name_id,
+ const OSSL_DISPATCH *fns,
+ OSSL_PROVIDER *prov)