rhash.h 17 KB

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