]> git.ipfire.org Git - thirdparty/git.git/blob - hash-ll.h
typo: replace 'commitish' with 'committish'
[thirdparty/git.git] / hash-ll.h
1 #ifndef HASH_LL_H
2 #define HASH_LL_H
3
4 #if defined(SHA1_APPLE)
5 #include <CommonCrypto/CommonDigest.h>
6 #elif defined(SHA1_OPENSSL)
7 #include <openssl/sha.h>
8 #elif defined(SHA1_DC)
9 #include "sha1dc_git.h"
10 #else /* SHA1_BLK */
11 #include "block-sha1/sha1.h"
12 #endif
13
14 #if defined(SHA256_NETTLE)
15 #include "sha256/nettle.h"
16 #elif defined(SHA256_GCRYPT)
17 #define SHA256_NEEDS_CLONE_HELPER
18 #include "sha256/gcrypt.h"
19 #elif defined(SHA256_OPENSSL)
20 #include <openssl/sha.h>
21 #else
22 #include "sha256/block/sha256.h"
23 #endif
24
25 #ifndef platform_SHA_CTX
26 /*
27 * platform's underlying implementation of SHA-1; could be OpenSSL,
28 * blk_SHA, Apple CommonCrypto, etc... Note that the relevant
29 * SHA-1 header may have already defined platform_SHA_CTX for our
30 * own implementations like block-sha1, so we list
31 * the default for OpenSSL compatible SHA-1 implementations here.
32 */
33 #define platform_SHA_CTX SHA_CTX
34 #define platform_SHA1_Init SHA1_Init
35 #define platform_SHA1_Update SHA1_Update
36 #define platform_SHA1_Final SHA1_Final
37 #endif
38
39 #define git_SHA_CTX platform_SHA_CTX
40 #define git_SHA1_Init platform_SHA1_Init
41 #define git_SHA1_Update platform_SHA1_Update
42 #define git_SHA1_Final platform_SHA1_Final
43
44 #ifndef platform_SHA256_CTX
45 #define platform_SHA256_CTX SHA256_CTX
46 #define platform_SHA256_Init SHA256_Init
47 #define platform_SHA256_Update SHA256_Update
48 #define platform_SHA256_Final SHA256_Final
49 #endif
50
51 #define git_SHA256_CTX platform_SHA256_CTX
52 #define git_SHA256_Init platform_SHA256_Init
53 #define git_SHA256_Update platform_SHA256_Update
54 #define git_SHA256_Final platform_SHA256_Final
55
56 #ifdef platform_SHA256_Clone
57 #define git_SHA256_Clone platform_SHA256_Clone
58 #endif
59
60 #ifdef SHA1_MAX_BLOCK_SIZE
61 #include "compat/sha1-chunked.h"
62 #undef git_SHA1_Update
63 #define git_SHA1_Update git_SHA1_Update_Chunked
64 #endif
65
66 static inline void git_SHA1_Clone(git_SHA_CTX *dst, const git_SHA_CTX *src)
67 {
68 memcpy(dst, src, sizeof(*dst));
69 }
70
71 #ifndef SHA256_NEEDS_CLONE_HELPER
72 static inline void git_SHA256_Clone(git_SHA256_CTX *dst, const git_SHA256_CTX *src)
73 {
74 memcpy(dst, src, sizeof(*dst));
75 }
76 #endif
77
78 /*
79 * Note that these constants are suitable for indexing the hash_algos array and
80 * comparing against each other, but are otherwise arbitrary, so they should not
81 * be exposed to the user or serialized to disk. To know whether a
82 * git_hash_algo struct points to some usable hash function, test the format_id
83 * field for being non-zero. Use the name field for user-visible situations and
84 * the format_id field for fixed-length fields on disk.
85 */
86 /* An unknown hash function. */
87 #define GIT_HASH_UNKNOWN 0
88 /* SHA-1 */
89 #define GIT_HASH_SHA1 1
90 /* SHA-256 */
91 #define GIT_HASH_SHA256 2
92 /* Number of algorithms supported (including unknown). */
93 #define GIT_HASH_NALGOS (GIT_HASH_SHA256 + 1)
94
95 /* "sha1", big-endian */
96 #define GIT_SHA1_FORMAT_ID 0x73686131
97
98 /* The length in bytes and in hex digits of an object name (SHA-1 value). */
99 #define GIT_SHA1_RAWSZ 20
100 #define GIT_SHA1_HEXSZ (2 * GIT_SHA1_RAWSZ)
101 /* The block size of SHA-1. */
102 #define GIT_SHA1_BLKSZ 64
103
104 /* "s256", big-endian */
105 #define GIT_SHA256_FORMAT_ID 0x73323536
106
107 /* The length in bytes and in hex digits of an object name (SHA-256 value). */
108 #define GIT_SHA256_RAWSZ 32
109 #define GIT_SHA256_HEXSZ (2 * GIT_SHA256_RAWSZ)
110 /* The block size of SHA-256. */
111 #define GIT_SHA256_BLKSZ 64
112
113 /* The length in byte and in hex digits of the largest possible hash value. */
114 #define GIT_MAX_RAWSZ GIT_SHA256_RAWSZ
115 #define GIT_MAX_HEXSZ GIT_SHA256_HEXSZ
116 /* The largest possible block size for any supported hash. */
117 #define GIT_MAX_BLKSZ GIT_SHA256_BLKSZ
118
119 struct object_id {
120 unsigned char hash[GIT_MAX_RAWSZ];
121 int algo; /* XXX requires 4-byte alignment */
122 };
123
124 #define GET_OID_QUIETLY 01
125 #define GET_OID_COMMIT 02
126 #define GET_OID_COMMITTISH 04
127 #define GET_OID_TREE 010
128 #define GET_OID_TREEISH 020
129 #define GET_OID_BLOB 040
130 #define GET_OID_FOLLOW_SYMLINKS 0100
131 #define GET_OID_RECORD_PATH 0200
132 #define GET_OID_ONLY_TO_DIE 04000
133 #define GET_OID_REQUIRE_PATH 010000
134
135 #define GET_OID_DISAMBIGUATORS \
136 (GET_OID_COMMIT | GET_OID_COMMITTISH | \
137 GET_OID_TREE | GET_OID_TREEISH | \
138 GET_OID_BLOB)
139
140 enum get_oid_result {
141 FOUND = 0,
142 MISSING_OBJECT = -1, /* The requested object is missing */
143 SHORT_NAME_AMBIGUOUS = -2,
144 /* The following only apply when symlinks are followed */
145 DANGLING_SYMLINK = -4, /*
146 * The initial symlink is there, but
147 * (transitively) points to a missing
148 * in-tree file
149 */
150 SYMLINK_LOOP = -5,
151 NOT_DIR = -6, /*
152 * Somewhere along the symlink chain, a path is
153 * requested which contains a file as a
154 * non-final element.
155 */
156 };
157
158 /* A suitably aligned type for stack allocations of hash contexts. */
159 union git_hash_ctx {
160 git_SHA_CTX sha1;
161 git_SHA256_CTX sha256;
162 };
163 typedef union git_hash_ctx git_hash_ctx;
164
165 typedef void (*git_hash_init_fn)(git_hash_ctx *ctx);
166 typedef void (*git_hash_clone_fn)(git_hash_ctx *dst, const git_hash_ctx *src);
167 typedef void (*git_hash_update_fn)(git_hash_ctx *ctx, const void *in, size_t len);
168 typedef void (*git_hash_final_fn)(unsigned char *hash, git_hash_ctx *ctx);
169 typedef void (*git_hash_final_oid_fn)(struct object_id *oid, git_hash_ctx *ctx);
170
171 struct git_hash_algo {
172 /*
173 * The name of the algorithm, as appears in the config file and in
174 * messages.
175 */
176 const char *name;
177
178 /* A four-byte version identifier, used in pack indices. */
179 uint32_t format_id;
180
181 /* The length of the hash in binary. */
182 size_t rawsz;
183
184 /* The length of the hash in hex characters. */
185 size_t hexsz;
186
187 /* The block size of the hash. */
188 size_t blksz;
189
190 /* The hash initialization function. */
191 git_hash_init_fn init_fn;
192
193 /* The hash context cloning function. */
194 git_hash_clone_fn clone_fn;
195
196 /* The hash update function. */
197 git_hash_update_fn update_fn;
198
199 /* The hash finalization function. */
200 git_hash_final_fn final_fn;
201
202 /* The hash finalization function for object IDs. */
203 git_hash_final_oid_fn final_oid_fn;
204
205 /* The OID of the empty tree. */
206 const struct object_id *empty_tree;
207
208 /* The OID of the empty blob. */
209 const struct object_id *empty_blob;
210
211 /* The all-zeros OID. */
212 const struct object_id *null_oid;
213 };
214 extern const struct git_hash_algo hash_algos[GIT_HASH_NALGOS];
215
216 /*
217 * Return a GIT_HASH_* constant based on the name. Returns GIT_HASH_UNKNOWN if
218 * the name doesn't match a known algorithm.
219 */
220 int hash_algo_by_name(const char *name);
221 /* Identical, except based on the format ID. */
222 int hash_algo_by_id(uint32_t format_id);
223 /* Identical, except based on the length. */
224 int hash_algo_by_length(int len);
225 /* Identical, except for a pointer to struct git_hash_algo. */
226 static inline int hash_algo_by_ptr(const struct git_hash_algo *p)
227 {
228 return p - hash_algos;
229 }
230
231 const struct object_id *null_oid(void);
232
233 static inline int hashcmp_algop(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)
234 {
235 /*
236 * Teach the compiler that there are only two possibilities of hash size
237 * here, so that it can optimize for this case as much as possible.
238 */
239 if (algop->rawsz == GIT_MAX_RAWSZ)
240 return memcmp(sha1, sha2, GIT_MAX_RAWSZ);
241 return memcmp(sha1, sha2, GIT_SHA1_RAWSZ);
242 }
243
244 static inline int hasheq_algop(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)
245 {
246 /*
247 * We write this here instead of deferring to hashcmp so that the
248 * compiler can properly inline it and avoid calling memcmp.
249 */
250 if (algop->rawsz == GIT_MAX_RAWSZ)
251 return !memcmp(sha1, sha2, GIT_MAX_RAWSZ);
252 return !memcmp(sha1, sha2, GIT_SHA1_RAWSZ);
253 }
254
255 static inline void oidcpy(struct object_id *dst, const struct object_id *src)
256 {
257 memcpy(dst->hash, src->hash, GIT_MAX_RAWSZ);
258 dst->algo = src->algo;
259 }
260
261 static inline struct object_id *oiddup(const struct object_id *src)
262 {
263 struct object_id *dst = xmalloc(sizeof(struct object_id));
264 oidcpy(dst, src);
265 return dst;
266 }
267
268 static inline void oid_set_algo(struct object_id *oid, const struct git_hash_algo *algop)
269 {
270 oid->algo = hash_algo_by_ptr(algop);
271 }
272
273 const char *empty_tree_oid_hex(void);
274 const char *empty_blob_oid_hex(void);
275
276 #endif