]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Add null digest implementation to the default provider
authorTomas Mraz <tomas@openssl.org>
Fri, 12 Nov 2021 15:31:35 +0000 (16:31 +0100)
committerTomas Mraz <tomas@openssl.org>
Mon, 15 Nov 2021 08:25:42 +0000 (09:25 +0100)
This is necessary to keep compatibility with 1.1.1.

Fixes #16660

Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/17016)

crypto/evp/digest.c
providers/defltprov.c
providers/implementations/digests/build.info
providers/implementations/digests/null_prov.c [new file with mode: 0644]
providers/implementations/include/prov/digestcommon.h
providers/implementations/include/prov/implementations.h
test/evp_extra_test.c

index ebee9d8d76c61430566ac1eca2a25f08ec759782..0a133c5c15a59c74715509b01c474df14bd34612 100644 (file)
@@ -229,7 +229,10 @@ static int evp_md_init_internal(EVP_MD_CTX *ctx, const EVP_MD *type,
         ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
         return 0;
 #else
-        EVP_MD *provmd = EVP_MD_fetch(NULL, OBJ_nid2sn(type->type), "");
+        /* The NULL digest is a special case */
+        EVP_MD *provmd = EVP_MD_fetch(NULL,
+                                      type->type != NID_undef ? OBJ_nid2sn(type->type)
+                                                              : "NULL", "");
 
         if (provmd == NULL) {
             ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
index ed4573cb8d4d6ef35e2534f70766328e43defa9f..3add4cdaf69e0af668b112ebd111500ce4205392 100644 (file)
@@ -153,6 +153,7 @@ static const OSSL_ALGORITHM deflt_digests[] = {
     { PROV_NAMES_MD5_SHA1, "provider=default", ossl_md5_sha1_functions },
 #endif /* OPENSSL_NO_MD5 */
 
+    { PROV_NAMES_NULL, "provider=default", ossl_nullmd_functions },
     { NULL, NULL, NULL }
 };
 
index 2c2b0c3db045f9f490b3133c1b8b822394bdeb5e..c6508b6e85b267c6c3866357f9b439972b1b8b09 100644 (file)
@@ -9,6 +9,7 @@ $SHA3_GOAL=../../libdefault.a ../../libfips.a
 $BLAKE2_GOAL=../../libdefault.a
 $SM3_GOAL=../../libdefault.a
 $MD5_GOAL=../../libdefault.a
+$NULL_GOAL=../../libdefault.a
 
 $MD2_GOAL=../../liblegacy.a
 $MD4_GOAL=../../liblegacy.a
@@ -22,6 +23,8 @@ SOURCE[$COMMON_GOAL]=digestcommon.c
 SOURCE[$SHA2_GOAL]=sha2_prov.c
 SOURCE[$SHA3_GOAL]=sha3_prov.c
 
+SOURCE[$NULL_GOAL]=null_prov.c
+
 IF[{- !$disabled{blake2} -}]
   SOURCE[$BLAKE2_GOAL]=blake2_prov.c blake2b_prov.c blake2s_prov.c
 ENDIF
diff --git a/providers/implementations/digests/null_prov.c b/providers/implementations/digests/null_prov.c
new file mode 100644 (file)
index 0000000..b220a19
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/crypto.h>
+#include "prov/digestcommon.h"
+#include "prov/implementations.h"
+
+typedef struct {
+    unsigned char nothing;
+} NULLMD_CTX;
+
+static int null_init(NULLMD_CTX *ctx)
+{
+    return 1;
+}
+
+static int null_update(NULLMD_CTX *ctx, const void *data, size_t datalen)
+{
+    return 1;
+}
+
+static int null_final(unsigned char *md, NULLMD_CTX *ctx)
+{
+    return 1;
+}
+
+/*
+ * We must override the PROV_FUNC_DIGEST_FINAL as dgstsize == 0
+ * and that would cause compilation warnings with the default implementation.
+ */
+#undef PROV_FUNC_DIGEST_FINAL
+#define PROV_FUNC_DIGEST_FINAL(name, dgstsize, fin)                            \
+static OSSL_FUNC_digest_final_fn name##_internal_final;                        \
+static int name##_internal_final(void *ctx, unsigned char *out, size_t *outl,  \
+                                 size_t outsz)                                 \
+{                                                                              \
+    if (ossl_prov_is_running() && fin(out, ctx)) {                             \
+        *outl = dgstsize;                                                      \
+        return 1;                                                              \
+    }                                                                          \
+    return 0;                                                                  \
+}
+
+IMPLEMENT_digest_functions(nullmd, NULLMD_CTX,
+                           0, 0, 0,
+                           null_init, null_update, null_final)
index b0ed83648dfcd26b36b2a1a73142f6329fea0684..abdb8bb2ad55a8d5d9a84caee48e834e639881e4 100644 (file)
@@ -35,6 +35,18 @@ static int name##_get_params(OSSL_PARAM params[])                              \
 { OSSL_FUNC_DIGEST_GETTABLE_PARAMS,                                            \
   (void (*)(void))ossl_digest_default_gettable_params }
 
+# define PROV_FUNC_DIGEST_FINAL(name, dgstsize, fin)                           \
+static OSSL_FUNC_digest_final_fn name##_internal_final;                        \
+static int name##_internal_final(void *ctx, unsigned char *out, size_t *outl,  \
+                                 size_t outsz)                                 \
+{                                                                              \
+    if (ossl_prov_is_running() && outsz >= dgstsize && fin(out, ctx)) {        \
+        *outl = dgstsize;                                                      \
+        return 1;                                                              \
+    }                                                                          \
+    return 0;                                                                  \
+}
+
 # define PROV_DISPATCH_FUNC_DIGEST_CONSTRUCT_START(                            \
     name, CTX, blksize, dgstsize, flags, upd, fin)                             \
 static OSSL_FUNC_digest_newctx_fn name##_newctx;                               \
