Commit 6b4a6faab37002535588cf1b7ed421256b4ef113

Edward Thomson 2021-12-12T15:41:47

sha: support OpenSSL for SHA256

diff --git a/cmake/SelectHashes.cmake b/cmake/SelectHashes.cmake
index d358acd..eb04dec 100644
--- a/cmake/SelectHashes.cmake
+++ b/cmake/SelectHashes.cmake
@@ -25,14 +25,7 @@ endif()
 if(USE_SHA1 STREQUAL "CollisionDetection")
 	set(GIT_SHA1_COLLISIONDETECT 1)
 elseif(USE_SHA1 STREQUAL "OpenSSL")
-	# OPENSSL_FOUND should already be set, we're checking USE_HTTPS
-
 	set(GIT_SHA1_OPENSSL 1)
-	if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
-		list(APPEND LIBGIT2_PC_LIBS "-lssl")
-	else()
-		list(APPEND LIBGIT2_PC_REQUIRES "openssl")
-	endif()
 elseif(USE_SHA1 STREQUAL "CommonCrypto")
 	set(GIT_SHA1_COMMON_CRYPTO 1)
 elseif(USE_SHA1 STREQUAL "mbedTLS")
@@ -63,6 +56,8 @@ endif()
 
 if(USE_SHA256 STREQUAL "Builtin")
 	set(GIT_SHA256_BUILTIN 1)
+elseif(USE_SHA256 STREQUAL "OpenSSL")
+	set(GIT_SHA256_OPENSSL 1)
 elseif(USE_SHA256 STREQUAL "CommonCrypto")
 	set(GIT_SHA256_COMMON_CRYPTO 1)
 elseif(USE_SHA256 STREQUAL "mbedTLS")
@@ -72,6 +67,13 @@ else()
 endif()
 
 # add library requirements
+if(USE_SHA1 STREQUAL "OpenSSL" OR USE_SHA256 STREQUAL "OpenSSL")
+	if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
+		list(APPEND LIBGIT2_PC_LIBS "-lssl")
+	else()
+		list(APPEND LIBGIT2_PC_REQUIRES "openssl")
+	endif()
+endif()
 
 if(USE_SHA1 STREQUAL "mbedTLS" OR USE_SHA256 STREQUAL "mbedTLS")
 	list(APPEND LIBGIT2_SYSTEM_INCLUDES ${MBEDTLS_INCLUDE_DIR})
diff --git a/src/features.h.in b/src/features.h.in
index 351fdf3..bfee316 100644
--- a/src/features.h.in
+++ b/src/features.h.in
@@ -50,6 +50,7 @@
 
 #cmakedefine GIT_SHA256_BUILTIN 1
 #cmakedefine GIT_SHA256_COMMON_CRYPTO 1
+#cmakedefine GIT_SHA256_OPENSSL 1
 #cmakedefine GIT_SHA256_MBEDTLS 1
 
 #cmakedefine GIT_RAND_GETENTROPY 1
diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt
index 509b751..cb83ecd 100644
--- a/src/util/CMakeLists.txt
+++ b/src/util/CMakeLists.txt
@@ -49,6 +49,8 @@ list(SORT UTIL_SRC_SHA1)
 
 if(USE_SHA256 STREQUAL "Builtin")
 	file(GLOB UTIL_SRC_SHA256 hash/builtin.* hash/rfc6234/*)
+elseif(USE_SHA256 STREQUAL "OpenSSL")
+	file(GLOB UTIL_SRC_SHA256 hash/openssl.*)
 elseif(USE_SHA256 STREQUAL "CommonCrypto")
 	file(GLOB UTIL_SRC_SHA256 hash/common_crypto.*)
 elseif(USE_SHA256 STREQUAL "mbedTLS")
diff --git a/src/util/hash/openssl.c b/src/util/hash/openssl.c
index 2011edf..f95ddb7 100644
--- a/src/util/hash/openssl.c
+++ b/src/util/hash/openssl.c
@@ -7,6 +7,8 @@
 
 #include "openssl.h"
 
+#ifdef GIT_SHA1_OPENSSL
+
 int git_hash_sha1_global_init(void)
 {
 	return 0;
@@ -27,7 +29,7 @@ int git_hash_sha1_init(git_hash_sha1_ctx *ctx)
 	GIT_ASSERT_ARG(ctx);
 
 	if (SHA1_Init(&ctx->c) != 1) {
-		git_error_set(GIT_ERROR_SHA, "hash_openssl: failed to initialize hash context");
+		git_error_set(GIT_ERROR_SHA, "failed to initialize sha1 context");
 		return -1;
 	}
 
@@ -39,7 +41,7 @@ int git_hash_sha1_update(git_hash_sha1_ctx *ctx, const void *data, size_t len)
 	GIT_ASSERT_ARG(ctx);
 
 	if (SHA1_Update(&ctx->c, data, len) != 1) {
-		git_error_set(GIT_ERROR_SHA, "hash_openssl: failed to update hash");
+		git_error_set(GIT_ERROR_SHA, "failed to update sha1");
 		return -1;
 	}
 
@@ -51,9 +53,66 @@ int git_hash_sha1_final(unsigned char *out, git_hash_sha1_ctx *ctx)
 	GIT_ASSERT_ARG(ctx);
 
 	if (SHA1_Final(out, &ctx->c) != 1) {
-		git_error_set(GIT_ERROR_SHA, "hash_openssl: failed to finalize hash");
+		git_error_set(GIT_ERROR_SHA, "failed to finalize sha1");
+		return -1;
+	}
+
+	return 0;
+}
+
+#endif
+
+#ifdef GIT_SHA256_OPENSSL
+
+int git_hash_sha256_global_init(void)
+{
+	return 0;
+}
+
+int git_hash_sha256_ctx_init(git_hash_sha256_ctx *ctx)
+{
+	return git_hash_sha256_init(ctx);
+}
+
+void git_hash_sha256_ctx_cleanup(git_hash_sha256_ctx *ctx)
+{
+	GIT_UNUSED(ctx);
+}
+
+int git_hash_sha256_init(git_hash_sha256_ctx *ctx)
+{
+	GIT_ASSERT_ARG(ctx);
+
+	if (SHA256_Init(&ctx->c) != 1) {
+		git_error_set(GIT_ERROR_SHA, "failed to initialize sha256 context");
+		return -1;
+	}
+
+	return 0;
+}
+
+int git_hash_sha256_update(git_hash_sha256_ctx *ctx, const void *data, size_t len)
+{
+	GIT_ASSERT_ARG(ctx);
+
+	if (SHA256_Update(&ctx->c, data, len) != 1) {
+		git_error_set(GIT_ERROR_SHA, "failed to update sha256");
 		return -1;
 	}
 
 	return 0;
 }
+
+int git_hash_sha256_final(unsigned char *out, git_hash_sha256_ctx *ctx)
+{
+	GIT_ASSERT_ARG(ctx);
+
+	if (SHA256_Final(out, &ctx->c) != 1) {
+		git_error_set(GIT_ERROR_SHA, "failed to finalize sha256");
+		return -1;
+	}
+
+	return 0;
+}
+
+#endif
diff --git a/src/util/hash/openssl.h b/src/util/hash/openssl.h
index 5fa42b8..ff4b6d6 100644
--- a/src/util/hash/openssl.h
+++ b/src/util/hash/openssl.h
@@ -12,8 +12,16 @@
 
 #include <openssl/sha.h>
 
+#ifdef GIT_SHA1_OPENSSL
 struct git_hash_sha1_ctx {
 	SHA_CTX c;
 };
+#endif
+
+#ifdef GIT_SHA256_OPENSSL
+struct git_hash_sha256_ctx {
+	SHA256_CTX c;
+};
+#endif
 
 #endif
diff --git a/src/util/hash/sha.h b/src/util/hash/sha.h
index d0928d3..4f59623 100644
--- a/src/util/hash/sha.h
+++ b/src/util/hash/sha.h
@@ -17,7 +17,7 @@ typedef struct git_hash_sha256_ctx git_hash_sha256_ctx;
 # include "common_crypto.h"
 #endif
 
-#if defined(GIT_SHA1_OPENSSL) || defined(GIT_SHA1_COMMON_CRYPTO)
+#if defined(GIT_SHA1_OPENSSL) || defined(GIT_SHA256_OPENSSL)
 # include "openssl.h"
 #endif