rhash.h 15 KB

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