Line | Count | Source |
1 | | #include "git-compat-util.h" |
2 | | #include "hash.h" |
3 | | #include "hex.h" |
4 | | |
5 | | static const struct object_id empty_tree_oid = { |
6 | | .hash = { |
7 | | 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60, |
8 | | 0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04 |
9 | | }, |
10 | | .algo = GIT_HASH_SHA1, |
11 | | }; |
12 | | static const struct object_id empty_blob_oid = { |
13 | | .hash = { |
14 | | 0xe6, 0x9d, 0xe2, 0x9b, 0xb2, 0xd1, 0xd6, 0x43, 0x4b, 0x8b, |
15 | | 0x29, 0xae, 0x77, 0x5a, 0xd8, 0xc2, 0xe4, 0x8c, 0x53, 0x91 |
16 | | }, |
17 | | .algo = GIT_HASH_SHA1, |
18 | | }; |
19 | | static const struct object_id null_oid_sha1 = { |
20 | | .hash = {0}, |
21 | | .algo = GIT_HASH_SHA1, |
22 | | }; |
23 | | static const struct object_id empty_tree_oid_sha256 = { |
24 | | .hash = { |
25 | | 0x6e, 0xf1, 0x9b, 0x41, 0x22, 0x5c, 0x53, 0x69, 0xf1, 0xc1, |
26 | | 0x04, 0xd4, 0x5d, 0x8d, 0x85, 0xef, 0xa9, 0xb0, 0x57, 0xb5, |
27 | | 0x3b, 0x14, 0xb4, 0xb9, 0xb9, 0x39, 0xdd, 0x74, 0xde, 0xcc, |
28 | | 0x53, 0x21 |
29 | | }, |
30 | | .algo = GIT_HASH_SHA256, |
31 | | }; |
32 | | static const struct object_id empty_blob_oid_sha256 = { |
33 | | .hash = { |
34 | | 0x47, 0x3a, 0x0f, 0x4c, 0x3b, 0xe8, 0xa9, 0x36, 0x81, 0xa2, |
35 | | 0x67, 0xe3, 0xb1, 0xe9, 0xa7, 0xdc, 0xda, 0x11, 0x85, 0x43, |
36 | | 0x6f, 0xe1, 0x41, 0xf7, 0x74, 0x91, 0x20, 0xa3, 0x03, 0x72, |
37 | | 0x18, 0x13 |
38 | | }, |
39 | | .algo = GIT_HASH_SHA256, |
40 | | }; |
41 | | static const struct object_id null_oid_sha256 = { |
42 | | .hash = {0}, |
43 | | .algo = GIT_HASH_SHA256, |
44 | | }; |
45 | | |
46 | | static void git_hash_sha1_init(struct git_hash_ctx *ctx) |
47 | 0 | { |
48 | 0 | ctx->algop = &hash_algos[GIT_HASH_SHA1]; |
49 | 0 | git_SHA1_Init(&ctx->state.sha1); |
50 | 0 | } |
51 | | |
52 | | static void git_hash_sha1_clone(struct git_hash_ctx *dst, const struct git_hash_ctx *src) |
53 | 0 | { |
54 | 0 | dst->algop = src->algop; |
55 | 0 | git_SHA1_Clone(&dst->state.sha1, &src->state.sha1); |
56 | 0 | } |
57 | | |
58 | | static void git_hash_sha1_update(struct git_hash_ctx *ctx, const void *data, size_t len) |
59 | 0 | { |
60 | 0 | git_SHA1_Update(&ctx->state.sha1, data, len); |
61 | 0 | } |
62 | | |
63 | | static void git_hash_sha1_final(unsigned char *hash, struct git_hash_ctx *ctx) |
64 | 0 | { |
65 | 0 | git_SHA1_Final(hash, &ctx->state.sha1); |
66 | 0 | } |
67 | | |
68 | | static void git_hash_sha1_final_oid(struct object_id *oid, struct git_hash_ctx *ctx) |
69 | 0 | { |
70 | 0 | git_SHA1_Final(oid->hash, &ctx->state.sha1); |
71 | 0 | memset(oid->hash + GIT_SHA1_RAWSZ, 0, GIT_MAX_RAWSZ - GIT_SHA1_RAWSZ); |
72 | 0 | oid->algo = GIT_HASH_SHA1; |
73 | 0 | } |
74 | | |
75 | | static void git_hash_sha1_init_unsafe(struct git_hash_ctx *ctx) |
76 | 0 | { |
77 | 0 | ctx->algop = unsafe_hash_algo(&hash_algos[GIT_HASH_SHA1]); |
78 | 0 | git_SHA1_Init_unsafe(&ctx->state.sha1_unsafe); |
79 | 0 | } |
80 | | |
81 | | static void git_hash_sha1_clone_unsafe(struct git_hash_ctx *dst, const struct git_hash_ctx *src) |
82 | 0 | { |
83 | 0 | dst->algop = src->algop; |
84 | 0 | git_SHA1_Clone_unsafe(&dst->state.sha1_unsafe, &src->state.sha1_unsafe); |
85 | 0 | } |
86 | | |
87 | | static void git_hash_sha1_update_unsafe(struct git_hash_ctx *ctx, const void *data, |
88 | | size_t len) |
89 | 0 | { |
90 | 0 | git_SHA1_Update_unsafe(&ctx->state.sha1_unsafe, data, len); |
91 | 0 | } |
92 | | |
93 | | static void git_hash_sha1_final_unsafe(unsigned char *hash, struct git_hash_ctx *ctx) |
94 | 0 | { |
95 | 0 | git_SHA1_Final_unsafe(hash, &ctx->state.sha1_unsafe); |
96 | 0 | } |
97 | | |
98 | | static void git_hash_sha1_final_oid_unsafe(struct object_id *oid, struct git_hash_ctx *ctx) |
99 | 0 | { |
100 | 0 | git_SHA1_Final_unsafe(oid->hash, &ctx->state.sha1_unsafe); |
101 | 0 | memset(oid->hash + GIT_SHA1_RAWSZ, 0, GIT_MAX_RAWSZ - GIT_SHA1_RAWSZ); |
102 | 0 | oid->algo = GIT_HASH_SHA1; |
103 | 0 | } |
104 | | |
105 | | static void git_hash_sha256_init(struct git_hash_ctx *ctx) |
106 | 0 | { |
107 | 0 | ctx->algop = unsafe_hash_algo(&hash_algos[GIT_HASH_SHA256]); |
108 | 0 | git_SHA256_Init(&ctx->state.sha256); |
109 | 0 | } |
110 | | |
111 | | static void git_hash_sha256_clone(struct git_hash_ctx *dst, const struct git_hash_ctx *src) |
112 | 0 | { |
113 | 0 | dst->algop = src->algop; |
114 | 0 | git_SHA256_Clone(&dst->state.sha256, &src->state.sha256); |
115 | 0 | } |
116 | | |
117 | | static void git_hash_sha256_update(struct git_hash_ctx *ctx, const void *data, size_t len) |
118 | 0 | { |
119 | 0 | git_SHA256_Update(&ctx->state.sha256, data, len); |
120 | 0 | } |
121 | | |
122 | | static void git_hash_sha256_final(unsigned char *hash, struct git_hash_ctx *ctx) |
123 | 0 | { |
124 | 0 | git_SHA256_Final(hash, &ctx->state.sha256); |
125 | 0 | } |
126 | | |
127 | | static void git_hash_sha256_final_oid(struct object_id *oid, struct git_hash_ctx *ctx) |
128 | 0 | { |
129 | 0 | git_SHA256_Final(oid->hash, &ctx->state.sha256); |
130 | | /* |
131 | | * This currently does nothing, so the compiler should optimize it out, |
132 | | * but keep it in case we extend the hash size again. |
133 | | */ |
134 | 0 | memset(oid->hash + GIT_SHA256_RAWSZ, 0, GIT_MAX_RAWSZ - GIT_SHA256_RAWSZ); |
135 | 0 | oid->algo = GIT_HASH_SHA256; |
136 | 0 | } |
137 | | |
138 | | static void git_hash_unknown_init(struct git_hash_ctx *ctx UNUSED) |
139 | 0 | { |
140 | 0 | BUG("trying to init unknown hash"); |
141 | 0 | } |
142 | | |
143 | | static void git_hash_unknown_clone(struct git_hash_ctx *dst UNUSED, |
144 | | const struct git_hash_ctx *src UNUSED) |
145 | 0 | { |
146 | 0 | BUG("trying to clone unknown hash"); |
147 | 0 | } |
148 | | |
149 | | static void git_hash_unknown_update(struct git_hash_ctx *ctx UNUSED, |
150 | | const void *data UNUSED, |
151 | | size_t len UNUSED) |
152 | 0 | { |
153 | 0 | BUG("trying to update unknown hash"); |
154 | 0 | } |
155 | | |
156 | | static void git_hash_unknown_final(unsigned char *hash UNUSED, |
157 | | struct git_hash_ctx *ctx UNUSED) |
158 | 0 | { |
159 | 0 | BUG("trying to finalize unknown hash"); |
160 | 0 | } |
161 | | |
162 | | static void git_hash_unknown_final_oid(struct object_id *oid UNUSED, |
163 | | struct git_hash_ctx *ctx UNUSED) |
164 | 0 | { |
165 | 0 | BUG("trying to finalize unknown hash"); |
166 | 0 | } |
167 | | |
168 | | static const struct git_hash_algo sha1_unsafe_algo = { |
169 | | .name = "sha1", |
170 | | .format_id = GIT_SHA1_FORMAT_ID, |
171 | | .rawsz = GIT_SHA1_RAWSZ, |
172 | | .hexsz = GIT_SHA1_HEXSZ, |
173 | | .blksz = GIT_SHA1_BLKSZ, |
174 | | .init_fn = git_hash_sha1_init_unsafe, |
175 | | .clone_fn = git_hash_sha1_clone_unsafe, |
176 | | .update_fn = git_hash_sha1_update_unsafe, |
177 | | .final_fn = git_hash_sha1_final_unsafe, |
178 | | .final_oid_fn = git_hash_sha1_final_oid_unsafe, |
179 | | .empty_tree = &empty_tree_oid, |
180 | | .empty_blob = &empty_blob_oid, |
181 | | .null_oid = &null_oid_sha1, |
182 | | }; |
183 | | |
184 | | const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = { |
185 | | { |
186 | | .name = NULL, |
187 | | .format_id = 0x00000000, |
188 | | .rawsz = 0, |
189 | | .hexsz = 0, |
190 | | .blksz = 0, |
191 | | .init_fn = git_hash_unknown_init, |
192 | | .clone_fn = git_hash_unknown_clone, |
193 | | .update_fn = git_hash_unknown_update, |
194 | | .final_fn = git_hash_unknown_final, |
195 | | .final_oid_fn = git_hash_unknown_final_oid, |
196 | | .empty_tree = NULL, |
197 | | .empty_blob = NULL, |
198 | | .null_oid = NULL, |
199 | | }, |
200 | | { |
201 | | .name = "sha1", |
202 | | .format_id = GIT_SHA1_FORMAT_ID, |
203 | | .rawsz = GIT_SHA1_RAWSZ, |
204 | | .hexsz = GIT_SHA1_HEXSZ, |
205 | | .blksz = GIT_SHA1_BLKSZ, |
206 | | .init_fn = git_hash_sha1_init, |
207 | | .clone_fn = git_hash_sha1_clone, |
208 | | .update_fn = git_hash_sha1_update, |
209 | | .final_fn = git_hash_sha1_final, |
210 | | .final_oid_fn = git_hash_sha1_final_oid, |
211 | | .unsafe = &sha1_unsafe_algo, |
212 | | .empty_tree = &empty_tree_oid, |
213 | | .empty_blob = &empty_blob_oid, |
214 | | .null_oid = &null_oid_sha1, |
215 | | }, |
216 | | { |
217 | | .name = "sha256", |
218 | | .format_id = GIT_SHA256_FORMAT_ID, |
219 | | .rawsz = GIT_SHA256_RAWSZ, |
220 | | .hexsz = GIT_SHA256_HEXSZ, |
221 | | .blksz = GIT_SHA256_BLKSZ, |
222 | | .init_fn = git_hash_sha256_init, |
223 | | .clone_fn = git_hash_sha256_clone, |
224 | | .update_fn = git_hash_sha256_update, |
225 | | .final_fn = git_hash_sha256_final, |
226 | | .final_oid_fn = git_hash_sha256_final_oid, |
227 | | .empty_tree = &empty_tree_oid_sha256, |
228 | | .empty_blob = &empty_blob_oid_sha256, |
229 | | .null_oid = &null_oid_sha256, |
230 | | } |
231 | | }; |
232 | | |
233 | | const struct object_id *null_oid(const struct git_hash_algo *algop) |
234 | 0 | { |
235 | 0 | return algop->null_oid; |
236 | 0 | } |
237 | | |
238 | | const char *empty_tree_oid_hex(const struct git_hash_algo *algop) |
239 | 0 | { |
240 | 0 | static char buf[GIT_MAX_HEXSZ + 1]; |
241 | 0 | return oid_to_hex_r(buf, algop->empty_tree); |
242 | 0 | } |
243 | | |
244 | | int hash_algo_by_name(const char *name) |
245 | 0 | { |
246 | 0 | if (!name) |
247 | 0 | return GIT_HASH_UNKNOWN; |
248 | 0 | for (size_t i = 1; i < GIT_HASH_NALGOS; i++) |
249 | 0 | if (!strcmp(name, hash_algos[i].name)) |
250 | 0 | return i; |
251 | 0 | return GIT_HASH_UNKNOWN; |
252 | 0 | } |
253 | | |
254 | | int hash_algo_by_id(uint32_t format_id) |
255 | 0 | { |
256 | 0 | for (size_t i = 1; i < GIT_HASH_NALGOS; i++) |
257 | 0 | if (format_id == hash_algos[i].format_id) |
258 | 0 | return i; |
259 | 0 | return GIT_HASH_UNKNOWN; |
260 | 0 | } |
261 | | |
262 | | int hash_algo_by_length(size_t len) |
263 | 0 | { |
264 | 0 | for (size_t i = 1; i < GIT_HASH_NALGOS; i++) |
265 | 0 | if (len == hash_algos[i].rawsz) |
266 | 0 | return i; |
267 | 0 | return GIT_HASH_UNKNOWN; |
268 | 0 | } |
269 | | |
270 | | const struct git_hash_algo *unsafe_hash_algo(const struct git_hash_algo *algop) |
271 | 0 | { |
272 | | /* If we have a faster "unsafe" implementation, use that. */ |
273 | 0 | if (algop->unsafe) |
274 | 0 | return algop->unsafe; |
275 | | /* Otherwise use the default one. */ |
276 | 0 | return algop; |
277 | 0 | } |