libfossil
fossil-hash.h
Go to the documentation of this file.
1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 #if !defined(NET_FOSSIL_SCM_FSL_HASH_H_INCLUDED)
4 #define NET_FOSSIL_SCM_FSL_HASH_H_INCLUDED
5 /*
6  Copyright (c) 2013 D. Richard Hipp
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the Simplified BSD License (also
10  known as the "2-Clause License" or "FreeBSD License".)
11 
12  This program is distributed in the hope that it will be useful,
13  but without any warranty; without even the implied warranty of
14  merchantability or fitness for a particular purpose.
15 
16  Author contact information:
17  drh@hwaci.com
18  http://www.hwaci.com/drh/
19 
20  *****************************************************************************
21  This file declares public APIs relating to generating hash values
22  hashing.
23 */
24 
25 #include "fossil-util.h" /* MUST come first b/c of config macros */
26 
27 #if defined(__cplusplus)
28 extern "C" {
29 #endif
30 
31 /**
32  Various set-in-stone constants used by the API.
33 */
35 /**
36  The length, in bytes, of fossil's hex-form UUID strings.
37 */
39 /**
40  The length, in bytes, of a hex-form MD5 hash.
41 */
43 };
44 
45 
46 typedef struct fsl_md5_cx fsl_md5_cx;
47 typedef struct fsl_sha1_cx fsl_sha1_cx;
48 
49 /**
50  The hash string of the initial MD5 state. Used as an
51  optimization for some places where we need an MD5 but know it
52  will not hash any data.
53 
54  Equivalent to what the md5sum command outputs for empty input:
55 
56  @code
57  # md5sum < /dev/null
58  d41d8cd98f00b204e9800998ecf8427e -
59  @endcode
60 */
61 #define FSL_MD5_INITIAL_HASH "d41d8cd98f00b204e9800998ecf8427e"
62 
63 /**
64  Holds state for MD5 calculations. It is intended to be used like
65  this:
66 
67  @code
68  unsigned char digest[16];
69  char hex[FSL_MD5_STRLEN+1];
70  fsl_md5_cx cx = fsl_md5_cx_empty;
71  // alternately: fsl_md5_init(&cx);
72  ...call fsl_md5_update(&cx,...) any number of times to
73  ...incrementally calculate the hash.
74  fsl_md5_final(&cx, digest); // ends the calculation
75  fsl_md5_digest_to_base16(digest, hex);
76  // digest now contains the raw 16-byte MD5 digest.
77  // hex now contains the 32-byte MD5 + a trailing NUL
78  @endcode
79 */
80 struct fsl_md5_cx {
81  int isInit;
84  unsigned char in[64];
85 };
86 #define fsl_md5_cx_empty_m { \
87  1/*isInit*/, \
88  {/*buf*/0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }, \
89  {/*bits*/0,0}, \
90  {0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, \
91  0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, \
92  0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, \
93  0,0,0,0}}
94 
95 /**
96  A fsl_md5_cx instance which holds the initial state
97  used for md5 calculations. Instances must either be
98  copy-initialized from this instance or they must be
99  passed to fsl_md5_init() before they are used.
100 */
102 
103 /**
104  Initializes the given context pointer. It must not be NULL. This
105  must be the first routine called on any fsl_md5_cx instances.
106  Alternately, copy-constructing fsl_md5_cx_empty has the same effect.
107 
108  @see fsl_md5_update()
109  @see fsl_md5_final()
110 */
112 
113 /**
114  Updates cx's state to reflect the addition of the data
115  specified by the range (buf, buf+len]. Neither cx nor buf may
116  be NULL. This may be called an arbitrary number of times between
117  fsl_md5_init() and fsl_md5_final().
118 
119  @see fsl_md5_init()
120  @see fsl_md5_final()
121 */
122 FSL_EXPORT void fsl_md5_update(fsl_md5_cx *cx, void const * buf, fsl_size_t len);
123 
124 /**
125  Finishes up the calculation of the md5 for the given context and
126  writes a 16-byte digest value to the 2nd parameter. Use
127  fsl_md5_digest_to_base16() to convert the digest output value to
128  hexidecimal form.
129 
130  @see fsl_md5_init()
131  @see fsl_md5_update()
132  @see fsl_md5_digest_to_base16()
133 */
134 FSL_EXPORT void fsl_md5_final(fsl_md5_cx * cx, unsigned char * digest);
135 
136 /**
137  Converts an md5 digest value (from fsl_md5_final()'s 2nd
138  parameter) to a 32-byte (FSL_MD5_STRLEN) CRC string plus a
139  terminating NUL byte. i.e. zBuf must be at least
140  (FSL_MD5_STRLEN+1) bytes long.
141 
142  @see fsl_md5_final()
143 */
144 FSL_EXPORT void fsl_md5_digest_to_base16(unsigned char *digest, char *zBuf);
145 
146 /**
147  The md5 counterpart of fsl_sha1sum_buffer(), identical in
148  semantics except that its result is an MD5 hash instead of an
149  SHA1 hash and the resulting hex string is FSL_MD5_STRLEN bytes
150  long plus a terminating NUL.
151 */
152 FSL_EXPORT int fsl_md5sum_buffer(fsl_buffer const *pIn, fsl_buffer *pCksum);
153 
154 /**
155  The md5 counterpart of fsl_sha1sum_cstr(), identical in
156  semantics except that its result is an MD5 hash instead of an
157  SHA1 hash and the resulting string is FSL_MD5_STRLEN bytes long
158  plus a terminating NUL.
159 */
160 FSL_EXPORT char *fsl_md5sum_cstr(const char *zIn, fsl_int_t len);
161 
162 /**
163  The MD5 counter part to fsl_sha1sum_stream(), with identical
164  semantics except that the generated hash is an MD5 string
165  instead of SHA1.
166 */
167 FSL_EXPORT int fsl_md5sum_stream(fsl_input_f src, void * srcState, fsl_buffer *pCksum);
168 
169 /**
170  Reads all input from src() and passes it through fsl_md5_update(cx,...).
171  Returns 0 on success, FSL_RC_MISUSE if !cx or !src. If src returns
172  a non-0 code, that code is returned from here.
173 */
174 FSL_EXPORT int fsl_md5_update_stream(fsl_md5_cx *cx, fsl_input_f src, void * srcState);
175 
176 /**
177  Equivalent to fsl_md5_update(cx, b->mem, b->used). Results are undefined
178  if either pointer is invalid or NULL.
179 */
181 
182 /**
183  Passes the first len bytes of str to fsl_md5_update(cx). If len
184  is less than 0 then fsl_strlen() is used to calculate the
185  length. Results are undefined if either pointer is invalid or
186  NULL. This is a no-op if !len or (len<0 && !*str).
187 */
188 FSL_EXPORT void fsl_md5_update_cstr(fsl_md5_cx *cx, char const * str, fsl_int_t len);
189 
190 /**
191  A fsl_md5_update_stream() proxy which updates cx to include the
192  contents of the given file.
193 */
194 FSL_EXPORT int fsl_md5_update_filename(fsl_md5_cx *cx, char const * fname);
195 
196 /**
197  The MD5 counter part to fsl_sha1sum_filename(), with identical
198  semantics except that the generated hash is an MD5 string
199  instead of SHA1.
200 */
201 FSL_EXPORT int fsl_md5sum_filename(const char *zFilename, fsl_buffer *pCksum);
202 
203 
204 /**
205  Holds state for SHA1 calculations. It is intended to be used
206  like this:
207 
208  @code
209  unsigned char digest[20]
210  char hex[FSL_UUID_STRLEN+1];
211  fsl_sha1_cx cx = fsl_sha1_cx_empty;
212  // alternately: fsl_sha1_init(&cx)
213  ...call fsl_sha1_update(&cx,...) any number of times to
214  ...incrementally calculate the hash.
215  fsl_sha1_final(&cx, digest); // ends the calculation
216  fsl_sha1_digest_to_base16(digest, hex);
217  // digest now contains the raw 20-byte SHA1 digest.
218  // hex now contains the 40-byte SHA1 + a trailing NUL
219  @endcode
220 */
221 struct fsl_sha1_cx {
222  unsigned int state[5];
223  unsigned int count[2];
224  unsigned char buffer[64];
225 };
226 /**
227  fsl_sha1_cx instance intended for in-struct copy initialization.
228 */
229 #define fsl_sha1_cx_empty_m { \
230  {0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 }, \
231  {0,0}, \
232  {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, \
233  0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0 \
234  } \
235  }
236 
237 /**
238  fsl_sha1_cx instance intended for copy initialization.
239  Its contents are equivalent to those set by fsl_sha1_init().
240 */
242 
243 /**
244  Initializes the given context with the initial SHA1 state. This
245  must be the first routine called on an SHA1 context, and passing
246  this context to other SHA1 routines without first having passed
247  it to this will lead to undefined results.
248 
249  @see fsl_sha1_update()
250  @see fsl_sha1_final()
251 */
252 FSL_EXPORT void fsl_sha1_init(fsl_sha1_cx *context);
253 
254 /**
255  Updates the given context to include the hash of the first len
256  bytes of the given data.
257 
258  @see fsl_sha1_init()
259  @see fsl_sha1_final()
260 */
261 FSL_EXPORT void fsl_sha1_update( fsl_sha1_cx *context, void const *data, fsl_size_t len);
262 
263 /**
264  Add padding and finalizes the message digest. If digest is not
265  NULL then it writes 20 bytes of digest to the 2nd parameter.
266 
267  @see fsl_sha1_update()
268  @see fsl_sha1_digest_to_base16()
269 */
270 FSL_EXPORT void fsl_sha1_final(fsl_sha1_cx *context, unsigned char * digest);
271 
272 /**
273  Convert a digest into base-16. digest must be at least 20 bytes
274  long and hold an SHA1 digest. zBuf must be at least (FSL_UUID_STRLEN
275  + 1) bytes long, for FSL_UUID_STRLEN characters of
276  hexidecimal-form SHA1 hash and 1 NUL byte.
277 
278  @see fsl_sha1_final()
279 */
280 FSL_EXPORT void fsl_sha1_digest_to_base16(unsigned char *digest, char *zBuf);
281 
282 /**
283  Computes the SHA1 checksum of pIn and stores the resulting
284  checksum in the buffer pCksum. pCksum's memory is re-used if is
285  has any allocated to it. pCksum may == pIn, in which case this
286  is a destructive operation (replacing the hashed data with its
287  hash code).
288 
289  Return 0 on success, FSL_RC_OOM if (re)allocating pCksum fails.
290 */
291 FSL_EXPORT int fsl_sha1sum_buffer(fsl_buffer const *pIn, fsl_buffer *pCksum);
292 
293 /**
294  Computes the SHA1 checksum of the first len bytes of the given
295  string. If len is negative then zInt must be NUL-terminated and
296  fsl_strlen() is used to find its length. The result is a
297  FSL_UUID_STRLEN-byte string (+NUL byte) returned in memory
298  obtained from fsl_malloc(), so it must be passed to fsl_free()
299  to free it. If NULL==zIn or !len then NULL is returned.
300 */
301 FSL_EXPORT char *fsl_sha1sum_cstr(const char *zIn, fsl_int_t len);
302 
303 /**
304  Consumes all input from src and calculates its SHA1 hash. The
305  result is set in pCksum (its contents, if any, are overwritten,
306  not appended to). Returns 0 on success. Returns FSL_RC_MISUSE if
307  !src or !pCksum. It keeps consuming input from src() until that
308  function reads fewer bytes than requested, at which point EOF is
309  assumed. If src() returns non-0, that code is returned from this
310  function.
311 */
312 FSL_EXPORT int fsl_sha1sum_stream(fsl_input_f src, void * srcState, fsl_buffer *pCksum);
313 
314 
315 /**
316  A fsl_sha1sum_stream() wrapper which calculates the SHA1 of
317  given file.
318 
319  Returns FSL_RC_IO if the file cannot be opened, FSL_RC_MISUSE if
320  !zFilename or !pCksum, else as per fsl_sha1sum_stream().
321 
322  TODO: the v1 impl has special behaviour for symlinks which this
323  function lacks. For that support we need a variant of this
324  function which takes a fsl_cx parameter (for the allow-symlinks
325  setting).
326 */
327 FSL_EXPORT int fsl_sha1sum_filename(const char *zFilename, fsl_buffer *pCksum);
328 
329 
330 #if defined(__cplusplus)
331 } /*extern "C"*/
332 #endif
333 #endif
334 /* NET_FOSSIL_SCM_FSL_HASH_H_INCLUDED */
fsl_uint_t fsl_size_t
fsl_size_t is an unsigned integer type used to denote absolute ranges and lengths.
unsigned int count[2]
Definition: fossil-hash.h:223
fsl_uint32_t buf[4]
Definition: fossil-hash.h:82
FSL_EXPORT char * fsl_md5sum_cstr(const char *zIn, fsl_int_t len)
The md5 counterpart of fsl_sha1sum_cstr(), identical in semantics except that its result is an MD5 ha...
FSL_EXPORT void fsl_md5_update(fsl_md5_cx *cx, void const *buf, fsl_size_t len)
Updates cx's state to reflect the addition of the data specified by the range (buf, buf+len].
FSL_EXPORT void fsl_md5_init(fsl_md5_cx *cx)
Initializes the given context pointer.
fsl_hash_constants
Various set-in-stone constants used by the API.
Definition: fossil-hash.h:34
FSL_EXPORT char * fsl_sha1sum_cstr(const char *zIn, fsl_int_t len)
Computes the SHA1 checksum of the first len bytes of the given string.
FSL_EXPORT void fsl_md5_update_cstr(fsl_md5_cx *cx, char const *str, fsl_int_t len)
Passes the first len bytes of str to fsl_md5_update(cx).
#define FSL_EXPORT
Definition: fossil-config.h:19
This file declares a number of utility classes and routines used by libfossil.
FSL_EXPORT const fsl_md5_cx fsl_md5_cx_empty
A fsl_md5_cx instance which holds the initial state used for md5 calculations.
Definition: fossil-hash.h:101
The length, in bytes, of fossil's hex-form UUID strings.
Definition: fossil-hash.h:38
fsl_uint32_t bits[2]
Definition: fossil-hash.h:83
unsigned char buffer[64]
Definition: fossil-hash.h:224
FSL_EXPORT void fsl_md5_final(fsl_md5_cx *cx, unsigned char *digest)
Finishes up the calculation of the md5 for the given context and writes a 16-byte digest value to the...
FSL_EXPORT void fsl_md5_update_buffer(fsl_md5_cx *cx, fsl_buffer const *b)
Equivalent to fsl_md5_update(cx, b->mem, b->used).
A general-purpose buffer class, analog to Fossil v1's Blob class, but it is not called fsl_blob to av...
Definition: fossil-util.h:632
Holds state for MD5 calculations.
Definition: fossil-hash.h:80
FSL_EXPORT int fsl_md5_update_stream(fsl_md5_cx *cx, fsl_input_f src, void *srcState)
Reads all input from src() and passes it through fsl_md5_update(cx,...).
FSL_EXPORT void fsl_sha1_update(fsl_sha1_cx *context, void const *data, fsl_size_t len)
Updates the given context to include the hash of the first len bytes of the given data...
int(* fsl_input_f)(void *state, void *dest, fsl_size_t *n)
Generic interface for streaming in data.
Definition: fossil-util.h:298
unsigned int fsl_uint32_t
Definition: fossil-config.h:82
fsl_int64_t fsl_int_t
fsl_int_t is a signed integer type used to denote "relative" ranges and lengths, or to tell a routine...
FSL_EXPORT int fsl_md5_update_filename(fsl_md5_cx *cx, char const *fname)
A fsl_md5_update_stream() proxy which updates cx to include the contents of the given file...
FSL_EXPORT int fsl_md5sum_buffer(fsl_buffer const *pIn, fsl_buffer *pCksum)
The md5 counterpart of fsl_sha1sum_buffer(), identical in semantics except that its result is an MD5 ...
unsigned int state[5]
Definition: fossil-hash.h:222
FSL_EXPORT int fsl_md5sum_filename(const char *zFilename, fsl_buffer *pCksum)
The MD5 counter part to fsl_sha1sum_filename(), with identical semantics except that the generated ha...
FSL_EXPORT void fsl_sha1_digest_to_base16(unsigned char *digest, char *zBuf)
Convert a digest into base-16.
FSL_EXPORT int fsl_md5sum_stream(fsl_input_f src, void *srcState, fsl_buffer *pCksum)
The MD5 counter part to fsl_sha1sum_stream(), with identical semantics except that the generated hash...
FSL_EXPORT void fsl_sha1_final(fsl_sha1_cx *context, unsigned char *digest)
Add padding and finalizes the message digest.
FSL_EXPORT int fsl_sha1sum_filename(const char *zFilename, fsl_buffer *pCksum)
A fsl_sha1sum_stream() wrapper which calculates the SHA1 of given file.
FSL_EXPORT int fsl_sha1sum_buffer(fsl_buffer const *pIn, fsl_buffer *pCksum)
Computes the SHA1 checksum of pIn and stores the resulting checksum in the buffer pCksum...
FSL_EXPORT void fsl_sha1_init(fsl_sha1_cx *context)
Initializes the given context with the initial SHA1 state.
FSL_EXPORT const fsl_sha1_cx fsl_sha1_cx_empty
fsl_sha1_cx instance intended for copy initialization.
Definition: fossil-hash.h:241
The length, in bytes, of a hex-form MD5 hash.
Definition: fossil-hash.h:42
FSL_EXPORT void fsl_md5_digest_to_base16(unsigned char *digest, char *zBuf)
Converts an md5 digest value (from fsl_md5_final()'s 2nd parameter) to a 32-byte (FSL_MD5_STRLEN) CRC...
Holds state for SHA1 calculations.
Definition: fossil-hash.h:221
unsigned char in[64]
Definition: fossil-hash.h:84
FSL_EXPORT int fsl_sha1sum_stream(fsl_input_f src, void *srcState, fsl_buffer *pCksum)
Consumes all input from src and calculates its SHA1 hash.