algorithms.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /* algorithms.c - the algorithms supported by the rhash library
  2. *
  3. * Copyright: 2011-2012 Aleksey Kravchenko <rhash.admin@gmail.com>
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a
  6. * copy of this software and associated documentation files (the "Software"),
  7. * to deal in the Software without restriction, including without limitation
  8. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9. * and/or sell copies of the Software, and to permit persons to whom the
  10. * Software is furnished to do so.
  11. *
  12. * This program is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  14. * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk!
  15. */
  16. #include <stdio.h>
  17. #include <assert.h>
  18. #include "byte_order.h"
  19. #include "rhash.h"
  20. #include "algorithms.h"
  21. /* header files of all supported hash sums */
  22. #if 0
  23. #include "aich.h"
  24. #include "crc32.h"
  25. #include "ed2k.h"
  26. #include "edonr.h"
  27. #include "gost.h"
  28. #include "has160.h"
  29. #include "md4.h"
  30. #endif
  31. #include "md5.h"
  32. #if 0
  33. #include "ripemd-160.h"
  34. #include "snefru.h"
  35. #endif
  36. #include "sha1.h"
  37. #include "sha256.h"
  38. #include "sha512.h"
  39. #include "sha3.h"
  40. #if 0
  41. #include "tiger.h"
  42. #include "tth.h"
  43. #include "whirlpool.h"
  44. #endif
  45. #ifdef USE_OPENSSL
  46. /* note: BTIH and AICH depends on the used SHA1 algorithm */
  47. # define NEED_OPENSSL_INIT (RHASH_MD4 | RHASH_MD5 | \
  48. RHASH_SHA1 | RHASH_SHA224 | RHASH_SHA256 | RHASH_SHA384 | RHASH_SHA512 | \
  49. RHASH_BTIH | RHASH_AICH | RHASH_RIPEMD160 | RHASH_WHIRLPOOL)
  50. #else
  51. # define NEED_OPENSSL_INIT 0
  52. #endif /* USE_OPENSSL */
  53. #ifdef GENERATE_GOST_LOOKUP_TABLE
  54. # define NEED_GOST_INIT (RHASH_GOST | RHASH_GOST_CRYPTOPRO)
  55. #else
  56. # define NEED_GOST_INIT 0
  57. #endif /* GENERATE_GOST_LOOKUP_TABLE */
  58. #ifdef GENERATE_CRC32_TABLE
  59. # define NEED_CRC32_INIT RHASH_CRC32
  60. #else
  61. # define NEED_CRC32_INIT 0
  62. #endif /* GENERATE_CRC32_TABLE */
  63. #define RHASH_NEED_INIT_ALG (NEED_CRC32_INIT | NEED_GOST_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. #endif
  72. #if 0
  73. rhash_info info_crc32 = { RHASH_CRC32, F_BE32, 4, "CRC32", "crc32" };
  74. rhash_info info_md4 = { RHASH_MD4, F_LE32, 16, "MD4", "md4" };
  75. #endif
  76. rhash_info info_md5 = { RHASH_MD5, F_LE32, 16, "MD5", "md5" };
  77. rhash_info info_sha1 = { RHASH_SHA1, F_BE32, 20, "SHA1", "sha1" };
  78. #if 0
  79. rhash_info info_tiger = { RHASH_TIGER, F_LE64, 24, "TIGER", "tiger" };
  80. rhash_info info_tth = { RHASH_TTH, F_BS32, 24, "TTH", "tree:tiger" };
  81. rhash_info info_btih = { RHASH_BTIH, 0, 20, "BTIH", "btih" };
  82. rhash_info info_ed2k = { RHASH_ED2K, F_LE32, 16, "ED2K", "ed2k" };
  83. rhash_info info_aich = { RHASH_AICH, F_BS32, 20, "AICH", "aich" };
  84. rhash_info info_whirlpool = { RHASH_WHIRLPOOL, F_BE64, 64, "WHIRLPOOL", "whirlpool" };
  85. rhash_info info_rmd160 = { RHASH_RIPEMD160, F_LE32, 20, "RIPEMD-160", "ripemd160" };
  86. rhash_info info_gost = { RHASH_GOST, F_LE32, 32, "GOST", "gost" };
  87. rhash_info info_gostpro = { RHASH_GOST_CRYPTOPRO, F_LE32, 32, "GOST-CRYPTOPRO", "gost-cryptopro" };
  88. rhash_info info_has160 = { RHASH_HAS160, F_LE32, 20, "HAS-160", "has160" };
  89. rhash_info info_snf128 = { RHASH_SNEFRU128, F_BE32, 16, "SNEFRU-128", "snefru128" };
  90. rhash_info info_snf256 = { RHASH_SNEFRU256, F_BE32, 32, "SNEFRU-256", "snefru256" };
  91. #endif
  92. rhash_info info_sha224 = { RHASH_SHA224, F_BE32, 28, "SHA-224", "sha224" };
  93. rhash_info info_sha256 = { RHASH_SHA256, F_BE32, 32, "SHA-256", "sha256" };
  94. rhash_info info_sha384 = { RHASH_SHA384, F_BE64, 48, "SHA-384", "sha384" };
  95. rhash_info info_sha512 = { RHASH_SHA512, F_BE64, 64, "SHA-512", "sha512" };
  96. #if 0
  97. rhash_info info_edr256 = { RHASH_EDONR256, F_LE32, 32, "EDON-R256", "edon-r256" };
  98. rhash_info info_edr512 = { RHASH_EDONR512, F_LE64, 64, "EDON-R512", "edon-r512" };
  99. #endif
  100. rhash_info info_sha3_224 = { RHASH_SHA3_224, F_LE64, 28, "SHA3-224", "sha3-224" };
  101. rhash_info info_sha3_256 = { RHASH_SHA3_256, F_LE64, 32, "SHA3-256", "sha3-256" };
  102. rhash_info info_sha3_384 = { RHASH_SHA3_384, F_LE64, 48, "SHA3-384", "sha3-384" };
  103. rhash_info info_sha3_512 = { RHASH_SHA3_512, F_LE64, 64, "SHA3-512", "sha3-512" };
  104. /* some helper macros */
  105. #define dgshft(name) (((char*)&((name##_ctx*)0)->hash) - (char*)0)
  106. #define dgshft2(name, field) (((char*)&((name##_ctx*)0)->field) - (char*)0)
  107. #define ini(name) ((pinit_t)(name##_init))
  108. #define upd(name) ((pupdate_t)(name##_update))
  109. #define fin(name) ((pfinal_t)(name##_final))
  110. #define iuf(name) ini(name), upd(name), fin(name)
  111. #define diuf(name) dgshft(name), ini(name), upd(name), fin(name)
  112. /* information about all hashes */
  113. rhash_hash_info rhash_hash_info_default[RHASH_HASH_COUNT] =
  114. {
  115. #if 0
  116. { &info_crc32, sizeof(uint32_t), 0, iuf(rhash_crc32), 0 }, /* 32 bit */
  117. { &info_md4, sizeof(md4_ctx), dgshft(md4), iuf(rhash_md4), 0 }, /* 128 bit */
  118. #endif
  119. { &info_md5, sizeof(md5_ctx), dgshft(md5), iuf(rhash_md5), 0 }, /* 128 bit */
  120. { &info_sha1, sizeof(sha1_ctx), dgshft(sha1), iuf(rhash_sha1), 0 }, /* 160 bit */
  121. #if 0
  122. { &info_tiger, sizeof(tiger_ctx), dgshft(tiger), iuf(rhash_tiger), 0 }, /* 192 bit */
  123. { &info_tth, sizeof(tth_ctx), dgshft2(tth, tiger.hash), iuf(rhash_tth), 0 }, /* 192 bit */
  124. { &info_ed2k, sizeof(ed2k_ctx), dgshft2(ed2k, md4_context_inner.hash), iuf(rhash_ed2k), 0 }, /* 128 bit */
  125. { &info_aich, sizeof(aich_ctx), dgshft2(aich, sha1_context.hash), iuf(rhash_aich), (pcleanup_t)rhash_aich_cleanup }, /* 160 bit */
  126. { &info_whirlpool, sizeof(whirlpool_ctx), dgshft(whirlpool), iuf(rhash_whirlpool), 0 }, /* 512 bit */
  127. { &info_rmd160, sizeof(ripemd160_ctx), dgshft(ripemd160), iuf(rhash_ripemd160), 0 }, /* 160 bit */
  128. { &info_gost, sizeof(gost_ctx), dgshft(gost), iuf(rhash_gost), 0 }, /* 256 bit */
  129. { &info_gostpro, sizeof(gost_ctx), dgshft(gost), ini(rhash_gost_cryptopro), upd(rhash_gost), fin(rhash_gost), 0 }, /* 256 bit */
  130. { &info_has160, sizeof(has160_ctx), dgshft(has160), iuf(rhash_has160), 0 }, /* 160 bit */
  131. { &info_snf128, sizeof(snefru_ctx), dgshft(snefru), ini(rhash_snefru128), upd(rhash_snefru), fin(rhash_snefru), 0 }, /* 128 bit */
  132. { &info_snf256, sizeof(snefru_ctx), dgshft(snefru), ini(rhash_snefru256), upd(rhash_snefru), fin(rhash_snefru), 0 }, /* 256 bit */
  133. #endif
  134. { &info_sha224, sizeof(sha256_ctx), dgshft(sha256), ini(rhash_sha224), upd(rhash_sha256), fin(rhash_sha256), 0 }, /* 224 bit */
  135. { &info_sha256, sizeof(sha256_ctx), dgshft(sha256), iuf(rhash_sha256), 0 }, /* 256 bit */
  136. { &info_sha384, sizeof(sha512_ctx), dgshft(sha512), ini(rhash_sha384), upd(rhash_sha512), fin(rhash_sha512), 0 }, /* 384 bit */
  137. { &info_sha512, sizeof(sha512_ctx), dgshft(sha512), iuf(rhash_sha512), 0 }, /* 512 bit */
  138. #if 0
  139. { &info_edr256, sizeof(edonr_ctx), dgshft2(edonr, u.data256.hash) + 32, iuf(rhash_edonr256), 0 }, /* 256 bit */
  140. { &info_edr512, sizeof(edonr_ctx), dgshft2(edonr, u.data512.hash) + 64, iuf(rhash_edonr512), 0 }, /* 512 bit */
  141. #endif
  142. { &info_sha3_224, sizeof(sha3_ctx), dgshft(sha3), ini(rhash_sha3_224), upd(rhash_sha3), fin(rhash_sha3), 0 }, /* 224 bit */
  143. { &info_sha3_256, sizeof(sha3_ctx), dgshft(sha3), ini(rhash_sha3_256), upd(rhash_sha3), fin(rhash_sha3), 0 }, /* 256 bit */
  144. { &info_sha3_384, sizeof(sha3_ctx), dgshft(sha3), ini(rhash_sha3_384), upd(rhash_sha3), fin(rhash_sha3), 0 }, /* 384 bit */
  145. { &info_sha3_512, sizeof(sha3_ctx), dgshft(sha3), ini(rhash_sha3_512), upd(rhash_sha3), fin(rhash_sha3), 0 }, /* 512 bit */
  146. };
  147. /**
  148. * Initialize requested algorithms.
  149. */
  150. void rhash_init_algorithms(unsigned mask)
  151. {
  152. (void)mask; /* unused now */
  153. /* verify that RHASH_HASH_COUNT is the index of the major bit of RHASH_ALL_HASHES */
  154. assert(1 == (RHASH_ALL_HASHES >> (RHASH_HASH_COUNT - 1)));
  155. #ifdef GENERATE_CRC32_TABLE
  156. rhash_crc32_init_table();
  157. #endif
  158. #ifdef GENERATE_GOST_LOOKUP_TABLE
  159. rhash_gost_init_table();
  160. #endif
  161. rhash_uninitialized_algorithms = 0;
  162. }
  163. #if 0
  164. /* CRC32 helper functions */
  165. /**
  166. * Initialize crc32 hash.
  167. *
  168. * @param crc32 pointer to the hash to initialize
  169. */
  170. static void rhash_crc32_init(uint32_t* crc32)
  171. {
  172. *crc32 = 0; /* note: context size is sizeof(uint32_t) */
  173. }
  174. /**
  175. * Calculate message CRC32 hash.
  176. * Can be called repeatedly with chunks of the message to be hashed.
  177. *
  178. * @param crc32 pointer to the hash
  179. * @param msg message chunk
  180. * @param size length of the message chunk
  181. */
  182. static void rhash_crc32_update(uint32_t* crc32, const unsigned char* msg, size_t size)
  183. {
  184. *crc32 = rhash_get_crc32(*crc32, msg, size);
  185. }
  186. /**
  187. * Store calculated hash into the given array.
  188. *
  189. * @param crc32 pointer to the current hash value
  190. * @param result calculated hash in binary form
  191. */
  192. static void rhash_crc32_final(uint32_t* crc32, unsigned char* result)
  193. {
  194. #if defined(CPU_IA32) || defined(CPU_X64)
  195. /* intel CPUs support assigment with non 32-bit aligned pointers */
  196. *(unsigned*)result = be2me_32(*crc32);
  197. #else
  198. /* correct saving BigEndian integer on all archs */
  199. result[0] = (unsigned char)(*crc32 >> 24), result[1] = (unsigned char)(*crc32 >> 16);
  200. result[2] = (unsigned char)(*crc32 >> 8), result[3] = (unsigned char)(*crc32);
  201. #endif
  202. }
  203. #endif