]> git.ipfire.org Git - thirdparty/git.git/blame - hash-ll.h
cmake: also build unit tests
[thirdparty/git.git] / hash-ll.h
CommitLineData
d1cbe1e6
EN
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
66static 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
72static 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
119struct 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
140enum 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. */
159union git_hash_ctx {
160 git_SHA_CTX sha1;
161 git_SHA256_CTX sha256;
162};
163typedef union git_hash_ctx git_hash_ctx;
164
165typedef void (*git_hash_init_fn)(git_hash_ctx *ctx);
166typedef void (*git_hash_clone_fn)(git_hash_ctx *dst, const git_hash_ctx *src);
167typedef void (*git_hash_update_fn)(git_hash_ctx *ctx, const void *in, size_t len);
168typedef void (*git_hash_final_fn)(unsigned char *hash, git_hash_ctx *ctx);
169typedef void (*git_hash_final_oid_fn)(struct object_id *oid, git_hash_ctx *ctx);
170
171struct 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};
214extern 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 */
220int hash_algo_by_name(const char *name);
221/* Identical, except based on the format ID. */
222int hash_algo_by_id(uint32_t format_id);
223/* Identical, except based on the length. */
224int hash_algo_by_length(int len);
225/* Identical, except for a pointer to struct git_hash_algo. */
226static inline int hash_algo_by_ptr(const struct git_hash_algo *p)
227{
228 return p - hash_algos;
229}
230
231const struct object_id *null_oid(void);
232
233static 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
244static 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
255static 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
261static 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
268static 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
273const char *empty_tree_oid_hex(void);
274const char *empty_blob_oid_hex(void);
275
276#endif