sha: support FIPS-compliant OpenSSL for SHA1

This commit is contained in:
Edward Thomson
2024-10-10 00:01:16 +01:00
parent 7f7dfe71cc
commit 3d268285f9
6 changed files with 101 additions and 14 deletions

View File

@@ -28,6 +28,8 @@ if(USE_SHA1 STREQUAL "CollisionDetection")
set(GIT_SHA1_COLLISIONDETECT 1)
elseif(USE_SHA1 STREQUAL "OpenSSL")
set(GIT_SHA1_OPENSSL 1)
elseif(USE_SHA1 STREQUAL "OpenSSL-FIPS")
set(GIT_SHA1_OPENSSL_FIPS 1)
elseif(USE_SHA1 STREQUAL "OpenSSL-Dynamic")
set(GIT_SHA1_OPENSSL 1)
set(GIT_SHA1_OPENSSL_DYNAMIC 1)
@@ -66,12 +68,12 @@ if(USE_SHA256 STREQUAL "Builtin")
set(GIT_SHA256_BUILTIN 1)
elseif(USE_SHA256 STREQUAL "OpenSSL")
set(GIT_SHA256_OPENSSL 1)
elseif(USE_SHA256 STREQUAL "OpenSSL-FIPS")
set(GIT_SHA256_OPENSSL_FIPS 1)
elseif(USE_SHA256 STREQUAL "OpenSSL-Dynamic")
set(GIT_SHA256_OPENSSL 1)
set(GIT_SHA256_OPENSSL_DYNAMIC 1)
list(APPEND LIBGIT2_SYSTEM_LIBS dl)
elseif(USE_SHA256 STREQUAL "OpenSSL-FIPS")
set(GIT_SHA256_OPENSSL_FIPS 1)
elseif(USE_SHA256 STREQUAL "CommonCrypto")
set(GIT_SHA256_COMMON_CRYPTO 1)
elseif(USE_SHA256 STREQUAL "mbedTLS")
@@ -83,7 +85,8 @@ else()
endif()
# add library requirements
if(USE_SHA1 STREQUAL "OpenSSL" OR USE_SHA256 STREQUAL "OpenSSL")
if(USE_SHA1 STREQUAL "OpenSSL" OR USE_SHA256 STREQUAL "OpenSSL" OR
USE_SHA1 STREQUAL "OpenSSL-FIPS" OR USE_SHA256 STREQUAL "OpenSSL-FIPS")
if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
list(APPEND LIBGIT2_PC_LIBS "-lssl")
else()

View File

