algorithms.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. /* algorithms.c - the algorithms supported by the rhash library
  2. *
  3. * Copyright (c) 2011, Aleksey Kravchenko <[email protected]>
  4. *
  5. * Permission to use, copy, modify, and/or distribute this software for any
  6. * purpose with or without fee is hereby granted.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
  9. * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  10. * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
  11. * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  12. * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  13. * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  14. * PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #include "algorithms.h"
  17. #include "byte_order.h"
  18. #include "rhash.h"
  19. /* header files of all supported hash functions */
  20. #if 0
  21. #include "aich.h"
  22. #include "blake2b.h"
  23. #include "blake2s.h"
  24. #include "crc32.h"
  25. #include "ed2k.h"
  26. #include "edonr.h"
  27. #include "gost12.h"
  28. #include "gost94.h"
  29. #include "has160.h"
  30. #include "md4.h"
  31. #endif
  32. #include "md5.h"
  33. #if 0
  34. #include "ripemd-160.h"
  35. #include "snefru.h"
  36. #endif
  37. #include "sha1.h"
  38. #include "sha256.h"
  39. #include "sha512.h"
  40. #include "sha3.h"
  41. #if 0
  42. #include "tiger.h"
  43. #include "tth.h"
  44. #include "whirlpool.h"
  45. #endif
  46. #ifdef USE_OPENSSL
  47. # include "plug_openssl.h"
  48. #endif /* USE_OPENSSL */
  49. #include <assert.h>
  50. #ifdef USE_OPENSSL
  51. /* note: BTIH and AICH depends on the used SHA1 algorithm */
  52. # define NEED_OPENSSL_INIT (RHASH_MD4 | RHASH_MD5 | \
  53. RHASH_SHA1 | RHASH_SHA224 | RHASH_SHA256 | RHASH_SHA384 | RHASH_SHA512 | \
  54. RHASH_BTIH | RHASH_AICH | RHASH_RIPEMD160 | RHASH_WHIRLPOOL)
  55. #else
  56. # define NEED_OPENSSL_INIT 0
  57. #endif /* USE_OPENSSL */
  58. #ifdef GENERATE_GOST94_LOOKUP_TABLE
  59. # define NEED_GOST94_INIT (RHASH_GOST94 | RHASH_GOST94_CRYPTOPRO)
  60. #else
  61. # define NEED_GOST94_INIT 0
  62. #endif /* GENERATE_GOST94_LOOKUP_TABLE */
  63. #define RHASH_NEED_INIT_ALG (NEED_GOST94_INIT | NEED_OPENSSL_INIT)
  64. unsigned rhash_uninitialized_algorithms = RHASH_NEED_INIT_ALG;
  65. rhash_hash_info* rhash_info_table = rhash_hash_info_default;
  66. int rhash_info_size = RHASH_HASH_COUNT;
  67. #if 0
  68. static void rhash_crc32_init(uint32_t* crc32);
  69. static void rhash_crc32_update(uint32_t* crc32, const unsigned char* msg, size_t size);
  70. static void rhash_crc32_final(uint32_t* crc32, unsigned char* result);
  71. static void rhash_crc32c_init(uint32_t* crc32);
  72. static void rhash_crc32c_update(uint32_t* crc32, const unsigned char* msg, size_t size);
  73. static void rhash_crc32c_final(uint32_t* crc32, unsigned char* result);
  74. #endif
  75. #if 0
  76. rhash_info info_crc32 = { RHASH_CRC32, F_BE32, 4, "CRC32", "crc32" };
  77. rhash_info info_crc32c = { RHASH_CRC32C, F_BE32, 4, "CRC32C", "crc32c" };
  78. rhash_info info_md4 = { RHASH_MD4, F_LE32, 16, "MD4", "md4" };
  79. #endif
  80. rhash_info info_md5 = { RHASH_MD5, F_LE32, 16, "MD5", "md5" };
  81. rhash_info info_sha1 = { RHASH_SHA1, F_BE32, 20, "SHA1", "sha1" };
  82. #if 0
  83. rhash_info info_tiger = { RHASH_TIGER, F_LE64, 24, "TIGER", "tiger" };
  84. rhash_info info_tth = { RHASH_TTH, F_BS32 | F_SPCEXP, 24, "TTH", "tree:tiger" };
  85. rhash_info info_btih = { RHASH_BTIH, F_SPCEXP, 20, "BTIH", "btih" };
  86. rhash_info info_ed2k = { RHASH_ED2K, F_LE32, 16, "ED2K", "ed2k" };
  87. rhash_info info_aich = { RHASH_AICH, F_BS32 | F_SPCEXP, 20, "AICH", "aich" };
  88. rhash_info info_whirlpool = { RHASH_WHIRLPOOL, F_BE64, 64, "WHIRLPOOL", "whirlpool" };
  89. rhash_info info_rmd160 = { RHASH_RIPEMD160, F_LE32, 20, "RIPEMD-160", "ripemd160" };
  90. rhash_info info_gost12_256 = { RHASH_GOST12_256, F_LE64, 32, "GOST12-256", "gost12-256" };
  91. rhash_info info_gost12_512 = { RHASH_GOST12_512, F_LE64, 64, "GOST12-512", "gost12-512" };
  92. rhash_info info_gost94 = { RHASH_GOST94, F_LE32, 32, "GOST94", "gost94" };
  93. rhash_info info_gost94pro = { RHASH_GOST94_CRYPTOPRO, F_LE32, 32, "GOST94-CRYPTOPRO", "gost94-cryptopro" };
  94. rhash_info info_has160 = { RHASH_HAS160, F_LE32, 20, "HAS-160", "has160" };
  95. rhash_info info_snf128 = { RHASH_SNEFRU128, F_BE32, 16, "SNEFRU-128", "snefru128" };
  96. rhash_info info_snf256 = { RHASH_SNEFRU256, F_BE32, 32, "SNEFRU-256", "snefru256" };
  97. #endif
  98. rhash_info info_sha224 = { RHASH_SHA224, F_BE32, 28, "SHA-224", "sha224" };
  99. rhash_info info_sha256 = { RHASH_SHA256, F_BE32, 32, "SHA-256", "sha256" };
  100. rhash_info info_sha384 = { RHASH_SHA384, F_BE64, 48, "SHA-384", "sha384" };
  101. rhash_info info_sha512 = { RHASH_SHA512, F_BE64, 64, "SHA-512", "sha512" };
  102. #if 0
  103. rhash_info info_edr256 = { RHASH_EDONR256, F_LE32, 32, "EDON-R256", "edon-r256" };
  104. rhash_info info_edr512 = { RHASH_EDONR512, F_LE64, 64, "EDON-R512", "edon-r512" };
  105. rhash_info info_blake2s = { RHASH_BLAKE2S, F_LE32, 32, "BLAKE2S", "blake2s" };
  106. rhash_info info_blake2b = { RHASH_BLAKE2B, F_LE64, 64, "BLAKE2B", "blake2b" };
  107. #endif
  108. rhash_info info_sha3_224 = { RHASH_SHA3_224, F_LE64, 28, "SHA3-224", "sha3-224" };
  109. rhash_info info_sha3_256 = { RHASH_SHA3_256, F_LE64, 32, "SHA3-256", "sha3-256" };
  110. rhash_info info_sha3_384 = { RHASH_SHA3_384, F_LE64, 48, "SHA3-384", "sha3-384" };
  111. rhash_info info_sha3_512 = { RHASH_SHA3_512, F_LE64, 64, "SHA3-512", "sha3-512" };
  112. /* some helper macros */
  113. #define dgshft(name) ((uintptr_t)((char*)&((name##_ctx*)0)->hash))
  114. #define dgshft2(name, field) ((uintptr_t)((char*)&((name##_ctx*)0)->field))
  115. #define ini(name) ((pinit_t)(name##_init))
  116. #define upd(name) ((pupdate_t)(name##_update))
  117. #define fin(name) ((pfinal_t)(name##_final))
  118. #define iuf(name) ini(name), upd(name), fin(name)
  119. #define iuf2(name1, name2) ini(name1), upd(name2), fin(name2)
  120. /* information about all supported hash functions */
  121. rhash_hash_info rhash_hash_info_default[RHASH_HASH_COUNT] =
  122. {
  123. #if 0
  124. { &info_crc32, sizeof(uint32_t), 0, iuf(rhash_crc32), 0 }, /* 32 bit */
  125. { &info_md4, sizeof(md4_ctx), dgshft(md4), iuf(rhash_md4), 0 }, /* 128 bit */
  126. #endif
  127. { &info_md5, sizeof(md5_ctx), dgshft(md5), iuf(rhash_md5), 0 }, /* 128 bit */
  128. { &info_sha1, sizeof(sha1_ctx), dgshft(sha1), iuf(rhash_sha1), 0 }, /* 160 bit */
  129. #if 0
  130. { &info_tiger, sizeof(tiger_ctx), dgshft(tiger), iuf(rhash_tiger), 0 }, /* 192 bit */
  131. { &info_tth, sizeof(tth_ctx), dgshft2(tth, tiger.hash), iuf(rhash_tth), 0 }, /* 192 bit */
  132. { &info_ed2k, sizeof(ed2k_ctx), dgshft2(ed2k, md4_context_inner.hash), iuf(rhash_ed2k), 0 }, /* 128 bit */
  133. { &info_aich, sizeof(aich_ctx), dgshft2(aich, sha1_context.hash), iuf(rhash_aich), (pcleanup_t)rhash_aich_cleanup }, /* 160 bit */
  134. { &info_whirlpool, sizeof(whirlpool_ctx), dgshft(whirlpool), iuf(rhash_whirlpool), 0 }, /* 512 bit */
  135. { &info_rmd160, sizeof(ripemd160_ctx), dgshft(ripemd160), iuf(rhash_ripemd160), 0 }, /* 160 bit */
  136. { &info_gost94, sizeof(gost94_ctx), dgshft(gost94), iuf(rhash_gost94), 0 }, /* 256 bit */
  137. { &info_gost94pro, sizeof(gost94_ctx), dgshft(gost94), iuf2(rhash_gost94_cryptopro, rhash_gost94), 0 }, /* 256 bit */
  138. { &info_has160, sizeof(has160_ctx), dgshft(has160), iuf(rhash_has160), 0 }, /* 160 bit */
  139. { &info_gost12_256, sizeof(gost12_ctx), dgshft2(gost12, h) + 32, iuf2(rhash_gost12_256, rhash_gost12), 0 }, /* 256 bit */
  140. { &info_gost12_512, sizeof(gost12_ctx), dgshft2(gost12, h), iuf2(rhash_gost12_512, rhash_gost12), 0 }, /* 512 bit */
  141. #endif
  142. { &info_sha224, sizeof(sha256_ctx), dgshft(sha256), iuf2(rhash_sha224, rhash_sha256), 0 }, /* 224 bit */
  143. { &info_sha256, sizeof(sha256_ctx), dgshft(sha256), iuf(rhash_sha256), 0 }, /* 256 bit */
  144. { &info_sha384, sizeof(sha512_ctx), dgshft(sha512), iuf2(rhash_sha384, rhash_sha512), 0 }, /* 384 bit */
  145. { &info_sha512, sizeof(sha512_ctx), dgshft(sha512), iuf(rhash_sha512), 0 }, /* 512 bit */
  146. #if 0
  147. { &info_edr256, sizeof(edonr_ctx), dgshft2(edonr, u.data256.hash) + 32, iuf(rhash_edonr256), 0 }, /* 256 bit */
  148. { &info_edr512, sizeof(edonr_ctx), dgshft2(edonr, u.data512.hash) + 64, iuf(rhash_edonr512), 0 }, /* 512 bit */
  149. #endif
  150. { &info_sha3_224, sizeof(sha3_ctx), dgshft(sha3), iuf2(rhash_sha3_224, rhash_sha3), 0 }, /* 224 bit */
  151. { &info_sha3_256, sizeof(sha3_ctx), dgshft(sha3), iuf2(rhash_sha3_256, rhash_sha3), 0 }, /* 256 bit */
  152. { &info_sha3_384, sizeof(sha3_ctx), dgshft(sha3), iuf2(rhash_sha3_384, rhash_sha3), 0 }, /* 384 bit */
  153. { &info_sha3_512, sizeof(sha3_ctx), dgshft(sha3), iuf2(rhash_sha3_512, rhash_sha3), 0 }, /* 512 bit */
  154. #if 0
  155. { &info_crc32c, sizeof(uint32_t), 0, iuf(rhash_crc32c), 0 }, /* 32 bit */
  156. { &info_snf128, sizeof(snefru_ctx), dgshft(snefru), iuf2(rhash_snefru128, rhash_snefru), 0 }, /* 128 bit */
  157. { &info_snf256, sizeof(snefru_ctx), dgshft(snefru), iuf2(rhash_snefru256, rhash_snefru), 0 }, /* 256 bit */
  158. { &info_blake2s, sizeof(blake2s_ctx), dgshft(blake2s), iuf(rhash_blake2s), 0 }, /* 256 bit */
  159. { &info_blake2b, sizeof(blake2b_ctx), dgshft(blake2b), iuf(rhash_blake2b), 0 }, /* 512 bit */
  160. #endif
  161. };
  162. /**
  163. * Initialize requested algorithms.
  164. *
  165. * @param mask ids of hash sums to initialize
  166. */
  167. void rhash_init_algorithms(unsigned mask)
  168. {
  169. (void)mask; /* unused now */
  170. /* verify that RHASH_HASH_COUNT is the index of the major bit of RHASH_ALL_HASHES */
  171. assert(1 == (RHASH_ALL_HASHES >> (RHASH_HASH_COUNT - 1)));
  172. #ifdef GENERATE_GOST94_LOOKUP_TABLE
  173. rhash_gost94_init_table();
  174. #endif
  175. rhash_uninitialized_algorithms = 0;
  176. }
  177. /**
  178. * Returns information about a hash function by its hash_id.
  179. *
  180. * @param hash_id the id of hash algorithm
  181. * @return pointer to the rhash_info structure containing the information
  182. */
  183. const rhash_info* rhash_info_by_id(unsigned hash_id)
  184. {
  185. hash_id &= RHASH_ALL_HASHES;
  186. /* check that one and only one bit is set */
  187. if (!hash_id || (hash_id & (hash_id - 1)) != 0) return NULL;
  188. return rhash_info_table[rhash_ctz(hash_id)].info;
  189. }
  190. #if 0
  191. /* CRC32 helper functions */
  192. /**
  193. * Initialize crc32 hash.
  194. *
  195. * @param crc32 pointer to the hash to initialize
  196. */
  197. static void rhash_crc32_init(uint32_t* crc32)
  198. {
  199. *crc32 = 0; /* note: context size is sizeof(uint32_t) */
  200. }
  201. /**
  202. * Calculate message CRC32 hash.
  203. * Can be called repeatedly with chunks of the message to be hashed.
  204. *
  205. * @param crc32 pointer to the hash
  206. * @param msg message chunk
  207. * @param size length of the message chunk
  208. */
  209. static void rhash_crc32_update(uint32_t* crc32, const unsigned char* msg, size_t size)
  210. {
  211. *crc32 = rhash_get_crc32(*crc32, msg, size);
  212. }
  213. /**
  214. * Store calculated hash into the given array.
  215. *
  216. * @param crc32 pointer to the current hash value
  217. * @param result calculated hash in binary form
  218. */
  219. static void rhash_crc32_final(uint32_t* crc32, unsigned char* result)
  220. {
  221. #if defined(CPU_IA32) || defined(CPU_X64)
  222. /* intel CPUs support assigment with non 32-bit aligned pointers */
  223. *(unsigned*)result = be2me_32(*crc32);
  224. #else
  225. /* correct saving BigEndian integer on all archs */
  226. result[0] = (unsigned char)(*crc32 >> 24), result[1] = (unsigned char)(*crc32 >> 16);
  227. result[2] = (unsigned char)(*crc32 >> 8), result[3] = (unsigned char)(*crc32);
  228. #endif
  229. }
  230. /**
  231. * Initialize crc32c hash.
  232. *
  233. * @param crc32c pointer to the hash to initialize
  234. */
  235. static void rhash_crc32c_init(uint32_t* crc32c)
  236. {
  237. *crc32c = 0; /* note: context size is sizeof(uint32_t) */
  238. }
  239. /**
  240. * Calculate message CRC32C hash.
  241. * Can be called repeatedly with chunks of the message to be hashed.
  242. *
  243. * @param crc32c pointer to the hash
  244. * @param msg message chunk
  245. * @param size length of the message chunk
  246. */
  247. static void rhash_crc32c_update(uint32_t* crc32c, const unsigned char* msg, size_t size)
  248. {
  249. *crc32c = rhash_get_crc32c(*crc32c, msg, size);
  250. }
  251. /**
  252. * Store calculated hash into the given array.
  253. *
  254. * @param crc32c pointer to the current hash value
  255. * @param result calculated hash in binary form
  256. */
  257. static void rhash_crc32c_final(uint32_t* crc32c, unsigned char* result)
  258. {
  259. #if defined(CPU_IA32) || defined(CPU_X64)
  260. /* intel CPUs support assigment with non 32-bit aligned pointers */
  261. *(unsigned*)result = be2me_32(*crc32c);
  262. #else
  263. /* correct saving BigEndian integer on all archs */
  264. result[0] = (unsigned char)(*crc32c >> 24), result[1] = (unsigned char)(*crc32c >> 16);
  265. result[2] = (unsigned char)(*crc32c >> 8), result[3] = (unsigned char)(*crc32c);
  266. #endif
  267. }
  268. #endif
  269. #if !defined(NO_IMPORT_EXPORT)
  270. /**
  271. * Export a hash function context to a memory region,
  272. * or calculate the size required for context export.
  273. *
  274. * @param hash_id identifier of the hash function
  275. * @param ctx the algorithm context containing current hashing state
  276. * @param out pointer to the memory region or NULL
  277. * @param size size of memory region
  278. * @return the size of the exported data on success, 0 on fail.
  279. */
  280. size_t rhash_export_alg(unsigned hash_id, const void* ctx, void* out, size_t size)
  281. {
  282. switch (hash_id)
  283. {
  284. case RHASH_TTH:
  285. return rhash_tth_export((const tth_ctx*)ctx, out, size);
  286. case RHASH_AICH:
  287. return rhash_aich_export((const aich_ctx*)ctx, out, size);
  288. }
  289. return 0;
  290. }
  291. /**
  292. * Import a hash function context from a memory region.
  293. *
  294. * @param hash_id identifier of the hash function
  295. * @param ctx pointer to the algorithm context
  296. * @param in pointer to the data to import
  297. * @param size size of data to import
  298. * @return the size of the imported data on success, 0 on fail.
  299. */
  300. size_t rhash_import_alg(unsigned hash_id, void* ctx, const void* in, size_t size)
  301. {
  302. switch (hash_id)
  303. {
  304. case RHASH_TTH:
  305. return rhash_tth_import((tth_ctx*)ctx, in, size);
  306. case RHASH_AICH:
  307. return rhash_aich_import((aich_ctx*)ctx, in, size);
  308. }
  309. return 0;
  310. }
  311. #endif /* !defined(NO_IMPORT_EXPORT) */
  312. #ifdef USE_OPENSSL
  313. void rhash_load_sha1_methods(rhash_hashing_methods* methods, int methods_type)
  314. {
  315. int use_openssl;
  316. switch (methods_type) {
  317. case METHODS_OPENSSL:
  318. use_openssl = 1;
  319. break;
  320. case METHODS_SELECTED:
  321. assert(rhash_info_table[3].info->hash_id == RHASH_SHA1);
  322. use_openssl = ARE_OPENSSL_METHODS(rhash_info_table[3]);
  323. break;
  324. default:
  325. use_openssl = 0;
  326. break;
  327. }
  328. if (use_openssl) {
  329. methods->init = rhash_ossl_sha1_init();
  330. methods->update = rhash_ossl_sha1_update();
  331. methods->final = rhash_ossl_sha1_final();
  332. } else {
  333. methods->init = (pinit_t)&rhash_sha1_init;
  334. methods->update = (pupdate_t)&rhash_sha1_update;
  335. methods->final = (pfinal_t)&rhash_sha1_final;
  336. }
  337. }
  338. #endif