Always go the legacy route if EVP_MD_CTX_FLAG_NO_INIT is set
[openssl.git] / crypto / evp / digest.c
index c2a6e83ad58d5ecb9344f98606b2de427d4a4b22..adde3e13aba583bf4a65393fa2e77986645b4d2e 100644 (file)
@@ -165,7 +165,7 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
 
     if (type->prov == NULL) {
 #ifdef FIPS_MODE
-        /* We only do explict fetches inside the FIPS module */
+        /* We only do explicit fetches inside the FIPS module */
         EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR);
         return 0;
 #else
@@ -303,7 +303,9 @@ int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count)
         return 0;
     }
 
-    if (ctx->digest == NULL || ctx->digest->prov == NULL)
+    if (ctx->digest == NULL
+            || ctx->digest->prov == NULL
+            || (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) != 0)
         goto legacy;
 
     if (ctx->digest->dupdate == NULL) {
@@ -422,7 +424,8 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
         return 0;
     }
 
-    if (in->digest->prov == NULL)
+    if (in->digest->prov == NULL
+            || (in->flags & EVP_MD_CTX_FLAG_NO_INIT) != 0)
         goto legacy;
 
     if (in->digest->dupctx == NULL) {
@@ -680,7 +683,7 @@ int EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2)
                                                       p2, p1);
         break;
     default:
-        return EVP_CTRL_RET_UNSUPPORTED;
+        goto conclude;
     }
 
     if (set_params)
@@ -730,12 +733,19 @@ 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 ((nid = OBJ_sn2nid(name)) == NID_undef
-        && (nid = OBJ_ln2nid(name)) == NID_undef)
+
+    if (legacy_method == NULL)
         return;
+    nid = EVP_MD_nid(legacy_method);
     if (*legacy_nid != NID_undef && *legacy_nid != nid) {
         *legacy_nid = -1;
         return;
@@ -746,7 +756,7 @@ static void set_legacy_nid(const char *name, void *vlegacy_nid)
 
 static void *evp_md_from_dispatch(int name_id,
                                   const OSSL_DISPATCH *fns,
-                                  OSSL_PROVIDER *prov, void *unused)
+                                  OSSL_PROVIDER *prov)
 {
     EVP_MD *md = NULL;
     int fncnt = 0;
@@ -760,7 +770,7 @@ static void *evp_md_from_dispatch(int name_id,
 #ifndef FIPS_MODE
     /* TODO(3.x) get rid of the need for legacy NIDs */
     md->type = NID_undef;
-    evp_doall_names(prov, name_id, set_legacy_nid, &md->type);
+    evp_names_do_all(prov, name_id, set_legacy_nid, &md->type);
     if (md->type == -1) {
         ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
         EVP_MD_free(md);
@@ -873,8 +883,7 @@ EVP_MD *EVP_MD_fetch(OPENSSL_CTX *ctx, const char *algorithm,
 {
     EVP_MD *md =
         evp_generic_fetch(ctx, OSSL_OP_DIGEST, algorithm, properties,
-                          evp_md_from_dispatch, NULL, evp_md_up_ref,
-                          evp_md_free);
+                          evp_md_from_dispatch, evp_md_up_ref, evp_md_free);
 
     return md;
 }
@@ -902,11 +911,11 @@ void EVP_MD_free(EVP_MD *md)
     OPENSSL_free(md);
 }
 
-void EVP_MD_do_all_ex(OPENSSL_CTX *libctx,
-                          void (*fn)(EVP_MD *mac, void *arg),
-                          void *arg)
+void EVP_MD_do_all_provided(OPENSSL_CTX *libctx,
+                            void (*fn)(EVP_MD *mac, void *arg),
+                            void *arg)
 {
     evp_generic_do_all(libctx, OSSL_OP_DIGEST,
                        (void (*)(void *, void *))fn, arg,
-                       evp_md_from_dispatch, NULL, evp_md_free);
+                       evp_md_from_dispatch, evp_md_free);
 }