From bbf034ab931cd6346420066cbb00cf16ae893510 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Fri, 22 Feb 2019 13:43:16 +0100 Subject: [PATCH 1/6] hash: move `git_hash_prov` into Win32 backend The structure `git_hash_prov` is only ever used by the Win32 SHA1 backend. As such, it doesn't make much sense to expose it via the generic "hash.h" header, as it is an implementation detail of the Win32 backend only. Move the typedef of `git_hash_prov` into "hash/sha1/win32.h" to fix this. --- src/hash.h | 1 - src/hash/hash_win32.h | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/hash.h b/src/hash.h index bd3e3b5de..0d2e7e4b3 100644 --- a/src/hash.h +++ b/src/hash.h @@ -11,7 +11,6 @@ #include "git2/oid.h" -typedef struct git_hash_prov git_hash_prov; typedef struct git_hash_ctx git_hash_ctx; int git_hash_ctx_init(git_hash_ctx *ctx); diff --git a/src/hash/hash_win32.h b/src/hash/hash_win32.h index ca448c241..b9a85f8dc 100644 --- a/src/hash/hash_win32.h +++ b/src/hash/hash_win32.h @@ -106,14 +106,14 @@ struct hash_cng_prov { DWORD hash_object_size; }; -struct git_hash_prov { +typedef struct { enum hash_win32_prov_type type; union { struct hash_cryptoapi_prov cryptoapi; struct hash_cng_prov cng; } prov; -}; +} git_hash_prov; /* Hash contexts */ From bd48bf3fb9368541bafda7877cf159f94884c187 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Fri, 14 Jun 2019 14:21:32 +0200 Subject: [PATCH 2/6] hash: introduce source files to break include circles The hash source files have circular include dependencies right now, which shows by our broken generic hash implementation. The "hash.h" header declares two functions and the `git_hash_ctx` typedef before actually including the hash backend header and can only declare the remaining hash functions after the include due to possibly static function declarations inside of the implementation includes. Let's break this cycle and help maintainability by creating a real implementation file for each of the hash implementations. Instead of relying on the exact include order, we now especially avoid the use of `GIT_INLINE` for function declarations. --- cmake/Modules/SelectHashes.cmake | 2 ++ src/hash.h | 14 ++++---- src/hash/hash_collisiondetect.c | 48 ++++++++++++++++++++++++++ src/hash/hash_collisiondetect.h | 34 +----------------- src/hash/hash_common_crypto.c | 57 ++++++++++++++++++++++++++++++ src/hash/hash_common_crypto.h | 42 ----------------------- src/hash/hash_generic.c | 18 ++++++++-- src/hash/hash_generic.h | 10 ------ src/hash/hash_mbedtls.c | 10 ++++++ src/hash/hash_mbedtls.h | 9 ++--- src/hash/hash_openssl.c | 59 ++++++++++++++++++++++++++++++++ src/hash/hash_openssl.h | 46 ++----------------------- src/hash/hash_win32.c | 16 +++++++-- src/hash/hash_win32.h | 13 ------- 14 files changed, 217 insertions(+), 161 deletions(-) create mode 100644 src/hash/hash_collisiondetect.c create mode 100644 src/hash/hash_common_crypto.c create mode 100644 src/hash/hash_openssl.c diff --git a/cmake/Modules/SelectHashes.cmake b/cmake/Modules/SelectHashes.cmake index 450e2bddb..78ff41f57 100644 --- a/cmake/Modules/SelectHashes.cmake +++ b/cmake/Modules/SelectHashes.cmake @@ -40,8 +40,10 @@ ELSEIF(SHA1_BACKEND STREQUAL "OpenSSL") ELSE() LIST(APPEND LIBGIT2_PC_REQUIRES "openssl") ENDIF() + FILE(GLOB SRC_SHA1 hash/hash_openssl.c) ELSEIF(SHA1_BACKEND STREQUAL "CommonCrypto") SET(GIT_SHA1_COMMON_CRYPTO 1) + FILE(GLOB SRC_SHA1 hash/hash_common_crypto.c) ELSEIF(SHA1_BACKEND STREQUAL "mbedTLS") SET(GIT_SHA1_MBEDTLS 1) FILE(GLOB SRC_SHA1 hash/hash_mbedtls.c) diff --git a/src/hash.h b/src/hash.h index 0d2e7e4b3..1ccf66d5f 100644 --- a/src/hash.h +++ b/src/hash.h @@ -13,8 +13,10 @@ typedef struct git_hash_ctx git_hash_ctx; -int git_hash_ctx_init(git_hash_ctx *ctx); -void git_hash_ctx_cleanup(git_hash_ctx *ctx); +typedef struct { + void *data; + size_t len; +} git_buf_vec; #if defined(GIT_SHA1_COLLISIONDETECT) # include "hash/hash_collisiondetect.h" @@ -30,10 +32,10 @@ void git_hash_ctx_cleanup(git_hash_ctx *ctx); # include "hash/hash_generic.h" #endif -typedef struct { - void *data; - size_t len; -} git_buf_vec; +int git_hash_global_init(void); + +int git_hash_ctx_init(git_hash_ctx *ctx); +void git_hash_ctx_cleanup(git_hash_ctx *ctx); int git_hash_init(git_hash_ctx *c); int git_hash_update(git_hash_ctx *c, const void *data, size_t len); diff --git a/src/hash/hash_collisiondetect.c b/src/hash/hash_collisiondetect.c new file mode 100644 index 000000000..baf278981 --- /dev/null +++ b/src/hash/hash_collisiondetect.c @@ -0,0 +1,48 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ + +#include "hash_collisiondetect.h" + +int git_hash_global_init(void) +{ + return 0; +} + +int git_hash_ctx_init(git_hash_ctx *ctx) +{ + return git_hash_init(ctx); +} + +void git_hash_ctx_cleanup(git_hash_ctx *ctx) +{ + GIT_UNUSED(ctx); +} + +int git_hash_init(git_hash_ctx *ctx) +{ + assert(ctx); + SHA1DCInit(&ctx->c); + return 0; +} + +int git_hash_update(git_hash_ctx *ctx, const void *data, size_t len) +{ + assert(ctx); + SHA1DCUpdate(&ctx->c, data, len); + return 0; +} + +int git_hash_final(git_oid *out, git_hash_ctx *ctx) +{ + assert(ctx); + if (SHA1DCFinal(out->id, &ctx->c)) { + git_error_set(GIT_ERROR_SHA1, "SHA1 collision attack detected"); + return -1; + } + + return 0; +} diff --git a/src/hash/hash_collisiondetect.h b/src/hash/hash_collisiondetect.h index 743209802..8cba5fe8c 100644 --- a/src/hash/hash_collisiondetect.h +++ b/src/hash/hash_collisiondetect.h @@ -9,43 +9,11 @@ #define INCLUDE_hash_hash_collisiondetect_h__ #include "hash.h" + #include "sha1dc/sha1.h" struct git_hash_ctx { SHA1_CTX c; }; -#define git_hash_ctx_init(ctx) git_hash_init(ctx) -#define git_hash_ctx_cleanup(ctx) - -GIT_INLINE(int) git_hash_global_init(void) -{ - return 0; -} - -GIT_INLINE(int) git_hash_init(git_hash_ctx *ctx) -{ - assert(ctx); - SHA1DCInit(&ctx->c); - return 0; -} - -GIT_INLINE(int) git_hash_update(git_hash_ctx *ctx, const void *data, size_t len) -{ - assert(ctx); - SHA1DCUpdate(&ctx->c, data, len); - return 0; -} - -GIT_INLINE(int) git_hash_final(git_oid *out, git_hash_ctx *ctx) -{ - assert(ctx); - if (SHA1DCFinal(out->id, &ctx->c)) { - git_error_set(GIT_ERROR_SHA1, "SHA1 collision attack detected"); - return -1; - } - - return 0; -} - #endif diff --git a/src/hash/hash_common_crypto.c b/src/hash/hash_common_crypto.c new file mode 100644 index 000000000..1ad6f4a01 --- /dev/null +++ b/src/hash/hash_common_crypto.c @@ -0,0 +1,57 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ + +#include "hash_common_crypto.h" + +#define CC_LONG_MAX ((CC_LONG)-1) + +int git_hash_global_init(void) +{ + return 0; +} + +int git_hash_ctx_init(git_hash_ctx *ctx) +{ + return git_hash_init(ctx); +} + +void git_hash_ctx_cleanup(git_hash_ctx *ctx) +{ + GIT_UNUSED(ctx); +} + +int git_hash_init(git_hash_ctx *ctx) +{ + assert(ctx); + CC_SHA1_Init(&ctx->c); + return 0; +} + +int git_hash_update(git_hash_ctx *ctx, const void *_data, size_t len) +{ + const unsigned char *data = _data; + + assert(ctx); + + while (len > 0) { + CC_LONG chunk = (len > CC_LONG_MAX) ? CC_LONG_MAX : (CC_LONG)len; + + CC_SHA1_Update(&ctx->c, data, chunk); + + data += chunk; + len -= chunk; + } + + return 0; +} + +int git_hash_final(git_oid *out, git_hash_ctx *ctx) +{ + assert(ctx); + CC_SHA1_Final(out->id, &ctx->c); + return 0; +} diff --git a/src/hash/hash_common_crypto.h b/src/hash/hash_common_crypto.h index ce352a633..55bec2c1a 100644 --- a/src/hash/hash_common_crypto.h +++ b/src/hash/hash_common_crypto.h @@ -16,46 +16,4 @@ struct git_hash_ctx { CC_SHA1_CTX c; }; -#define CC_LONG_MAX ((CC_LONG)-1) - -#define git_hash_ctx_init(ctx) git_hash_init(ctx) -#define git_hash_ctx_cleanup(ctx) - -GIT_INLINE(int) git_hash_global_init(void) -{ - return 0; -} - -GIT_INLINE(int) git_hash_init(git_hash_ctx *ctx) -{ - assert(ctx); - CC_SHA1_Init(&ctx->c); - return 0; -} - -GIT_INLINE(int) git_hash_update(git_hash_ctx *ctx, const void *_data, size_t len) -{ - const unsigned char *data = _data; - - assert(ctx); - - while (len > 0) { - CC_LONG chunk = (len > CC_LONG_MAX) ? CC_LONG_MAX : (CC_LONG)len; - - CC_SHA1_Update(&ctx->c, data, chunk); - - data += chunk; - len -= chunk; - } - - return 0; -} - -GIT_INLINE(int) git_hash_final(git_oid *out, git_hash_ctx *ctx) -{ - assert(ctx); - CC_SHA1_Final(out->id, &ctx->c); - return 0; -} - #endif diff --git a/src/hash/hash_generic.c b/src/hash/hash_generic.c index 7b33b6194..55fbf8de5 100644 --- a/src/hash/hash_generic.c +++ b/src/hash/hash_generic.c @@ -7,8 +7,6 @@ #include "hash_generic.h" -#include "hash.h" - #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) /* @@ -221,6 +219,21 @@ static void hash__block(git_hash_ctx *ctx, const unsigned int *data) ctx->H[4] += E; } +int git_hash_global_init(void) +{ + return 0; +} + +int git_hash_ctx_init(git_hash_ctx *ctx) +{ + return git_hash_init(ctx); +} + +void git_hash_ctx_cleanup(git_hash_ctx *ctx) +{ + GIT_UNUSED(ctx); +} + int git_hash_init(git_hash_ctx *ctx) { ctx->size = 0; @@ -285,4 +298,3 @@ int git_hash_final(git_oid *out, git_hash_ctx *ctx) return 0; } - diff --git a/src/hash/hash_generic.h b/src/hash/hash_generic.h index fb0009ccf..b97796ce1 100644 --- a/src/hash/hash_generic.h +++ b/src/hash/hash_generic.h @@ -8,8 +8,6 @@ #ifndef INCLUDE_hash_hash_generic_h__ #define INCLUDE_hash_hash_generic_h__ -#include "common.h" - #include "hash.h" struct git_hash_ctx { @@ -18,12 +16,4 @@ struct git_hash_ctx { unsigned int W[16]; }; -#define git_hash_ctx_init(ctx) git_hash_init(ctx) -#define git_hash_ctx_cleanup(ctx) - -GIT_INLINE(int) git_hash_global_init(void) -{ - return 0; -} - #endif diff --git a/src/hash/hash_mbedtls.c b/src/hash/hash_mbedtls.c index a19d76308..b29226c38 100644 --- a/src/hash/hash_mbedtls.c +++ b/src/hash/hash_mbedtls.c @@ -9,6 +9,16 @@ #include "hash.h" #include "hash/hash_mbedtls.h" +int git_hash_global_init(void) +{ + return 0; +} + +int git_hash_ctx_init(git_hash_ctx *ctx) +{ + return git_hash_init(ctx); +} + void git_hash_ctx_cleanup(git_hash_ctx *ctx) { assert(ctx); diff --git a/src/hash/hash_mbedtls.h b/src/hash/hash_mbedtls.h index 7f3decd7d..834b79dcf 100644 --- a/src/hash/hash_mbedtls.h +++ b/src/hash/hash_mbedtls.h @@ -8,17 +8,12 @@ #ifndef INCLUDE_hash_mbedtld_h__ #define INCLUDE_hash_mbedtld_h__ +#include "hash.h" + #include struct git_hash_ctx { mbedtls_sha1_context c; }; -#define git_hash_ctx_init(ctx) git_hash_init(ctx) - -GIT_INLINE(int) git_hash_global_init(void) -{ - return 0; -} - #endif /* INCLUDE_hash_mbedtld_h__ */ diff --git a/src/hash/hash_openssl.c b/src/hash/hash_openssl.c new file mode 100644 index 000000000..8a6dd7a22 --- /dev/null +++ b/src/hash/hash_openssl.c @@ -0,0 +1,59 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ + +#include "hash_openssl.h" + +int git_hash_global_init(void) +{ + return 0; +} + +int git_hash_ctx_init(git_hash_ctx *ctx) +{ + return git_hash_init(ctx); +} + +void git_hash_ctx_cleanup(git_hash_ctx *ctx) +{ + GIT_UNUSED(ctx); +} + +int git_hash_init(git_hash_ctx *ctx) +{ + assert(ctx); + + if (SHA1_Init(&ctx->c) != 1) { + git_error_set(GIT_ERROR_SHA1, "hash_openssl: failed to initialize hash context"); + return -1; + } + + return 0; +} + +int git_hash_update(git_hash_ctx *ctx, const void *data, size_t len) +{ + assert(ctx); + + if (SHA1_Update(&ctx->c, data, len) != 1) { + git_error_set(GIT_ERROR_SHA1, "hash_openssl: failed to update hash"); + return -1; + } + + return 0; +} + +int git_hash_final(git_oid *out, git_hash_ctx *ctx) +{ + assert(ctx); + + if (SHA1_Final(out->id, &ctx->c) != 1) { + git_error_set(GIT_ERROR_SHA1, "hash_openssl: failed to finalize hash"); + return -1; + } + + return 0; +} diff --git a/src/hash/hash_openssl.h b/src/hash/hash_openssl.h index 8dbfd5ad5..c08ae1008 100644 --- a/src/hash/hash_openssl.h +++ b/src/hash/hash_openssl.h @@ -8,6 +8,8 @@ #ifndef INCLUDE_hash_hash_openssl_h__ #define INCLUDE_hash_hash_openssl_h__ +#include "common.h" + #include "hash.h" #include @@ -16,48 +18,4 @@ struct git_hash_ctx { SHA_CTX c; }; -#define git_hash_ctx_init(ctx) git_hash_init(ctx) -#define git_hash_ctx_cleanup(ctx) - -GIT_INLINE(int) git_hash_global_init(void) -{ - return 0; -} - -GIT_INLINE(int) git_hash_init(git_hash_ctx *ctx) -{ - assert(ctx); - - if (SHA1_Init(&ctx->c) != 1) { - git_error_set(GIT_ERROR_SHA1, "hash_openssl: failed to initialize hash context"); - return -1; - } - - return 0; -} - -GIT_INLINE(int) git_hash_update(git_hash_ctx *ctx, const void *data, size_t len) -{ - assert(ctx); - - if (SHA1_Update(&ctx->c, data, len) != 1) { - git_error_set(GIT_ERROR_SHA1, "hash_openssl: failed to update hash"); - return -1; - } - - return 0; -} - -GIT_INLINE(int) git_hash_final(git_oid *out, git_hash_ctx *ctx) -{ - assert(ctx); - - if (SHA1_Final(out->id, &ctx->c) != 1) { - git_error_set(GIT_ERROR_SHA1, "hash_openssl: failed to finalize hash"); - return -1; - } - - return 0; -} - #endif diff --git a/src/hash/hash_win32.c b/src/hash/hash_win32.c index 4b6830358..4d00c54d3 100644 --- a/src/hash/hash_win32.c +++ b/src/hash/hash_win32.c @@ -8,11 +8,21 @@ #include "hash_win32.h" #include "global.h" -#include "hash.h" #include #include +#define GIT_HASH_CNG_DLL_NAME "bcrypt.dll" + +/* BCRYPT_SHA1_ALGORITHM */ +#define GIT_HASH_CNG_HASH_TYPE L"SHA1" + +/* BCRYPT_OBJECT_LENGTH */ +#define GIT_HASH_CNG_HASH_OBJECT_LEN L"ObjectLength" + +/* BCRYPT_HASH_REUSEABLE_FLAGS */ +#define GIT_HASH_CNG_HASH_REUSABLE 0x00000020 + static struct git_hash_prov hash_prov = {0}; /* Hash initialization */ @@ -101,7 +111,7 @@ GIT_INLINE(void) hash_cryptoapi_prov_shutdown(void) hash_prov.type = INVALID; } -static void git_hash_global_shutdown(void) +static void sha1_shutdown(void) { if (hash_prov.type == CNG) hash_cng_prov_shutdown(); @@ -119,7 +129,7 @@ int git_hash_global_init(void) if ((error = hash_cng_prov_init()) < 0) error = hash_cryptoapi_prov_init(); - git__on_shutdown(git_hash_global_shutdown); + git__on_shutdown(sha1_shutdown); return error; } diff --git a/src/hash/hash_win32.h b/src/hash/hash_win32.h index b9a85f8dc..e4970ce28 100644 --- a/src/hash/hash_win32.h +++ b/src/hash/hash_win32.h @@ -36,17 +36,6 @@ struct hash_cryptoapi_prov { * would not exist when building in pre-Windows 2008 environments. */ -#define GIT_HASH_CNG_DLL_NAME "bcrypt.dll" - -/* BCRYPT_SHA1_ALGORITHM */ -#define GIT_HASH_CNG_HASH_TYPE L"SHA1" - -/* BCRYPT_OBJECT_LENGTH */ -#define GIT_HASH_CNG_HASH_OBJECT_LEN L"ObjectLength" - -/* BCRYPT_HASH_REUSEABLE_FLAGS */ -#define GIT_HASH_CNG_HASH_REUSABLE 0x00000020 - /* Function declarations for CNG */ typedef NTSTATUS (WINAPI *hash_win32_cng_open_algorithm_provider_fn)( HANDLE /* BCRYPT_ALG_HANDLE */ *phAlgorithm, @@ -138,6 +127,4 @@ struct git_hash_ctx { } ctx; }; -extern int git_hash_global_init(void); - #endif From fda206228f5df603a6fc3a81092e36850d4879b2 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Fri, 14 Jun 2019 14:22:19 +0200 Subject: [PATCH 3/6] hash: move SHA1 implementations into 'sha1/' folder As we will include additional hash algorithms in the future due to upstream git discussing a move away from SHA1, we should accomodate for that and prepare for the move. As a first step, move all SHA1 implementations into a common subdirectory. Also, create a SHA1-specific header file that lives inside the hash folder. This header will contain the SHA1-specific header includes, function declarations and the SHA1 context structure. --- cmake/Modules/SelectHashes.cmake | 12 ++++----- src/hash.h | 15 ++--------- src/hash/sha1.h | 27 +++++++++++++++++++ .../collisiondetect.c} | 2 +- .../collisiondetect.h} | 4 +-- .../common_crypto.c} | 2 +- .../common_crypto.h} | 4 +-- src/hash/{hash_generic.c => sha1/generic.c} | 2 +- src/hash/{hash_generic.h => sha1/generic.h} | 4 +-- src/hash/{hash_mbedtls.c => sha1/mbedtls.c} | 4 +-- src/hash/{hash_mbedtls.h => sha1/mbedtls.h} | 6 ++--- src/hash/{hash_openssl.c => sha1/openssl.c} | 2 +- src/hash/{hash_openssl.h => sha1/openssl.h} | 4 +-- src/hash/{ => sha1}/sha1dc/sha1.c | 0 src/hash/{ => sha1}/sha1dc/sha1.h | 0 src/hash/{ => sha1}/sha1dc/ubc_check.c | 0 src/hash/{ => sha1}/sha1dc/ubc_check.h | 0 src/hash/{hash_win32.c => sha1/win32.c} | 2 +- src/hash/{hash_win32.h => sha1/win32.h} | 0 19 files changed, 52 insertions(+), 38 deletions(-) create mode 100644 src/hash/sha1.h rename src/hash/{hash_collisiondetect.c => sha1/collisiondetect.c} (96%) rename src/hash/{hash_collisiondetect.h => sha1/collisiondetect.h} (77%) rename src/hash/{hash_common_crypto.c => sha1/common_crypto.c} (96%) rename src/hash/{hash_common_crypto.h => sha1/common_crypto.h} (78%) rename src/hash/{hash_generic.c => sha1/generic.c} (99%) rename src/hash/{hash_generic.h => sha1/generic.h} (81%) rename src/hash/{hash_mbedtls.c => sha1/mbedtls.c} (92%) rename src/hash/{hash_mbedtls.h => sha1/mbedtls.h} (72%) rename src/hash/{hash_openssl.c => sha1/openssl.c} (97%) rename src/hash/{hash_openssl.h => sha1/openssl.h} (81%) rename src/hash/{ => sha1}/sha1dc/sha1.c (100%) rename src/hash/{ => sha1}/sha1dc/sha1.h (100%) rename src/hash/{ => sha1}/sha1dc/ubc_check.c (100%) rename src/hash/{ => sha1}/sha1dc/ubc_check.h (100%) rename src/hash/{hash_win32.c => sha1/win32.c} (99%) rename src/hash/{hash_win32.h => sha1/win32.h} (100%) diff --git a/cmake/Modules/SelectHashes.cmake b/cmake/Modules/SelectHashes.cmake index 78ff41f57..e6751adbd 100644 --- a/cmake/Modules/SelectHashes.cmake +++ b/cmake/Modules/SelectHashes.cmake @@ -30,7 +30,7 @@ IF(SHA1_BACKEND STREQUAL "CollisionDetection") ADD_DEFINITIONS(-DSHA1DC_NO_STANDARD_INCLUDES=1) ADD_DEFINITIONS(-DSHA1DC_CUSTOM_INCLUDE_SHA1_C=\"common.h\") ADD_DEFINITIONS(-DSHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C=\"common.h\") - FILE(GLOB SRC_SHA1 hash/hash_collisiondetect.c hash/sha1dc/*) + FILE(GLOB SRC_SHA1 hash/sha1/collisiondetect.c hash/sha1/sha1dc/*) ELSEIF(SHA1_BACKEND STREQUAL "OpenSSL") # OPENSSL_FOUND should already be set, we're checking HTTPS_BACKEND @@ -40,13 +40,13 @@ ELSEIF(SHA1_BACKEND STREQUAL "OpenSSL") ELSE() LIST(APPEND LIBGIT2_PC_REQUIRES "openssl") ENDIF() - FILE(GLOB SRC_SHA1 hash/hash_openssl.c) + FILE(GLOB SRC_SHA1 hash/sha1/openssl.c) ELSEIF(SHA1_BACKEND STREQUAL "CommonCrypto") SET(GIT_SHA1_COMMON_CRYPTO 1) - FILE(GLOB SRC_SHA1 hash/hash_common_crypto.c) + FILE(GLOB SRC_SHA1 hash/sha1/common_crypto.c) ELSEIF(SHA1_BACKEND STREQUAL "mbedTLS") SET(GIT_SHA1_MBEDTLS 1) - FILE(GLOB SRC_SHA1 hash/hash_mbedtls.c) + FILE(GLOB SRC_SHA1 hash/sha1/mbedtls.c) LIST(APPEND LIBGIT2_SYSTEM_INCLUDES ${MBEDTLS_INCLUDE_DIR}) LIST(APPEND LIBGIT2_LIBS ${MBEDTLS_LIBRARIES}) # mbedTLS has no pkgconfig file, hence we can't require it @@ -55,9 +55,9 @@ ELSEIF(SHA1_BACKEND STREQUAL "mbedTLS") LIST(APPEND LIBGIT2_PC_LIBS ${MBEDTLS_LIBRARIES}) ELSEIF(SHA1_BACKEND STREQUAL "Win32") SET(GIT_SHA1_WIN32 1) - FILE(GLOB SRC_SHA1 hash/hash_win32.c) + FILE(GLOB SRC_SHA1 hash/sha1/win32.c) ELSEIF(SHA1_BACKEND STREQUAL "Generic") - FILE(GLOB SRC_SHA1 hash/hash_generic.c) + FILE(GLOB SRC_SHA1 hash/sha1/generic.c) # ELSEIF(NOT USE_SHA1) ELSE() MESSAGE(FATAL_ERROR "Asked for unknown SHA1 backend: ${SHA1_BACKEND}") diff --git a/src/hash.h b/src/hash.h index 1ccf66d5f..ddd0ea201 100644 --- a/src/hash.h +++ b/src/hash.h @@ -4,6 +4,7 @@ * This file is part of libgit2, distributed under the GNU GPL v2 with * a Linking Exception. For full terms see the included COPYING file. */ + #ifndef INCLUDE_hash_h__ #define INCLUDE_hash_h__ @@ -18,19 +19,7 @@ typedef struct { size_t len; } git_buf_vec; -#if defined(GIT_SHA1_COLLISIONDETECT) -# include "hash/hash_collisiondetect.h" -#elif defined(GIT_SHA1_COMMON_CRYPTO) -# include "hash/hash_common_crypto.h" -#elif defined(GIT_SHA1_OPENSSL) -# include "hash/hash_openssl.h" -#elif defined(GIT_SHA1_WIN32) -# include "hash/hash_win32.h" -#elif defined(GIT_SHA1_MBEDTLS) -# include "hash/hash_mbedtls.h" -#else -# include "hash/hash_generic.h" -#endif +#include "hash/sha1.h" int git_hash_global_init(void); diff --git a/src/hash/sha1.h b/src/hash/sha1.h new file mode 100644 index 000000000..db0e5c195 --- /dev/null +++ b/src/hash/sha1.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ + +#ifndef INCLUDE_hash_sha1_h__ +#define INCLUDE_hash_sha1_h__ + +#include "common.h" + +#if defined(GIT_SHA1_COLLISIONDETECT) +# include "sha1/collisiondetect.h" +#elif defined(GIT_SHA1_COMMON_CRYPTO) +# include "sha1/common_crypto.h" +#elif defined(GIT_SHA1_OPENSSL) +# include "sha1/openssl.h" +#elif defined(GIT_SHA1_WIN32) +# include "sha1/win32.h" +#elif defined(GIT_SHA1_MBEDTLS) +# include "sha1/mbedtls.h" +#else +# include "sha1/generic.h" +#endif + +#endif diff --git a/src/hash/hash_collisiondetect.c b/src/hash/sha1/collisiondetect.c similarity index 96% rename from src/hash/hash_collisiondetect.c rename to src/hash/sha1/collisiondetect.c index baf278981..79ec4e549 100644 --- a/src/hash/hash_collisiondetect.c +++ b/src/hash/sha1/collisiondetect.c @@ -5,7 +5,7 @@ * a Linking Exception. For full terms see the included COPYING file. */ -#include "hash_collisiondetect.h" +#include "collisiondetect.h" int git_hash_global_init(void) { diff --git a/src/hash/hash_collisiondetect.h b/src/hash/sha1/collisiondetect.h similarity index 77% rename from src/hash/hash_collisiondetect.h rename to src/hash/sha1/collisiondetect.h index 8cba5fe8c..3dc30febe 100644 --- a/src/hash/hash_collisiondetect.h +++ b/src/hash/sha1/collisiondetect.h @@ -5,8 +5,8 @@ * a Linking Exception. For full terms see the included COPYING file. */ -#ifndef INCLUDE_hash_hash_collisiondetect_h__ -#define INCLUDE_hash_hash_collisiondetect_h__ +#ifndef INCLUDE_hash_sha1_collisiondetect_h__ +#define INCLUDE_hash_sha1_collisiondetect_h__ #include "hash.h" diff --git a/src/hash/hash_common_crypto.c b/src/hash/sha1/common_crypto.c similarity index 96% rename from src/hash/hash_common_crypto.c rename to src/hash/sha1/common_crypto.c index 1ad6f4a01..2fa52183a 100644 --- a/src/hash/hash_common_crypto.c +++ b/src/hash/sha1/common_crypto.c @@ -5,7 +5,7 @@ * a Linking Exception. For full terms see the included COPYING file. */ -#include "hash_common_crypto.h" +#include "common_crypto.h" #define CC_LONG_MAX ((CC_LONG)-1) diff --git a/src/hash/hash_common_crypto.h b/src/hash/sha1/common_crypto.h similarity index 78% rename from src/hash/hash_common_crypto.h rename to src/hash/sha1/common_crypto.h index 55bec2c1a..3be882892 100644 --- a/src/hash/hash_common_crypto.h +++ b/src/hash/sha1/common_crypto.h @@ -5,8 +5,8 @@ * a Linking Exception. For full terms see the included COPYING file. */ -#ifndef INCLUDE_hash_hash_common_crypto_h__ -#define INCLUDE_hash_hash_common_crypto_h__ +#ifndef INCLUDE_hash_sha1_common_crypto_h__ +#define INCLUDE_hash_sha1_common_crypto_h__ #include "hash.h" diff --git a/src/hash/hash_generic.c b/src/hash/sha1/generic.c similarity index 99% rename from src/hash/hash_generic.c rename to src/hash/sha1/generic.c index 55fbf8de5..157b9183e 100644 --- a/src/hash/hash_generic.c +++ b/src/hash/sha1/generic.c @@ -5,7 +5,7 @@ * a Linking Exception. For full terms see the included COPYING file. */ -#include "hash_generic.h" +#include "generic.h" #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) diff --git a/src/hash/hash_generic.h b/src/hash/sha1/generic.h similarity index 81% rename from src/hash/hash_generic.h rename to src/hash/sha1/generic.h index b97796ce1..041b9ef68 100644 --- a/src/hash/hash_generic.h +++ b/src/hash/sha1/generic.h @@ -5,8 +5,8 @@ * a Linking Exception. For full terms see the included COPYING file. */ -#ifndef INCLUDE_hash_hash_generic_h__ -#define INCLUDE_hash_hash_generic_h__ +#ifndef INCLUDE_hash_sha1_generic_h__ +#define INCLUDE_hash_sha1_generic_h__ #include "hash.h" diff --git a/src/hash/hash_mbedtls.c b/src/hash/sha1/mbedtls.c similarity index 92% rename from src/hash/hash_mbedtls.c rename to src/hash/sha1/mbedtls.c index b29226c38..1215197de 100644 --- a/src/hash/hash_mbedtls.c +++ b/src/hash/sha1/mbedtls.c @@ -5,9 +5,7 @@ * a Linking Exception. For full terms see the included COPYING file. */ -#include "common.h" -#include "hash.h" -#include "hash/hash_mbedtls.h" +#include "mbedtls.h" int git_hash_global_init(void) { diff --git a/src/hash/hash_mbedtls.h b/src/hash/sha1/mbedtls.h similarity index 72% rename from src/hash/hash_mbedtls.h rename to src/hash/sha1/mbedtls.h index 834b79dcf..d066cbdd9 100644 --- a/src/hash/hash_mbedtls.h +++ b/src/hash/sha1/mbedtls.h @@ -5,8 +5,8 @@ * a Linking Exception. For full terms see the included COPYING file. */ -#ifndef INCLUDE_hash_mbedtld_h__ -#define INCLUDE_hash_mbedtld_h__ +#ifndef INCLUDE_hash_sha1_mbedtls_h__ +#define INCLUDE_hash_sha1_mbedtls_h__ #include "hash.h" @@ -16,4 +16,4 @@ struct git_hash_ctx { mbedtls_sha1_context c; }; -#endif /* INCLUDE_hash_mbedtld_h__ */ +#endif /* INCLUDE_hash_sha1_mbedtls_h__ */ diff --git a/src/hash/hash_openssl.c b/src/hash/sha1/openssl.c similarity index 97% rename from src/hash/hash_openssl.c rename to src/hash/sha1/openssl.c index 8a6dd7a22..fd3a4daa4 100644 --- a/src/hash/hash_openssl.c +++ b/src/hash/sha1/openssl.c @@ -5,7 +5,7 @@ * a Linking Exception. For full terms see the included COPYING file. */ -#include "hash_openssl.h" +#include "openssl.h" int git_hash_global_init(void) { diff --git a/src/hash/hash_openssl.h b/src/hash/sha1/openssl.h similarity index 81% rename from src/hash/hash_openssl.h rename to src/hash/sha1/openssl.h index c08ae1008..f2ec5815e 100644 --- a/src/hash/hash_openssl.h +++ b/src/hash/sha1/openssl.h @@ -5,8 +5,8 @@ * a Linking Exception. For full terms see the included COPYING file. */ -#ifndef INCLUDE_hash_hash_openssl_h__ -#define INCLUDE_hash_hash_openssl_h__ +#ifndef INCLUDE_hash_sha1_openssl_h__ +#define INCLUDE_hash_sha1_openssl_h__ #include "common.h" diff --git a/src/hash/sha1dc/sha1.c b/src/hash/sha1/sha1dc/sha1.c similarity index 100% rename from src/hash/sha1dc/sha1.c rename to src/hash/sha1/sha1dc/sha1.c diff --git a/src/hash/sha1dc/sha1.h b/src/hash/sha1/sha1dc/sha1.h similarity index 100% rename from src/hash/sha1dc/sha1.h rename to src/hash/sha1/sha1dc/sha1.h diff --git a/src/hash/sha1dc/ubc_check.c b/src/hash/sha1/sha1dc/ubc_check.c similarity index 100% rename from src/hash/sha1dc/ubc_check.c rename to src/hash/sha1/sha1dc/ubc_check.c diff --git a/src/hash/sha1dc/ubc_check.h b/src/hash/sha1/sha1dc/ubc_check.h similarity index 100% rename from src/hash/sha1dc/ubc_check.h rename to src/hash/sha1/sha1dc/ubc_check.h diff --git a/src/hash/hash_win32.c b/src/hash/sha1/win32.c similarity index 99% rename from src/hash/hash_win32.c rename to src/hash/sha1/win32.c index 4d00c54d3..0dac9becb 100644 --- a/src/hash/hash_win32.c +++ b/src/hash/sha1/win32.c @@ -5,7 +5,7 @@ * a Linking Exception. For full terms see the included COPYING file. */ -#include "hash_win32.h" +#include "win32.h" #include "global.h" diff --git a/src/hash/hash_win32.h b/src/hash/sha1/win32.h similarity index 100% rename from src/hash/hash_win32.h rename to src/hash/sha1/win32.h From d46d3b539b3e0ed3871d2ac22271a6469ed7c215 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Fri, 5 Apr 2019 10:59:46 +0200 Subject: [PATCH 4/6] hash: split into generic and SHA1-specific interface As a preparatory step to allow multiple hashing APIs to exist at the same time, split the hashing functions into one layer for generic hashing and one layer for SHA1-specific hashing. Right now, this is simply an additional indirection layer that doesn't yet serve any purpose. In the future, the generic API will be extended to allow for choosing which hash to use, though, by simply passing an enum to the hash context initialization function. This is necessary as a first step to be ready for Git's move to SHA256. --- src/hash.c | 30 ++++++++++++++++++++++++++++++ src/hash/sha1.h | 9 +++++++++ src/hash/sha1/collisiondetect.c | 14 +++++++------- src/hash/sha1/common_crypto.c | 14 +++++++------- src/hash/sha1/generic.c | 14 +++++++------- src/hash/sha1/mbedtls.c | 14 +++++++------- src/hash/sha1/openssl.c | 14 +++++++------- src/hash/sha1/win32.c | 16 ++++++++-------- 8 files changed, 82 insertions(+), 43 deletions(-) diff --git a/src/hash.c b/src/hash.c index cc6676d4d..a3cb1c468 100644 --- a/src/hash.c +++ b/src/hash.c @@ -7,6 +7,36 @@ #include "hash.h" +int git_hash_global_init(void) +{ + return git_hash_sha1_global_init(); +} + +int git_hash_ctx_init(git_hash_ctx *ctx) +{ + return git_hash_sha1_ctx_init(ctx); +} + +void git_hash_ctx_cleanup(git_hash_ctx *ctx) +{ + git_hash_sha1_ctx_cleanup(ctx); +} + +int git_hash_init(git_hash_ctx *c) +{ + return git_hash_sha1_init(c); +} + +int git_hash_update(git_hash_ctx *c, const void *data, size_t len) +{ + return git_hash_sha1_update(c, data, len); +} + +int git_hash_final(git_oid *out, git_hash_ctx *c) +{ + return git_hash_sha1_final(out, c); +} + int git_hash_buf(git_oid *out, const void *data, size_t len) { git_hash_ctx ctx; diff --git a/src/hash/sha1.h b/src/hash/sha1.h index db0e5c195..38a4464be 100644 --- a/src/hash/sha1.h +++ b/src/hash/sha1.h @@ -24,4 +24,13 @@ # include "sha1/generic.h" #endif +int git_hash_sha1_global_init(void); + +int git_hash_sha1_ctx_init(git_hash_ctx *ctx); +void git_hash_sha1_ctx_cleanup(git_hash_ctx *ctx); + +int git_hash_sha1_init(git_hash_ctx *c); +int git_hash_sha1_update(git_hash_ctx *c, const void *data, size_t len); +int git_hash_sha1_final(git_oid *out, git_hash_ctx *c); + #endif diff --git a/src/hash/sha1/collisiondetect.c b/src/hash/sha1/collisiondetect.c index 79ec4e549..e0c3db642 100644 --- a/src/hash/sha1/collisiondetect.c +++ b/src/hash/sha1/collisiondetect.c @@ -7,36 +7,36 @@ #include "collisiondetect.h" -int git_hash_global_init(void) +int git_hash_sha1_global_init(void) { return 0; } -int git_hash_ctx_init(git_hash_ctx *ctx) +int git_hash_sha1_ctx_init(git_hash_ctx *ctx) { - return git_hash_init(ctx); + return git_hash_sha1_init(ctx); } -void git_hash_ctx_cleanup(git_hash_ctx *ctx) +void git_hash_sha1_ctx_cleanup(git_hash_ctx *ctx) { GIT_UNUSED(ctx); } -int git_hash_init(git_hash_ctx *ctx) +int git_hash_sha1_init(git_hash_ctx *ctx) { assert(ctx); SHA1DCInit(&ctx->c); return 0; } -int git_hash_update(git_hash_ctx *ctx, const void *data, size_t len) +int git_hash_sha1_update(git_hash_ctx *ctx, const void *data, size_t len) { assert(ctx); SHA1DCUpdate(&ctx->c, data, len); return 0; } -int git_hash_final(git_oid *out, git_hash_ctx *ctx) +int git_hash_sha1_final(git_oid *out, git_hash_ctx *ctx) { assert(ctx); if (SHA1DCFinal(out->id, &ctx->c)) { diff --git a/src/hash/sha1/common_crypto.c b/src/hash/sha1/common_crypto.c index 2fa52183a..3539fd012 100644 --- a/src/hash/sha1/common_crypto.c +++ b/src/hash/sha1/common_crypto.c @@ -9,29 +9,29 @@ #define CC_LONG_MAX ((CC_LONG)-1) -int git_hash_global_init(void) +int git_hash_sha1_global_init(void) { return 0; } -int git_hash_ctx_init(git_hash_ctx *ctx) +int git_hash_sha1_ctx_init(git_hash_ctx *ctx) { - return git_hash_init(ctx); + return git_hash_sha1_init(ctx); } -void git_hash_ctx_cleanup(git_hash_ctx *ctx) +void git_hash_sha1_ctx_cleanup(git_hash_ctx *ctx) { GIT_UNUSED(ctx); } -int git_hash_init(git_hash_ctx *ctx) +int git_hash_sha1_init(git_hash_ctx *ctx) { assert(ctx); CC_SHA1_Init(&ctx->c); return 0; } -int git_hash_update(git_hash_ctx *ctx, const void *_data, size_t len) +int git_hash_sha1_update(git_hash_ctx *ctx, const void *_data, size_t len) { const unsigned char *data = _data; @@ -49,7 +49,7 @@ int git_hash_update(git_hash_ctx *ctx, const void *_data, size_t len) return 0; } -int git_hash_final(git_oid *out, git_hash_ctx *ctx) +int git_hash_sha1_final(git_oid *out, git_hash_ctx *ctx) { assert(ctx); CC_SHA1_Final(out->id, &ctx->c); diff --git a/src/hash/sha1/generic.c b/src/hash/sha1/generic.c index 157b9183e..a5a9f4cc8 100644 --- a/src/hash/sha1/generic.c +++ b/src/hash/sha1/generic.c @@ -219,22 +219,22 @@ static void hash__block(git_hash_ctx *ctx, const unsigned int *data) ctx->H[4] += E; } -int git_hash_global_init(void) +int git_hash_sha1_global_init(void) { return 0; } -int git_hash_ctx_init(git_hash_ctx *ctx) +int git_hash_sha1_ctx_init(git_hash_ctx *ctx) { - return git_hash_init(ctx); + return git_hash_sha1_init(ctx); } -void git_hash_ctx_cleanup(git_hash_ctx *ctx) +void git_hash_sha1_ctx_cleanup(git_hash_ctx *ctx) { GIT_UNUSED(ctx); } -int git_hash_init(git_hash_ctx *ctx) +int git_hash_sha1_init(git_hash_ctx *ctx) { ctx->size = 0; @@ -248,7 +248,7 @@ int git_hash_init(git_hash_ctx *ctx) return 0; } -int git_hash_update(git_hash_ctx *ctx, const void *data, size_t len) +int git_hash_sha1_update(git_hash_ctx *ctx, const void *data, size_t len) { unsigned int lenW = ctx->size & 63; @@ -278,7 +278,7 @@ int git_hash_update(git_hash_ctx *ctx, const void *data, size_t len) return 0; } -int git_hash_final(git_oid *out, git_hash_ctx *ctx) +int git_hash_sha1_final(git_oid *out, git_hash_ctx *ctx) { static const unsigned char pad[64] = { 0x80 }; unsigned int padlen[2]; diff --git a/src/hash/sha1/mbedtls.c b/src/hash/sha1/mbedtls.c index 1215197de..8ebf9409b 100644 --- a/src/hash/sha1/mbedtls.c +++ b/src/hash/sha1/mbedtls.c @@ -7,23 +7,23 @@ #include "mbedtls.h" -int git_hash_global_init(void) +int git_hash_sha1_global_init(void) { return 0; } -int git_hash_ctx_init(git_hash_ctx *ctx) +int git_hash_sha1_ctx_init(git_hash_ctx *ctx) { - return git_hash_init(ctx); + return git_hash_sha1_init(ctx); } -void git_hash_ctx_cleanup(git_hash_ctx *ctx) +void git_hash_sha1_ctx_cleanup(git_hash_ctx *ctx) { assert(ctx); mbedtls_sha1_free(&ctx->c); } -int git_hash_init(git_hash_ctx *ctx) +int git_hash_sha1_init(git_hash_ctx *ctx) { assert(ctx); mbedtls_sha1_init(&ctx->c); @@ -31,14 +31,14 @@ int git_hash_init(git_hash_ctx *ctx) return 0; } -int git_hash_update(git_hash_ctx *ctx, const void *data, size_t len) +int git_hash_sha1_update(git_hash_ctx *ctx, const void *data, size_t len) { assert(ctx); mbedtls_sha1_update(&ctx->c, data, len); return 0; } -int git_hash_final(git_oid *out, git_hash_ctx *ctx) +int git_hash_sha1_final(git_oid *out, git_hash_ctx *ctx) { assert(ctx); mbedtls_sha1_finish(&ctx->c, out->id); diff --git a/src/hash/sha1/openssl.c b/src/hash/sha1/openssl.c index fd3a4daa4..d93cd8b05 100644 --- a/src/hash/sha1/openssl.c +++ b/src/hash/sha1/openssl.c @@ -7,22 +7,22 @@ #include "openssl.h" -int git_hash_global_init(void) +int git_hash_sha1_global_init(void) { return 0; } -int git_hash_ctx_init(git_hash_ctx *ctx) +int git_hash_sha1_ctx_init(git_hash_ctx *ctx) { - return git_hash_init(ctx); + return git_hash_sha1_init(ctx); } -void git_hash_ctx_cleanup(git_hash_ctx *ctx) +void git_hash_sha1_ctx_cleanup(git_hash_ctx *ctx) { GIT_UNUSED(ctx); } -int git_hash_init(git_hash_ctx *ctx) +int git_hash_sha1_init(git_hash_ctx *ctx) { assert(ctx); @@ -34,7 +34,7 @@ int git_hash_init(git_hash_ctx *ctx) return 0; } -int git_hash_update(git_hash_ctx *ctx, const void *data, size_t len) +int git_hash_sha1_update(git_hash_ctx *ctx, const void *data, size_t len) { assert(ctx); @@ -46,7 +46,7 @@ int git_hash_update(git_hash_ctx *ctx, const void *data, size_t len) return 0; } -int git_hash_final(git_oid *out, git_hash_ctx *ctx) +int git_hash_sha1_final(git_oid *out, git_hash_ctx *ctx) { assert(ctx); diff --git a/src/hash/sha1/win32.c b/src/hash/sha1/win32.c index 0dac9becb..8814ac3a6 100644 --- a/src/hash/sha1/win32.c +++ b/src/hash/sha1/win32.c @@ -119,7 +119,7 @@ static void sha1_shutdown(void) hash_cryptoapi_prov_shutdown(); } -int git_hash_global_init(void) +int git_hash_sha1_global_init(void) { int error = 0; @@ -141,7 +141,7 @@ GIT_INLINE(int) hash_ctx_cryptoapi_init(git_hash_ctx *ctx) ctx->type = CRYPTOAPI; ctx->prov = &hash_prov; - return git_hash_init(ctx); + return git_hash_sha1_init(ctx); } GIT_INLINE(int) hash_cryptoapi_init(git_hash_ctx *ctx) @@ -281,7 +281,7 @@ GIT_INLINE(void) hash_ctx_cng_cleanup(git_hash_ctx *ctx) /* Indirection between CryptoAPI and CNG */ -int git_hash_ctx_init(git_hash_ctx *ctx) +int git_hash_sha1_ctx_init(git_hash_ctx *ctx) { int error = 0; @@ -292,7 +292,7 @@ int git_hash_ctx_init(git_hash_ctx *ctx) * initialized with git_libgit2_init. Otherwise, it must be initialized * at first use. */ - if (hash_prov.type == INVALID && (error = git_hash_global_init()) < 0) + if (hash_prov.type == INVALID && (error = git_hash_sha1_global_init()) < 0) return error; memset(ctx, 0x0, sizeof(git_hash_ctx)); @@ -300,25 +300,25 @@ int git_hash_ctx_init(git_hash_ctx *ctx) return (hash_prov.type == CNG) ? hash_ctx_cng_init(ctx) : hash_ctx_cryptoapi_init(ctx); } -int git_hash_init(git_hash_ctx *ctx) +int git_hash_sha1_init(git_hash_ctx *ctx) { assert(ctx && ctx->type); return (ctx->type == CNG) ? hash_cng_init(ctx) : hash_cryptoapi_init(ctx); } -int git_hash_update(git_hash_ctx *ctx, const void *data, size_t len) +int git_hash_sha1_update(git_hash_ctx *ctx, const void *data, size_t len) { assert(ctx && ctx->type); return (ctx->type == CNG) ? hash_cng_update(ctx, data, len) : hash_cryptoapi_update(ctx, data, len); } -int git_hash_final(git_oid *out, git_hash_ctx *ctx) +int git_hash_sha1_final(git_oid *out, git_hash_ctx *ctx) { assert(ctx && ctx->type); return (ctx->type == CNG) ? hash_cng_final(out, ctx) : hash_cryptoapi_final(out, ctx); } -void git_hash_ctx_cleanup(git_hash_ctx *ctx) +void git_hash_sha1_ctx_cleanup(git_hash_ctx *ctx) { assert(ctx); From 8832172e9b73bc4edf938fbac6db850eef436699 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Fri, 22 Feb 2019 14:32:40 +0100 Subject: [PATCH 5/6] hash: move SHA1 implementations to its own hashing context Create a separate `git_hash_sha1_ctx` structure that is specific to the SHA1 implementation and move all SHA1 functions over to use that one instead of the generic `git_hash_ctx`. The `git_hash_ctx` for now simply has a union containing this single SHA1 implementation, only, without any mechanism to distinguish between different algortihms. --- src/hash.c | 16 ++++++++-------- src/hash.h | 8 ++++++-- src/hash/sha1.h | 12 +++++++----- src/hash/sha1/collisiondetect.c | 10 +++++----- src/hash/sha1/collisiondetect.h | 4 ++-- src/hash/sha1/common_crypto.c | 10 +++++----- src/hash/sha1/common_crypto.h | 4 ++-- src/hash/sha1/generic.c | 16 ++++++++-------- src/hash/sha1/generic.h | 4 ++-- src/hash/sha1/mbedtls.c | 10 +++++----- src/hash/sha1/mbedtls.h | 4 ++-- src/hash/sha1/openssl.c | 10 +++++----- src/hash/sha1/openssl.h | 6 ++---- src/hash/sha1/win32.c | 32 ++++++++++++++++---------------- src/hash/sha1/win32.h | 10 ++++------ 15 files changed, 79 insertions(+), 77 deletions(-) diff --git a/src/hash.c b/src/hash.c index a3cb1c468..7d9a41a89 100644 --- a/src/hash.c +++ b/src/hash.c @@ -14,27 +14,27 @@ int git_hash_global_init(void) int git_hash_ctx_init(git_hash_ctx *ctx) { - return git_hash_sha1_ctx_init(ctx); + return git_hash_sha1_ctx_init(&ctx->sha1); } void git_hash_ctx_cleanup(git_hash_ctx *ctx) { - git_hash_sha1_ctx_cleanup(ctx); + git_hash_sha1_ctx_cleanup(&ctx->sha1); } -int git_hash_init(git_hash_ctx *c) +int git_hash_init(git_hash_ctx *ctx) { - return git_hash_sha1_init(c); + return git_hash_sha1_init(&ctx->sha1); } -int git_hash_update(git_hash_ctx *c, const void *data, size_t len) +int git_hash_update(git_hash_ctx *ctx, const void *data, size_t len) { - return git_hash_sha1_update(c, data, len); + return git_hash_sha1_update(&ctx->sha1, data, len); } -int git_hash_final(git_oid *out, git_hash_ctx *c) +int git_hash_final(git_oid *out, git_hash_ctx *ctx) { - return git_hash_sha1_final(out, c); + return git_hash_sha1_final(out, &ctx->sha1); } int git_hash_buf(git_oid *out, const void *data, size_t len) diff --git a/src/hash.h b/src/hash.h index ddd0ea201..18fb5d655 100644 --- a/src/hash.h +++ b/src/hash.h @@ -12,8 +12,6 @@ #include "git2/oid.h" -typedef struct git_hash_ctx git_hash_ctx; - typedef struct { void *data; size_t len; @@ -21,6 +19,12 @@ typedef struct { #include "hash/sha1.h" +typedef struct git_hash_ctx { + union { + git_hash_sha1_ctx sha1; + }; +} git_hash_ctx; + int git_hash_global_init(void); int git_hash_ctx_init(git_hash_ctx *ctx); diff --git a/src/hash/sha1.h b/src/hash/sha1.h index 38a4464be..fb8d62f80 100644 --- a/src/hash/sha1.h +++ b/src/hash/sha1.h @@ -10,6 +10,8 @@ #include "common.h" +typedef struct git_hash_sha1_ctx git_hash_sha1_ctx; + #if defined(GIT_SHA1_COLLISIONDETECT) # include "sha1/collisiondetect.h" #elif defined(GIT_SHA1_COMMON_CRYPTO) @@ -26,11 +28,11 @@ int git_hash_sha1_global_init(void); -int git_hash_sha1_ctx_init(git_hash_ctx *ctx); -void git_hash_sha1_ctx_cleanup(git_hash_ctx *ctx); +int git_hash_sha1_ctx_init(git_hash_sha1_ctx *ctx); +void git_hash_sha1_ctx_cleanup(git_hash_sha1_ctx *ctx); -int git_hash_sha1_init(git_hash_ctx *c); -int git_hash_sha1_update(git_hash_ctx *c, const void *data, size_t len); -int git_hash_sha1_final(git_oid *out, git_hash_ctx *c); +int git_hash_sha1_init(git_hash_sha1_ctx *c); +int git_hash_sha1_update(git_hash_sha1_ctx *c, const void *data, size_t len); +int git_hash_sha1_final(git_oid *out, git_hash_sha1_ctx *c); #endif diff --git a/src/hash/sha1/collisiondetect.c b/src/hash/sha1/collisiondetect.c index e0c3db642..e6a126780 100644 --- a/src/hash/sha1/collisiondetect.c +++ b/src/hash/sha1/collisiondetect.c @@ -12,31 +12,31 @@ int git_hash_sha1_global_init(void) return 0; } -int git_hash_sha1_ctx_init(git_hash_ctx *ctx) +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_ctx *ctx) +void git_hash_sha1_ctx_cleanup(git_hash_sha1_ctx *ctx) { GIT_UNUSED(ctx); } -int git_hash_sha1_init(git_hash_ctx *ctx) +int git_hash_sha1_init(git_hash_sha1_ctx *ctx) { assert(ctx); SHA1DCInit(&ctx->c); return 0; } -int git_hash_sha1_update(git_hash_ctx *ctx, const void *data, size_t len) +int git_hash_sha1_update(git_hash_sha1_ctx *ctx, const void *data, size_t len) { assert(ctx); SHA1DCUpdate(&ctx->c, data, len); return 0; } -int git_hash_sha1_final(git_oid *out, git_hash_ctx *ctx) +int git_hash_sha1_final(git_oid *out, git_hash_sha1_ctx *ctx) { assert(ctx); if (SHA1DCFinal(out->id, &ctx->c)) { diff --git a/src/hash/sha1/collisiondetect.h b/src/hash/sha1/collisiondetect.h index 3dc30febe..eb88e86c1 100644 --- a/src/hash/sha1/collisiondetect.h +++ b/src/hash/sha1/collisiondetect.h @@ -8,11 +8,11 @@ #ifndef INCLUDE_hash_sha1_collisiondetect_h__ #define INCLUDE_hash_sha1_collisiondetect_h__ -#include "hash.h" +#include "hash/sha1.h" #include "sha1dc/sha1.h" -struct git_hash_ctx { +struct git_hash_sha1_ctx { SHA1_CTX c; }; diff --git a/src/hash/sha1/common_crypto.c b/src/hash/sha1/common_crypto.c index 3539fd012..0449a3c9d 100644 --- a/src/hash/sha1/common_crypto.c +++ b/src/hash/sha1/common_crypto.c @@ -14,24 +14,24 @@ int git_hash_sha1_global_init(void) return 0; } -int git_hash_sha1_ctx_init(git_hash_ctx *ctx) +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_ctx *ctx) +void git_hash_sha1_ctx_cleanup(git_hash_sha1_ctx *ctx) { GIT_UNUSED(ctx); } -int git_hash_sha1_init(git_hash_ctx *ctx) +int git_hash_sha1_init(git_hash_sha1_ctx *ctx) { assert(ctx); CC_SHA1_Init(&ctx->c); return 0; } -int git_hash_sha1_update(git_hash_ctx *ctx, const void *_data, size_t len) +int git_hash_sha1_update(git_hash_sha1_ctx *ctx, const void *_data, size_t len) { const unsigned char *data = _data; @@ -49,7 +49,7 @@ int git_hash_sha1_update(git_hash_ctx *ctx, const void *_data, size_t len) return 0; } -int git_hash_sha1_final(git_oid *out, git_hash_ctx *ctx) +int git_hash_sha1_final(git_oid *out, git_hash_sha1_ctx *ctx) { assert(ctx); CC_SHA1_Final(out->id, &ctx->c); diff --git a/src/hash/sha1/common_crypto.h b/src/hash/sha1/common_crypto.h index 3be882892..a5fcfb33e 100644 --- a/src/hash/sha1/common_crypto.h +++ b/src/hash/sha1/common_crypto.h @@ -8,11 +8,11 @@ #ifndef INCLUDE_hash_sha1_common_crypto_h__ #define INCLUDE_hash_sha1_common_crypto_h__ -#include "hash.h" +#include "hash/sha1.h" #include -struct git_hash_ctx { +struct git_hash_sha1_ctx { CC_SHA1_CTX c; }; diff --git a/src/hash/sha1/generic.c b/src/hash/sha1/generic.c index a5a9f4cc8..607fe3a43 100644 --- a/src/hash/sha1/generic.c +++ b/src/hash/sha1/generic.c @@ -111,7 +111,7 @@ #define T_40_59(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, ((B&C)+(D&(B^C))) , 0x8f1bbcdc, A, B, C, D, E ) #define T_60_79(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (B^C^D) , 0xca62c1d6, A, B, C, D, E ) -static void hash__block(git_hash_ctx *ctx, const unsigned int *data) +static void hash__block(git_hash_sha1_ctx *ctx, const unsigned int *data) { unsigned int A,B,C,D,E; unsigned int array[16]; @@ -224,17 +224,17 @@ int git_hash_sha1_global_init(void) return 0; } -int git_hash_sha1_ctx_init(git_hash_ctx *ctx) +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_ctx *ctx) +void git_hash_sha1_ctx_cleanup(git_hash_sha1_ctx *ctx) { GIT_UNUSED(ctx); } -int git_hash_sha1_init(git_hash_ctx *ctx) +int git_hash_sha1_init(git_hash_sha1_ctx *ctx) { ctx->size = 0; @@ -248,7 +248,7 @@ int git_hash_sha1_init(git_hash_ctx *ctx) return 0; } -int git_hash_sha1_update(git_hash_ctx *ctx, const void *data, size_t len) +int git_hash_sha1_update(git_hash_sha1_ctx *ctx, const void *data, size_t len) { unsigned int lenW = ctx->size & 63; @@ -278,7 +278,7 @@ int git_hash_sha1_update(git_hash_ctx *ctx, const void *data, size_t len) return 0; } -int git_hash_sha1_final(git_oid *out, git_hash_ctx *ctx) +int git_hash_sha1_final(git_oid *out, git_hash_sha1_ctx *ctx) { static const unsigned char pad[64] = { 0x80 }; unsigned int padlen[2]; @@ -289,8 +289,8 @@ int git_hash_sha1_final(git_oid *out, git_hash_ctx *ctx) padlen[1] = htonl((uint32_t)(ctx->size << 3)); i = ctx->size & 63; - git_hash_update(ctx, pad, 1+ (63 & (55 - i))); - git_hash_update(ctx, padlen, 8); + git_hash_sha1_update(ctx, pad, 1+ (63 & (55 - i))); + git_hash_sha1_update(ctx, padlen, 8); /* Output hash */ for (i = 0; i < 5; i++) diff --git a/src/hash/sha1/generic.h b/src/hash/sha1/generic.h index 041b9ef68..e4cc6026b 100644 --- a/src/hash/sha1/generic.h +++ b/src/hash/sha1/generic.h @@ -8,9 +8,9 @@ #ifndef INCLUDE_hash_sha1_generic_h__ #define INCLUDE_hash_sha1_generic_h__ -#include "hash.h" +#include "hash/sha1.h" -struct git_hash_ctx { +struct git_hash_sha1_ctx { unsigned long long size; unsigned int H[5]; unsigned int W[16]; diff --git a/src/hash/sha1/mbedtls.c b/src/hash/sha1/mbedtls.c index 8ebf9409b..e44343fcf 100644 --- a/src/hash/sha1/mbedtls.c +++ b/src/hash/sha1/mbedtls.c @@ -12,18 +12,18 @@ int git_hash_sha1_global_init(void) return 0; } -int git_hash_sha1_ctx_init(git_hash_ctx *ctx) +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_ctx *ctx) +void git_hash_sha1_ctx_cleanup(git_hash_sha1_ctx *ctx) { assert(ctx); mbedtls_sha1_free(&ctx->c); } -int git_hash_sha1_init(git_hash_ctx *ctx) +int git_hash_sha1_init(git_hash_sha1_ctx *ctx) { assert(ctx); mbedtls_sha1_init(&ctx->c); @@ -31,14 +31,14 @@ int git_hash_sha1_init(git_hash_ctx *ctx) return 0; } -int git_hash_sha1_update(git_hash_ctx *ctx, const void *data, size_t len) +int git_hash_sha1_update(git_hash_sha1_ctx *ctx, const void *data, size_t len) { assert(ctx); mbedtls_sha1_update(&ctx->c, data, len); return 0; } -int git_hash_sha1_final(git_oid *out, git_hash_ctx *ctx) +int git_hash_sha1_final(git_oid *out, git_hash_sha1_ctx *ctx) { assert(ctx); mbedtls_sha1_finish(&ctx->c, out->id); diff --git a/src/hash/sha1/mbedtls.h b/src/hash/sha1/mbedtls.h index d066cbdd9..15f7462a4 100644 --- a/src/hash/sha1/mbedtls.h +++ b/src/hash/sha1/mbedtls.h @@ -8,11 +8,11 @@ #ifndef INCLUDE_hash_sha1_mbedtls_h__ #define INCLUDE_hash_sha1_mbedtls_h__ -#include "hash.h" +#include "hash/sha1.h" #include -struct git_hash_ctx { +struct git_hash_sha1_ctx { mbedtls_sha1_context c; }; diff --git a/src/hash/sha1/openssl.c b/src/hash/sha1/openssl.c index d93cd8b05..ba3212ff2 100644 --- a/src/hash/sha1/openssl.c +++ b/src/hash/sha1/openssl.c @@ -12,17 +12,17 @@ int git_hash_sha1_global_init(void) return 0; } -int git_hash_sha1_ctx_init(git_hash_ctx *ctx) +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_ctx *ctx) +void git_hash_sha1_ctx_cleanup(git_hash_sha1_ctx *ctx) { GIT_UNUSED(ctx); } -int git_hash_sha1_init(git_hash_ctx *ctx) +int git_hash_sha1_init(git_hash_sha1_ctx *ctx) { assert(ctx); @@ -34,7 +34,7 @@ int git_hash_sha1_init(git_hash_ctx *ctx) return 0; } -int git_hash_sha1_update(git_hash_ctx *ctx, const void *data, size_t len) +int git_hash_sha1_update(git_hash_sha1_ctx *ctx, const void *data, size_t len) { assert(ctx); @@ -46,7 +46,7 @@ int git_hash_sha1_update(git_hash_ctx *ctx, const void *data, size_t len) return 0; } -int git_hash_sha1_final(git_oid *out, git_hash_ctx *ctx) +int git_hash_sha1_final(git_oid *out, git_hash_sha1_ctx *ctx) { assert(ctx); diff --git a/src/hash/sha1/openssl.h b/src/hash/sha1/openssl.h index f2ec5815e..a223ca03e 100644 --- a/src/hash/sha1/openssl.h +++ b/src/hash/sha1/openssl.h @@ -8,13 +8,11 @@ #ifndef INCLUDE_hash_sha1_openssl_h__ #define INCLUDE_hash_sha1_openssl_h__ -#include "common.h" - -#include "hash.h" +#include "hash/sha1.h" #include -struct git_hash_ctx { +struct git_hash_sha1_ctx { SHA_CTX c; }; diff --git a/src/hash/sha1/win32.c b/src/hash/sha1/win32.c index 8814ac3a6..1b944e27f 100644 --- a/src/hash/sha1/win32.c +++ b/src/hash/sha1/win32.c @@ -136,7 +136,7 @@ int git_hash_sha1_global_init(void) /* CryptoAPI: available in Windows XP and newer */ -GIT_INLINE(int) hash_ctx_cryptoapi_init(git_hash_ctx *ctx) +GIT_INLINE(int) hash_ctx_cryptoapi_init(git_hash_sha1_ctx *ctx) { ctx->type = CRYPTOAPI; ctx->prov = &hash_prov; @@ -144,7 +144,7 @@ GIT_INLINE(int) hash_ctx_cryptoapi_init(git_hash_ctx *ctx) return git_hash_sha1_init(ctx); } -GIT_INLINE(int) hash_cryptoapi_init(git_hash_ctx *ctx) +GIT_INLINE(int) hash_cryptoapi_init(git_hash_sha1_ctx *ctx) { if (ctx->ctx.cryptoapi.valid) CryptDestroyHash(ctx->ctx.cryptoapi.hash_handle); @@ -159,7 +159,7 @@ GIT_INLINE(int) hash_cryptoapi_init(git_hash_ctx *ctx) return 0; } -GIT_INLINE(int) hash_cryptoapi_update(git_hash_ctx *ctx, const void *_data, size_t len) +GIT_INLINE(int) hash_cryptoapi_update(git_hash_sha1_ctx *ctx, const void *_data, size_t len) { const BYTE *data = (BYTE *)_data; @@ -180,7 +180,7 @@ GIT_INLINE(int) hash_cryptoapi_update(git_hash_ctx *ctx, const void *_data, size return 0; } -GIT_INLINE(int) hash_cryptoapi_final(git_oid *out, git_hash_ctx *ctx) +GIT_INLINE(int) hash_cryptoapi_final(git_oid *out, git_hash_sha1_ctx *ctx) { DWORD len = 20; int error = 0; @@ -198,7 +198,7 @@ GIT_INLINE(int) hash_cryptoapi_final(git_oid *out, git_hash_ctx *ctx) return error; } -GIT_INLINE(void) hash_ctx_cryptoapi_cleanup(git_hash_ctx *ctx) +GIT_INLINE(void) hash_ctx_cryptoapi_cleanup(git_hash_sha1_ctx *ctx) { if (ctx->ctx.cryptoapi.valid) CryptDestroyHash(ctx->ctx.cryptoapi.hash_handle); @@ -206,7 +206,7 @@ GIT_INLINE(void) hash_ctx_cryptoapi_cleanup(git_hash_ctx *ctx) /* CNG: Available in Windows Server 2008 and newer */ -GIT_INLINE(int) hash_ctx_cng_init(git_hash_ctx *ctx) +GIT_INLINE(int) hash_ctx_cng_init(git_hash_sha1_ctx *ctx) { if ((ctx->ctx.cng.hash_object = git__malloc(hash_prov.prov.cng.hash_object_size)) == NULL) return -1; @@ -224,7 +224,7 @@ GIT_INLINE(int) hash_ctx_cng_init(git_hash_ctx *ctx) return 0; } -GIT_INLINE(int) hash_cng_init(git_hash_ctx *ctx) +GIT_INLINE(int) hash_cng_init(git_hash_sha1_ctx *ctx) { BYTE hash[GIT_OID_RAWSZ]; @@ -242,7 +242,7 @@ GIT_INLINE(int) hash_cng_init(git_hash_ctx *ctx) return 0; } -GIT_INLINE(int) hash_cng_update(git_hash_ctx *ctx, const void *_data, size_t len) +GIT_INLINE(int) hash_cng_update(git_hash_sha1_ctx *ctx, const void *_data, size_t len) { PBYTE data = (PBYTE)_data; @@ -261,7 +261,7 @@ GIT_INLINE(int) hash_cng_update(git_hash_ctx *ctx, const void *_data, size_t len return 0; } -GIT_INLINE(int) hash_cng_final(git_oid *out, git_hash_ctx *ctx) +GIT_INLINE(int) hash_cng_final(git_oid *out, git_hash_sha1_ctx *ctx) { if (ctx->prov->prov.cng.finish_hash(ctx->ctx.cng.hash_handle, out->id, GIT_OID_RAWSZ, 0) < 0) { git_error_set(GIT_ERROR_OS, "hash could not be finished"); @@ -273,7 +273,7 @@ GIT_INLINE(int) hash_cng_final(git_oid *out, git_hash_ctx *ctx) return 0; } -GIT_INLINE(void) hash_ctx_cng_cleanup(git_hash_ctx *ctx) +GIT_INLINE(void) hash_ctx_cng_cleanup(git_hash_sha1_ctx *ctx) { ctx->prov->prov.cng.destroy_hash(ctx->ctx.cng.hash_handle); git__free(ctx->ctx.cng.hash_object); @@ -281,7 +281,7 @@ GIT_INLINE(void) hash_ctx_cng_cleanup(git_hash_ctx *ctx) /* Indirection between CryptoAPI and CNG */ -int git_hash_sha1_ctx_init(git_hash_ctx *ctx) +int git_hash_sha1_ctx_init(git_hash_sha1_ctx *ctx) { int error = 0; @@ -295,30 +295,30 @@ int git_hash_sha1_ctx_init(git_hash_ctx *ctx) if (hash_prov.type == INVALID && (error = git_hash_sha1_global_init()) < 0) return error; - memset(ctx, 0x0, sizeof(git_hash_ctx)); + memset(ctx, 0x0, sizeof(git_hash_sha1_ctx)); return (hash_prov.type == CNG) ? hash_ctx_cng_init(ctx) : hash_ctx_cryptoapi_init(ctx); } -int git_hash_sha1_init(git_hash_ctx *ctx) +int git_hash_sha1_init(git_hash_sha1_ctx *ctx) { assert(ctx && ctx->type); return (ctx->type == CNG) ? hash_cng_init(ctx) : hash_cryptoapi_init(ctx); } -int git_hash_sha1_update(git_hash_ctx *ctx, const void *data, size_t len) +int git_hash_sha1_update(git_hash_sha1_ctx *ctx, const void *data, size_t len) { assert(ctx && ctx->type); return (ctx->type == CNG) ? hash_cng_update(ctx, data, len) : hash_cryptoapi_update(ctx, data, len); } -int git_hash_sha1_final(git_oid *out, git_hash_ctx *ctx) +int git_hash_sha1_final(git_oid *out, git_hash_sha1_ctx *ctx) { assert(ctx && ctx->type); return (ctx->type == CNG) ? hash_cng_final(out, ctx) : hash_cryptoapi_final(out, ctx); } -void git_hash_sha1_ctx_cleanup(git_hash_ctx *ctx) +void git_hash_sha1_ctx_cleanup(git_hash_sha1_ctx *ctx) { assert(ctx); diff --git a/src/hash/sha1/win32.h b/src/hash/sha1/win32.h index e4970ce28..791d20a42 100644 --- a/src/hash/sha1/win32.h +++ b/src/hash/sha1/win32.h @@ -5,12 +5,10 @@ * a Linking Exception. For full terms see the included COPYING file. */ -#ifndef INCLUDE_hash_hash_win32_h__ -#define INCLUDE_hash_hash_win32_h__ +#ifndef INCLUDE_hash_sha1_win32_h__ +#define INCLUDE_hash_sha1_win32_h__ -#include "common.h" - -#include "hash.h" +#include "hash/sha1.h" #include #include @@ -117,7 +115,7 @@ struct hash_cng_ctx { PBYTE hash_object; }; -struct git_hash_ctx { +struct git_hash_sha1_ctx { enum hash_win32_prov_type type; git_hash_prov *prov; From b7187ed745a066806881d71d248cca66d7cd3f0a Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Fri, 22 Feb 2019 14:38:31 +0100 Subject: [PATCH 6/6] hash: add ability to distinguish algorithms Create an enum that allows us to distinguish between different hashing algorithms. This enum is embedded into each `git_hash_ctx` and will instruct the code to which hashing function the particular request shall be dispatched. As we do not yet have multiple hashing algorithms, we simply initialize the hash algorithm to always be SHA1. At a later point, we will have to extend the `git_hash_init_ctx` function to get as parameter which algorithm shall be used. --- src/hash.c | 38 +++++++++++++++++++++++++++++++++----- src/hash.h | 6 ++++++ 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/hash.c b/src/hash.c index 7d9a41a89..ccd8a1639 100644 --- a/src/hash.c +++ b/src/hash.c @@ -14,27 +14,55 @@ int git_hash_global_init(void) int git_hash_ctx_init(git_hash_ctx *ctx) { - return git_hash_sha1_ctx_init(&ctx->sha1); + int error; + + if ((error = git_hash_sha1_ctx_init(&ctx->sha1)) < 0) + return error; + + ctx->algo = GIT_HASH_ALGO_SHA1; + + return 0; } void git_hash_ctx_cleanup(git_hash_ctx *ctx) { - git_hash_sha1_ctx_cleanup(&ctx->sha1); + switch (ctx->algo) { + case GIT_HASH_ALGO_SHA1: + git_hash_sha1_ctx_cleanup(&ctx->sha1); + return; + default: + assert(0); + } } int git_hash_init(git_hash_ctx *ctx) { - return git_hash_sha1_init(&ctx->sha1); + switch (ctx->algo) { + case GIT_HASH_ALGO_SHA1: + return git_hash_sha1_init(&ctx->sha1); + default: + assert(0); + } } int git_hash_update(git_hash_ctx *ctx, const void *data, size_t len) { - return git_hash_sha1_update(&ctx->sha1, data, len); + switch (ctx->algo) { + case GIT_HASH_ALGO_SHA1: + return git_hash_sha1_update(&ctx->sha1, data, len); + default: + assert(0); + } } int git_hash_final(git_oid *out, git_hash_ctx *ctx) { - return git_hash_sha1_final(out, &ctx->sha1); + switch (ctx->algo) { + case GIT_HASH_ALGO_SHA1: + return git_hash_sha1_final(out, &ctx->sha1); + default: + assert(0); + } } int git_hash_buf(git_oid *out, const void *data, size_t len) diff --git a/src/hash.h b/src/hash.h index 18fb5d655..017bb286c 100644 --- a/src/hash.h +++ b/src/hash.h @@ -17,12 +17,18 @@ typedef struct { size_t len; } git_buf_vec; +typedef enum { + GIT_HASH_ALGO_UNKNOWN = 0, + GIT_HASH_ALGO_SHA1, +} git_hash_algo_t; + #include "hash/sha1.h" typedef struct git_hash_ctx { union { git_hash_sha1_ctx sha1; }; + git_hash_algo_t algo; } git_hash_ctx; int git_hash_global_init(void);