Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Kitware
GitHub Repository: Kitware/CMake
Path: blob/master/Utilities/cmlibrhash/librhash/rhash.h
3150 views
1
/** @file rhash.h LibRHash interface */
2
#ifndef RHASH_H
3
#define RHASH_H
4
5
#include <stdio.h>
6
7
#ifdef __cplusplus
8
extern "C" {
9
#endif
10
11
#ifndef RHASH_API
12
/**
13
* Modifier for LibRHash functions
14
*/
15
# define RHASH_API
16
#endif
17
18
/**
19
* Identifiers of supported hash functions.
20
* The rhash_init() function allows mixing several ids using
21
* binary OR, to calculate several hash functions for one message.
22
*/
23
enum rhash_ids
24
{
25
#if 0
26
RHASH_CRC32 = 0x01,
27
RHASH_MD4 = 0x02,
28
RHASH_MD5 = 0x04,
29
RHASH_SHA1 = 0x08,
30
RHASH_TIGER = 0x10,
31
RHASH_TTH = 0x20,
32
RHASH_BTIH = 0x40,
33
RHASH_ED2K = 0x80,
34
RHASH_AICH = 0x100,
35
RHASH_WHIRLPOOL = 0x200,
36
RHASH_RIPEMD160 = 0x400,
37
RHASH_GOST94 = 0x800,
38
RHASH_GOST94_CRYPTOPRO = 0x1000,
39
RHASH_HAS160 = 0x2000,
40
RHASH_GOST12_256 = 0x4000,
41
RHASH_GOST12_512 = 0x8000,
42
RHASH_SHA224 = 0x10000,
43
RHASH_SHA256 = 0x20000,
44
RHASH_SHA384 = 0x40000,
45
RHASH_SHA512 = 0x80000,
46
RHASH_EDONR256 = 0x0100000,
47
RHASH_EDONR512 = 0x0200000,
48
RHASH_SHA3_224 = 0x0400000,
49
RHASH_SHA3_256 = 0x0800000,
50
RHASH_SHA3_384 = 0x1000000,
51
RHASH_SHA3_512 = 0x2000000,
52
RHASH_CRC32C = 0x4000000,
53
RHASH_SNEFRU128 = 0x8000000,
54
RHASH_SNEFRU256 = 0x10000000,
55
RHASH_BLAKE2S = 0x20000000,
56
RHASH_BLAKE2B = 0x40000000,
57
58
/**
59
* The bit-mask containing all supported hash functions.
60
*/
61
RHASH_ALL_HASHES = RHASH_CRC32 | RHASH_CRC32C | RHASH_MD4 | RHASH_MD5 |
62
RHASH_ED2K | RHASH_SHA1 |RHASH_TIGER | RHASH_TTH |
63
RHASH_GOST94 | RHASH_GOST94_CRYPTOPRO | RHASH_GOST12_256 | RHASH_GOST12_512 |
64
RHASH_BTIH | RHASH_AICH | RHASH_WHIRLPOOL | RHASH_RIPEMD160 |
65
RHASH_HAS160 | RHASH_SNEFRU128 | RHASH_SNEFRU256 |
66
RHASH_SHA224 | RHASH_SHA256 | RHASH_SHA384 | RHASH_SHA512 |
67
RHASH_SHA3_224 | RHASH_SHA3_256 | RHASH_SHA3_384 | RHASH_SHA3_512 |
68
RHASH_EDONR256 | RHASH_EDONR512 | RHASH_BLAKE2S | RHASH_BLAKE2B,
69
70
RHASH_GOST = RHASH_GOST94, /* deprecated constant name */
71
RHASH_GOST_CRYPTOPRO = RHASH_GOST94_CRYPTOPRO, /* deprecated constant name */
72
73
/* bit-flag for extra hash identifiers */
74
RHASH_EXTENDED_BIT = (int)0x80000000,
75
76
/**
77
* The number of supported hash functions.
78
*/
79
RHASH_HASH_COUNT = 31
80
#else
81
RHASH_MD5 = 0x01,
82
RHASH_SHA1 = 0x02,
83
RHASH_SHA224 = 0x04,
84
RHASH_SHA256 = 0x08,
85
RHASH_SHA384 = 0x10,
86
RHASH_SHA512 = 0x20,
87
RHASH_SHA3_224 = 0x40,
88
RHASH_SHA3_256 = 0x80,
89
RHASH_SHA3_384 = 0x100,
90
RHASH_SHA3_512 = 0x200,
91
RHASH_ALL_HASHES =
92
RHASH_MD5 |
93
RHASH_SHA1 |
94
RHASH_SHA224 |
95
RHASH_SHA256 |
96
RHASH_SHA384 |
97
RHASH_SHA512 |
98
RHASH_SHA3_224 |
99
RHASH_SHA3_256 |
100
RHASH_SHA3_384 |
101
RHASH_SHA3_512,
102
RHASH_HASH_COUNT = 10
103
#endif
104
};
105
106
/**
107
* The rhash context structure contains contexts for several hash functions.
108
*/
109
struct rhash_context
110
{
111
/**
112
* The size of the hashed message.
113
*/
114
unsigned long long msg_size;
115
116
/**
117
* The bit-mask containing identifiers of the hash functions being calculated.
118
*/
119
unsigned hash_id;
120
};
121
122
#ifndef LIBRHASH_RHASH_CTX_DEFINED
123
#define LIBRHASH_RHASH_CTX_DEFINED
124
/**
125
* Hashing context.
126
*/
127
typedef struct rhash_context* rhash;
128
#endif /* LIBRHASH_RHASH_CTX_DEFINED */
129
130
/**
131
* Type of a callback to be called periodically while hashing a file.
132
*/
133
typedef void (*rhash_callback_t)(void* data, unsigned long long offset);
134
135
/**
136
* Initialize static data of rhash algorithms
137
*/
138
RHASH_API void rhash_library_init(void);
139
140
141
/* HIGH-LEVEL LIBRHASH INTERFACE */
142
143
/**
144
* Compute a message digest of the given message.
145
*
146
* @param hash_id id of message digest to compute
147
* @param message the message to process
148
* @param length message length
149
* @param result buffer to receive the binary message digest value
150
* @return 0 on success, -1 on error
151
*/
152
RHASH_API int rhash_msg(unsigned hash_id, const void* message, size_t length, unsigned char* result);
153
154
/**
155
* Compute a single message digest for the given file.
156
*
157
* @param hash_id id of hash function to compute
158
* @param filepath path to the file to process
159
* @param result buffer to receive message digest
160
* @return 0 on success, -1 on fail with error code stored in errno
161
*/
162
RHASH_API int rhash_file(unsigned hash_id, const char* filepath, unsigned char* result);
163
164
#ifdef _WIN32
165
/**
166
* Compute a single message digest for the given file (Windows-specific function).
167
*
168
* @param hash_id id of hash function to compute
169
* @param filepath path to the file to process
170
* @param result buffer to receive the binary message digest value
171
* @return 0 on success, -1 on fail with error code stored in errno
172
*/
173
RHASH_API int rhash_wfile(unsigned hash_id, const wchar_t* filepath, unsigned char* result);
174
#endif
175
176
177
/* LOW-LEVEL LIBRHASH INTERFACE */
178
179
/**
180
* Allocate and initialize RHash context for calculating a single or multiple hash functions.
181
* The context after usage must be freed by calling rhash_free().
182
*
183
* @param count the size of the hash_ids array, the count must be greater than zero
184
* @param hash_ids array of identifiers of hash functions. Each element must
185
* be an identifier of one hash function
186
* @return initialized rhash context, NULL on fail with error code stored in errno
187
*/
188
RHASH_API rhash rhash_init_multi(size_t count, const unsigned hash_ids[]);
189
190
/**
191
* Allocate and initialize RHash context for calculating a single hash function.
192
*
193
* This function also supports a depricated way to initialize rhash context
194
* for multiple hash functions, by passing a bitwise union of several hash
195
* identifiers. Only single-bit identifiers (not greater than RHASH_SNEFRU256)
196
* can be used in such bitwise union.
197
*
198
* @param hash_id identifier of a hash function
199
* @return initialized rhash context, NULL on fail with error code stored in errno
200
*/
201
RHASH_API rhash rhash_init(unsigned hash_id);
202
203
/**
204
* Calculate message digests of message.
205
* Can be called repeatedly with chunks of the message to be hashed.
206
*
207
* @param ctx the rhash context
208
* @param message message chunk
209
* @param length length of the message chunk
210
* @return 0 on success, -1 on fail with error code stored in errno
211
*/
212
RHASH_API int rhash_update(rhash ctx, const void* message, size_t length);
213
214
/**
215
* Process a file or stream. Multiple message digests can be computed.
216
* First, inintialize ctx parameter with rhash_init() before calling
217
* rhash_file_update(). Then use rhash_final() and rhash_print()
218
* to retrive message digests. Finaly call rhash_free() on ctx
219
* to free allocated memory or call rhash_reset() to reuse ctx.
220
*
221
* @param ctx rhash context
222
* @param fd descriptor of the file to hash
223
* @return 0 on success, -1 on fail with error code stored in errno
224
*/
225
RHASH_API int rhash_file_update(rhash ctx, FILE* fd);
226
227
/**
228
* Finalize message digest calculation and optionally store the first message digest.
229
*
230
* @param ctx the rhash context
231
* @param first_result optional buffer to store a calculated message digest with the lowest available id
232
* @return 0 on success, -1 on fail with error code stored in errno
233
*/
234
RHASH_API int rhash_final(rhash ctx, unsigned char* first_result);
235
236
/**
237
* Re-initialize RHash context to reuse it.
238
* Useful to speed up processing of many small messages.
239
*
240
* @param ctx context to reinitialize
241
*/
242
RHASH_API void rhash_reset(rhash ctx);
243
244
/**
245
* Free RHash context memory.
246
*
247
* @param ctx the context to free
248
*/
249
RHASH_API void rhash_free(rhash ctx);
250
251
/**
252
* Set the callback function to be called from the
253
* rhash_file() and rhash_file_update() functions
254
* on processing every file block. The file block
255
* size is set internally by rhash and now is 8 KiB.
256
*
257
* @param ctx rhash context
258
* @param callback pointer to the callback function
259
* @param callback_data pointer to data passed to the callback
260
*/
261
RHASH_API void rhash_set_callback(rhash ctx, rhash_callback_t callback, void* callback_data);
262
263
/**
264
* Export RHash context data to a memory region.
265
* The size of the memory required for export
266
* is returned by rhash_export(ctx, NULL, 0).
267
*
268
* @param ctx the rhash context to export
269
* @param out pointer to a memory region, or NULL
270
* @param size the size of a memory region
271
* @return the size of exported data on success export.
272
* The size of memory required for export if out is NULL.
273
* 0 on fail with error code stored in errno
274
*/
275
RHASH_API size_t rhash_export(rhash ctx, void* out, size_t size);
276
277
/**
278
* Import rhash context from a memory region.
279
* The returned rhash context must be released after usage
280
* by rhash_free().
281
*
282
* @param in pointer to a memory region
283
* @param size the size of a memory region
284
* @return imported rhash context on success,
285
* NULL on fail with error code stored in errno
286
*/
287
RHASH_API rhash rhash_import(const void* in, size_t size);
288
289
/* INFORMATION FUNCTIONS */
290
291
/**
292
* Returns the number of supported hash algorithms.
293
*
294
* @return the number of supported hash functions
295
*/
296
RHASH_API int rhash_count(void);
297
298
/**
299
* Returns the size of binary message digest for given hash function.
300
*
301
* @param hash_id the id of the hash function
302
* @return the size of the message digest in bytes
303
*/
304
RHASH_API int rhash_get_digest_size(unsigned hash_id);
305
306
/**
307
* Returns the length of message digest string in its default output format.
308
*
309
* @param hash_id the id of the hash function
310
* @return the length of the message digest
311
*/
312
RHASH_API int rhash_get_hash_length(unsigned hash_id);
313
314
/**
315
* Detect default message digest output format for the given hash algorithm.
316
*
317
* @param hash_id the id of hash algorithm
318
* @return 1 for base32 format, 0 for hexadecimal
319
*/
320
RHASH_API int rhash_is_base32(unsigned hash_id);
321
322
/**
323
* Returns the name of the given hash function.
324
*
325
* @param hash_id id of the hash function
326
* @return hash function name
327
*/
328
RHASH_API const char* rhash_get_name(unsigned hash_id); /* get hash function name */
329
330
/**
331
* Returns a name part of magnet urn of the given hash algorithm.
332
* Such magnet_name is used to generate a magnet link of the form
333
* urn:&lt;magnet_name&gt;=&lt;hash_value&gt;.
334
*
335
* @param hash_id id of the hash algorithm
336
* @return name
337
*/
338
RHASH_API const char* rhash_get_magnet_name(unsigned hash_id); /* get name part of magnet urn */
339
340
/* HASH SUM OUTPUT INTERFACE */
341
342
#if 0
343
/**
344
* Flags for printing a message digest.
345
*/
346
enum rhash_print_sum_flags
347
{
348
/*
349
* Print in a default format
350
*/
351
RHPR_DEFAULT = 0x0,
352
/*
353
* Output as binary message digest
354
*/
355
RHPR_RAW = 0x1,
356
/*
357
* Print as a hexadecimal string
358
*/
359
RHPR_HEX = 0x2,
360
/*
361
* Print as a base32-encoded string
362
*/
363
RHPR_BASE32 = 0x3,
364
/*
365
* Print as a base64-encoded string
366
*/
367
RHPR_BASE64 = 0x4,
368
/*
369
* Print as an uppercase string. Can be used
370
* for base32 or hexadecimal format only.
371
*/
372
RHPR_UPPERCASE = 0x8,
373
/*
374
* Reverse message digest bytes. Can be used for GOST hash functions.
375
*/
376
RHPR_REVERSE = 0x10,
377
/*
378
* Don't print 'magnet:?' prefix in rhash_print_magnet
379
*/
380
RHPR_NO_MAGNET = 0x20,
381
/*
382
* Print file size in rhash_print_magnet
383
*/
384
RHPR_FILESIZE = 0x40,
385
/*
386
* Print as URL-encoded string
387
*/
388
RHPR_URLENCODE = 0x80
389
};
390
#endif
391
392
393
/**
394
* Print to the specified buffer the text representation of the given message digest.
395
*
396
* @param output a buffer to print the message digest to
397
* @param bytes a binary message digest to print
398
* @param size a size of the message digest in bytes
399
* @param flags a bit-mask controlling how to format the message digest,
400
* can be a mix of the flags: RHPR_RAW, RHPR_HEX, RHPR_BASE32,
401
* RHPR_BASE64, RHPR_URLENCODE, RHPR_UPPERCASE, RHPR_REVERSE
402
* @return the number of written characters
403
*/
404
RHASH_API size_t rhash_print_bytes(char* output,
405
const unsigned char* bytes, size_t size, int flags);
406
407
/**
408
* Print to the specified output buffer the text representation of the message digest
409
* with the given hash_id. If the hash_id is zero, then print the message digest with
410
* the lowest hash_id calculated by the hash context.
411
* The function call fails if the context doesn't include the message digest with the
412
* given hash_id.
413
*
414
* @param output a buffer to print the message digest to
415
* @param ctx algorithms state
416
* @param hash_id id of the message digest to print or 0 to print the first
417
* message digest saved in the context.
418
* @param flags a bitmask controlling how to print the message digest. Can contain
419
* flags RHPR_UPPERCASE, RHPR_HEX, RHPR_BASE32, RHPR_BASE64, etc.
420
* @return the number of written characters on success or 0 on fail
421
*/
422
RHASH_API size_t rhash_print(char* output, rhash ctx, unsigned hash_id,
423
int flags);
424
425
/**
426
* Print magnet link with given filepath and calculated message digest into the
427
* output buffer. The hash_mask can limit which message digests will be printed.
428
* The function returns the size of the required buffer.
429
* If output is NULL the .
430
*
431
* @param output a string buffer to receive the magnet link or NULL
432
* @param filepath the file path to be printed or NULL
433
* @param context algorithms state
434
* @param hash_mask bit mask of the message digest to add to the link
435
* @param flags can be combination of bits RHPR_UPPERCASE, RHPR_NO_MAGNET,
436
* RHPR_FILESIZE
437
* @return number of written characters, including terminating '\0' on success, 0 on fail
438
*/
439
RHASH_API size_t rhash_print_magnet(char* output, const char* filepath,
440
rhash context, unsigned hash_mask, int flags);
441
442
443
/* MESSAGE API */
444
445
/**
446
* The type of an unsigned integer large enough to hold a pointer.
447
*/
448
#if defined(UINTPTR_MAX)
449
typedef uintptr_t rhash_uptr_t;
450
#elif defined(_LP64) || defined(__LP64__) || defined(__x86_64) || \
451
defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
452
typedef unsigned long long rhash_uptr_t;
453
#else
454
typedef unsigned long rhash_uptr_t;
455
#endif
456
457
/**
458
* The value returned by rhash_transmit on error.
459
*/
460
#define RHASH_ERROR ((rhash_uptr_t)-1)
461
/**
462
* Convert a pointer to rhash_uptr_t.
463
*/
464
#define RHASH_STR2UPTR(str) ((rhash_uptr_t)(char*)(str))
465
/**
466
* Convert a rhash_uptr_t to a void* pointer.
467
*/
468
#define RHASH_UPTR2PVOID(u) ((void*)((u) + 0))
469
470
/**
471
* Process a rhash message.
472
*
473
* @param msg_id message identifier
474
* @param dst message destination (can be NULL for generic messages)
475
* @param ldata data depending on message
476
* @param rdata data depending on message
477
* @return message-specific data
478
*/
479
RHASH_API rhash_uptr_t rhash_transmit(
480
unsigned msg_id, void* dst, rhash_uptr_t ldata, rhash_uptr_t rdata);
481
482
/* rhash message constants */
483
484
#define RMSG_GET_CONTEXT 1
485
#define RMSG_CANCEL 2
486
#define RMSG_IS_CANCELED 3
487
#define RMSG_GET_FINALIZED 4
488
#define RMSG_SET_AUTOFINAL 5
489
#define RMSG_SET_OPENSSL_MASK 10
490
#define RMSG_GET_OPENSSL_MASK 11
491
#define RMSG_GET_OPENSSL_SUPPORTED_MASK 12
492
#define RMSG_GET_OPENSSL_AVAILABLE_MASK 13
493
#define RMSG_GET_LIBRHASH_VERSION 20
494
495
/* HELPER MACROS */
496
497
/**
498
* Get a pointer to the context of the specified hash function.
499
*/
500
#define rhash_get_context_ptr(ctx, hash_id) RHASH_UPTR2PVOID(rhash_transmit(RMSG_GET_CONTEXT, ctx, hash_id, 0))
501
/**
502
* Cancel file processing.
503
*/
504
#define rhash_cancel(ctx) rhash_transmit(RMSG_CANCEL, ctx, 0, 0)
505
/**
506
* Return non-zero if a message digest calculation was canceled, zero otherwise.
507
*/
508
#define rhash_is_canceled(ctx) rhash_transmit(RMSG_IS_CANCELED, ctx, 0, 0)
509
/**
510
* Return non-zero if rhash_final was called for rhash_context.
511
*/
512
#define rhash_get_finalized(ctx) rhash_transmit(RMSG_GET_FINALIZED, ctx, 0, 0)
513
514
/**
515
* Turn on/off the auto-final flag for the given rhash_context. By default
516
* auto-final is on, which means rhash_final is called automatically, if
517
* needed when a message digest is retrieved by rhash_print call.
518
*/
519
#define rhash_set_autofinal(ctx, on) rhash_transmit(RMSG_SET_AUTOFINAL, ctx, on, 0)
520
521
/**
522
* Set the bit-mask of hash algorithms to be calculated by OpenSSL library.
523
* The call rhash_set_openssl_mask(0) made before rhash_library_init(),
524
* turns off loading of the OpenSSL dynamic library.
525
* This call works if the LibRHash was compiled with OpenSSL support.
526
*/
527
#define rhash_set_openssl_mask(mask) rhash_transmit(RMSG_SET_OPENSSL_MASK, NULL, mask, 0)
528
529
/**
530
* Return current bit-mask of hash algorithms selected to be calculated by OpenSSL
531
* library. Return RHASH_ERROR if LibRHash is compiled without OpenSSL support.
532
*/
533
#define rhash_get_openssl_mask() rhash_transmit(RMSG_GET_OPENSSL_MASK, NULL, 0, 0)
534
535
/**
536
* Return the bit-mask of algorithms that can be provided by the OpenSSL plugin,
537
* if the library is compiled with OpenSSL support, 0 otherwise. This bit-mask is
538
* a constant value computed at compile-time.
539
*/
540
#define rhash_get_openssl_supported_mask() rhash_transmit(RMSG_GET_OPENSSL_SUPPORTED_MASK, NULL, 0, 0)
541
542
/**
543
* Return the bit-mask of algorithms that are successfully loaded from
544
* OpenSSL library. If the library is not loaded or not supported by LibRHash,
545
* then return 0.
546
*/
547
#define rhash_get_openssl_available_mask() rhash_transmit(RMSG_GET_OPENSSL_AVAILABLE_MASK, NULL, 0, 0)
548
549
/**
550
* Return librhash version.
551
*/
552
#define rhash_get_version() rhash_transmit(RMSG_GET_LIBRHASH_VERSION, NULL, 0, 0)
553
554
/**
555
* Return non-zero if LibRHash has been compiled with OpenSSL support,
556
* and zero otherwise.
557
*/
558
#define rhash_is_openssl_supported() (rhash_get_openssl_mask() != RHASH_ERROR)
559
560
/**
561
* Legacy macro. The bit mask of hash algorithms implemented by OpenSSL.
562
*/
563
# define RHASH_OPENSSL_SUPPORTED_HASHES (rhash_get_openssl_supported_mask())
564
565
#ifdef __cplusplus
566
} /* extern "C" */
567
#endif /* __cplusplus */
568
569
#endif /* RHASH_H */
570
571