md5.c
上传用户:lyxiangda
上传日期:2007-01-12
资源大小:3042k
文件大小:14k
源码类别:

CA认证

开发平台:

WINDOWS

  1. /*
  2.  * The contents of this file are subject to the Mozilla Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/MPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is the Netscape security libraries.
  13.  * 
  14.  * The Initial Developer of the Original Code is Netscape
  15.  * Communications Corporation. Portions created by Netscape are 
  16.  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All
  17.  * Rights Reserved.
  18.  * 
  19.  * Contributor(s):
  20.  * 
  21.  * Alternatively, the contents of this file may be used under the
  22.  * terms of the GNU General Public License Version 2 or later (the
  23.  * "GPL"), in which case the provisions of the GPL are applicable 
  24.  * instead of those above. If you wish to allow use of your 
  25.  * version of this file only under the terms of the GPL and not to
  26.  * allow others to use your version of this file under the MPL,
  27.  * indicate your decision by deleting the provisions above and
  28.  * replace them with the notice and other provisions required by
  29.  * the GPL.  If you do not delete the provisions above, a recipient
  30.  * may use your version of this file under either the MPL or the
  31.  * GPL.
  32.  */
  33. #include "prerr.h"
  34. #include "secerr.h"
  35. #include "prtypes.h"
  36. #include "prlong.h"
  37. #include "blapi.h"
  38. #define MD5_HASH_LEN 16
  39. #define MD5_BUFFER_SIZE 64
  40. #define MD5_END_BUFFER (MD5_BUFFER_SIZE - 8)
  41. #define CV0_1 0x67452301
  42. #define CV0_2 0xefcdab89
  43. #define CV0_3 0x98badcfe
  44. #define CV0_4 0x10325476
  45. #define T1_0  0xd76aa478
  46. #define T1_1  0xe8c7b756
  47. #define T1_2  0x242070db
  48. #define T1_3  0xc1bdceee
  49. #define T1_4  0xf57c0faf
  50. #define T1_5  0x4787c62a
  51. #define T1_6  0xa8304613
  52. #define T1_7  0xfd469501
  53. #define T1_8  0x698098d8
  54. #define T1_9  0x8b44f7af
  55. #define T1_10 0xffff5bb1
  56. #define T1_11 0x895cd7be
  57. #define T1_12 0x6b901122
  58. #define T1_13 0xfd987193
  59. #define T1_14 0xa679438e
  60. #define T1_15 0x49b40821
  61. #define T2_0  0xf61e2562
  62. #define T2_1  0xc040b340
  63. #define T2_2  0x265e5a51
  64. #define T2_3  0xe9b6c7aa
  65. #define T2_4  0xd62f105d
  66. #define T2_5  0x02441453
  67. #define T2_6  0xd8a1e681
  68. #define T2_7  0xe7d3fbc8
  69. #define T2_8  0x21e1cde6
  70. #define T2_9  0xc33707d6
  71. #define T2_10 0xf4d50d87
  72. #define T2_11 0x455a14ed
  73. #define T2_12 0xa9e3e905
  74. #define T2_13 0xfcefa3f8
  75. #define T2_14 0x676f02d9
  76. #define T2_15 0x8d2a4c8a
  77. #define T3_0  0xfffa3942
  78. #define T3_1  0x8771f681
  79. #define T3_2  0x6d9d6122
  80. #define T3_3  0xfde5380c
  81. #define T3_4  0xa4beea44
  82. #define T3_5  0x4bdecfa9
  83. #define T3_6  0xf6bb4b60
  84. #define T3_7  0xbebfbc70
  85. #define T3_8  0x289b7ec6
  86. #define T3_9  0xeaa127fa
  87. #define T3_10 0xd4ef3085
  88. #define T3_11 0x04881d05
  89. #define T3_12 0xd9d4d039
  90. #define T3_13 0xe6db99e5
  91. #define T3_14 0x1fa27cf8
  92. #define T3_15 0xc4ac5665
  93. #define T4_0  0xf4292244
  94. #define T4_1  0x432aff97
  95. #define T4_2  0xab9423a7
  96. #define T4_3  0xfc93a039
  97. #define T4_4  0x655b59c3
  98. #define T4_5  0x8f0ccc92
  99. #define T4_6  0xffeff47d
  100. #define T4_7  0x85845dd1
  101. #define T4_8  0x6fa87e4f
  102. #define T4_9  0xfe2ce6e0
  103. #define T4_10 0xa3014314
  104. #define T4_11 0x4e0811a1
  105. #define T4_12 0xf7537e82
  106. #define T4_13 0xbd3af235
  107. #define T4_14 0x2ad7d2bb
  108. #define T4_15 0xeb86d391
  109. #define R1B0  0
  110. #define R1B1  1
  111. #define R1B2  2
  112. #define R1B3  3
  113. #define R1B4  4
  114. #define R1B5  5
  115. #define R1B6  6
  116. #define R1B7  7
  117. #define R1B8  8
  118. #define R1B9  9
  119. #define R1B10 10
  120. #define R1B11 11
  121. #define R1B12 12
  122. #define R1B13 13
  123. #define R1B14 14
  124. #define R1B15 15
  125. #define R2B0  1
  126. #define R2B1  6
  127. #define R2B2  11
  128. #define R2B3  0
  129. #define R2B4  5
  130. #define R2B5  10
  131. #define R2B6  15
  132. #define R2B7  4
  133. #define R2B8  9
  134. #define R2B9  14
  135. #define R2B10 3 
  136. #define R2B11 8 
  137. #define R2B12 13
  138. #define R2B13 2 
  139. #define R2B14 7 
  140. #define R2B15 12
  141. #define R3B0  5
  142. #define R3B1  8
  143. #define R3B2  11
  144. #define R3B3  14
  145. #define R3B4  1
  146. #define R3B5  4
  147. #define R3B6  7
  148. #define R3B7  10
  149. #define R3B8  13
  150. #define R3B9  0
  151. #define R3B10 3 
  152. #define R3B11 6 
  153. #define R3B12 9 
  154. #define R3B13 12
  155. #define R3B14 15
  156. #define R3B15 2 
  157. #define R4B0  0
  158. #define R4B1  7
  159. #define R4B2  14
  160. #define R4B3  5
  161. #define R4B4  12
  162. #define R4B5  3
  163. #define R4B6  10
  164. #define R4B7  1
  165. #define R4B8  8
  166. #define R4B9  15
  167. #define R4B10 6 
  168. #define R4B11 13
  169. #define R4B12 4 
  170. #define R4B13 11
  171. #define R4B14 2 
  172. #define R4B15 9 
  173. #define S1_0 7
  174. #define S1_1 12
  175. #define S1_2 17
  176. #define S1_3 22
  177. #define S2_0 5
  178. #define S2_1 9
  179. #define S2_2 14
  180. #define S2_3 20
  181. #define S3_0 4
  182. #define S3_1 11
  183. #define S3_2 16
  184. #define S3_3 23
  185. #define S4_0 6
  186. #define S4_1 10
  187. #define S4_2 15
  188. #define S4_3 21
  189. struct MD5ContextStr {
  190. PRUint32      lsbInput;
  191. PRUint32      msbInput;
  192. PRUint32      cv[4];
  193. union {
  194. PRUint8 b[64];
  195. PRUint32 w[16];
  196. } u;
  197. };
  198. #define inBuf u.b
  199. SECStatus 
  200. MD5_Hash(unsigned char *dest, const char *src)
  201. {
  202. return MD5_HashBuf(dest, (unsigned char *)src, PL_strlen(src));
  203. }
  204. SECStatus 
  205. MD5_HashBuf(unsigned char *dest, const unsigned char *src, uint32 src_length)
  206. {
  207. unsigned int len;
  208. MD5Context *cx = MD5_NewContext();
  209. if (cx == NULL) {
  210. PORT_SetError(PR_OUT_OF_MEMORY_ERROR);
  211. return SECFailure;
  212. }
  213. MD5_Begin(cx);
  214. MD5_Update(cx, src, src_length);
  215. MD5_End(cx, dest, &len, MD5_HASH_LEN);
  216. MD5_DestroyContext(cx, PR_TRUE);
  217. return SECSuccess;
  218. }
  219. MD5Context *
  220. MD5_NewContext(void)
  221. {
  222. MD5Context *cx = (MD5Context *)PORT_ZAlloc(sizeof(MD5Context));
  223. if (cx == NULL) {
  224. PORT_SetError(PR_OUT_OF_MEMORY_ERROR);
  225. return NULL;
  226. }
  227. return cx;
  228. }
  229. void 
  230. MD5_DestroyContext(MD5Context *cx, PRBool freeit)
  231. {
  232. if (freeit) {
  233. PORT_ZFree(cx, sizeof(MD5Context));
  234. }
  235. }
  236. void 
  237. MD5_Begin(MD5Context *cx)
  238. {
  239. cx->lsbInput = 0;
  240. cx->msbInput = 0;
  241. memset(cx->inBuf, 0, sizeof(cx->inBuf));
  242. cx->cv[0] = CV0_1;
  243. cx->cv[1] = CV0_2;
  244. cx->cv[2] = CV0_3;
  245. cx->cv[3] = CV0_4;
  246. }
  247. #define cls(i32, s) (tmp = i32, tmp << s | tmp >> (32 - s))
  248. #define MASK 0x00ff00ff
  249. #ifdef IS_LITTLE_ENDIAN
  250. #define lendian(i32) 
  251. (i32)
  252. #else
  253. #define lendian(i32) 
  254. (tmp = i32 >> 16 | i32 << 16, (tmp & MASK) << 8 | tmp >> 8 & MASK)
  255. #endif
  256. #if defined(SOLARIS) || defined(HPUX)
  257. #define addto64(sumhigh, sumlow, addend) 
  258. sumlow += addend; sumhigh += (sumlow < addend);
  259. #else
  260. #define addto64(sumhigh, sumlow, addend) 
  261. sumlow += addend; if (sumlow < addend) ++sumhigh;
  262. #endif
  263. #define F(X, Y, Z) 
  264. ((X & Y) | ((~X) & Z))
  265. #define G(X, Y, Z) 
  266. ((X & Z) | (Y & (~Z)))
  267. #define H(X, Y, Z) 
  268. (X ^ Y ^ Z)
  269. #define I(X, Y, Z) 
  270. (Y ^ (X | (~Z)))
  271. #define FF(a, b, c, d, bufint, s, ti) 
  272. a = b + cls(a + F(b, c, d) + bufint + ti, s)
  273. #define GG(a, b, c, d, bufint, s, ti) 
  274. a = b + cls(a + G(b, c, d) + bufint + ti, s)
  275. #define HH(a, b, c, d, bufint, s, ti) 
  276. a = b + cls(a + H(b, c, d) + bufint + ti, s)
  277. #define II(a, b, c, d, bufint, s, ti) 
  278. a = b + cls(a + I(b, c, d) + bufint + ti, s)
  279. static void
  280. md5_compress(MD5Context *cx)
  281. {
  282. PRUint32 a, b, c, d;
  283. PRUint32 tmp;
  284. a = cx->cv[0];
  285. b = cx->cv[1];
  286. c = cx->cv[2];
  287. d = cx->cv[3];
  288. #ifndef IS_LITTLE_ENDIAN
  289. cx->u.w[0] = lendian(cx->u.w[0]);
  290. cx->u.w[1] = lendian(cx->u.w[1]);
  291. cx->u.w[2] = lendian(cx->u.w[2]);
  292. cx->u.w[3] = lendian(cx->u.w[3]);
  293. cx->u.w[4] = lendian(cx->u.w[4]);
  294. cx->u.w[5] = lendian(cx->u.w[5]);
  295. cx->u.w[6] = lendian(cx->u.w[6]);
  296. cx->u.w[7] = lendian(cx->u.w[7]);
  297. cx->u.w[8] = lendian(cx->u.w[8]);
  298. cx->u.w[9] = lendian(cx->u.w[9]);
  299. cx->u.w[10] = lendian(cx->u.w[10]);
  300. cx->u.w[11] = lendian(cx->u.w[11]);
  301. cx->u.w[12] = lendian(cx->u.w[12]);
  302. cx->u.w[13] = lendian(cx->u.w[13]);
  303. cx->u.w[14] = lendian(cx->u.w[14]);
  304. cx->u.w[15] = lendian(cx->u.w[15]);
  305. #endif
  306. FF(a, b, c, d, cx->u.w[R1B0 ], S1_0, T1_0);
  307. FF(d, a, b, c, cx->u.w[R1B1 ], S1_1, T1_1);
  308. FF(c, d, a, b, cx->u.w[R1B2 ], S1_2, T1_2);
  309. FF(b, c, d, a, cx->u.w[R1B3 ], S1_3, T1_3);
  310. FF(a, b, c, d, cx->u.w[R1B4 ], S1_0, T1_4);
  311. FF(d, a, b, c, cx->u.w[R1B5 ], S1_1, T1_5);
  312. FF(c, d, a, b, cx->u.w[R1B6 ], S1_2, T1_6);
  313. FF(b, c, d, a, cx->u.w[R1B7 ], S1_3, T1_7);
  314. FF(a, b, c, d, cx->u.w[R1B8 ], S1_0, T1_8);
  315. FF(d, a, b, c, cx->u.w[R1B9 ], S1_1, T1_9);
  316. FF(c, d, a, b, cx->u.w[R1B10], S1_2, T1_10);
  317. FF(b, c, d, a, cx->u.w[R1B11], S1_3, T1_11);
  318. FF(a, b, c, d, cx->u.w[R1B12], S1_0, T1_12);
  319. FF(d, a, b, c, cx->u.w[R1B13], S1_1, T1_13);
  320. FF(c, d, a, b, cx->u.w[R1B14], S1_2, T1_14);
  321. FF(b, c, d, a, cx->u.w[R1B15], S1_3, T1_15);
  322. GG(a, b, c, d, cx->u.w[R2B0 ], S2_0, T2_0);
  323. GG(d, a, b, c, cx->u.w[R2B1 ], S2_1, T2_1);
  324. GG(c, d, a, b, cx->u.w[R2B2 ], S2_2, T2_2);
  325. GG(b, c, d, a, cx->u.w[R2B3 ], S2_3, T2_3);
  326. GG(a, b, c, d, cx->u.w[R2B4 ], S2_0, T2_4);
  327. GG(d, a, b, c, cx->u.w[R2B5 ], S2_1, T2_5);
  328. GG(c, d, a, b, cx->u.w[R2B6 ], S2_2, T2_6);
  329. GG(b, c, d, a, cx->u.w[R2B7 ], S2_3, T2_7);
  330. GG(a, b, c, d, cx->u.w[R2B8 ], S2_0, T2_8);
  331. GG(d, a, b, c, cx->u.w[R2B9 ], S2_1, T2_9);
  332. GG(c, d, a, b, cx->u.w[R2B10], S2_2, T2_10);
  333. GG(b, c, d, a, cx->u.w[R2B11], S2_3, T2_11);
  334. GG(a, b, c, d, cx->u.w[R2B12], S2_0, T2_12);
  335. GG(d, a, b, c, cx->u.w[R2B13], S2_1, T2_13);
  336. GG(c, d, a, b, cx->u.w[R2B14], S2_2, T2_14);
  337. GG(b, c, d, a, cx->u.w[R2B15], S2_3, T2_15);
  338. HH(a, b, c, d, cx->u.w[R3B0 ], S3_0, T3_0);
  339. HH(d, a, b, c, cx->u.w[R3B1 ], S3_1, T3_1);
  340. HH(c, d, a, b, cx->u.w[R3B2 ], S3_2, T3_2);
  341. HH(b, c, d, a, cx->u.w[R3B3 ], S3_3, T3_3);
  342. HH(a, b, c, d, cx->u.w[R3B4 ], S3_0, T3_4);
  343. HH(d, a, b, c, cx->u.w[R3B5 ], S3_1, T3_5);
  344. HH(c, d, a, b, cx->u.w[R3B6 ], S3_2, T3_6);
  345. HH(b, c, d, a, cx->u.w[R3B7 ], S3_3, T3_7);
  346. HH(a, b, c, d, cx->u.w[R3B8 ], S3_0, T3_8);
  347. HH(d, a, b, c, cx->u.w[R3B9 ], S3_1, T3_9);
  348. HH(c, d, a, b, cx->u.w[R3B10], S3_2, T3_10);
  349. HH(b, c, d, a, cx->u.w[R3B11], S3_3, T3_11);
  350. HH(a, b, c, d, cx->u.w[R3B12], S3_0, T3_12);
  351. HH(d, a, b, c, cx->u.w[R3B13], S3_1, T3_13);
  352. HH(c, d, a, b, cx->u.w[R3B14], S3_2, T3_14);
  353. HH(b, c, d, a, cx->u.w[R3B15], S3_3, T3_15);
  354. II(a, b, c, d, cx->u.w[R4B0 ], S4_0, T4_0);
  355. II(d, a, b, c, cx->u.w[R4B1 ], S4_1, T4_1);
  356. II(c, d, a, b, cx->u.w[R4B2 ], S4_2, T4_2);
  357. II(b, c, d, a, cx->u.w[R4B3 ], S4_3, T4_3);
  358. II(a, b, c, d, cx->u.w[R4B4 ], S4_0, T4_4);
  359. II(d, a, b, c, cx->u.w[R4B5 ], S4_1, T4_5);
  360. II(c, d, a, b, cx->u.w[R4B6 ], S4_2, T4_6);
  361. II(b, c, d, a, cx->u.w[R4B7 ], S4_3, T4_7);
  362. II(a, b, c, d, cx->u.w[R4B8 ], S4_0, T4_8);
  363. II(d, a, b, c, cx->u.w[R4B9 ], S4_1, T4_9);
  364. II(c, d, a, b, cx->u.w[R4B10], S4_2, T4_10);
  365. II(b, c, d, a, cx->u.w[R4B11], S4_3, T4_11);
  366. II(a, b, c, d, cx->u.w[R4B12], S4_0, T4_12);
  367. II(d, a, b, c, cx->u.w[R4B13], S4_1, T4_13);
  368. II(c, d, a, b, cx->u.w[R4B14], S4_2, T4_14);
  369. II(b, c, d, a, cx->u.w[R4B15], S4_3, T4_15);
  370. cx->cv[0] += a;
  371. cx->cv[1] += b;
  372. cx->cv[2] += c;
  373. cx->cv[3] += d;
  374. }
  375. void 
  376. MD5_Update(MD5Context *cx, const unsigned char *input, unsigned int inputLen)
  377. {
  378. PRUint32 bytesToConsume;
  379. PRUint32 inBufIndex = cx->lsbInput & 63;
  380. /* Add the number of input bytes to the 64-bit input counter. */
  381. addto64(cx->msbInput, cx->lsbInput, inputLen);
  382. if (inBufIndex) {
  383. /* There is already data in the buffer.  Fill with input. */
  384. bytesToConsume = PR_MIN(inputLen, MD5_BUFFER_SIZE - inBufIndex);
  385. memcpy(&cx->inBuf[inBufIndex], input, bytesToConsume);
  386. if (inBufIndex + bytesToConsume >= MD5_BUFFER_SIZE)
  387. /* The buffer is filled.  Run the compression function. */
  388. md5_compress(cx);
  389. /* Remaining input. */
  390. inputLen -= bytesToConsume;
  391. input += bytesToConsume;
  392. }
  393. /* Iterate over 64-byte chunks of the message. */
  394. while (inputLen >= MD5_BUFFER_SIZE) {
  395. memcpy(cx->inBuf, input, MD5_BUFFER_SIZE);
  396. md5_compress(cx);
  397. inputLen -= MD5_BUFFER_SIZE;
  398. input += MD5_BUFFER_SIZE;
  399. }
  400. /* Tail of message (message bytes mod 64). */
  401. if (inputLen)
  402. memcpy(cx->inBuf, input, inputLen);
  403. }
  404. static const unsigned char padbytes[] = {
  405. 0x80, 0x00, 0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
  406. 0x00, 0x00, 0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
  407. 0x00, 0x00, 0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
  408. 0x00, 0x00, 0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
  409. 0x00, 0x00, 0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
  410. 0x00, 0x00, 0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
  411. 0x00, 0x00, 0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
  412. 0x00, 0x00, 0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
  413. 0x00, 0x00, 0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
  414. 0x00, 0x00, 0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
  415. 0x00, 0x00, 0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
  416. 0x00, 0x00, 0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00
  417. };
  418. void 
  419. MD5_End(MD5Context *cx, unsigned char *digest,
  420.         unsigned int *digestLen, unsigned int maxDigestLen)
  421. {
  422. PRUint32 tmp;
  423. PRUint32 lowInput, highInput;
  424. PRUint32 inBufIndex = cx->lsbInput & 63;
  425. if (maxDigestLen < MD5_HASH_LEN) {
  426. PORT_SetError(SEC_ERROR_INVALID_ARGS);
  427. return;
  428. }
  429. /* Copy out the length of bits input before padding. */
  430. lowInput = cx->lsbInput; 
  431. highInput = (cx->msbInput << 3) | (lowInput >> 29);
  432. lowInput <<= 3;
  433. if (inBufIndex < MD5_END_BUFFER) {
  434. MD5_Update(cx, padbytes, MD5_END_BUFFER - inBufIndex);
  435. } else {
  436. MD5_Update(cx, padbytes, 
  437.            MD5_END_BUFFER + MD5_BUFFER_SIZE - inBufIndex);
  438. }
  439. /* Store the number of bytes input (before padding) in final 64 bits. */
  440. cx->u.w[14] = lendian(lowInput);
  441. cx->u.w[15] = lendian(highInput);
  442. /* Final call to compress. */
  443. md5_compress(cx);
  444. /* Copy the resulting values out of the chain variables into return buf. */
  445. *digestLen = MD5_HASH_LEN;
  446. #ifndef IS_LITTLE_ENDIAN
  447. cx->cv[0] = lendian(cx->cv[0]);
  448. cx->cv[1] = lendian(cx->cv[1]);
  449. cx->cv[2] = lendian(cx->cv[2]);
  450. cx->cv[3] = lendian(cx->cv[3]);
  451. #endif
  452. memcpy(digest, cx->cv, MD5_HASH_LEN);
  453. }
  454. unsigned int 
  455. MD5_FlattenSize(MD5Context *cx)
  456. {
  457. return sizeof(*cx);
  458. }
  459. SECStatus 
  460. MD5_Flatten(MD5Context *cx, unsigned char *space)
  461. {
  462. memcpy(space, cx, sizeof(*cx));
  463. return SECSuccess;
  464. }
  465. MD5Context * 
  466. MD5_Resurrect(unsigned char *space, void *arg)
  467. {
  468. MD5Context *cx = MD5_NewContext();
  469. if (cx)
  470. memcpy(cx, space, sizeof(*cx));
  471. return cx;
  472. }
  473. void 
  474. MD5_TraceState(MD5Context *cx)
  475. {
  476. PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
  477. }