@@ -36,7 +36,7 @@ if(USE_SHA1 STREQUAL "CollisionDetection")
target_compile_definitions(util PRIVATE SHA1DC_NO_STANDARD_INCLUDES=1)
target_compile_definitions(util PRIVATE SHA1DC_CUSTOM_INCLUDE_SHA1_C=\"git2_util.h\")
target_compile_definitions(util PRIVATE SHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C=\"git2_util.h\")
elseif(USE_SHA1 STREQUAL "OpenSSL" OR USE_SHA1 STREQUAL "OpenSSL-Dynamic")
elseif(USE_SHA1 STREQUAL "OpenSSL" OR USE_SHA1 STREQUAL "OpenSSL-Dynamic" OR USE_SHA1 STREQUAL "OpenSSL-FIPS")
add_definitions(-DOPENSSL_API_COMPAT=0x10100000L)
file(GLOB UTIL_SRC_SHA1 hash/openssl.*)
elseif(USE_SHA1 STREQUAL "CommonCrypto")

View File

@@ -54,6 +54,7 @@
#cmakedefine GIT_SHA1_WIN32 1
#cmakedefine GIT_SHA1_COMMON_CRYPTO 1
#cmakedefine GIT_SHA1_OPENSSL 1
#cmakedefine GIT_SHA1_OPENSSL_FIPS 1
#cmakedefine GIT_SHA1_OPENSSL_DYNAMIC 1
#cmakedefine GIT_SHA1_MBEDTLS 1
@@ -61,8 +62,8 @@
#cmakedefine GIT_SHA256_WIN32 1
#cmakedefine GIT_SHA256_COMMON_CRYPTO 1
#cmakedefine GIT_SHA256_OPENSSL 1
#cmakedefine GIT_SHA256_OPENSSL_DYNAMIC 1
#cmakedefine GIT_SHA256_OPENSSL_FIPS 1
#cmakedefine GIT_SHA256_OPENSSL_DYNAMIC 1
#cmakedefine GIT_SHA256_MBEDTLS 1
#cmakedefine GIT_RAND_GETENTROPY 1

View File

@@ -120,6 +120,79 @@ int git_hash_sha1_final(unsigned char *out, git_hash_sha1_ctx *ctx)
#endif
#ifdef GIT_SHA1_OPENSSL_FIPS
static const EVP_MD *SHA1_ENGINE_DIGEST_TYPE = NULL;
int git_hash_sha1_global_init(void)
{
SHA1_ENGINE_DIGEST_TYPE = EVP_sha1();
return SHA1_ENGINE_DIGEST_TYPE != NULL ? 0 : -1;
}
int git_hash_sha1_ctx_init(git_hash_sha1_ctx *ctx)
{
return git_hash_sha1_init(ctx);
}
void git_hash_sha1_ctx_cleanup(git_hash_sha1_ctx *ctx)
{
#if OPENSSL_VERSION_NUMBER < 0x10100000L
EVP_MD_CTX_destroy(ctx->c);
#else
EVP_MD_CTX_free(ctx->c);
#endif
}
int git_hash_sha1_init(git_hash_sha1_ctx *ctx)
{
GIT_ASSERT_ARG(ctx);
GIT_ASSERT(SHA1_ENGINE_DIGEST_TYPE);
#if OPENSSL_VERSION_NUMBER < 0x10100000L
ctx->c = EVP_MD_CTX_create();
#else
ctx->c = EVP_MD_CTX_new();
#endif
GIT_ASSERT(ctx->c);
if (EVP_DigestInit_ex(ctx->c, SHA1_ENGINE_DIGEST_TYPE, NULL) != 1) {
git_hash_sha1_ctx_cleanup(ctx);
git_error_set(GIT_ERROR_SHA, "failed to initialize sha1 context");
return -1;
}
return 0;
}
int git_hash_sha1_update(git_hash_sha1_ctx *ctx, const void *data, size_t len)
{
GIT_ASSERT_ARG(ctx);
if (EVP_DigestUpdate(ctx->c, data, len) != 1) {
git_error_set(GIT_ERROR_SHA, "failed to update sha1");
return -1;
}
return 0;
}
int git_hash_sha1_final(unsigned char *out, git_hash_sha1_ctx *ctx)
{
unsigned int len = 0;
GIT_ASSERT_ARG(ctx);
if (EVP_DigestFinal(ctx->c, out, &len) != 1) {
git_error_set(GIT_ERROR_SHA, "failed to finalize sha1");
return -1;
}
return 0;
}
#endif
#ifdef GIT_SHA256_OPENSSL
# ifdef GIT_OPENSSL_DYNAMIC
@@ -196,7 +269,7 @@ int git_hash_sha256_final(unsigned char *out, git_hash_sha256_ctx *ctx)
#ifdef GIT_SHA256_OPENSSL_FIPS
static const EVP_MD* SHA256_ENGINE_DIGEST_TYPE = NULL;
static const EVP_MD *SHA256_ENGINE_DIGEST_TYPE = NULL;
int git_hash_sha256_global_init(void)
{
@@ -221,13 +294,14 @@ void git_hash_sha256_ctx_cleanup(git_hash_sha256_ctx *ctx)
int git_hash_sha256_init(git_hash_sha256_ctx *ctx)
{
GIT_ASSERT_ARG(ctx);
GIT_ASSERT(SHA256_ENGINE_DIGEST_TYPE);
#if OPENSSL_VERSION_NUMBER < 0x10100000L
ctx->c = EVP_MD_CTX_create();
#else
ctx->c = EVP_MD_CTX_new();
#endif
GIT_ASSERT(ctx->c);
if (EVP_DigestInit_ex(ctx->c, SHA256_ENGINE_DIGEST_TYPE, NULL) != 1) {
@@ -264,4 +338,4 @@ int git_hash_sha256_final(unsigned char *out, git_hash_sha256_ctx *ctx)
return 0;
}
#endif
#endif

View File

@@ -11,11 +11,11 @@
#include "hash/sha.h"
#ifndef GIT_OPENSSL_DYNAMIC
#ifdef GIT_SHA256_OPENSSL_FIPS
#include <openssl/evp.h>
#else
#include <openssl/sha.h>
#endif
# if defined(GIT_SHA1_OPENSSL_FIPS) || defined(GIT_SHA256_OPENSSL_FIPS)
# include <openssl/evp.h>
# else
# include <openssl/sha.h>
# endif
#else
typedef struct {
@@ -40,6 +40,12 @@ struct git_hash_sha1_ctx {
};
#endif
#ifdef GIT_SHA1_OPENSSL_FIPS
struct git_hash_sha1_ctx {
EVP_MD_CTX* c;
};
#endif
#ifdef GIT_SHA256_OPENSSL
struct git_hash_sha256_ctx {
SHA256_CTX c;

View File

@@ -17,7 +17,10 @@ typedef struct git_hash_sha256_ctx git_hash_sha256_ctx;
# include "common_crypto.h"
#endif
#if defined(GIT_SHA1_OPENSSL) || defined(GIT_SHA256_OPENSSL) || defined(GIT_SHA256_OPENSSL_FIPS)
#if defined(GIT_SHA1_OPENSSL) || \
defined(GIT_SHA1_OPENSSL_FIPS) || \
defined(GIT_SHA256_OPENSSL) || \
defined(GIT_SHA256_OPENSSL_FIPS)
# include "openssl.h"
#endif