md32_common.h 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. #include <contrib/libs/openssl/redef.h>
  2. /*
  3. * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved.
  4. *
  5. * Licensed under the OpenSSL license (the "License"). You may not use
  6. * this file except in compliance with the License. You can obtain a copy
  7. * in the file LICENSE in the source distribution or at
  8. * https://www.openssl.org/source/license.html
  9. */
  10. /*-
  11. * This is a generic 32 bit "collector" for message digest algorithms.
  12. * Whenever needed it collects input character stream into chunks of
  13. * 32 bit values and invokes a block function that performs actual hash
  14. * calculations.
  15. *
  16. * Porting guide.
  17. *
  18. * Obligatory macros:
  19. *
  20. * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN
  21. * this macro defines byte order of input stream.
  22. * HASH_CBLOCK
  23. * size of a unit chunk HASH_BLOCK operates on.
  24. * HASH_LONG
  25. * has to be at least 32 bit wide.
  26. * HASH_CTX
  27. * context structure that at least contains following
  28. * members:
  29. * typedef struct {
  30. * ...
  31. * HASH_LONG Nl,Nh;
  32. * either {
  33. * HASH_LONG data[HASH_LBLOCK];
  34. * unsigned char data[HASH_CBLOCK];
  35. * };
  36. * unsigned int num;
  37. * ...
  38. * } HASH_CTX;
  39. * data[] vector is expected to be zeroed upon first call to
  40. * HASH_UPDATE.
  41. * HASH_UPDATE
  42. * name of "Update" function, implemented here.
  43. * HASH_TRANSFORM
  44. * name of "Transform" function, implemented here.
  45. * HASH_FINAL
  46. * name of "Final" function, implemented here.
  47. * HASH_BLOCK_DATA_ORDER
  48. * name of "block" function capable of treating *unaligned* input
  49. * message in original (data) byte order, implemented externally.
  50. * HASH_MAKE_STRING
  51. * macro converting context variables to an ASCII hash string.
  52. *
  53. * MD5 example:
  54. *
  55. * #define DATA_ORDER_IS_LITTLE_ENDIAN
  56. *
  57. * #define HASH_LONG MD5_LONG
  58. * #define HASH_CTX MD5_CTX
  59. * #define HASH_CBLOCK MD5_CBLOCK
  60. * #define HASH_UPDATE MD5_Update
  61. * #define HASH_TRANSFORM MD5_Transform
  62. * #define HASH_FINAL MD5_Final
  63. * #define HASH_BLOCK_DATA_ORDER md5_block_data_order
  64. */
  65. #include <openssl/crypto.h>
  66. #if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN)
  67. # error "DATA_ORDER must be defined!"
  68. #endif
  69. #ifndef HASH_CBLOCK
  70. # error "HASH_CBLOCK must be defined!"
  71. #endif
  72. #ifndef HASH_LONG
  73. # error "HASH_LONG must be defined!"
  74. #endif
  75. #ifndef HASH_CTX
  76. # error "HASH_CTX must be defined!"
  77. #endif
  78. #ifndef HASH_UPDATE
  79. # error "HASH_UPDATE must be defined!"
  80. #endif
  81. #ifndef HASH_TRANSFORM
  82. # error "HASH_TRANSFORM must be defined!"
  83. #endif
  84. #ifndef HASH_FINAL
  85. # error "HASH_FINAL must be defined!"
  86. #endif
  87. #ifndef HASH_BLOCK_DATA_ORDER
  88. # error "HASH_BLOCK_DATA_ORDER must be defined!"
  89. #endif
  90. #define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
  91. #if defined(DATA_ORDER_IS_BIG_ENDIAN)
  92. # define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \
  93. l|=(((unsigned long)(*((c)++)))<<16), \
  94. l|=(((unsigned long)(*((c)++)))<< 8), \
  95. l|=(((unsigned long)(*((c)++))) ) )
  96. # define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
  97. *((c)++)=(unsigned char)(((l)>>16)&0xff), \
  98. *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
  99. *((c)++)=(unsigned char)(((l) )&0xff), \
  100. l)
  101. #elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
  102. # define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \
  103. l|=(((unsigned long)(*((c)++)))<< 8), \
  104. l|=(((unsigned long)(*((c)++)))<<16), \
  105. l|=(((unsigned long)(*((c)++)))<<24) )
  106. # define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
  107. *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
  108. *((c)++)=(unsigned char)(((l)>>16)&0xff), \
  109. *((c)++)=(unsigned char)(((l)>>24)&0xff), \
  110. l)
  111. #endif
  112. /*
  113. * Time for some action :-)
  114. */
  115. int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len)
  116. {
  117. const unsigned char *data = data_;
  118. unsigned char *p;
  119. HASH_LONG l;
  120. size_t n;
  121. if (len == 0)
  122. return 1;
  123. l = (c->Nl + (((HASH_LONG) len) << 3)) & 0xffffffffUL;
  124. if (l < c->Nl) /* overflow */
  125. c->Nh++;
  126. c->Nh += (HASH_LONG) (len >> 29); /* might cause compiler warning on
  127. * 16-bit */
  128. c->Nl = l;
  129. n = c->num;
  130. if (n != 0) {
  131. p = (unsigned char *)c->data;
  132. if (len >= HASH_CBLOCK || len + n >= HASH_CBLOCK) {
  133. memcpy(p + n, data, HASH_CBLOCK - n);
  134. HASH_BLOCK_DATA_ORDER(c, p, 1);
  135. n = HASH_CBLOCK - n;
  136. data += n;
  137. len -= n;
  138. c->num = 0;
  139. /*
  140. * We use memset rather than OPENSSL_cleanse() here deliberately.
  141. * Using OPENSSL_cleanse() here could be a performance issue. It
  142. * will get properly cleansed on finalisation so this isn't a
  143. * security problem.
  144. */
  145. memset(p, 0, HASH_CBLOCK); /* keep it zeroed */
  146. } else {
  147. memcpy(p + n, data, len);
  148. c->num += (unsigned int)len;
  149. return 1;
  150. }
  151. }
  152. n = len / HASH_CBLOCK;
  153. if (n > 0) {
  154. HASH_BLOCK_DATA_ORDER(c, data, n);
  155. n *= HASH_CBLOCK;
  156. data += n;
  157. len -= n;
  158. }
  159. if (len != 0) {
  160. p = (unsigned char *)c->data;
  161. c->num = (unsigned int)len;
  162. memcpy(p, data, len);
  163. }
  164. return 1;
  165. }
  166. void HASH_TRANSFORM(HASH_CTX *c, const unsigned char *data)
  167. {
  168. HASH_BLOCK_DATA_ORDER(c, data, 1);
  169. }
  170. int HASH_FINAL(unsigned char *md, HASH_CTX *c)
  171. {
  172. unsigned char *p = (unsigned char *)c->data;
  173. size_t n = c->num;
  174. p[n] = 0x80; /* there is always room for one */
  175. n++;
  176. if (n > (HASH_CBLOCK - 8)) {
  177. memset(p + n, 0, HASH_CBLOCK - n);
  178. n = 0;
  179. HASH_BLOCK_DATA_ORDER(c, p, 1);
  180. }
  181. memset(p + n, 0, HASH_CBLOCK - 8 - n);
  182. p += HASH_CBLOCK - 8;
  183. #if defined(DATA_ORDER_IS_BIG_ENDIAN)
  184. (void)HOST_l2c(c->Nh, p);
  185. (void)HOST_l2c(c->Nl, p);
  186. #elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
  187. (void)HOST_l2c(c->Nl, p);
  188. (void)HOST_l2c(c->Nh, p);
  189. #endif
  190. p -= HASH_CBLOCK;
  191. HASH_BLOCK_DATA_ORDER(c, p, 1);
  192. c->num = 0;
  193. OPENSSL_cleanse(p, HASH_CBLOCK);
  194. #ifndef HASH_MAKE_STRING
  195. # error "HASH_MAKE_STRING must be defined!"
  196. #else
  197. HASH_MAKE_STRING(c, md);
  198. #endif
  199. return 1;
  200. }
  201. #ifndef MD32_REG_T
  202. # if defined(__alpha) || defined(__sparcv9) || defined(__mips)
  203. # define MD32_REG_T long
  204. /*
  205. * This comment was originally written for MD5, which is why it
  206. * discusses A-D. But it basically applies to all 32-bit digests,
  207. * which is why it was moved to common header file.
  208. *
  209. * In case you wonder why A-D are declared as long and not
  210. * as MD5_LONG. Doing so results in slight performance
  211. * boost on LP64 architectures. The catch is we don't
  212. * really care if 32 MSBs of a 64-bit register get polluted
  213. * with eventual overflows as we *save* only 32 LSBs in
  214. * *either* case. Now declaring 'em long excuses the compiler
  215. * from keeping 32 MSBs zeroed resulting in 13% performance
  216. * improvement under SPARC Solaris7/64 and 5% under AlphaLinux.
  217. * Well, to be honest it should say that this *prevents*
  218. * performance degradation.
  219. */
  220. # else
  221. /*
  222. * Above is not absolute and there are LP64 compilers that
  223. * generate better code if MD32_REG_T is defined int. The above
  224. * pre-processor condition reflects the circumstances under which
  225. * the conclusion was made and is subject to further extension.
  226. */
  227. # define MD32_REG_T int
  228. # endif
  229. #endif