@@ -58,16 +70,7 @@ static void *name##_dupctx(void *ctx)                                          \
         *ret = *in;                                                            \
     return ret;                                                                \
 }                                                                              \
-static OSSL_FUNC_digest_final_fn name##_internal_final;                        \
-static int name##_internal_final(void *ctx, unsigned char *out, size_t *outl,  \
-                                 size_t outsz)                                 \
-{                                                                              \
-    if (ossl_prov_is_running() && outsz >= dgstsize && fin(out, ctx)) {        \
-        *outl = dgstsize;                                                      \
-        return 1;                                                              \
-    }                                                                          \
-    return 0;                                                                  \
-}                                                                              \
+PROV_FUNC_DIGEST_FINAL(name, dgstsize, fin)                                    \
 PROV_FUNC_DIGEST_GET_PARAM(name, blksize, dgstsize, flags)                     \
 const OSSL_DISPATCH ossl_##name##_functions[] = {                              \
     { OSSL_FUNC_DIGEST_NEWCTX, (void (*)(void))name##_newctx },                \
index cb1b7925c57c6e7df324160b24baf61fab4f5d85..d7b591cf725c936c198ba4b0abc7e4361f1b0424 100644 (file)
@@ -40,6 +40,7 @@ extern const OSSL_DISPATCH ossl_md4_functions[];
 extern const OSSL_DISPATCH ossl_mdc2_functions[];
 extern const OSSL_DISPATCH ossl_wp_functions[];
 extern const OSSL_DISPATCH ossl_ripemd160_functions[];
+extern const OSSL_DISPATCH ossl_nullmd_functions[];
 
 /* Ciphers */
 extern const OSSL_DISPATCH ossl_null_functions[];
index 8ac8a4299da88a73fb3d40abe07f78e17132c17c..d026ef0c1c5bbead9979133c2b1a3f42363bacf1 100644 (file)
@@ -1445,6 +1445,35 @@ static int test_EVP_Digest(void)
     return ret;
 }
 
+static int test_EVP_md_null(void)
+{
+    int ret = 0;
+    EVP_MD_CTX *md_ctx = NULL;
+    const EVP_MD *md_null = EVP_md_null();
+    unsigned char md_value[EVP_MAX_MD_SIZE];
+    unsigned int md_len = sizeof(md_value);
+
+    if (nullprov != NULL)
+        return TEST_skip("Test does not support a non-default library context");
+
+    if (!TEST_ptr(md_null)
+        || !TEST_ptr(md_ctx = EVP_MD_CTX_new()))
+        goto out;
+
+    if (!TEST_true(EVP_DigestInit_ex(md_ctx, md_null, NULL))
+        || !TEST_true(EVP_DigestUpdate(md_ctx, "test", 4))
+        || !TEST_true(EVP_DigestFinal_ex(md_ctx, md_value, &md_len)))
+        goto out;
+
+    if (!TEST_uint_eq(md_len, 0))
+        goto out;
+
+    ret = 1;
+ out:
+    EVP_MD_CTX_free(md_ctx);
+    return ret;
+}
+
 static int test_d2i_AutoPrivateKey(int i)
 {
     int ret = 0;
@@ -4249,6 +4278,7 @@ int setup_tests(void)
     ADD_TEST(test_siphash_digestsign);
 #endif
     ADD_TEST(test_EVP_Digest);
+    ADD_TEST(test_EVP_md_null);
     ADD_ALL_TESTS(test_EVP_PKEY_sign, 3);
     ADD_ALL_TESTS(test_EVP_Enveloped, 2);
     ADD_ALL_TESTS(test_d2i_AutoPrivateKey, OSSL_NELEM(keydata));