@matheusbsbs / matheus-bagliano / commits / 768e30ea27
Fork 0

hash: implement and use a context cloning function

For all of our SHA-1 implementations and most of our SHA-256 implementations, the hash context we use is a real struct. For these implementations, it's possible to copy a hash context by making a copy of the struct. However, for our libgcrypt implementation, our hash context is a pointer. Consequently, copying it does not lead to an independent hash context like we intended. Fortunately, however, libgcrypt provides us with a handy function to copy hash contexts. Let's add a cloning function to the hash algorithm API, and use it in the one place we need to make a hash context copy. With this change, our libgcrypt SHA-256 implementation is fully functional with all of our other hash implementations. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

brian m. carlson committed Feb 22, 2020 at 20:17 UTC 768e30ea27c58aa69893e10b96ba5ba5680dc3cf
4 files changed +46 -1
csum-file.c
+1 -1
@@ -157,7 +157,7 @@ void hashfile_checkpoint(struct hashfile *f, struct hashfile_checkpoint *checkpo
157 {
158 hashflush(f);
159 checkpoint->offset = f->total;
160 - checkpoint->ctx = f->ctx;
160 + the_hash_algo->clone_fn(&checkpoint->ctx, &f->ctx);
161 }
162
163 int hashfile_truncate(struct hashfile *f, struct hashfile_checkpoint *checkpoint)
hash.h
+21
@@ -16,6 +16,7 @@
16 #endif
17
18 #if defined(SHA256_GCRYPT)
19 +#define SHA256_NEEDS_CLONE_HELPER
20 #include "sha256/gcrypt.h"
21 #elif defined(SHA256_OPENSSL)
22 #include <openssl/sha.h>
@@ -54,12 +55,28 @@
55 #define git_SHA256_Update platform_SHA256_Update
56 #define git_SHA256_Final platform_SHA256_Final
57
58 +#ifdef platform_SHA256_Clone
59 +#define git_SHA256_Clone platform_SHA256_Clone
60 +#endif
61 +
62 #ifdef SHA1_MAX_BLOCK_SIZE
63 #include "compat/sha1-chunked.h"
64 #undef git_SHA1_Update
65 #define git_SHA1_Update git_SHA1_Update_Chunked
66 #endif
67
68 +static inline void git_SHA1_Clone(git_SHA_CTX *dst, const git_SHA_CTX *src)
69 +{
70 + memcpy(dst, src, sizeof(*dst));
71 +}
72 +
73 +#ifndef SHA256_NEEDS_CLONE_HELPER
74 +static inline void git_SHA256_Clone(git_SHA256_CTX *dst, const git_SHA256_CTX *src)
75 +{
76 + memcpy(dst, src, sizeof(*dst));
77 +}
78 +#endif
79 +
80 /*
81 * Note that these constants are suitable for indexing the hash_algos array and
82 * comparing against each other, but are otherwise arbitrary, so they should not
@@ -85,6 +102,7 @@ union git_hash_ctx {
102 typedef union git_hash_ctx git_hash_ctx;
103
104 typedef void (*git_hash_init_fn)(git_hash_ctx *ctx);
105 +typedef void (*git_hash_clone_fn)(git_hash_ctx *dst, const git_hash_ctx *src);
106 typedef void (*git_hash_update_fn)(git_hash_ctx *ctx, const void *in, size_t len);
107 typedef void (*git_hash_final_fn)(unsigned char *hash, git_hash_ctx *ctx);
108
@@ -110,6 +128,9 @@ struct git_hash_algo {
128 /* The hash initialization function. */
129 git_hash_init_fn init_fn;
130
131 + /* The hash context cloning function. */
132 + git_hash_clone_fn clone_fn;
133 +
134 /* The hash update function. */
135 git_hash_update_fn update_fn;
136
sha1-file.c
+18
@@ -74,6 +74,11 @@ static void git_hash_sha1_init(git_hash_ctx *ctx)
74 git_SHA1_Init(&ctx->sha1);
75 }
76
77 +static void git_hash_sha1_clone(git_hash_ctx *dst, const git_hash_ctx *src)
78 +{
79 + git_SHA1_Clone(&dst->sha1, &src->sha1);
80 +}
81 +
82 static void git_hash_sha1_update(git_hash_ctx *ctx, const void *data, size_t len)
83 {
84 git_SHA1_Update(&ctx->sha1, data, len);
@@ -90,6 +95,11 @@ static void git_hash_sha256_init(git_hash_ctx *ctx)
95 git_SHA256_Init(&ctx->sha256);
96 }
97
98 +static void git_hash_sha256_clone(git_hash_ctx *dst, const git_hash_ctx *src)
99 +{
100 + git_SHA256_Clone(&dst->sha256, &src->sha256);
101 +}
102 +
103 static void git_hash_sha256_update(git_hash_ctx *ctx, const void *data, size_t len)
104 {
105 git_SHA256_Update(&ctx->sha256, data, len);
@@ -105,6 +115,11 @@ static void git_hash_unknown_init(git_hash_ctx *ctx)
115 BUG("trying to init unknown hash");
116 }
117
118 +static void git_hash_unknown_clone(git_hash_ctx *dst, const git_hash_ctx *src)
119 +{
120 + BUG("trying to clone unknown hash");
121 +}
122 +
123 static void git_hash_unknown_update(git_hash_ctx *ctx, const void *data, size_t len)
124 {
125 BUG("trying to update unknown hash");
@@ -123,6 +138,7 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
138 0,
139 0,
140 git_hash_unknown_init,
141 + git_hash_unknown_clone,
142 git_hash_unknown_update,
143 git_hash_unknown_final,
144 NULL,
@@ -136,6 +152,7 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
152 GIT_SHA1_HEXSZ,
153 GIT_SHA1_BLKSZ,
154 git_hash_sha1_init,
155 + git_hash_sha1_clone,
156 git_hash_sha1_update,
157 git_hash_sha1_final,
158 &empty_tree_oid,
@@ -149,6 +166,7 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
166 GIT_SHA256_HEXSZ,
167 GIT_SHA256_BLKSZ,
168 git_hash_sha256_init,
169 + git_hash_sha256_clone,
170 git_hash_sha256_update,
171 git_hash_sha256_final,
172 &empty_tree_oid_sha256,
sha256/gcrypt.h
+6
@@ -22,8 +22,14 @@ inline void gcrypt_SHA256_Final(unsigned char *digest, gcrypt_SHA256_CTX *ctx)
22 memcpy(digest, gcry_md_read(*ctx, GCRY_MD_SHA256), SHA256_DIGEST_SIZE);
23 }
24
25 +inline void gcrypt_SHA256_Clone(gcrypt_SHA256_CTX *dst, const gcrypt_SHA256_CTX *src)
26 +{
27 + gcry_md_copy(dst, *src);
28 +}
29 +
30 #define platform_SHA256_CTX gcrypt_SHA256_CTX
31 #define platform_SHA256_Init gcrypt_SHA256_Init
32 +#define platform_SHA256_Clone gcrypt_SHA256_Clone
33 #define platform_SHA256_Update gcrypt_SHA256_Update
34 #define platform_SHA256_Final gcrypt_SHA256_Final
35