md5.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. // SPDX-License-Identifier: LGPL-2.1 OR BSD-3-Clause
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include "main_helper.h"
  6. #define MD5_CBLOCK 64
  7. #define MD5_LBLOCK (MD5_CBLOCK/4)
  8. #define MD5_DIGEST_LENGTH 16
  9. #define DATA_ORDER_IS_LITTLE_ENDIAN
  10. #define HASH_MAKE_STRING(c,s) do { \
  11. unsigned long ll; \
  12. ll=(c)->A; HOST_l2c(ll,(s)); \
  13. ll=(c)->B; HOST_l2c(ll,(s)); \
  14. ll=(c)->C; HOST_l2c(ll,(s)); \
  15. ll=(c)->D; HOST_l2c(ll,(s)); \
  16. } while (0)
  17. #define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
  18. #if defined(DATA_ORDER_IS_BIG_ENDIAN)
  19. #define HOST_c2l(c,l) \
  20. (l =(((unsigned long)(*((c)++)))<<24), \
  21. l|=(((unsigned long)(*((c)++)))<<16), \
  22. l|=(((unsigned long)(*((c)++)))<< 8), \
  23. l|=(((unsigned long)(*((c)++))) ))
  24. #define HOST_l2c(l,c) \
  25. (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
  26. *((c)++)=(unsigned char)(((l)>>16)&0xff), \
  27. *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
  28. *((c)++)=(unsigned char)(((l) )&0xff))
  29. #endif
  30. #if defined(DATA_ORDER_IS_LITTLE_ENDIAN)
  31. #define HOST_c2l(c,l) \
  32. (l =(((unsigned long)(*((c)++))) ), \
  33. l|=(((unsigned long)(*((c)++)))<< 8), \
  34. l|=(((unsigned long)(*((c)++)))<<16), \
  35. l|=(((unsigned long)(*((c)++)))<<24))
  36. #define HOST_l2c(l,c) \
  37. (*((c)++)=(unsigned char)(((l) )&0xff), \
  38. *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
  39. *((c)++)=(unsigned char)(((l)>>16)&0xff), \
  40. *((c)++)=(unsigned char)(((l)>>24)&0xff))
  41. #endif
  42. #define MD32_REG_T long
  43. #define F(b,c,d) ((((c) ^ (d)) & (b)) ^ (d))
  44. #define G(b,c,d) ((((b) ^ (c)) & (d)) ^ (c))
  45. #define H(b,c,d) ((b) ^ (c) ^ (d))
  46. #define I(b,c,d) (((~(d)) | (b)) ^ (c))
  47. #define R0(a,b,c,d,k,s,t) { \
  48. a+=((k)+(t)+F((b),(c),(d))); \
  49. a=ROTATE(a,s); \
  50. a+=b; };
  51. #define R1(a,b,c,d,k,s,t) { \
  52. a+=((k)+(t)+G((b),(c),(d))); \
  53. a=ROTATE(a,s); \
  54. a+=b; };
  55. #define R2(a,b,c,d,k,s,t) { \
  56. a+=((k)+(t)+H((b),(c),(d))); \
  57. a=ROTATE(a,s); \
  58. a+=b; };
  59. #define R3(a,b,c,d,k,s,t) { \
  60. a+=((k)+(t)+I((b),(c),(d))); \
  61. a=ROTATE(a,s); \
  62. a+=b; };
  63. void md5_block_data_order (MD5_CTX *c, const void *data_, size_t num)
  64. {
  65. const unsigned char *data=data_;
  66. register unsigned MD32_REG_T A,B,C,D,l;
  67. #ifndef MD32_XARRAY
  68. /* See comment in crypto/sha/sha_locl.h for details. */
  69. unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
  70. XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15;
  71. # define X(i) XX##i
  72. #else
  73. Uint32 XX[MD5_LBLOCK];
  74. # define X(i) XX[i]
  75. #endif
  76. A=c->A;
  77. B=c->B;
  78. C=c->C;
  79. D=c->D;
  80. for (;num--;) {
  81. HOST_c2l(data,l); X( 0)=l;
  82. HOST_c2l(data,l); X( 1)=l;
  83. /* Round 0 */
  84. R0(A,B,C,D,X( 0), 7,0xd76aa478L); HOST_c2l(data,l); X( 2)=l;
  85. R0(D,A,B,C,X( 1),12,0xe8c7b756L); HOST_c2l(data,l); X( 3)=l;
  86. R0(C,D,A,B,X( 2),17,0x242070dbL); HOST_c2l(data,l); X( 4)=l;
  87. R0(B,C,D,A,X( 3),22,0xc1bdceeeL); HOST_c2l(data,l); X( 5)=l;
  88. R0(A,B,C,D,X( 4), 7,0xf57c0fafL); HOST_c2l(data,l); X( 6)=l;
  89. R0(D,A,B,C,X( 5),12,0x4787c62aL); HOST_c2l(data,l); X( 7)=l;
  90. R0(C,D,A,B,X( 6),17,0xa8304613L); HOST_c2l(data,l); X( 8)=l;
  91. R0(B,C,D,A,X( 7),22,0xfd469501L); HOST_c2l(data,l); X( 9)=l;
  92. R0(A,B,C,D,X( 8), 7,0x698098d8L); HOST_c2l(data,l); X(10)=l;
  93. R0(D,A,B,C,X( 9),12,0x8b44f7afL); HOST_c2l(data,l); X(11)=l;
  94. R0(C,D,A,B,X(10),17,0xffff5bb1L); HOST_c2l(data,l); X(12)=l;
  95. R0(B,C,D,A,X(11),22,0x895cd7beL); HOST_c2l(data,l); X(13)=l;
  96. R0(A,B,C,D,X(12), 7,0x6b901122L); HOST_c2l(data,l); X(14)=l;
  97. R0(D,A,B,C,X(13),12,0xfd987193L); HOST_c2l(data,l); X(15)=l;
  98. R0(C,D,A,B,X(14),17,0xa679438eL);
  99. R0(B,C,D,A,X(15),22,0x49b40821L);
  100. /* Round 1 */
  101. R1(A,B,C,D,X( 1), 5,0xf61e2562L);
  102. R1(D,A,B,C,X( 6), 9,0xc040b340L);
  103. R1(C,D,A,B,X(11),14,0x265e5a51L);
  104. R1(B,C,D,A,X( 0),20,0xe9b6c7aaL);
  105. R1(A,B,C,D,X( 5), 5,0xd62f105dL);
  106. R1(D,A,B,C,X(10), 9,0x02441453L);
  107. R1(C,D,A,B,X(15),14,0xd8a1e681L);
  108. R1(B,C,D,A,X( 4),20,0xe7d3fbc8L);
  109. R1(A,B,C,D,X( 9), 5,0x21e1cde6L);
  110. R1(D,A,B,C,X(14), 9,0xc33707d6L);
  111. R1(C,D,A,B,X( 3),14,0xf4d50d87L);
  112. R1(B,C,D,A,X( 8),20,0x455a14edL);
  113. R1(A,B,C,D,X(13), 5,0xa9e3e905L);
  114. R1(D,A,B,C,X( 2), 9,0xfcefa3f8L);
  115. R1(C,D,A,B,X( 7),14,0x676f02d9L);
  116. R1(B,C,D,A,X(12),20,0x8d2a4c8aL);
  117. /* Round 2 */
  118. R2(A,B,C,D,X( 5), 4,0xfffa3942L);
  119. R2(D,A,B,C,X( 8),11,0x8771f681L);
  120. R2(C,D,A,B,X(11),16,0x6d9d6122L);
  121. R2(B,C,D,A,X(14),23,0xfde5380cL);
  122. R2(A,B,C,D,X( 1), 4,0xa4beea44L);
  123. R2(D,A,B,C,X( 4),11,0x4bdecfa9L);
  124. R2(C,D,A,B,X( 7),16,0xf6bb4b60L);
  125. R2(B,C,D,A,X(10),23,0xbebfbc70L);
  126. R2(A,B,C,D,X(13), 4,0x289b7ec6L);
  127. R2(D,A,B,C,X( 0),11,0xeaa127faL);
  128. R2(C,D,A,B,X( 3),16,0xd4ef3085L);
  129. R2(B,C,D,A,X( 6),23,0x04881d05L);
  130. R2(A,B,C,D,X( 9), 4,0xd9d4d039L);
  131. R2(D,A,B,C,X(12),11,0xe6db99e5L);
  132. R2(C,D,A,B,X(15),16,0x1fa27cf8L);
  133. R2(B,C,D,A,X( 2),23,0xc4ac5665L);
  134. /* Round 3 */
  135. R3(A,B,C,D,X( 0), 6,0xf4292244L);
  136. R3(D,A,B,C,X( 7),10,0x432aff97L);
  137. R3(C,D,A,B,X(14),15,0xab9423a7L);
  138. R3(B,C,D,A,X( 5),21,0xfc93a039L);
  139. R3(A,B,C,D,X(12), 6,0x655b59c3L);
  140. R3(D,A,B,C,X( 3),10,0x8f0ccc92L);
  141. R3(C,D,A,B,X(10),15,0xffeff47dL);
  142. R3(B,C,D,A,X( 1),21,0x85845dd1L);
  143. R3(A,B,C,D,X( 8), 6,0x6fa87e4fL);
  144. R3(D,A,B,C,X(15),10,0xfe2ce6e0L);
  145. R3(C,D,A,B,X( 6),15,0xa3014314L);
  146. R3(B,C,D,A,X(13),21,0x4e0811a1L);
  147. R3(A,B,C,D,X( 4), 6,0xf7537e82L);
  148. R3(D,A,B,C,X(11),10,0xbd3af235L);
  149. R3(C,D,A,B,X( 2),15,0x2ad7d2bbL);
  150. R3(B,C,D,A,X( 9),21,0xeb86d391L);
  151. A = c->A += A;
  152. B = c->B += B;
  153. C = c->C += C;
  154. D = c->D += D;
  155. }
  156. }
  157. /* Implemented from RFC1321 The MD5 Message-Digest Algorithm
  158. */
  159. #define INIT_DATA_A (unsigned long)0x67452301L
  160. #define INIT_DATA_B (unsigned long)0xefcdab89L
  161. #define INIT_DATA_C (unsigned long)0x98badcfeL
  162. #define INIT_DATA_D (unsigned long)0x10325476L
  163. Int32 MD5_Init (MD5_CTX *c)
  164. {
  165. c->A=INIT_DATA_A;
  166. c->B=INIT_DATA_B;
  167. c->C=INIT_DATA_C;
  168. c->D=INIT_DATA_D;
  169. c->Nl=0;
  170. c->Nh=0;
  171. c->num=0;
  172. return 1;
  173. }
  174. Int32 MD5_Update (MD5_CTX *c, const void *data_, size_t len)
  175. {
  176. const unsigned char *data=data_;
  177. unsigned char *p;
  178. Uint32 l;
  179. size_t n;
  180. if (len==0) return 1;
  181. l=(c->Nl+(((Uint32)len)<<3))&0xffffffffUL;
  182. /* 95-05-24 eay Fixed a bug with the overflow handling, thanks to
  183. * Wei Dai <weidai@eskimo.com> for pointing it out. */
  184. if (l < c->Nl) /* overflow */
  185. c->Nh++;
  186. c->Nh+=(len>>29); /* might cause compiler warning on 16-bit */
  187. c->Nl=l;
  188. n = c->num;
  189. if (n != 0) {
  190. p=(unsigned char *)c->data;
  191. if (len >= MD5_CBLOCK || len+n >= MD5_CBLOCK) {
  192. osal_memcpy (p+n,data,MD5_CBLOCK-n);
  193. md5_block_data_order (c,p,1);
  194. n = MD5_CBLOCK-n;
  195. data += n;
  196. len -= n;
  197. c->num = 0;
  198. osal_memset (p,0,MD5_CBLOCK); /* keep it zeroed */
  199. } else {
  200. osal_memcpy (p+n,data,len);
  201. c->num += (unsigned int)len;
  202. return 1;
  203. }
  204. }
  205. n = len/MD5_CBLOCK;
  206. if (n > 0) {
  207. md5_block_data_order (c,data,n);
  208. n *= MD5_CBLOCK;
  209. data += n;
  210. len -= n;
  211. }
  212. if (len != 0) {
  213. p = (unsigned char *)c->data;
  214. c->num = len;
  215. osal_memcpy (p,data,len);
  216. }
  217. return 1;
  218. }
  219. Int32 MD5_Final (Uint8* md, MD5_CTX *c)
  220. {
  221. unsigned char *p = (unsigned char *)c->data;
  222. size_t n = c->num;
  223. p[n] = 0x80; /* there is always room for one */
  224. n++;
  225. if (n > (MD5_CBLOCK-8)) {
  226. osal_memset (p+n,0,MD5_CBLOCK-n);
  227. n=0;
  228. md5_block_data_order (c,p,1);
  229. }
  230. osal_memset (p+n,0,MD5_CBLOCK-8-n);
  231. p += MD5_CBLOCK-8;
  232. #if defined(DATA_ORDER_IS_BIG_ENDIAN)
  233. (void)HOST_l2c(c->Nh,p);
  234. (void)HOST_l2c(c->Nl,p);
  235. #elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
  236. (void)HOST_l2c(c->Nl,p);
  237. (void)HOST_l2c(c->Nh,p);
  238. #endif
  239. p -= MD5_CBLOCK;
  240. md5_block_data_order (c,p,1);
  241. c->num=0;
  242. osal_memset (p,0,MD5_CBLOCK);
  243. HASH_MAKE_STRING(c,md);
  244. return 1;
  245. }
  246. Uint8* MD5 (const Uint8* d, size_t n, Uint8* md)
  247. {
  248. MD5_CTX c;
  249. static unsigned char m[MD5_DIGEST_LENGTH];
  250. if (md == NULL) md=m;
  251. if (!MD5_Init(&c))
  252. return NULL;
  253. MD5_Update(&c,d,n);
  254. MD5_Final(md,&c);
  255. return(md);
  256. }