aboutsummaryrefslogtreecommitdiff
path: root/providers
diff options
context:
space:
mode:
authorShane Lontis <shane.lontis@oracle.com>2019-04-11 20:27:59 +1000
committerShane Lontis <shane.lontis@oracle.com>2019-06-04 12:09:50 +1000
commitd5e5e2ffafc7dbc861f7d285508cf129c5e8f5ac (patch)
tree3920b0febd6d2716940fb022b57894fe2ebf565d /providers
parentbf5b04ea25d6ac7d31e388b4e87d3eb5cd1e1e2b (diff)
downloadopenssl-d5e5e2ffafc7dbc861f7d285508cf129c5e8f5ac.zip
openssl-d5e5e2ffafc7dbc861f7d285508cf129c5e8f5ac.tar.gz
openssl-d5e5e2ffafc7dbc861f7d285508cf129c5e8f5ac.tar.bz2
Move digests to providers
Move digest code into the relevant providers (fips, default, legacy). The headers are temporarily moved to be internal, and will be moved into providers after all external references are resolved. The deprecated digest code can not be removed until EVP_PKEY (signing) is supported by providers. EVP_MD data can also not yet be cleaned up for the same reasons. Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/8763)
Diffstat (limited to 'providers')
-rw-r--r--providers/build.info2
-rw-r--r--providers/common/digests/build.info4
-rw-r--r--providers/common/digests/sha2.c105
-rw-r--r--providers/common/digests/sha3.c277
-rw-r--r--providers/common/include/internal/core_mkdigest.h95
-rw-r--r--providers/common/include/internal/provider_algs.h25
-rw-r--r--providers/default/build.info1
-rw-r--r--providers/default/defltprov.c35
-rw-r--r--providers/default/digests/blake2.c40
-rw-r--r--providers/default/digests/blake2_impl.h129
-rw-r--r--providers/default/digests/blake2b.c329
-rw-r--r--providers/default/digests/blake2s.c319
-rw-r--r--providers/default/digests/build.info17
-rw-r--r--providers/default/digests/md5.c17
-rw-r--r--providers/default/digests/md5_sha1.c46
-rw-r--r--providers/default/digests/null.c75
-rw-r--r--providers/default/digests/sm3.c17
-rw-r--r--providers/fips/fipsprov.c13
-rw-r--r--providers/legacy/digests/build.info20
-rw-r--r--providers/legacy/digests/md2.c57
-rw-r--r--providers/legacy/digests/md4.c18
-rw-r--r--providers/legacy/digests/mdc2.c37
-rw-r--r--providers/legacy/digests/ripemd.c18
-rw-r--r--providers/legacy/digests/wp.c18
-rw-r--r--providers/legacy/legacyprov.c20
25 files changed, 1617 insertions, 117 deletions
diff --git a/providers/build.info b/providers/build.info
index f379f74..192a5de 100644
--- a/providers/build.info
+++ b/providers/build.info
@@ -20,6 +20,6 @@ IF[{- !$disabled{legacy} -}]
SOURCE[legacy]=legacy.ld
GENERATE[legacy.ld]=../util/providers.num
ENDIF
- INCLUDE[legacy]=.. ../include ../crypto/include
+ INCLUDE[legacy]=.. ../include ../crypto/include common/include
DEPEND[legacy]=../libcrypto
ENDIF
diff --git a/providers/common/digests/build.info b/providers/common/digests/build.info
index b98df29..8ce0b44 100644
--- a/providers/common/digests/build.info
+++ b/providers/common/digests/build.info
@@ -1,5 +1,5 @@
SOURCE[../../../libcrypto]=\
- sha2.c
+ sha2.c sha3.c
SOURCE[../../fips]=\
- sha2.c
+ sha2.c sha3.c
diff --git a/providers/common/digests/sha2.c b/providers/common/digests/sha2.c
index 5b219ab..4b5979e 100644
--- a/providers/common/digests/sha2.c
+++ b/providers/common/digests/sha2.c
@@ -7,81 +7,64 @@
* https://www.openssl.org/source/license.html
*/
-#include <openssl/sha.h>
#include <openssl/crypto.h>
#include <openssl/core_numbers.h>
+#include <openssl/sha.h>
+#include <openssl/params.h>
+#include <openssl/core_names.h>
+#include "internal/core_mkdigest.h"
#include "internal/provider_algs.h"
+#include "internal/sha.h"
-/*
- * Forward declaration of everything implemented here. This is not strictly
- * necessary for the compiler, but provides an assurance that the signatures
- * of the functions in the dispatch table are correct.
- */
-static OSSL_OP_digest_newctx_fn sha256_newctx;
-#if 0 /* Not defined here */
-static OSSL_OP_digest_init_fn sha256_init;
-static OSSL_OP_digest_update_fn sha256_update;
-#endif
-static OSSL_OP_digest_final_fn sha256_final;
-static OSSL_OP_digest_freectx_fn sha256_freectx;
-static OSSL_OP_digest_dupctx_fn sha256_dupctx;
-static OSSL_OP_digest_size_fn sha256_size;
-static OSSL_OP_digest_block_size_fn sha256_size;
+static OSSL_OP_digest_set_params_fn sha1_set_params;
-static int sha256_final(void *ctx,
- unsigned char *md, size_t *mdl, size_t mdsz)
+/* Special set_params method for SSL3 */
+static int sha1_set_params(void *vctx, const OSSL_PARAM params[])
{
- if (mdsz >= SHA256_DIGEST_LENGTH
- && SHA256_Final(md, ctx)) {
- *mdl = SHA256_DIGEST_LENGTH;
- return 1;
- }
+ int cmd = 0;
+ size_t msg_len = 0;
+ const void *msg = NULL;
+ const OSSL_PARAM *p;
+ SHA_CTX *ctx = (SHA_CTX *)vctx;
+ if (ctx != NULL && params != NULL) {
+ p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_CMD);
+ if (p != NULL && !OSSL_PARAM_get_int(p, &cmd))
+ return 0;
+ p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_MSG);
+ if (p != NULL && !OSSL_PARAM_get_octet_ptr(p, &msg, &msg_len))
+ return 0;
+ return sha1_ctrl(ctx, cmd, msg_len, (void *)msg);
+ }
return 0;
}
-static void *sha256_newctx(void *provctx)
-{
- SHA256_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
-
- return ctx;
-}
-
-static void sha256_freectx(void *vctx)
-{
- SHA256_CTX *ctx = (SHA256_CTX *)vctx;
+OSSL_FUNC_DIGEST_CONSTRUCT_PARAMS(sha1, SHA_CTX,
+ SHA_CBLOCK, SHA_DIGEST_LENGTH,
+ SHA1_Init, SHA1_Update, SHA1_Final,
+ sha1_set_params)
- OPENSSL_clear_free(ctx, sizeof(*ctx));
-}
+OSSL_FUNC_DIGEST_CONSTRUCT(sha224, SHA256_CTX,
+ SHA256_CBLOCK, SHA224_DIGEST_LENGTH,
+ SHA224_Init, SHA224_Update, SHA224_Final)
-static void *sha256_dupctx(void *ctx)
-{
- SHA256_CTX *in = (SHA256_CTX *)ctx;
- SHA256_CTX *ret = OPENSSL_malloc(sizeof(*ret));
+OSSL_FUNC_DIGEST_CONSTRUCT(sha256, SHA256_CTX,
+ SHA256_CBLOCK, SHA256_DIGEST_LENGTH,
+ SHA256_Init, SHA256_Update, SHA256_Final)
- *ret = *in;
+OSSL_FUNC_DIGEST_CONSTRUCT(sha384, SHA512_CTX,
+ SHA512_CBLOCK, SHA384_DIGEST_LENGTH,
+ SHA384_Init, SHA384_Update, SHA384_Final)
- return ret;
-}
+OSSL_FUNC_DIGEST_CONSTRUCT(sha512, SHA512_CTX,
+ SHA512_CBLOCK, SHA512_DIGEST_LENGTH,
+ SHA512_Init, SHA512_Update, SHA512_Final)
-static size_t sha256_size(void)
-{
- return SHA256_DIGEST_LENGTH;
-}
+OSSL_FUNC_DIGEST_CONSTRUCT(sha512_224, SHA512_CTX,
+ SHA512_CBLOCK, SHA224_DIGEST_LENGTH,
+ sha512_224_init, SHA512_Update, SHA512_Final)
-static size_t sha256_block_size(void)
-{
- return SHA256_CBLOCK;
-}
+OSSL_FUNC_DIGEST_CONSTRUCT(sha512_256, SHA512_CTX,
+ SHA512_CBLOCK, SHA256_DIGEST_LENGTH,
+ sha512_256_init, SHA512_Update, SHA512_Final)
-const OSSL_DISPATCH sha256_functions[] = {
- { OSSL_FUNC_DIGEST_NEWCTX, (void (*)(void))sha256_newctx },
- { OSSL_FUNC_DIGEST_INIT, (void (*)(void))SHA256_Init },
- { OSSL_FUNC_DIGEST_UPDATE, (void (*)(void))SHA256_Update },
- { OSSL_FUNC_DIGEST_FINAL, (void (*)(void))sha256_final },
- { OSSL_FUNC_DIGEST_FREECTX, (void (*)(void))sha256_freectx },
- { OSSL_FUNC_DIGEST_DUPCTX, (void (*)(void))sha256_dupctx },
- { OSSL_FUNC_DIGEST_SIZE, (void (*)(void))sha256_size },
- { OSSL_FUNC_DIGEST_BLOCK_SIZE, (void (*)(void))sha256_block_size },
- { 0, NULL }
-};
diff --git a/providers/common/digests/sha3.c b/providers/common/digests/sha3.c
new file mode 100644
index 0000000..7b898b6
--- /dev/null
+++ b/providers/common/digests/sha3.c
@@ -0,0 +1,277 @@
+/*
+ * Copyright 2019 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/core_names.h>
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/evp.h>
+#include <openssl/params.h>
+#include "internal/sha3.h"
+#include "internal/core_mkdigest.h"
+#include "internal/provider_algs.h"
+
+/*
+ * Forward declaration of any unique methods implemented here. This is not strictly
+ * necessary for the compiler, but provides an assurance that the signatures
+ * of the functions in the dispatch table are correct.
+ */
+static OSSL_OP_digest_init_fn keccak_init;
+static OSSL_OP_digest_update_fn keccak_update;
+static OSSL_OP_digest_final_fn keccak_final;
+static OSSL_OP_digest_freectx_fn keccak_freectx;
+static OSSL_OP_digest_dupctx_fn keccak_dupctx;
+static OSSL_OP_digest_set_params_fn shake_set_params;
+static sha3_absorb_fn generic_sha3_absorb;
+static sha3_final_fn generic_sha3_final;
+
+#if defined(OPENSSL_CPUID_OBJ) && defined(__s390__) && defined(KECCAK1600_ASM)
+/*
+ * IBM S390X support
+ */
+# include "s390x_arch.h"
+# define S390_SHA3 1
+# define S390_SHA3_CAPABLE(name) \
+ ((OPENSSL_s390xcap_P.kimd[0] & S390X_CAPBIT(S390X_##name)) && \
+ (OPENSSL_s390xcap_P.klmd[0] & S390X_CAPBIT(S390X_##name)))
+
+#endif
+
+static int keccak_init(void *vctx)
+{
+ /* The newctx() handles most of the ctx fixed setup. */
+ sha3_reset((KECCAK1600_CTX *)vctx);
+ return 1;
+}
+
+static int keccak_update(void *vctx, const unsigned char *inp, size_t len)
+{
+ KECCAK1600_CTX *ctx = vctx;
+ const size_t bsz = ctx->block_size;
+ size_t num, rem;
+
+ if (len == 0)
+ return 1;
+
+ /* Is there anything in the buffer already ? */
+ if ((num = ctx->bufsz) != 0) {
+ /* Calculate how much space is left in the buffer */
+ rem = bsz - num;
+ /* If the new input does not fill the buffer then just add it */
+ if (len < rem) {
+ memcpy(ctx->buf + num, inp, len);
+ ctx->bufsz += len;
+ return 1;
+ }
+ /* otherwise fill up the buffer and absorb the buffer */
+ memcpy(ctx->buf + num, inp, rem);
+ /* Update the input pointer */
+ inp += rem;
+ len -= rem;
+ ctx->meth.absorb(ctx, ctx->buf, bsz);
+ ctx->bufsz = 0;
+ }
+ /* Absorb the input - rem = leftover part of the input < blocksize) */
+ rem = ctx->meth.absorb(ctx, inp, len);
+ /* Copy the leftover bit of the input into the buffer */
+ if (rem) {
+ memcpy(ctx->buf, inp + len - rem, rem);
+ ctx->bufsz = rem;
+ }
+ return 1;
+}
+
+static int keccak_final(void *vctx, unsigned char *out, size_t *outl,
+ size_t outsz)
+{
+ int ret;
+ KECCAK1600_CTX *ctx = vctx;
+
+ ret = ctx->meth.final(out, ctx);
+ *outl = ctx->md_size;
+ return ret;
+}
+
+/*-
+ * Generic software version of the absorb() and final().
+ */
+static size_t generic_sha3_absorb(void *vctx, const void *inp, size_t len)
+{
+ KECCAK1600_CTX *ctx = vctx;
+
+ return SHA3_absorb(ctx->A, inp, len, ctx->block_size);
+}
+
+static int generic_sha3_final(unsigned char *md, void *vctx)
+{
+ return sha3_final(md, (KECCAK1600_CTX *)vctx);
+}
+
+static PROV_SHA3_METHOD sha3_generic_md =
+{
+ generic_sha3_absorb,
+ generic_sha3_final
+};
+
+#if defined(S390_SHA3)
+
+static sha3_absorb_fn s390x_sha3_absorb;
+static sha3_final_fn s390x_sha3_final;
+static sha3_final_fn s390x_shake_final;
+
+/*-
+ * The platform specific parts of the absorb() and final() for S390X.
+ */
+static size_t s390x_sha3_absorb(void *vctx, const void *inp, size_t len)
+{
+ KECCAK1600_CTX *ctx = vctx;
+ size_t rem = len % ctx->block_size;
+
+ s390x_kimd(inp, len - rem, ctx->pad, ctx->A);
+ return rem;
+}
+
+static int s390x_sha3_final(unsigned char *md, void *vctx)
+{
+ KECCAK1600_CTX *ctx = vctx;
+
+ s390x_klmd(ctx->buf, ctx->bufsz, NULL, 0, ctx->pad, ctx->A);
+ memcpy(md, ctx->A, ctx->md_size);
+}
+
+static int s390x_shake_final(unsigned char *md, void *vctx)
+{
+ KECCAK1600_CTX *ctx = vctx;
+
+ s390x_klmd(ctx->buf, ctx->bufsz, md, ctx->md_size, ctx->pad, ctx->A);
+ return 1;
+}
+
+static PROV_SHA3_METHOD sha3_s390x_md =
+{
+ s390x_sha3_absorb,
+ s390x_sha3_final
+};
+
+static PROV_SHA3_METHOD shake_s390x_md =
+{
+ s390x_sha3_absorb,
+ s390x_shake_final
+};
+
+# define SHA3_SET_MD(uname, typ) \
+ if (S390_SHA3_CAPABLE(uname)) { \
+ ctx->pad = S390X_##uname; \
+ ctx->meth = typ##_s390x_md; \
+ } else { \
+ ctx->meth = sha3_generic_md; \
+ }
+#else
+# define SHA3_SET_MD(uname, typ) ctx->meth = sha3_generic_md;
+#endif /* S390_SHA3 */
+
+#define SHA3_newctx(typ, uname, name, bitlen, pad) \
+static OSSL_OP_digest_newctx_fn name##_newctx; \
+static void *name##_newctx(void *provctx) \
+{ \
+ KECCAK1600_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); \
+ \
+ if (ctx == NULL) \
+ return NULL; \
+ sha3_init(ctx, pad, bitlen); \
+ SHA3_SET_MD(name, typ) \
+ return ctx; \
+}
+
+#define KMAC_newctx(uname, bitlen, pad) \
+static OSSL_OP_digest_newctx_fn uname##_newctx; \
+static void *uname##_newctx(void *provctx) \
+{ \
+ KECCAK1600_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); \
+ \
+ if (ctx == NULL) \
+ return NULL; \
+ keccak_kmac_init(ctx, pad, bitlen); \
+ ctx->meth = sha3_generic_md; \
+ return ctx; \
+}
+
+#define OSSL_FUNC_SHA3_DIGEST(name, bitlen, dgstsize, stparams) \
+static OSSL_OP_digest_size_fn name##_size; \
+static OSSL_OP_digest_block_size_fn name##_block_size; \
+static size_t name##_block_size(void) \
+{ \
+ return SHA3_BLOCKSIZE(bitlen); \
+} \
+static size_t name##_size(void) \
+{ \
+ return dgstsize; \
+} \
+const OSSL_DISPATCH name##_functions[] = { \
+ { OSSL_FUNC_DIGEST_NEWCTX, (void (*)(void))name##_newctx }, \
+ { OSSL_FUNC_DIGEST_INIT, (void (*)(void))keccak_init }, \
+ { OSSL_FUNC_DIGEST_UPDATE, (void (*)(void))keccak_update }, \
+ { OSSL_FUNC_DIGEST_FINAL, (void (*)(void))keccak_final }, \
+ { OSSL_FUNC_DIGEST_FREECTX, (void (*)(void))keccak_freectx }, \
+ { OSSL_FUNC_DIGEST_DUPCTX, (void (*)(void))keccak_dupctx }, \
+ { OSSL_FUNC_DIGEST_SIZE, (void (*)(void))name##_size }, \
+ { OSSL_FUNC_DIGEST_BLOCK_SIZE, (void (*)(void))name##_block_size }, \
+ { OSSL_FUNC_DIGEST_SET_PARAMS, (void (*)(void))stparams },\
+OSSL_FUNC_DIGEST_CONSTRUCT_END
+
+static void keccak_freectx(void *vctx)
+{
+ KECCAK1600_CTX *ctx = (KECCAK1600_CTX *)vctx;
+
+ OPENSSL_clear_free(ctx, sizeof(*ctx));
+}
+
+static void *keccak_dupctx(void *ctx)
+{
+ KECCAK1600_CTX *in = (KECCAK1600_CTX *)ctx;
+ KECCAK1600_CTX *ret = OPENSSL_malloc(sizeof(*ret));
+
+ *ret = *in;
+ return ret;
+}
+
+static int shake_set_params(void *vctx, const OSSL_PARAM params[])
+{
+ const OSSL_PARAM *p;
+ KECCAK1600_CTX *ctx = (KECCAK1600_CTX *)vctx;
+
+ if (ctx != NULL && params != NULL) {
+ p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_XOFLEN);
+ if (p != NULL && !OSSL_PARAM_get_size_t(p, &ctx->md_size))
+ return 0;
+ return 1;
+ }
+ return 0; /* Null Parameter */
+}
+
+#define SHA3(bitlen) \
+ SHA3_newctx(sha3, SHA3_##bitlen, sha3_##bitlen, bitlen, '\x06') \
+ OSSL_FUNC_SHA3_DIGEST(sha3_##bitlen, bitlen, SHA3_MDSIZE(bitlen), NULL)
+
+#define SHAKE(bitlen) \
+ SHA3_newctx(shake, SHAKE_##bitlen, shake_##bitlen, bitlen, '\x1f') \
+ OSSL_FUNC_SHA3_DIGEST(shake_##bitlen, bitlen, SHA3_MDSIZE(bitlen), \
+ shake_set_params)
+#define KMAC(bitlen) \
+ KMAC_newctx(keccak_kmac_##bitlen, bitlen, '\x04') \
+ OSSL_FUNC_SHA3_DIGEST(keccak_kmac_##bitlen, bitlen, KMAC_MDSIZE(bitlen), \
+ shake_set_params)
+
+SHA3(224)
+SHA3(256)
+SHA3(384)
+SHA3(512)
+SHAKE(128)
+SHAKE(256)
+KMAC(128)
+KMAC(256)
diff --git a/providers/common/include/internal/core_mkdigest.h b/providers/common/include/internal/core_mkdigest.h
new file mode 100644
index 0000000..7225196
--- /dev/null
+++ b/providers/common/include/internal/core_mkdigest.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2019 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
+ */
+
+#ifndef OSSL_CORE_MKDIGEST_H
+# define OSSL_CORE_MKDIGEST_H
+
+# include <openssl/core_numbers.h>
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+# define OSSL_FUNC_DIGEST_ALLOC_METHODS(name, CTX_NAME) \
+static OSSL_OP_digest_newctx_fn name##_newctx; \
+static OSSL_OP_digest_freectx_fn name##_freectx; \
+static OSSL_OP_digest_dupctx_fn name##_dupctx; \
+static void *name##_newctx(void *prov_ctx) \
+{ \
+ CTX_NAME *ctx = OPENSSL_zalloc(sizeof(*ctx)); \
+ return ctx; \
+} \
+static void name##_freectx(void *vctx) \
+{ \
+ CTX_NAME *ctx = (CTX_NAME *)vctx; \
+ OPENSSL_clear_free(ctx, sizeof(*ctx)); \
+} \
+static void *name##_dupctx(void *ctx) \
+{ \
+ CTX_NAME *in = (CTX_NAME *)ctx; \
+ CTX_NAME *ret = OPENSSL_malloc(sizeof(*ret)); \
+ *ret = *in; \
+ return ret; \
+}
+
+# define OSSL_FUNC_DIGEST_SET_FINAL(name, dgstsize, fin) \
+static OSSL_OP_digest_final_fn name##_wrapfinal; \
+static int name##_wrapfinal(void *ctx, unsigned char *out, size_t *outl, size_t outsz) \
+{ \
+ if (outsz >= dgstsize && fin(out, ctx)) { \
+ *outl = dgstsize; \
+ return 1; \
+ } \
+ return 0; \
+}
+
+# define OSSL_FUNC_DIGEST_COMMON(name, blksize, dgstsize, init, upd) \
+static OSSL_OP_digest_block_size_fn name##_block_size; \
+static OSSL_OP_digest_size_fn name##_size; \
+static size_t name##_block_size(void) \
+{ \
+ return blksize; \
+} \
+static size_t name##_size(void) \
+{ \
+ return dgstsize; \
+} \
+const OSSL_DISPATCH name##_functions[] = { \
+ { OSSL_FUNC_DIGEST_NEWCTX, (void (*)(void))name##_newctx }, \
+ { OSSL_FUNC_DIGEST_INIT, (void (*)(void))init }, \
+ { OSSL_FUNC_DIGEST_UPDATE, (void (*)(void))upd }, \
+ { OSSL_FUNC_DIGEST_FINAL, (void (*)(void))name##_wrapfinal }, \
+ { OSSL_FUNC_DIGEST_FREECTX, (void (*)(void))name##_freectx }, \
+ { OSSL_FUNC_DIGEST_DUPCTX, (void (*)(void))name##_dupctx }, \
+ { OSSL_FUNC_DIGEST_SIZE, (void (*)(void))name##_size }, \
+ { OSSL_FUNC_DIGEST_BLOCK_SIZE, (void (*)(void))name##_block_size },
+
+# define OSSL_FUNC_DIGEST_CONSTRUCT_START(name, CTX, blksize, dgstsize, init, upd, fin) \
+OSSL_FUNC_DIGEST_ALLOC_METHODS(name, CTX) \
+OSSL_FUNC_DIGEST_SET_FINAL(name, dgstsize, fin) \
+OSSL_FUNC_DIGEST_COMMON(name, blksize, dgstsize, init, upd)
+
+# define OSSL_FUNC_DIGEST_CONSTRUCT_END \
+ { 0, NULL } \
+};
+
+# define OSSL_FUNC_DIGEST_CONSTRUCT(name, CTX, blksize, dgstsize, init, upd, fin) \
+OSSL_FUNC_DIGEST_CONSTRUCT_START(name, CTX, blksize, dgstsize, init, upd, fin) \
+OSSL_FUNC_DIGEST_CONSTRUCT_END
+
+# define OSSL_FUNC_DIGEST_CONSTRUCT_PARAMS(name, CTX, blksize, dgstsize, init, upd, fin, setparams) \
+OSSL_FUNC_DIGEST_CONSTRUCT_START(name, CTX, blksize, dgstsize, init, upd, fin) \
+ { OSSL_FUNC_DIGEST_SET_PARAMS, (void (*)(void))setparams }, \
+OSSL_FUNC_DIGEST_CONSTRUCT_END
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif /* OSSL_CORE_MKDIGEST_H */
diff --git a/providers/common/include/internal/provider_algs.h b/providers/common/include/internal/provider_algs.h
index dd9211b..0e26da0 100644
--- a/providers/common/include/internal/provider_algs.h
+++ b/providers/common/include/internal/provider_algs.h
@@ -8,7 +8,32 @@
*/
/* Digests */
+extern const OSSL_DISPATCH sha1_functions[];
+extern const OSSL_DISPATCH sha224_functions[];
extern const OSSL_DISPATCH sha256_functions[];
+extern const OSSL_DISPATCH sha384_functions[];
+extern const OSSL_DISPATCH sha512_functions[];
+extern const OSSL_DISPATCH sha512_224_functions[];
+extern const OSSL_DISPATCH sha512_256_functions[];
+extern const OSSL_DISPATCH sha3_224_functions[];
+extern const OSSL_DISPATCH sha3_256_functions[];
+extern const OSSL_DISPATCH sha3_384_functions[];
+extern const OSSL_DISPATCH sha3_512_functions[];
+extern const OSSL_DISPATCH keccak_kmac_128_functions[];
+extern const OSSL_DISPATCH keccak_kmac_256_functions[];
+extern const OSSL_DISPATCH shake_128_functions[];
+extern const OSSL_DISPATCH shake_256_functions[];
+extern const OSSL_DISPATCH blake2s256_functions[];
+extern const OSSL_DISPATCH blake2b512_functions[];
+extern const OSSL_DISPATCH md5_functions[];
+extern const OSSL_DISPATCH md5_sha1_functions[];
+extern const OSSL_DISPATCH sm3_functions[];
+extern const OSSL_DISPATCH nullmd_functions[];
+extern const OSSL_DISPATCH md2_functions[];
+extern const OSSL_DISPATCH md4_functions[];
+extern const OSSL_DISPATCH mdc2_functions[];
+extern const OSSL_DISPATCH wp_functions[];
+extern const OSSL_DISPATCH ripemd160_functions[];
/* Ciphers */
extern const OSSL_DISPATCH aes256ecb_functions[];
diff --git a/providers/default/build.info b/providers/default/build.info
index eab90a3..985d681 100644
--- a/providers/default/build.info
+++ b/providers/default/build.info
@@ -1,3 +1,4 @@
+SUBDIRS=digests
LIBS=../../libcrypto
SOURCE[../../libcrypto]=\
defltprov.c
diff --git a/providers/default/defltprov.c b/providers/default/defltprov.c
index 95b2abf..9899940 100644
--- a/providers/default/defltprov.c
+++ b/providers/default/defltprov.c
@@ -51,7 +51,42 @@ static int deflt_get_params(const OSSL_PROVIDER *prov,
}
static const OSSL_ALGORITHM deflt_digests[] = {
+ { "SHA1", "default=yes", sha1_functions },
+
+ { "SHA224", "default=yes", sha224_functions },
{ "SHA256", "default=yes", sha256_functions },
+ { "SHA384", "default=yes", sha384_functions },
+ { "SHA512", "default=yes", sha512_functions },
+ { "SHA512-224", "default=yes", sha512_224_functions },
+ { "SHA512-256", "default=yes", sha512_256_functions },
+
+ { "SHA3-224", "default=yes", sha3_224_functions },
+ { "SHA3-256", "default=yes", sha3_256_functions },
+ { "SHA3-384", "default=yes", sha3_384_functions },
+ { "SHA3-512", "default=yes", sha3_512_functions },
+
+ { "KMAC128", "default=yes", keccak_kmac_128_functions },
+ { "KMAC256", "default=yes", keccak_kmac_256_functions },
+
+ { "SHAKE128", "default=yes", shake_128_functions },
+ { "SHAKE256", "default=yes", shake_256_functions },
+
+#ifndef OPENSSL_NO_BLAKE2
+ { "BLAKE2s256", "default=yes", blake2s256_functions },
+ { "BLAKE2b512", "default=yes", blake2b512_functions },
+#endif /* OPENSSL_NO_BLAKE2 */
+
+#ifndef OPENSSL_NO_SM3
+ { "SM3", "default=yes", sm3_functions },
+#endif /* OPENSSL_NO_SM3 */
+
+#ifndef OPENSSL_NO_MD5
+ { "MD5", "default=yes", md5_functions },
+ { "MD5-SHA1", "default=yes", md5_sha1_functions },
+#endif /* OPENSSL_NO_MD5 */
+
+ /*{ "UNDEF", "default=yes", nullmd_functions }, */
+
{ NULL, NULL, NULL }
};
diff --git a/providers/default/digests/blake2.c b/providers/default/digests/blake2.c
new file mode 100644
index 0000000..18a8d60
--- /dev/null
+++ b/providers/default/digests/blake2.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2019 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 "internal/blake2.h"
+#include "internal/core_mkdigest.h"
+#include "internal/provider_algs.h"
+
+OSSL_OP_digest_init_fn blake2s256_init;
+OSSL_OP_digest_init_fn blake2b512_init;
+
+int blake2s256_init(void *ctx)
+{
+ BLAKE2S_PARAM P;
+
+ blake2s_param_init(&P);
+ return blake2s_init((BLAKE2S_CTX *)ctx, &P);
+}
+
+int blake2b512_init(void *ctx)
+{
+ BLAKE2B_PARAM P;
+
+ blake2b_param_init(&P);
+ return blake2b_init((BLAKE2B_CTX *)ctx, &P);
+}
+
+OSSL_FUNC_DIGEST_CONSTRUCT(blake2s256, BLAKE2S_CTX,
+ BLAKE2S_BLOCKBYTES, BLAKE2S_DIGEST_LENGTH,
+ blake2s256_init, blake2s_update, blake2s_final)
+
+OSSL_FUNC_DIGEST_CONSTRUCT(blake2b512, BLAKE2B_CTX,
+ BLAKE2B_BLOCKBYTES, BLAKE2B_DIGEST_LENGTH,
+ blake2b512_init, blake2b_update, blake2b_final)
diff --git a/providers/default/digests/blake2_impl.h b/providers/default/digests/blake2_impl.h
new file mode 100644
index 0000000..52477a8
--- /dev/null
+++ b/providers/default/digests/blake2_impl.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2016-2017 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
+ */
+
+/*
+ * Derived from the BLAKE2 reference implementation written by Samuel Neves.
+ * Copyright 2012, Samuel Neves <sneves@dei.uc.pt>
+ * More information about the BLAKE2 hash function and its implementations
+ * can be found at https://blake2.net.
+ */
+
+#include <string.h>
+
+static ossl_inline uint32_t load32(const uint8_t *src)
+{
+ const union {
+ long one;
+ char little;
+ } is_endian = { 1 };
+
+ if (is_endian.little) {
+ uint32_t w;
+ memcpy(&w, src, sizeof(w));
+ return w;
+ } else {
+ uint32_t w = ((uint32_t)src[0])
+ | ((uint32_t)src[1] << 8)
+ | ((uint32_t)src[2] << 16)
+ | ((uint32_t)src[3] << 24);
+ return w;
+ }
+}
+
+static ossl_inline uint64_t load64(const uint8_t *src)
+{
+ const union {
+ long one;
+ char little;
+ } is_endian = { 1 };
+
+ if (is_endian.little) {
+ uint64_t w;
+ memcpy(&w, src, sizeof(w));
+ return w;
+ } else {
+ uint64_t w = ((uint64_t)src[0])
+ | ((uint64_t)src[1] << 8)
+ | ((uint64_t)src[2] << 16)
+ | ((uint64_t)src[3] << 24)
+ | ((uint64_t)src[4] << 32)
+ | ((uint64_t)src[5] << 40)
+ | ((uint64_t)src[6] << 48)
+ | ((uint64_t)src[7] << 56);
+ return w;
+ }
+}
+
+static ossl_inline void store32(uint8_t *dst, uint32_t w)
+{
+ const union {
+ long one;
+ char little;
+ } is_endian = { 1 };
+
+ if (is_endian.little) {
+ memcpy(dst, &w, sizeof(w));
+ } else {
+ uint8_t *p = (uint8_t *)dst;
+ int i;
+
+ for (i = 0; i < 4; i++)
+ p[i] = (uint8_t)(w >> (8 * i));
+ }
+}
+
+static ossl_inline void store64(uint8_t *dst, uint64_t w)
+{
+ const union {
+ long one;
+ char little;
+ } is_endian = { 1 };
+
+ if (is_endian.little) {
+ memcpy(dst, &w, sizeof(w));
+ } else {
+ uint8_t *p = (uint8_t *)dst;
+ int i;
+
+ for (i = 0; i < 8; i++)
+ p[i] = (uint8_t)(w >> (8 * i));
+ }
+}
+
+static ossl_inline uint64_t load48(const uint8_t *src)
+{
+ uint64_t w = ((uint64_t)src[0])
+ | ((uint64_t)src[1] << 8)
+ | ((uint64_t)src[2] << 16)
+ | ((uint64_t)src[3] << 24)
+ | ((uint64_t)src[4] << 32)
+ | ((uint64_t)src[5] << 40);
+ return w;
+}
+
+static ossl_inline void store48(uint8_t *dst, uint64_t w)
+{
+ uint8_t *p = (uint8_t *)dst;
+ p[0] = (uint8_t)w;
+ p[1] = (uint8_t)(w>>8);
+ p[2] = (uint8_t)(w>>16);
+ p[3] = (uint8_t)(w>>24);
+ p[4] = (uint8_t)(w>>32);
+ p[5] = (uint8_t)(w>>40);
+}
+
+static ossl_inline uint32_t rotr32(const uint32_t w, const unsigned int c)
+{
+ return (w >> c) | (w << (32 - c));
+}
+
+static ossl_inline uint64_t rotr64(const uint64_t w, const unsigned int c)
+{
+ return (w >> c) | (w << (64 - c));
+}
diff --git a/providers/default/digests/blake2b.c b/providers/default/digests/blake2b.c
new file mode 100644
index 0000000..8801270
--- /dev/null
+++ b/providers/default/digests/blake2b.c
@@ -0,0 +1,329 @@
+/*
+ * Copyright 2016-2019 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
+ */
+
+/*
+ * Derived from the BLAKE2 reference implementation written by Samuel Neves.
+ * Copyright 2012, Samuel Neves <sneves@dei.uc.pt>
+ * More information about the BLAKE2 hash function and its implementations
+ * can be found at https://blake2.net.
+ */
+
+#include <assert.h>
+#include <string.h>
+#include <openssl/crypto.h>
+#include "blake2_impl.h"
+
+#include "internal/blake2.h"
+
+static const uint64_t blake2b_IV[8] =
+{
+ 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL,
+ 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,
+ 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
+ 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
+};
+
+static const uint8_t blake2b_sigma[12][16] =
+{
+ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
+ { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,
+ { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,
+ { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,
+ { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,
+ { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,
+ { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,
+ { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,
+ { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,
+ { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,
+ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
+ { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }
+};
+
+/* Set that it's the last block we'll compress */
+static ossl_inline void blake2b_set_lastblock(BLAKE2B_CTX *S)
+{
+ S->f[0] = -1;
+}
+
+/* Initialize the hashing state. */
+static ossl_inline void blake2b_init0(BLAKE2B_CTX *S)
+{
+ int i;
+
+ memset(S, 0, sizeof(BLAKE2B_CTX));
+ for (i = 0; i < 8; ++i) {
+ S->h[i] = blake2b_IV[i];
+ }
+}
+
+/* init xors IV with input parameter block and sets the output length */
+static void blake2b_init_param(BLAKE2B_CTX *S, const BLAKE2B_PARAM *P)
+{
+ size_t i;
+ const uint8_t *p = (const uint8_t *)(P);
+
+ blake2b_init0(S);
+ S->outlen = P->digest_length;
+
+ /* The param struct is carefully hand packed, and should be 64 bytes on
+ * every platform. */
+ assert(sizeof(BLAKE2B_PARAM) == 64);
+ /* IV XOR ParamBlock */
+ for (i = 0; i < 8; ++i) {
+ S->h[i] ^= load64(p + sizeof(S->h[i]) * i);
+ }
+}
+
+/* Initialize the parameter block with default values */
+void blake2b_param_init(BLAKE2B_PARAM *P)
+{
+ P->digest_length = BLAKE2B_DIGEST_LENGTH;
+ P->key_length = 0;
+ P->fanout = 1;
+ P->depth = 1;
+ store32(P->leaf_length, 0);
+ store64(P->node_offset, 0);
+ P->node_depth = 0;
+ P->inner_length = 0;
+ memset(P->reserved, 0, sizeof(P->reserved));
+ memset(P->salt, 0, sizeof(P->salt));
+ memset(P->personal, 0, sizeof(P->personal));
+}
+
+void blake2b_param_set_digest_length(BLAKE2B_PARAM *P, uint8_t outlen)
+{
+ P->digest_length = outlen;
+}
+
+void blake2b_param_set_key_length(BLAKE2B_PARAM *P, uint8_t keylen)
+{
+ P->key_length = keylen;
+}
+
+void blake2b_param_set_personal(BLAKE2B_PARAM *P, const uint8_t *personal, size_t len)
+{
+ memcpy(P->personal, personal, len);
+ memset(P->personal + len, 0, BLAKE2B_PERSONALBYTES - len);
+}
+
+void blake2b_param_set_salt(BLAKE2B_PARAM *P, const uint8_t *salt, size_t len)
+{
+ memcpy(P->salt, salt, len);
+ memset(P->salt + len, 0, BLAKE2B_SALTBYTES - len);
+}
+
+/*
+ * Initialize the hashing context with the given parameter block.
+ * Always returns 1.
+ */
+int blake2b_init(BLAKE2B_CTX *c, const BLAKE2B_PARAM *P)
+{
+ blake2b_init_param(c, P);
+ return 1;
+}
+
+/*
+ * Initialize the hashing context with the given parameter block and key.
+ * Always returns 1.
+ */
+int blake2b_init_key(BLAKE2B_CTX *c, const BLAKE2B_PARAM *P, const void *key)
+{
+ blake2b_init_param(c, P);
+
+ /* Pad the key to form first data block */
+ {
+ uint8_t block[BLAKE2B_BLOCKBYTES] = {0};
+
+ memcpy(block, key, P->key_length);
+ blake2b_update(c, block, BLAKE2B_BLOCKBYTES);
+ OPENSSL_cleanse(block, BLAKE2B_BLOCKBYTES);
+ }
+
+ return 1;
+}
+
+/* Permute the state while xoring in the block of data. */
+static void blake2b_compress(BLAKE2B_CTX *S,
+ const uint8_t *blocks,
+ size_t len)
+{
+ uint64_t m[16];
+ uint64_t v[16];
+ int i;
+ size_t increment;
+
+ /*
+ * There are two distinct usage vectors for this function:
+ *
+ * a) BLAKE2b_Update uses it to process complete blocks,
+ * possibly more than one at a time;
+ *
+ * b) BLAK2b_Final uses it to process last block, always
+ * single but possibly incomplete, in which case caller
+ * pads input with zeros.
+ */
+ assert(len < BLAKE2B_BLOCKBYTES || len % BLAKE2B_BLOCKBYTES == 0);
+
+ /*
+ * Since last block is always processed with separate call,
+ * |len| not being multiple of complete blocks can be observed
+ * only with |len| being less than BLAKE2B_BLOCKBYTES ("less"
+ * including even zero), which is why following assignment doesn't
+ * have to reside inside the main loop below.
+ */
+ increment = len < BLAKE2B_BLOCKBYTES ? len : BLAKE2B_BLOCKBYTES;
+
+ for (i = 0; i < 8; ++i) {
+ v[i] = S->h[i];
+ }
+
+ do {
+ for (i = 0; i < 16; ++i) {
+ m[i] = load64(blocks + i * sizeof(m[i]));
+ }
+
+ /* blake2b_increment_counter */
+ S->t[0] += increment;
+ S->t[1] += (S->t[0] < increment);
+
+ v[8] = blake2b_IV[0];
+ v[9] = blake2b_IV[1];
+ v[10] = blake2b_IV[2];
+ v[11] = blake2b_IV[3];
+ v[12] = S->t[0] ^ blake2b_IV[4];
+ v[13] = S->t[1] ^ blake2b_IV[5];
+ v[14] = S->f[0] ^ blake2b_IV[6];
+ v[15] = S->f[1] ^ blake2b_IV[7];
+#define G(r,i,a,b,c,d) \
+ do { \
+ a = a + b + m[blake2b_sigma[r][2*i+0]]; \
+ d = rotr64(d ^ a, 32); \
+ c = c + d; \
+ b = rotr64(b ^ c, 24); \
+ a = a + b + m[blake2b_sigma[r][2*i+1]]; \
+ d = rotr64(d ^ a, 16); \
+ c = c + d; \
+ b = rotr64(b ^ c, 63); \
+ } while (0)
+#define ROUND(r) \
+ do { \
+ G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
+ G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
+ G(r,2,v[ 2],v[ 6],v[10],v[14]); \
+ G(r,3,v[ 3],v[ 7],v[11],v[15]); \
+ G(r,4,v[ 0],v[ 5],v[10],v[15]); \
+ G(r,5,v[ 1],v[ 6],v[11],v[12]); \
+ G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
+ G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
+ } while (0)
+#if defined(OPENSSL_SMALL_FOOTPRINT)
+ /* 3x size reduction on x86_64, almost 7x on ARMv8, 9x on ARMv4 */
+ for (i = 0; i < 12; i++) {
+ ROUND(i);
+ }
+#else
+ ROUND(0);
+ ROUND(1);
+ ROUND(2);
+ ROUND(3);
+ ROUND(4);
+ ROUND(5);
+ ROUND(6);
+ ROUND(7);
+ ROUND(8);
+ ROUND(9);
+ ROUND(10);
+ ROUND(11);
+#endif
+
+ for (i = 0; i < 8; ++i) {
+ S->h[i] = v[i] ^= v[i + 8] ^ S->h[i];
+ }
+#undef G
+#undef ROUND
+ blocks += increment;
+ len -= increment;
+ } while (len);
+}
+
+/* Absorb the input data into the hash state. Always returns 1. */
+int blake2b_update(BLAKE2B_CTX *c, const void *data, size_t datalen)
+{
+ const uint8_t *in = data;
+ size_t fill;
+
+ /*
+ * Intuitively one would expect intermediate buffer, c->buf, to
+ * store incomplete blocks. But in this case we are interested to
+ * temporarily stash even complete blocks, because last one in the
+ * stream has to be treated in special way, and at this point we
+ * don't know if last block in *this* call is last one "ever". This
+ * is the reason for why |datalen| is compared as >, and not >=.
+ */
+ fill = sizeof(c->buf) - c->buflen;
+ if (datalen > fill) {
+ if (c->buflen) {
+ memcpy(c->buf + c->buflen, in, fill); /* Fill buffer */
+ blake2b_compress(c, c->buf, BLAKE2B_BLOCKBYTES);
+ c->buflen = 0;
+ in += fill;
+ datalen -= fill;
+ }
+ if (datalen > BLAKE2B_BLOCKBYTES) {
+ size_t stashlen = datalen % BLAKE2B_BLOCKBYTES;
+ /*
+ * If |datalen| is a multiple of the blocksize, stash
+ * last complete block, it can be final one...
+ */
+ stashlen = stashlen ? stashlen : BLAKE2B_BLOCKBYTES;
+ datalen -= stashlen;
+ blake2b_compress(c, in, datalen);
+ in += datalen;
+ datalen = stashlen;
+ }
+ }
+
+ assert(datalen <= BLAKE2B_BLOCKBYTES);
+
+ memcpy(c->buf + c->buflen, in, datalen);
+ c->buflen += datalen; /* Be lazy, do not compress */
+
+ return 1;
+}
+
+/*
+ * Calculate the final hash and save it in md.
+ * Always returns 1.
+ */
+int blake2b_final(unsigned char *md, BLAKE2B_CTX *c)
+{
+ uint8_t outbuffer[BLAKE2B_OUTBYTES] = {0};
+ uint8_t *target = outbuffer;
+ int iter = (c->outlen + 7) / 8;
+ int i;
+
+ /* Avoid writing to the temporary buffer if possible */
+ if ((c->outlen % sizeof(c->h[0])) == 0)
+ target = md;
+
+ blake2b_set_lastblock(c);
+ /* Padding */
+ memset(c->buf + c->buflen, 0, sizeof(c->buf) - c->buflen);
+ blake2b_compress(c, c->buf, c->buflen);
+
+ /* Output full hash to buffer */
+ for (i = 0; i < iter; ++i)
+ store64(target + sizeof(c->h[i]) * i, c->h[i]);
+
+ if (target != md)
+ memcpy(md, target, c->outlen);
+
+ OPENSSL_cleanse(c, sizeof(BLAKE2B_CTX));
+ return 1;
+}
diff --git a/providers/default/digests/blake2s.c b/providers/default/digests/blake2s.c
new file mode 100644
index 0000000..a9c757e
--- /dev/null
+++ b/providers/default/digests/blake2s.c
@@ -0,0 +1,319 @@
+/*
+ * Copyright 2016-2019 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
+ */
+
+/*
+ * Derived from the BLAKE2 reference implementation written by Samuel Neves.
+ * Copyright 2012, Samuel Neves <sneves@dei.uc.pt>
+ * More information about the BLAKE2 hash function and its implementations
+ * can be found at https://blake2.net.
+ */
+
+#include <assert.h>
+#include <string.h>
+#include <openssl/crypto.h>
+#include "blake2_impl.h"
+#include "internal/blake2.h"
+
+static const uint32_t blake2s_IV[8] =
+{
+ 0x6A09E667U, 0xBB67AE85U, 0x3C6EF372U, 0xA54FF53AU,
+ 0x510E527FU, 0x9B05688CU, 0x1F83D9ABU, 0x5BE0CD19U
+};
+
+static const uint8_t blake2s_sigma[10][16] =
+{
+ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
+ { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,
+ { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,
+ { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,
+ { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,
+ { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,
+ { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,
+ { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,
+ { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,
+ { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,
+};
+
+/* Set that it's the last block we'll compress */
+static ossl_inline void blake2s_set_lastblock(BLAKE2S_CTX *S)
+{
+ S->f[0] = -1;
+}
+
+/* Initialize the hashing state. */
+static ossl_inline void blake2s_init0(BLAKE2S_CTX *S)
+{
+ int i;
+
+ memset(S, 0, sizeof(BLAKE2S_CTX));
+ for (i = 0; i < 8; ++i) {
+ S->h[i] = blake2s_IV[i];
+ }
+}
+
+/* init xors IV with input parameter block and sets the output length */
+static void blake2s_init_param(BLAKE2S_CTX *S, const BLAKE2S_PARAM *P)
+{
+ size_t i;
+ const uint8_t *p = (const uint8_t *)(P);
+
+ blake2s_init0(S);
+ S->outlen = P->digest_length;
+
+ /* The param struct is carefully hand packed, and should be 32 bytes on
+ * every platform. */
+ assert(sizeof(BLAKE2S_PARAM) == 32);
+ /* IV XOR ParamBlock */
+ for (i = 0; i < 8; ++i) {
+ S->h[i] ^= load32(&p[i*4]);
+ }
+}
+
+void blake2s_param_init(BLAKE2S_PARAM *P)
+{
+ P->digest_length = BLAKE2S_DIGEST_LENGTH;
+ P->key_length = 0;
+ P->fanout = 1;
+ P->depth = 1;
+ store32(P->leaf_length, 0);
+ store48(P->node_offset, 0);
+ P->node_depth = 0;
+ P->inner_length = 0;
+ memset(P->salt, 0, sizeof(P->salt));
+ memset(P->personal, 0, sizeof(P->personal));
+}
+
+void blake2s_param_set_digest_length(BLAKE2S_PARAM *P, uint8_t outlen)
+{
+ P->digest_length = outlen;
+}
+
+void blake2s_param_set_key_length(BLAKE2S_PARAM *P, uint8_t keylen)
+{
+ P->key_length = keylen;
+}
+
+void blake2s_param_set_personal(BLAKE2S_PARAM *P, const uint8_t *personal, size_t len)
+{
+ memcpy(P->personal, personal, len);
+ memset(P->personal + len, 0, BLAKE2S_PERSONALBYTES - len);
+}
+
+void blake2s_param_set_salt(BLAKE2S_PARAM *P, const uint8_t *salt, size_t len)
+{
+ memcpy(P->salt, salt, len);
+ memset(P->salt + len, 0, BLAKE2S_SALTBYTES - len);}
+
+/*
+ * Initialize the hashing context with the given parameter block.
+ * Always returns 1.
+ */
+int blake2s_init(BLAKE2S_CTX *c, const BLAKE2S_PARAM *P)
+{
+ blake2s_init_param(c, P);
+ return 1;
+}
+
+/*
+ * Initialize the hashing context with the given parameter block and key.
+ * Always returns 1.
+ */
+int blake2s_init_key(BLAKE2S_CTX *c, const BLAKE2S_PARAM *P, const void *key)
+{
+ blake2s_init_param(c, P);
+
+ /* Pad the key to form first data block */
+ {
+ uint8_t block[BLAKE2S_BLOCKBYTES] = {0};
+
+ memcpy(block, key, P->key_length);
+ blake2s_update(c, block, BLAKE2S_BLOCKBYTES);
+ OPENSSL_cleanse(block, BLAKE2S_BLOCKBYTES);
+ }
+
+ return 1;
+}
+
+/* Permute the state while xoring in the block of data. */
+static void blake2s_compress(BLAKE2S_CTX *S,
+ const uint8_t *blocks,
+ size_t len)
+{
+ uint32_t m[16];
+ uint32_t v[16];
+ size_t i;
+ size_t increment;
+
+ /*
+ * There are two distinct usage vectors for this function:
+ *
+ * a) BLAKE2s_Update uses it to process complete blocks,
+ * possibly more than one at a time;
+ *
+ * b) BLAK2s_Final uses it to process last block, always
+ * single but possibly incomplete, in which case caller
+ * pads input with zeros.
+ */
+ assert(len < BLAKE2S_BLOCKBYTES || len % BLAKE2S_BLOCKBYTES == 0);
+
+ /*
+ * Since last block is always processed with separate call,
+ * |len| not being multiple of complete blocks can be observed
+ * only with |len| being less than BLAKE2S_BLOCKBYTES ("less"
+ * including even zero), which is why following assignment doesn't
+ * have to reside inside the main loop below.
+ */
+ increment = len < BLAKE2S_BLOCKBYTES ? len : BLAKE2S_BLOCKBYTES;
+
+ for (i = 0; i < 8; ++i) {
+ v[i] = S->h[i];
+ }
+
+ do {
+ for (i = 0; i < 16; ++i) {
+ m[i] = load32(blocks + i * sizeof(m[i]));
+ }
+
+ /* blake2s_increment_counter */
+ S->t[0] += increment;
+ S->t[1] += (S->t[0] < increment);
+
+ v[ 8] = blake2s_IV[0];
+ v[ 9] = blake2s_IV[1];
+ v[10] = blake2s_IV[2];
+ v[11] = blake2s_IV[3];
+ v[12] = S->t[0] ^ blake2s_IV[4];
+ v[13] = S->t[1] ^ blake2s_IV[5];
+ v[14] = S->f[0] ^ blake2s_IV[6];
+ v[15] = S->f[1] ^ blake2s_IV[7];
+#define G(r,i,a,b,c,d) \
+ do { \
+ a = a + b + m[blake2s_sigma[r][2*i+0]]; \
+ d = rotr32(d ^ a, 16); \
+ c = c + d; \
+ b = rotr32(b ^ c, 12); \
+ a = a + b + m[blake2s_sigma[r][2*i+1]]; \
+ d = rotr32(d ^ a, 8); \
+ c = c + d; \
+ b = rotr32(b ^ c, 7); \
+ } while (0)
+#define ROUND(r) \
+ do { \
+ G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
+ G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
+ G(r,2,v[ 2],v[ 6],v[10],v[14]); \
+ G(r,3,v[ 3],v[ 7],v[11],v[15]); \
+ G(r,4,v[ 0],v[ 5],v[10],v[15]); \
+ G(r,5,v[ 1],v[ 6],v[11],v[12]); \
+ G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
+ G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
+ } while (0)
+#if defined(OPENSSL_SMALL_FOOTPRINT)
+ /* almost 3x reduction on x86_64, 4.5x on ARMv8, 4x on ARMv4 */
+ for (i = 0; i < 10; i++) {
+ ROUND(i);
+ }
+#else
+ ROUND(0);
+ ROUND(1);
+ ROUND(2);
+ ROUND(3);
+ ROUND(4);
+ ROUND(5);
+ ROUND(6);
+ ROUND(7);
+ ROUND(8);
+ ROUND(9);
+#endif
+
+ for (i = 0; i < 8; ++i) {
+ S->h[i] = v[i] ^= v[i + 8] ^ S->h[i];
+ }
+#undef G
+#undef ROUND
+ blocks += increment;
+ len -= increment;
+ } while (len);
+}
+
+/* Absorb the input data into the hash state. Always returns 1. */
+int blake2s_update(BLAKE2S_CTX *c, const void *data, size_t datalen)
+{
+ const uint8_t *in = data;
+ size_t fill;
+
+ /*
+ * Intuitively one would expect intermediate buffer, c->buf, to
+ * store incomplete blocks. But in this case we are interested to
+ * temporarily stash even complete blocks, because last one in the
+ * stream has to be treated in special way, and at this point we
+ * don't know if last block in *this* call is last one "ever". This
+ * is the reason for why |datalen| is compared as >, and not >=.
+ */
+ fill = sizeof(c->buf) - c->buflen;
+ if (datalen > fill) {
+ if (c->buflen) {
+ memcpy(c->buf + c->buflen, in, fill); /* Fill buffer */
+ blake2s_compress(c, c->buf, BLAKE2S_BLOCKBYTES);
+ c->buflen = 0;
+ in += fill;
+ datalen -= fill;
+ }
+ if (datalen > BLAKE2S_BLOCKBYTES) {
+ size_t stashlen = datalen % BLAKE2S_BLOCKBYTES;
+ /*
+ * If |datalen| is a multiple of the blocksize, stash
+ * last complete block, it can be final one...
+ */
+ stashlen = stashlen ? stashlen : BLAKE2S_BLOCKBYTES;
+ datalen -= stashlen;
+ blake2s_compress(c, in, datalen);
+ in += datalen;
+ datalen = stashlen;
+ }
+ }
+
+ assert(datalen <= BLAKE2S_BLOCKBYTES);
+
+ memcpy(c->buf + c->buflen, in, datalen);
+ c->buflen += datalen; /* Be lazy, do not compress */
+
+ return 1;
+}
+
+/*
+ * Calculate the final hash and save it in md.
+ * Always returns 1.
+ */
+int blake2s_final(unsigned char *md, BLAKE2S_CTX *c)
+{
+ uint8_t outbuffer[BLAKE2S_OUTBYTES] = {0};
+ uint8_t *target = outbuffer;
+ int iter = (c->outlen + 3) / 4;
+ int i;
+
+ /* Avoid writing to the temporary buffer if possible */
+ if ((c->outlen % sizeof(c->h[0])) == 0)
+ target = md;
+
+ blake2s_set_lastblock(c);
+ /* Padding */
+ memset(c->buf + c->buflen, 0, sizeof(c->buf) - c->buflen);
+ blake2s_compress(c, c->buf, c->buflen);
+
+ /* Output full hash to buffer */
+ for (i = 0; i < iter; ++i)
+ store32(target + sizeof(c->h[i]) * i, c->h[i]);
+
+ if (target != md)
+ memcpy(md, target, c->outlen);
+
+ OPENSSL_cleanse(c, sizeof(BLAKE2S_CTX));
+ return 1;
+}
diff --git a/providers/default/digests/build.info b/providers/default/digests/build.info
new file mode 100644
index 0000000..0f15d12
--- /dev/null
+++ b/providers/default/digests/build.info
@@ -0,0 +1,17 @@
+SOURCE[../../../libcrypto]=\
+ null.c
+
+IF[{- !$disabled{blake2} -}]
+ SOURCE[../../../libcrypto]=\
+ blake2.c blake2b.c blake2s.c
+ENDIF
+
+IF[{- !$disabled{sm3} -}]
+ SOURCE[../../../libcrypto]=\
+ sm3.c
+ENDIF
+
+IF[{- !$disabled{md5} -}]
+ SOURCE[../../../libcrypto]=\
+ md5.c md5_sha1.c
+ENDIF
diff --git a/providers/default/digests/md5.c b/providers/default/digests/md5.c
new file mode 100644
index 0000000..81636f6
--- /dev/null
+++ b/providers/default/digests/md5.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2019 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 <openssl/md5.h>
+#include "internal/core_mkdigest.h"
+#include "internal/provider_algs.h"
+
+OSSL_FUNC_DIGEST_CONSTRUCT(md5, MD5_CTX,
+ MD5_CBLOCK, MD5_DIGEST_LENGTH,
+ MD5_Init, MD5_Update, MD5_Final)
diff --git a/providers/default/digests/md5_sha1.c b/providers/default/digests/md5_sha1.c
new file mode 100644
index 0000000..59a7df8
--- /dev/null
+++ b/providers/default/digests/md5_sha1.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2019 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 <string.h>
+#include <openssl/crypto.h>
+#include <openssl/evp.h>
+#include <openssl/params.h>
+#include <openssl/core_names.h>
+#include "internal/core_mkdigest.h"
+#include "internal/md5_sha1.h"
+#include "internal/provider_algs.h"
+
+static OSSL_OP_digest_set_params_fn md5_sha1_set_params;
+
+/* Special set_params method for SSL3 */
+static int md5_sha1_set_params(void *vctx, const OSSL_PARAM params[])
+{
+ int cmd = 0;
+ size_t msg_len = 0;
+ const void *msg = NULL;
+ const OSSL_PARAM *p;
+ MD5_SHA1_CTX *ctx = (MD5_SHA1_CTX *)vctx;
+
+ if (ctx != NULL && params != NULL) {
+ p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_CMD);
+ if (p != NULL && !OSSL_PARAM_get_int(p, &cmd))
+ return 0;
+ p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_MSG);
+ if (p != NULL && !OSSL_PARAM_get_octet_ptr(p, &msg, &msg_len))
+ return 0;
+ return md5_sha1_ctrl(ctx, cmd, msg_len, (void *)msg);
+ }
+ return 0;
+}
+
+OSSL_FUNC_DIGEST_CONSTRUCT_PARAMS(md5_sha1, MD5_SHA1_CTX,
+ MD5_SHA1_CBLOCK, MD5_SHA1_DIGEST_LENGTH,
+ md5_sha1_init, md5_sha1_update, md5_sha1_final,
+ md5_sha1_set_params)
diff --git a/providers/default/digests/null.c b/providers/default/digests/null.c
new file mode 100644
index 0000000..d7644f4
--- /dev/null
+++ b/providers/default/digests/null.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2019 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/core_numbers.h>
+#include <openssl/whrlpool.h>
+#include "internal/provider_algs.h"
+
+static int nullmd_dummy = 1;
+
+static OSSL_OP_digest_init_fn nullmd_init;
+static OSSL_OP_digest_update_fn nullmd_update;
+static OSSL_OP_digest_final_fn nullmd_final;
+static OSSL_OP_digest_newctx_fn nullmd_newctx;
+static OSSL_OP_digest_freectx_fn nullmd_freectx;
+static OSSL_OP_digest_dupctx_fn nullmd_dupctx;
+static OSSL_OP_digest_size_fn nullmd_size;
+static OSSL_OP_digest_block_size_fn nullmd_block_size;
+
+static size_t nullmd_block_size(void)
+{
+ return 0;
+}
+
+static size_t nullmd_size(void)
+{
+ return 0;
+}
+
+static int nullmd_init(void *vctx)
+{
+ return 1;
+}
+
+static int nullmd_update(void *vctx, const unsigned char *inp, size_t bytes)
+{
+ return 1;
+}
+
+static int nullmd_final(void *ctx, unsigned char *out, size_t *outl, size_t outsz)
+{
+ *outl = 0;
+ return 1;
+}
+
+static void *nullmd_newctx(void *prov_ctx)
+{
+ return &nullmd_dummy;
+}
+
+static void nullmd_freectx(void *vctx)
+{
+}
+
+static void *nullmd_dupctx(void *ctx)
+{
+ return &nullmd_dummy;
+}
+
+const OSSL_DISPATCH nullmd_functions[] = {
+ { OSSL_FUNC_DIGEST_NEWCTX, (void (*)(void))nullmd_newctx },
+ { OSSL_FUNC_DIGEST_INIT, (void (*)(void))nullmd_init },
+ { OSSL_FUNC_DIGEST_UPDATE, (void (*)(void))nullmd_update },
+ { OSSL_FUNC_DIGEST_FINAL, (void (*)(void))nullmd_final },
+ { OSSL_FUNC_DIGEST_FREECTX, (void (*)(void))nullmd_freectx },
+ { OSSL_FUNC_DIGEST_DUPCTX, (void (*)(void))nullmd_dupctx },
+ { OSSL_FUNC_DIGEST_SIZE, (void (*)(void))nullmd_size },
+ { OSSL_FUNC_DIGEST_BLOCK_SIZE, (void (*)(void))nullmd_block_size },
+ { 0, NULL }
+};
diff --git a/providers/default/digests/sm3.c b/providers/default/digests/sm3.c
new file mode 100644
index 0000000..bd039a8
--- /dev/null
+++ b/providers/default/digests/sm3.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2019 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 "internal/sm3.h"
+#include "internal/core_mkdigest.h"
+#include "internal/provider_algs.h"
+
+OSSL_FUNC_DIGEST_CONSTRUCT(sm3, SM3_CTX,
+ SM3_CBLOCK, SM3_DIGEST_LENGTH,
+ sm3_init, sm3_update, sm3_final)
diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c
index 37d7c5b..ab37d98 100644
--- a/providers/fips/fipsprov.c
+++ b/providers/fips/fipsprov.c
@@ -94,7 +94,20 @@ static int fips_get_params(const OSSL_PROVIDER *prov,
}
static const OSSL_ALGORITHM fips_digests[] = {
+ { "SHA1", "fips=yes", sha1_functions },
+ { "SHA224", "fips=yes", sha224_functions },
{ "SHA256", "fips=yes", sha256_functions },
+ { "SHA384", "fips=yes", sha384_functions },
+ { "SHA512", "fips=yes", sha512_functions },
+ { "SHA512-224", "fips=yes", sha512_224_functions },
+ { "SHA512-256", "fips=yes", sha512_256_functions },
+ { "SHA3-224", "fips=yes", sha3_224_functions },
+ { "SHA3-256", "fips=yes", sha3_256_functions },
+ { "SHA3-384", "fips=yes", sha3_384_functions },
+ { "SHA3-512", "fips=yes", sha3_512_functions },
+ { "KMAC128", "fips=yes", keccak_kmac_128_functions },
+ { "KMAC256", "fips=yes", keccak_kmac_256_functions },
+
{ NULL, NULL, NULL }
};
diff --git a/providers/legacy/digests/build.info b/providers/legacy/digests/build.info
index c4e1278..239efd2 100644
--- a/providers/legacy/digests/build.info
+++ b/providers/legacy/digests/build.info
@@ -2,3 +2,23 @@ IF[{- !$disabled{md2} -}]
SOURCE[../../legacy]=\
md2.c
ENDIF
+
+IF[{- !$disabled{md4} -}]
+ SOURCE[../../legacy]=\
+ md4.c
+ENDIF
+
+IF[{- !$disabled{mdc2} -}]
+ SOURCE[../../legacy]=\
+ mdc2.c
+ENDIF
+
+IF[{- !$disabled{whirlpool} -}]
+ SOURCE[../../legacy]=\
+ wp.c
+ENDIF
+
+IF[{- !$disabled{rmd160} -}]
+ SOURCE[../../legacy]=\
+ ripemd.c
+ENDIF \ No newline at end of file
diff --git a/providers/legacy/digests/md2.c b/providers/legacy/digests/md2.c
index 017a511..edd4b78 100644
--- a/providers/legacy/digests/md2.c
+++ b/providers/legacy/digests/md2.c
@@ -7,57 +7,12 @@
* https://www.openssl.org/source/license.html
*/
-#include <openssl/md2.h>
#include <openssl/crypto.h>
-#include <openssl/core_numbers.h>
-
-static int md2_final(void *ctx, unsigned char *md, size_t *size)
-{
- if (MD2_Final(md, ctx)) {
- *size = MD2_DIGEST_LENGTH;
- return 1;
- }
-
- return 0;
-}
-
-static void *md2_newctx(void)
-{
- MD2_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
-
- return ctx;
-}
-
-static void md2_freectx(void *vctx)
-{
- MD2_CTX *ctx = (MD2_CTX *)vctx;
-
- OPENSSL_clear_free(ctx, sizeof(*ctx));
-}
-
-static void *md2_dupctx(void *ctx)
-{
- MD2_CTX *in = (MD2_CTX *)ctx;
- MD2_CTX *ret = OPENSSL_malloc(sizeof(*ret));
-
- *ret = *in;
-
- return ret;
-}
+#include <openssl/md2.h>
-static size_t md2_size(void)
-{
- return MD2_DIGEST_LENGTH;
-}
+#include "internal/core_mkdigest.h"
+#include "internal/provider_algs.h"
-extern const OSSL_DISPATCH md2_functions[];
-const OSSL_DISPATCH md2_functions[] = {
- { OSSL_FUNC_DIGEST_NEWCTX, (void (*)(void))md2_newctx },
- { OSSL_FUNC_DIGEST_INIT, (void (*)(void))MD2_Init },
- { OSSL_FUNC_DIGEST_UPDATE, (void (*)(void))MD2_Update },
- { OSSL_FUNC_DIGEST_FINAL, (void (*)(void))md2_final },
- { OSSL_FUNC_DIGEST_FREECTX, (void (*)(void))md2_freectx },
- { OSSL_FUNC_DIGEST_DUPCTX, (void (*)(void))md2_dupctx },
- { OSSL_FUNC_DIGEST_SIZE, (void (*)(void))md2_size },
- { 0, NULL }
-};
+OSSL_FUNC_DIGEST_CONSTRUCT(md2, MD2_CTX,
+ MD2_BLOCK, MD2_DIGEST_LENGTH,
+ MD2_Init, MD2_Update, MD2_Final)
diff --git a/providers/legacy/digests/md4.c b/providers/legacy/digests/md4.c
new file mode 100644
index 0000000..86937f7
--- /dev/null
+++ b/providers/legacy/digests/md4.c
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2019 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 <openssl/md4.h>
+
+#include "internal/core_mkdigest.h"
+#include "internal/provider_algs.h"
+
+OSSL_FUNC_DIGEST_CONSTRUCT(md4, MD4_CTX,
+ MD4_CBLOCK, MD4_DIGEST_LENGTH,
+ MD4_Init, MD4_Update, MD4_Final)
diff --git a/providers/legacy/digests/mdc2.c b/providers/legacy/digests/mdc2.c
new file mode 100644
index 0000000..75d9398
--- /dev/null
+++ b/providers/legacy/digests/mdc2.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2019 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 <openssl/params.h>
+#include <openssl/mdc2.h>
+#include <openssl/core_names.h>
+
+#include "internal/core_mkdigest.h"
+#include "internal/provider_algs.h"
+
+static OSSL_OP_digest_set_params_fn mdc2_set_params;
+
+static int mdc2_set_params(void *vctx, const OSSL_PARAM params[])
+{
+ const OSSL_PARAM *p;
+ MDC2_CTX *ctx = (MDC2_CTX *)vctx;
+
+ if (ctx != NULL && params != NULL) {
+ p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_PAD_TYPE);
+ if (p != NULL && !OSSL_PARAM_get_int(p, &ctx->pad_type))
+ return 0;
+ return 1;
+ }
+ return 0; /* Null Parameter */
+}
+
+OSSL_FUNC_DIGEST_CONSTRUCT_PARAMS(mdc2, MDC2_CTX,
+ MDC2_BLOCK, MDC2_DIGEST_LENGTH,
+ MDC2_Init, MDC2_Update, MDC2_Final,
+ mdc2_set_params)
diff --git a/providers/legacy/digests/ripemd.c b/providers/legacy/digests/ripemd.c
new file mode 100644
index 0000000..1243512
--- /dev/null
+++ b/providers/legacy/digests/ripemd.c
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2019 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 <openssl/ripemd.h>
+
+#include "internal/core_mkdigest.h"
+#include "internal/provider_algs.h"
+
+OSSL_FUNC_DIGEST_CONSTRUCT(ripemd160, RIPEMD160_CTX,
+ RIPEMD160_CBLOCK, RIPEMD160_DIGEST_LENGTH,
+ RIPEMD160_Init, RIPEMD160_Update, RIPEMD160_Final)
diff --git a/providers/legacy/digests/wp.c b/providers/legacy/digests/wp.c
new file mode 100644
index 0000000..ece67e0
--- /dev/null
+++ b/providers/legacy/digests/wp.c
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2019 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 <openssl/whrlpool.h>
+
+#include "internal/core_mkdigest.h"
+#include "internal/provider_algs.h"
+
+OSSL_FUNC_DIGEST_CONSTRUCT(wp, WHIRLPOOL_CTX,
+ WHIRLPOOL_BBLOCK / 8, WHIRLPOOL_DIGEST_LENGTH,
+ WHIRLPOOL_Init, WHIRLPOOL_Update, WHIRLPOOL_Final)
diff --git a/providers/legacy/legacyprov.c b/providers/legacy/legacyprov.c
index 2d42229..9ca4e14 100644
--- a/providers/legacy/legacyprov.c
+++ b/providers/legacy/legacyprov.c
@@ -13,6 +13,7 @@
#include <openssl/core_numbers.h>
#include <openssl/core_names.h>
#include <openssl/params.h>
+#include "internal/provider_algs.h"
/* Functions provided by the core */
static OSSL_core_get_param_types_fn *c_get_param_types = NULL;
@@ -49,12 +50,27 @@ static int legacy_get_params(const OSSL_PROVIDER *prov,
return 1;
}
-extern const OSSL_DISPATCH md2_functions[];
-
static const OSSL_ALGORITHM legacy_digests[] = {
#ifndef OPENSSL_NO_MD2
{ "MD2", "legacy=yes", md2_functions },
#endif
+
+#ifndef OPENSSL_NO_MD4
+ { "MD4", "legacy=yes", md4_functions },
+#endif
+
+#ifndef OPENSSL_NO_MDC2
+ { "MDC2", "legacy=yes", mdc2_functions },
+#endif /* OPENSSL_NO_MDC2 */
+
+#ifndef OPENSSL_NO_WHIRLPOOL
+ { "whirlpool", "legacy=yes", wp_functions },
+#endif /* OPENSSL_NO_WHIRLPOOL */
+
+#ifndef OPENSSL_NO_RMD160
+ { "RIPEMD160", "legacy=yes", ripemd160_functions },
+#endif /* OPENSSL_NO_RMD160 */
+
{ NULL, NULL, NULL }
};