summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomas Mraz <tomas@openssl.org>2021-11-12 16:31:35 +0100
committerTomas Mraz <tomas@openssl.org>2021-11-15 09:25:42 +0100
commitbef9b48e5071cdd2b41a4f486d1bcb5e14b2a5c3 (patch)
tree1c519ac26b87291506e32ecd6719f32685b230e6
parent293e251e6f0367a9aa0d3d46037b19d1a6c91b20 (diff)
Add null digest implementation to the default provider
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)
-rw-r--r--crypto/evp/digest.c5
-rw-r--r--providers/defltprov.c1
-rw-r--r--providers/implementations/digests/build.info3
-rw-r--r--providers/implementations/digests/null_prov.c52
-rw-r--r--providers/implementations/include/prov/digestcommon.h23
-rw-r--r--providers/implementations/include/prov/implementations.h1
-rw-r--r--test/evp_extra_test.c30
7 files changed, 104 insertions, 11 deletions
diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c
index ebee9d8d76..0a133c5c15 100644
--- a/crypto/evp/digest.c
+++ b/crypto/evp/digest.c
@@ -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);
diff --git a/providers/defltprov.c b/providers/defltprov.c
index ed4573cb8d..3add4cdaf6 100644
--- a/providers/defltprov.c
+++ b/providers/defltprov.c
@@ -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 }
};
diff --git a/providers/implementations/digests/build.info b/providers/implementations/digests/build.info
index 2c2b0c3db0..c6508b6e85 100644
--- a/providers/implementations/digests/build.info
+++ b/providers/implementations/digests/build.info
@@ -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
index 0000000000..b220a1966f
--- /dev/null
+++ b/providers/implementations/digests/null_prov.c
@@ -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)
diff --git a/providers/implementations/include/prov/digestcommon.h b/providers/implementations/include/prov/digestcommon.h
index b0ed83648d..abdb8bb2ad 100644
--- a/providers/implementations/include/prov/digestcommon.h
+++ b/providers/implementations/include/prov/digestcommon.h
@@ -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 }, \
diff --git a/providers/implementations/include/prov/implementations.h b/providers/implementations/include/prov/implementations.h
index cb1b7925c5..d7b591cf72 100644
--- a/providers/implementations/include/prov/implementations.h
+++ b/providers/implementations/include/prov/implementations.h
@@ -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[];
diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c
index 8ac8a4299d..d026ef0c1c 100644
--- a/test/evp_extra_test.c
+++ b/test/evp_extra_test.c
@@ -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));