md5.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. // SPDX-License-Identifier: LGPL-2.1 OR BSD-3-Clause
  2. /*
  3. * Copyright (c) 2019, Chips&Media
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright notice, this
  10. * list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright notice,
  12. * this list of conditions and the following disclaimer in the documentation
  13. * and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  16. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  17. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  19. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  20. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  21. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  22. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  24. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <string.h>
  29. #include "main_helper.h"
  30. #define MD5_CBLOCK 64
  31. #define MD5_LBLOCK (MD5_CBLOCK/4)
  32. #define MD5_DIGEST_LENGTH 16
  33. #define DATA_ORDER_IS_LITTLE_ENDIAN
  34. #define HASH_MAKE_STRING(c,s) do { \
  35. unsigned long ll; \
  36. ll=(c)->A; HOST_l2c(ll,(s)); \
  37. ll=(c)->B; HOST_l2c(ll,(s)); \
  38. ll=(c)->C; HOST_l2c(ll,(s)); \
  39. ll=(c)->D; HOST_l2c(ll,(s)); \
  40. } while (0)
  41. #define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
  42. #if defined(DATA_ORDER_IS_BIG_ENDIAN)
  43. #define HOST_c2l(c,l) \
  44. (l =(((unsigned long)(*((c)++)))<<24), \
  45. l|=(((unsigned long)(*((c)++)))<<16), \
  46. l|=(((unsigned long)(*((c)++)))<< 8), \
  47. l|=(((unsigned long)(*((c)++))) ))
  48. #define HOST_l2c(l,c) \
  49. (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
  50. *((c)++)=(unsigned char)(((l)>>16)&0xff), \
  51. *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
  52. *((c)++)=(unsigned char)(((l) )&0xff))
  53. #endif
  54. #if defined(DATA_ORDER_IS_LITTLE_ENDIAN)
  55. #define HOST_c2l(c,l) \
  56. (l =(((unsigned long)(*((c)++))) ), \
  57. l|=(((unsigned long)(*((c)++)))<< 8), \
  58. l|=(((unsigned long)(*((c)++)))<<16), \
  59. l|=(((unsigned long)(*((c)++)))<<24))
  60. #define HOST_l2c(l,c) \
  61. (*((c)++)=(unsigned char)(((l) )&0xff), \
  62. *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
  63. *((c)++)=(unsigned char)(((l)>>16)&0xff), \
  64. *((c)++)=(unsigned char)(((l)>>24)&0xff))
  65. #endif
  66. #define MD32_REG_T long
  67. #define F(b,c,d) ((((c) ^ (d)) & (b)) ^ (d))
  68. #define G(b,c,d) ((((b) ^ (c)) & (d)) ^ (c))
  69. #define H(b,c,d) ((b) ^ (c) ^ (d))
  70. #define I(b,c,d) (((~(d)) | (b)) ^ (c))
  71. #define R0(a,b,c,d,k,s,t) { \
  72. a+=((k)+(t)+F((b),(c),(d))); \
  73. a=ROTATE(a,s); \
  74. a+=b; };
  75. #define R1(a,b,c,d,k,s,t) { \
  76. a+=((k)+(t)+G((b),(c),(d))); \
  77. a=ROTATE(a,s); \
  78. a+=b; };
  79. #define R2(a,b,c,d,k,s,t) { \
  80. a+=((k)+(t)+H((b),(c),(d))); \
  81. a=ROTATE(a,s); \
  82. a+=b; };
  83. #define R3(a,b,c,d,k,s,t) { \
  84. a+=((k)+(t)+I((b),(c),(d))); \
  85. a=ROTATE(a,s); \
  86. a+=b; };
  87. void md5_block_data_order (MD5_CTX *c, const void *data_, size_t num)
  88. {
  89. const unsigned char *data=data_;
  90. register unsigned MD32_REG_T A,B,C,D,l;
  91. #ifndef MD32_XARRAY
  92. /* See comment in crypto/sha/sha_locl.h for details. */
  93. unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
  94. XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15;
  95. # define X(i) XX##i
  96. #else
  97. Uint32 XX[MD5_LBLOCK];
  98. # define X(i) XX[i]
  99. #endif
  100. A=c->A;
  101. B=c->B;
  102. C=c->C;
  103. D=c->D;
  104. for (;num--;) {
  105. HOST_c2l(data,l); X( 0)=l;
  106. HOST_c2l(data,l); X( 1)=l;
  107. /* Round 0 */
  108. R0(A,B,C,D,X( 0), 7,0xd76aa478L); HOST_c2l(data,l); X( 2)=l;
  109. R0(D,A,B,C,X( 1),12,0xe8c7b756L); HOST_c2l(data,l); X( 3)=l;
  110. R0(C,D,A,B,X( 2),17,0x242070dbL); HOST_c2l(data,l); X( 4)=l;
  111. R0(B,C,D,A,X( 3),22,0xc1bdceeeL); HOST_c2l(data,l); X( 5)=l;
  112. R0(A,B,C,D,X( 4), 7,0xf57c0fafL); HOST_c2l(data,l); X( 6)=l;
  113. R0(D,A,B,C,X( 5),12,0x4787c62aL); HOST_c2l(data,l); X( 7)=l;
  114. R0(C,D,A,B,X( 6),17,0xa8304613L); HOST_c2l(data,l); X( 8)=l;
  115. R0(B,C,D,A,X( 7),22,0xfd469501L); HOST_c2l(data,l); X( 9)=l;
  116. R0(A,B,C,D,X( 8), 7,0x698098d8L); HOST_c2l(data,l); X(10)=l;
  117. R0(D,A,B,C,X( 9),12,0x8b44f7afL); HOST_c2l(data,l); X(11)=l;
  118. R0(C,D,A,B,X(10),17,0xffff5bb1L); HOST_c2l(data,l); X(12)=l;
  119. R0(B,C,D,A,X(11),22,0x895cd7beL); HOST_c2l(data,l); X(13)=l;
  120. R0(A,B,C,D,X(12), 7,0x6b901122L); HOST_c2l(data,l); X(14)=l;
  121. R0(D,A,B,C,X(13),12,0xfd987193L); HOST_c2l(data,l); X(15)=l;
  122. R0(C,D,A,B,X(14),17,0xa679438eL);
  123. R0(B,C,D,A,X(15),22,0x49b40821L);
  124. /* Round 1 */
  125. R1(A,B,C,D,X( 1), 5,0xf61e2562L);
  126. R1(D,A,B,C,X( 6), 9,0xc040b340L);
  127. R1(C,D,A,B,X(11),14,0x265e5a51L);
  128. R1(B,C,D,A,X( 0),20,0xe9b6c7aaL);
  129. R1(A,B,C,D,X( 5), 5,0xd62f105dL);
  130. R1(D,A,B,C,X(10), 9,0x02441453L);
  131. R1(C,D,A,B,X(15),14,0xd8a1e681L);
  132. R1(B,C,D,A,X( 4),20,0xe7d3fbc8L);
  133. R1(A,B,C,D,X( 9), 5,0x21e1cde6L);
  134. R1(D,A,B,C,X(14), 9,0xc33707d6L);
  135. R1(C,D,A,B,X( 3),14,0xf4d50d87L);
  136. R1(B,C,D,A,X( 8),20,0x455a14edL);
  137. R1(A,B,C,D,X(13), 5,0xa9e3e905L);
  138. R1(D,A,B,C,X( 2), 9,0xfcefa3f8L);
  139. R1(C,D,A,B,X( 7),14,0x676f02d9L);
  140. R1(B,C,D,A,X(12),20,0x8d2a4c8aL);
  141. /* Round 2 */
  142. R2(A,B,C,D,X( 5), 4,0xfffa3942L);
  143. R2(D,A,B,C,X( 8),11,0x8771f681L);
  144. R2(C,D,A,B,X(11),16,0x6d9d6122L);
  145. R2(B,C,D,A,X(14),23,0xfde5380cL);
  146. R2(A,B,C,D,X( 1), 4,0xa4beea44L);
  147. R2(D,A,B,C,X( 4),11,0x4bdecfa9L);
  148. R2(C,D,A,B,X( 7),16,0xf6bb4b60L);
  149. R2(B,C,D,A,X(10),23,0xbebfbc70L);
  150. R2(A,B,C,D,X(13), 4,0x289b7ec6L);
  151. R2(D,A,B,C,X( 0),11,0xeaa127faL);
  152. R2(C,D,A,B,X( 3),16,0xd4ef3085L);
  153. R2(B,C,D,A,X( 6),23,0x04881d05L);
  154. R2(A,B,C,D,X( 9), 4,0xd9d4d039L);
  155. R2(D,A,B,C,X(12),11,0xe6db99e5L);
  156. R2(C,D,A,B,X(15),16,0x1fa27cf8L);
  157. R2(B,C,D,A,X( 2),23,0xc4ac5665L);
  158. /* Round 3 */
  159. R3(A,B,C,D,X( 0), 6,0xf4292244L);
  160. R3(D,A,B,C,X( 7),10,0x432aff97L);
  161. R3(C,D,A,B,X(14),15,0xab9423a7L);
  162. R3(B,C,D,A,X( 5),21,0xfc93a039L);
  163. R3(A,B,C,D,X(12), 6,0x655b59c3L);
  164. R3(D,A,B,C,X( 3),10,0x8f0ccc92L);
  165. R3(C,D,A,B,X(10),15,0xffeff47dL);
  166. R3(B,C,D,A,X( 1),21,0x85845dd1L);
  167. R3(A,B,C,D,X( 8), 6,0x6fa87e4fL);
  168. R3(D,A,B,C,X(15),10,0xfe2ce6e0L);
  169. R3(C,D,A,B,X( 6),15,0xa3014314L);
  170. R3(B,C,D,A,X(13),21,0x4e0811a1L);
  171. R3(A,B,C,D,X( 4), 6,0xf7537e82L);
  172. R3(D,A,B,C,X(11),10,0xbd3af235L);
  173. R3(C,D,A,B,X( 2),15,0x2ad7d2bbL);
  174. R3(B,C,D,A,X( 9),21,0xeb86d391L);
  175. A = c->A += A;
  176. B = c->B += B;
  177. C = c->C += C;
  178. D = c->D += D;
  179. }
  180. }
  181. /* Implemented from RFC1321 The MD5 Message-Digest Algorithm
  182. */
  183. #define INIT_DATA_A (unsigned long)0x67452301L
  184. #define INIT_DATA_B (unsigned long)0xefcdab89L
  185. #define INIT_DATA_C (unsigned long)0x98badcfeL
  186. #define INIT_DATA_D (unsigned long)0x10325476L
  187. Int32 MD5_Init (MD5_CTX *c)
  188. {
  189. c->A=INIT_DATA_A;
  190. c->B=INIT_DATA_B;
  191. c->C=INIT_DATA_C;
  192. c->D=INIT_DATA_D;
  193. c->Nl=0;
  194. c->Nh=0;
  195. c->num=0;
  196. return 1;
  197. }
  198. Int32 MD5_Update (MD5_CTX *c, const void *data_, size_t len)
  199. {
  200. const unsigned char *data=data_;
  201. unsigned char *p;
  202. Uint32 l;
  203. size_t n;
  204. if (len==0) return 1;
  205. l=(c->Nl+(((Uint32)len)<<3))&0xffffffffUL;
  206. /* 95-05-24 eay Fixed a bug with the overflow handling, thanks to
  207. * Wei Dai <weidai@eskimo.com> for pointing it out. */
  208. if (l < c->Nl) /* overflow */
  209. c->Nh++;
  210. c->Nh+=(len>>29); /* might cause compiler warning on 16-bit */
  211. c->Nl=l;
  212. n = c->num;
  213. if (n != 0) {
  214. p=(unsigned char *)c->data;
  215. if (len >= MD5_CBLOCK || len+n >= MD5_CBLOCK) {
  216. osal_memcpy (p+n,data,MD5_CBLOCK-n);
  217. md5_block_data_order (c,p,1);
  218. n = MD5_CBLOCK-n;
  219. data += n;
  220. len -= n;
  221. c->num = 0;
  222. osal_memset (p,0,MD5_CBLOCK); /* keep it zeroed */
  223. } else {
  224. osal_memcpy (p+n,data,len);
  225. c->num += (unsigned int)len;
  226. return 1;
  227. }
  228. }
  229. n = len/MD5_CBLOCK;
  230. if (n > 0) {
  231. md5_block_data_order (c,data,n);
  232. n *= MD5_CBLOCK;
  233. data += n;//lint !e662
  234. len -= n;
  235. }
  236. if (len != 0) {
  237. p = (unsigned char *)c->data;
  238. c->num = len;
  239. osal_memcpy (p,data,len);
  240. }
  241. return 1;
  242. }
  243. Int32 MD5_Final (Uint8* md, MD5_CTX *c)
  244. {
  245. unsigned char *p = (unsigned char *)c->data;
  246. size_t n = c->num;
  247. p[n] = 0x80; /* there is always room for one */
  248. n++;
  249. if (n > (MD5_CBLOCK-8)) {
  250. osal_memset (p+n,0,MD5_CBLOCK-n);
  251. n=0;
  252. md5_block_data_order (c,p,1);
  253. }
  254. osal_memset (p+n,0,MD5_CBLOCK-8-n);
  255. p += MD5_CBLOCK-8;
  256. #if defined(DATA_ORDER_IS_BIG_ENDIAN)
  257. (void)HOST_l2c(c->Nh,p);
  258. (void)HOST_l2c(c->Nl,p);
  259. #elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
  260. (void)HOST_l2c(c->Nl,p);
  261. (void)HOST_l2c(c->Nh,p);
  262. #endif
  263. p -= MD5_CBLOCK;
  264. md5_block_data_order (c,p,1);
  265. c->num=0;
  266. osal_memset (p,0,MD5_CBLOCK);
  267. HASH_MAKE_STRING(c,md);
  268. return 1;
  269. }
  270. Uint8* MD5 (const Uint8* d, size_t n, Uint8* md)
  271. {
  272. MD5_CTX c;
  273. static unsigned char m[MD5_DIGEST_LENGTH];
  274. if (md == NULL) md=m;
  275. if (!MD5_Init(&c))
  276. return NULL;
  277. MD5_Update(&c,d,n);
  278. MD5_Final(md,&c);
  279. return(md);
  280. }