@@ -189,6 +189,8 @@ all::
#
# Define OPENSSL_SHA256 to use the SHA-256 routines in OpenSSL.
#
+# Define OPENSSL_EVP to use the SHA-3 and SHA-512 routines in OpenSSL.
+#
# Define NEEDS_CRYPTO_WITH_SSL if you need -lcrypto when using -lssl (Darwin).
#
# Define NEEDS_SSL_WITH_CRYPTO if you need -lssl when using -lcrypto (Darwin).
@@ -1716,6 +1718,11 @@ else
endif
endif
+ifdef OPENSSL_EVP
+ EXTLIBS += $(LIB_4_CRYPTO)
+ BASIC_CFLAGS += -DSHA_EVP_OPENSSL
+ LIB_OBJS += sha/sha_evp/sha_evp.o
+else
ifdef GCRYPT_SHA512
BASIC_CFLAGS += -DSHA512_GCRYPT
EXTLIBS += -lgcrypt
@@ -1723,7 +1730,6 @@ else
LIB_OBJS += sha/sha512/sha512.o
BASIC_CFLAGS += -DSHA512_BLK
endif
-
ifdef GCRYPT_SHA3
BASIC_CFLAGS += -DSHA3_GCRYPT
EXTLIBS += -lgcrypt
@@ -1731,6 +1737,7 @@ else
LIB_OBJS += sha/sha3/sha3.o
BASIC_CFLAGS += -DSHA3_BLK
endif
+endif
ifdef SHA1_MAX_BLOCK_SIZE
LIB_OBJS += compat/sha1-chunked.o
@@ -25,12 +25,18 @@
#if defined(SHA512_GCRYPT)
#include "sha/sha512/gcrypt.h"
+#elif defined(SHA_EVP_OPENSSL)
+#include <openssl/evp.h>
+#include "sha/sha_evp/sha_evp.h"
#else
#include "sha/sha512/sha512.h"
#endif
#if defined(SHA3_GCRYPT)
#include "sha/sha3/gcrypt.h"
+#elif defined(SHA_EVP_OPENSSL)
+#include <openssl/evp.h>
+#include "sha/sha_evp/sha_evp.h"
#else
#include "sha/sha3/sha3.h"
#endif
new file mode 100644
@@ -0,0 +1,99 @@
+#include "git-compat-util.h"
+#include "sha_evp.h"
+
+void evp_SHA2_224_Init(SHA_EVP_CTX *ctx)
+{
+ ctx->digest_ctx = NULL;
+ ctx->digest_md = EVP_sha224();
+}
+
+void evp_SHA2_256_Init(SHA_EVP_CTX *ctx)
+{
+ ctx->digest_ctx = NULL;
+ ctx->digest_md = EVP_sha256();
+}
+
+void evp_SHA2_512_Init(SHA_EVP_CTX *ctx)
+{
+ ctx->digest_ctx = NULL;
+ ctx->digest_md = EVP_sha512();
+}
+
+void evp_SHA2_512_224_Init(SHA_EVP_CTX *ctx)
+{
+ ctx->digest_ctx = NULL;
+ ctx->digest_md = EVP_sha512_224();
+}
+
+void evp_SHA2_512_256_Init(SHA_EVP_CTX *ctx)
+{
+ ctx->digest_ctx = NULL;
+ ctx->digest_md = EVP_sha512_256();
+}
+
+void evp_SHA3_224_Init(SHA_EVP_CTX *ctx)
+{
+ ctx->digest_ctx = NULL;
+ ctx->digest_md = EVP_sha3_224();
+}
+
+void evp_SHA3_256_Init(SHA_EVP_CTX *ctx)
+{
+ ctx->digest_ctx = NULL;
+ ctx->digest_md = EVP_sha3_256();
+}
+
+void evp_SHA3_384_Init(SHA_EVP_CTX *ctx)
+{
+ ctx->digest_ctx = NULL;
+ ctx->digest_md = EVP_sha3_384();
+}
+
+void evp_SHA3_512_Init(SHA_EVP_CTX *ctx)
+{
+ ctx->digest_ctx = NULL;
+ ctx->digest_md = EVP_sha3_512();
+}
+
+static void evp_SHA_Lazy_Init(SHA_EVP_CTX *ctx)
+{
+ /*
+ * The OpenSSL EVP digest API requires a dynamically sized context to be
+ * allocated and destroyed, however, the digest API we are emulating uses
+ * static structures and thus has no allocation or deallocation API.
+ *
+ * Due to this, we must call EVP_MD_CTX_destroy in Final to free up
+ * dynamically allocated memory. Context creation is thus done lazily in
+ * either Update or Final to handle cases where the context is reused
+ * after Final has been called.
+ */
+ if (ctx->digest_ctx) return;
+ if ((ctx->digest_ctx = EVP_MD_CTX_create()) == NULL)
+ abort();
+ if (EVP_DigestInit_ex(ctx->digest_ctx, ctx->digest_md, NULL) != 1)
+ abort();
+}
+
+void evp_SHA_Update(SHA_EVP_CTX *ctx, const void *data, size_t len)
+{
+ /* handle late Init as well as being called again after Final */
+ evp_SHA_Lazy_Init(ctx);
+
+ if (EVP_DigestUpdate(ctx->digest_ctx, data, len) != 1)
+ abort();
+}
+
+void evp_SHA_Final(unsigned char *result, SHA_EVP_CTX *ctx)
+{
+ unsigned int len;
+
+ /* handle case where Final is called without Update (empty hash) */
+ evp_SHA_Lazy_Init(ctx);
+
+ if (EVP_DigestFinal_ex(ctx->digest_ctx, result, &len) != 1)
+ abort();
+ assert(EVP_MD_size(ctx->digest_md) == len);
+
+ EVP_MD_CTX_destroy(ctx->digest_ctx);
+ ctx->digest_ctx = NULL;
+}
new file mode 100644
@@ -0,0 +1,51 @@
+#ifndef SHAEVP_BLOCK_H
+#define SHAEVP_BLOCK_H
+
+#include <openssl/evp.h>
+
+#define evp_SHA2_256_hash_size 32
+#define evp_SHA2_512_224_hash_size 28
+#define evp_SHA2_512_256_hash_size 32
+#define evp_SHA2_512_hash_size 64
+#define evp_SHA3_224_hash_size 28
+#define evp_SHA3_256_hash_size 32
+#define evp_SHA3_384_hash_size 48
+#define evp_SHA3_512_hash_size 64
+
+struct SHA_EVP_CTX {
+ EVP_MD_CTX *digest_ctx;
+ const EVP_MD* digest_md;
+};
+
+typedef struct SHA_EVP_CTX SHA_EVP_CTX;
+
+void evp_SHA2_224_Init(SHA_EVP_CTX *ctx);
+void evp_SHA2_256_Init(SHA_EVP_CTX *ctx);
+void evp_SHA2_512_Init(SHA_EVP_CTX *ctx);
+void evp_SHA2_512_224_Init(SHA_EVP_CTX *ctx);
+void evp_SHA2_512_256_Init(SHA_EVP_CTX *ctx);
+void evp_SHA3_224_Init(SHA_EVP_CTX *ctx);
+void evp_SHA3_256_Init(SHA_EVP_CTX *ctx);
+void evp_SHA3_384_Init(SHA_EVP_CTX *ctx);
+void evp_SHA3_512_Init(SHA_EVP_CTX *ctx);
+
+void evp_SHA_Update(SHA_EVP_CTX *ctx, const void *data, size_t len);
+void evp_SHA_Final(unsigned char *result, SHA_EVP_CTX *ctx);
+
+#define platform_SHA512_CTX SHA_EVP_CTX
+#define platform_SHA512_Init evp_SHA2_512_Init
+#define platform_SHA512_224_Init evp_SHA2_512_224_Init
+#define platform_SHA512_256_Init evp_SHA2_512_256_Init
+#define platform_SHA512_Update evp_SHA_Update
+#define platform_SHA512_Final evp_SHA_Final
+
+#define platform_SHA3_CTX SHA_EVP_CTX
+#define platform_SHA3_Init evp_SHA3_256_Init
+#define platform_SHA3_224_Init evp_SHA3_224_Init
+#define platform_SHA3_256_Init evp_SHA3_256_Init
+#define platform_SHA3_384_Init evp_SHA3_384_Init
+#define platform_SHA3_512_Init evp_SHA3_512_Init
+#define platform_SHA3_Update evp_SHA_Update
+#define platform_SHA3_Final evp_SHA_Final
+
+#endif
\ No newline at end of file