| OLD | NEW |
| (Empty) |
| 1 /* This Source Code Form is subject to the terms of the Mozilla Public | |
| 2 * License, v. 2.0. If a copy of the MPL was not distributed with this | |
| 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
| 4 | |
| 5 #ifdef FREEBL_NO_DEPEND | |
| 6 #include "stubs.h" | |
| 7 #endif | |
| 8 | |
| 9 #include "prerr.h" | |
| 10 #include "secerr.h" | |
| 11 | |
| 12 #include "prtypes.h" | |
| 13 #include "prlong.h" | |
| 14 | |
| 15 #include "blapi.h" | |
| 16 | |
| 17 #define MD5_HASH_LEN 16 | |
| 18 #define MD5_BUFFER_SIZE 64 | |
| 19 #define MD5_END_BUFFER (MD5_BUFFER_SIZE - 8) | |
| 20 | |
| 21 #define CV0_1 0x67452301 | |
| 22 #define CV0_2 0xefcdab89 | |
| 23 #define CV0_3 0x98badcfe | |
| 24 #define CV0_4 0x10325476 | |
| 25 | |
| 26 #define T1_0 0xd76aa478 | |
| 27 #define T1_1 0xe8c7b756 | |
| 28 #define T1_2 0x242070db | |
| 29 #define T1_3 0xc1bdceee | |
| 30 #define T1_4 0xf57c0faf | |
| 31 #define T1_5 0x4787c62a | |
| 32 #define T1_6 0xa8304613 | |
| 33 #define T1_7 0xfd469501 | |
| 34 #define T1_8 0x698098d8 | |
| 35 #define T1_9 0x8b44f7af | |
| 36 #define T1_10 0xffff5bb1 | |
| 37 #define T1_11 0x895cd7be | |
| 38 #define T1_12 0x6b901122 | |
| 39 #define T1_13 0xfd987193 | |
| 40 #define T1_14 0xa679438e | |
| 41 #define T1_15 0x49b40821 | |
| 42 | |
| 43 #define T2_0 0xf61e2562 | |
| 44 #define T2_1 0xc040b340 | |
| 45 #define T2_2 0x265e5a51 | |
| 46 #define T2_3 0xe9b6c7aa | |
| 47 #define T2_4 0xd62f105d | |
| 48 #define T2_5 0x02441453 | |
| 49 #define T2_6 0xd8a1e681 | |
| 50 #define T2_7 0xe7d3fbc8 | |
| 51 #define T2_8 0x21e1cde6 | |
| 52 #define T2_9 0xc33707d6 | |
| 53 #define T2_10 0xf4d50d87 | |
| 54 #define T2_11 0x455a14ed | |
| 55 #define T2_12 0xa9e3e905 | |
| 56 #define T2_13 0xfcefa3f8 | |
| 57 #define T2_14 0x676f02d9 | |
| 58 #define T2_15 0x8d2a4c8a | |
| 59 | |
| 60 #define T3_0 0xfffa3942 | |
| 61 #define T3_1 0x8771f681 | |
| 62 #define T3_2 0x6d9d6122 | |
| 63 #define T3_3 0xfde5380c | |
| 64 #define T3_4 0xa4beea44 | |
| 65 #define T3_5 0x4bdecfa9 | |
| 66 #define T3_6 0xf6bb4b60 | |
| 67 #define T3_7 0xbebfbc70 | |
| 68 #define T3_8 0x289b7ec6 | |
| 69 #define T3_9 0xeaa127fa | |
| 70 #define T3_10 0xd4ef3085 | |
| 71 #define T3_11 0x04881d05 | |
| 72 #define T3_12 0xd9d4d039 | |
| 73 #define T3_13 0xe6db99e5 | |
| 74 #define T3_14 0x1fa27cf8 | |
| 75 #define T3_15 0xc4ac5665 | |
| 76 | |
| 77 #define T4_0 0xf4292244 | |
| 78 #define T4_1 0x432aff97 | |
| 79 #define T4_2 0xab9423a7 | |
| 80 #define T4_3 0xfc93a039 | |
| 81 #define T4_4 0x655b59c3 | |
| 82 #define T4_5 0x8f0ccc92 | |
| 83 #define T4_6 0xffeff47d | |
| 84 #define T4_7 0x85845dd1 | |
| 85 #define T4_8 0x6fa87e4f | |
| 86 #define T4_9 0xfe2ce6e0 | |
| 87 #define T4_10 0xa3014314 | |
| 88 #define T4_11 0x4e0811a1 | |
| 89 #define T4_12 0xf7537e82 | |
| 90 #define T4_13 0xbd3af235 | |
| 91 #define T4_14 0x2ad7d2bb | |
| 92 #define T4_15 0xeb86d391 | |
| 93 | |
| 94 #define R1B0 0 | |
| 95 #define R1B1 1 | |
| 96 #define R1B2 2 | |
| 97 #define R1B3 3 | |
| 98 #define R1B4 4 | |
| 99 #define R1B5 5 | |
| 100 #define R1B6 6 | |
| 101 #define R1B7 7 | |
| 102 #define R1B8 8 | |
| 103 #define R1B9 9 | |
| 104 #define R1B10 10 | |
| 105 #define R1B11 11 | |
| 106 #define R1B12 12 | |
| 107 #define R1B13 13 | |
| 108 #define R1B14 14 | |
| 109 #define R1B15 15 | |
| 110 | |
| 111 #define R2B0 1 | |
| 112 #define R2B1 6 | |
| 113 #define R2B2 11 | |
| 114 #define R2B3 0 | |
| 115 #define R2B4 5 | |
| 116 #define R2B5 10 | |
| 117 #define R2B6 15 | |
| 118 #define R2B7 4 | |
| 119 #define R2B8 9 | |
| 120 #define R2B9 14 | |
| 121 #define R2B10 3 | |
| 122 #define R2B11 8 | |
| 123 #define R2B12 13 | |
| 124 #define R2B13 2 | |
| 125 #define R2B14 7 | |
| 126 #define R2B15 12 | |
| 127 | |
| 128 #define R3B0 5 | |
| 129 #define R3B1 8 | |
| 130 #define R3B2 11 | |
| 131 #define R3B3 14 | |
| 132 #define R3B4 1 | |
| 133 #define R3B5 4 | |
| 134 #define R3B6 7 | |
| 135 #define R3B7 10 | |
| 136 #define R3B8 13 | |
| 137 #define R3B9 0 | |
| 138 #define R3B10 3 | |
| 139 #define R3B11 6 | |
| 140 #define R3B12 9 | |
| 141 #define R3B13 12 | |
| 142 #define R3B14 15 | |
| 143 #define R3B15 2 | |
| 144 | |
| 145 #define R4B0 0 | |
| 146 #define R4B1 7 | |
| 147 #define R4B2 14 | |
| 148 #define R4B3 5 | |
| 149 #define R4B4 12 | |
| 150 #define R4B5 3 | |
| 151 #define R4B6 10 | |
| 152 #define R4B7 1 | |
| 153 #define R4B8 8 | |
| 154 #define R4B9 15 | |
| 155 #define R4B10 6 | |
| 156 #define R4B11 13 | |
| 157 #define R4B12 4 | |
| 158 #define R4B13 11 | |
| 159 #define R4B14 2 | |
| 160 #define R4B15 9 | |
| 161 | |
| 162 #define S1_0 7 | |
| 163 #define S1_1 12 | |
| 164 #define S1_2 17 | |
| 165 #define S1_3 22 | |
| 166 | |
| 167 #define S2_0 5 | |
| 168 #define S2_1 9 | |
| 169 #define S2_2 14 | |
| 170 #define S2_3 20 | |
| 171 | |
| 172 #define S3_0 4 | |
| 173 #define S3_1 11 | |
| 174 #define S3_2 16 | |
| 175 #define S3_3 23 | |
| 176 | |
| 177 #define S4_0 6 | |
| 178 #define S4_1 10 | |
| 179 #define S4_2 15 | |
| 180 #define S4_3 21 | |
| 181 | |
| 182 struct MD5ContextStr { | |
| 183 PRUint32 lsbInput; | |
| 184 PRUint32 msbInput; | |
| 185 PRUint32 cv[4]; | |
| 186 union { | |
| 187 PRUint8 b[64]; | |
| 188 PRUint32 w[16]; | |
| 189 } u; | |
| 190 }; | |
| 191 | |
| 192 #define inBuf u.b | |
| 193 | |
| 194 SECStatus | |
| 195 MD5_Hash(unsigned char *dest, const char *src) | |
| 196 { | |
| 197 return MD5_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src)); | |
| 198 } | |
| 199 | |
| 200 SECStatus | |
| 201 MD5_HashBuf(unsigned char *dest, const unsigned char *src, uint32 src_length) | |
| 202 { | |
| 203 unsigned int len; | |
| 204 MD5Context cx; | |
| 205 | |
| 206 MD5_Begin(&cx); | |
| 207 MD5_Update(&cx, src, src_length); | |
| 208 MD5_End(&cx, dest, &len, MD5_HASH_LEN); | |
| 209 memset(&cx, 0, sizeof cx); | |
| 210 return SECSuccess; | |
| 211 } | |
| 212 | |
| 213 MD5Context * | |
| 214 MD5_NewContext(void) | |
| 215 { | |
| 216 /* no need to ZAlloc, MD5_Begin will init the context */ | |
| 217 MD5Context *cx = (MD5Context *)PORT_Alloc(sizeof(MD5Context)); | |
| 218 if (cx == NULL) { | |
| 219 PORT_SetError(PR_OUT_OF_MEMORY_ERROR); | |
| 220 return NULL; | |
| 221 } | |
| 222 return cx; | |
| 223 } | |
| 224 | |
| 225 void | |
| 226 MD5_DestroyContext(MD5Context *cx, PRBool freeit) | |
| 227 { | |
| 228 memset(cx, 0, sizeof *cx); | |
| 229 if (freeit) { | |
| 230 PORT_Free(cx); | |
| 231 } | |
| 232 } | |
| 233 | |
| 234 void | |
| 235 MD5_Begin(MD5Context *cx) | |
| 236 { | |
| 237 cx->lsbInput = 0; | |
| 238 cx->msbInput = 0; | |
| 239 /* memset(cx->inBuf, 0, sizeof(cx->inBuf)); */ | |
| 240 cx->cv[0] = CV0_1; | |
| 241 cx->cv[1] = CV0_2; | |
| 242 cx->cv[2] = CV0_3; | |
| 243 cx->cv[3] = CV0_4; | |
| 244 } | |
| 245 | |
| 246 #define cls(i32, s) (tmp = i32, tmp << s | tmp >> (32 - s)) | |
| 247 | |
| 248 #if defined(SOLARIS) || defined(HPUX) | |
| 249 #define addto64(sumhigh, sumlow, addend) \ | |
| 250 sumlow += addend; sumhigh += (sumlow < addend); | |
| 251 #else | |
| 252 #define addto64(sumhigh, sumlow, addend) \ | |
| 253 sumlow += addend; if (sumlow < addend) ++sumhigh; | |
| 254 #endif | |
| 255 | |
| 256 #define MASK 0x00ff00ff | |
| 257 #ifdef IS_LITTLE_ENDIAN | |
| 258 #define lendian(i32) \ | |
| 259 (i32) | |
| 260 #else | |
| 261 #define lendian(i32) \ | |
| 262 (tmp = i32 >> 16 | i32 << 16, (tmp & MASK) << 8 | tmp >> 8 & MASK) | |
| 263 #endif | |
| 264 | |
| 265 #ifndef IS_LITTLE_ENDIAN | |
| 266 | |
| 267 #define lebytes(b4) \ | |
| 268 ((b4)[3] << 24 | (b4)[2] << 16 | (b4)[1] << 8 | (b4)[0]) | |
| 269 | |
| 270 static void | |
| 271 md5_prep_state_le(MD5Context *cx) | |
| 272 { | |
| 273 PRUint32 tmp; | |
| 274 cx->u.w[0] = lendian(cx->u.w[0]); | |
| 275 cx->u.w[1] = lendian(cx->u.w[1]); | |
| 276 cx->u.w[2] = lendian(cx->u.w[2]); | |
| 277 cx->u.w[3] = lendian(cx->u.w[3]); | |
| 278 cx->u.w[4] = lendian(cx->u.w[4]); | |
| 279 cx->u.w[5] = lendian(cx->u.w[5]); | |
| 280 cx->u.w[6] = lendian(cx->u.w[6]); | |
| 281 cx->u.w[7] = lendian(cx->u.w[7]); | |
| 282 cx->u.w[8] = lendian(cx->u.w[8]); | |
| 283 cx->u.w[9] = lendian(cx->u.w[9]); | |
| 284 cx->u.w[10] = lendian(cx->u.w[10]); | |
| 285 cx->u.w[11] = lendian(cx->u.w[11]); | |
| 286 cx->u.w[12] = lendian(cx->u.w[12]); | |
| 287 cx->u.w[13] = lendian(cx->u.w[13]); | |
| 288 cx->u.w[14] = lendian(cx->u.w[14]); | |
| 289 cx->u.w[15] = lendian(cx->u.w[15]); | |
| 290 } | |
| 291 | |
| 292 static void | |
| 293 md5_prep_buffer_le(MD5Context *cx, const PRUint8 *beBuf) | |
| 294 { | |
| 295 cx->u.w[0] = lebytes(&beBuf[0]); | |
| 296 cx->u.w[1] = lebytes(&beBuf[4]); | |
| 297 cx->u.w[2] = lebytes(&beBuf[8]); | |
| 298 cx->u.w[3] = lebytes(&beBuf[12]); | |
| 299 cx->u.w[4] = lebytes(&beBuf[16]); | |
| 300 cx->u.w[5] = lebytes(&beBuf[20]); | |
| 301 cx->u.w[6] = lebytes(&beBuf[24]); | |
| 302 cx->u.w[7] = lebytes(&beBuf[28]); | |
| 303 cx->u.w[8] = lebytes(&beBuf[32]); | |
| 304 cx->u.w[9] = lebytes(&beBuf[36]); | |
| 305 cx->u.w[10] = lebytes(&beBuf[40]); | |
| 306 cx->u.w[11] = lebytes(&beBuf[44]); | |
| 307 cx->u.w[12] = lebytes(&beBuf[48]); | |
| 308 cx->u.w[13] = lebytes(&beBuf[52]); | |
| 309 cx->u.w[14] = lebytes(&beBuf[56]); | |
| 310 cx->u.w[15] = lebytes(&beBuf[60]); | |
| 311 } | |
| 312 #endif | |
| 313 | |
| 314 | |
| 315 #define F(X, Y, Z) \ | |
| 316 ((X & Y) | ((~X) & Z)) | |
| 317 | |
| 318 #define G(X, Y, Z) \ | |
| 319 ((X & Z) | (Y & (~Z))) | |
| 320 | |
| 321 #define H(X, Y, Z) \ | |
| 322 (X ^ Y ^ Z) | |
| 323 | |
| 324 #define I(X, Y, Z) \ | |
| 325 (Y ^ (X | (~Z))) | |
| 326 | |
| 327 #define FF(a, b, c, d, bufint, s, ti) \ | |
| 328 a = b + cls(a + F(b, c, d) + bufint + ti, s) | |
| 329 | |
| 330 #define GG(a, b, c, d, bufint, s, ti) \ | |
| 331 a = b + cls(a + G(b, c, d) + bufint + ti, s) | |
| 332 | |
| 333 #define HH(a, b, c, d, bufint, s, ti) \ | |
| 334 a = b + cls(a + H(b, c, d) + bufint + ti, s) | |
| 335 | |
| 336 #define II(a, b, c, d, bufint, s, ti) \ | |
| 337 a = b + cls(a + I(b, c, d) + bufint + ti, s) | |
| 338 | |
| 339 static void | |
| 340 md5_compress(MD5Context *cx, const PRUint32 *wBuf) | |
| 341 { | |
| 342 PRUint32 a, b, c, d; | |
| 343 PRUint32 tmp; | |
| 344 a = cx->cv[0]; | |
| 345 b = cx->cv[1]; | |
| 346 c = cx->cv[2]; | |
| 347 d = cx->cv[3]; | |
| 348 FF(a, b, c, d, wBuf[R1B0 ], S1_0, T1_0); | |
| 349 FF(d, a, b, c, wBuf[R1B1 ], S1_1, T1_1); | |
| 350 FF(c, d, a, b, wBuf[R1B2 ], S1_2, T1_2); | |
| 351 FF(b, c, d, a, wBuf[R1B3 ], S1_3, T1_3); | |
| 352 FF(a, b, c, d, wBuf[R1B4 ], S1_0, T1_4); | |
| 353 FF(d, a, b, c, wBuf[R1B5 ], S1_1, T1_5); | |
| 354 FF(c, d, a, b, wBuf[R1B6 ], S1_2, T1_6); | |
| 355 FF(b, c, d, a, wBuf[R1B7 ], S1_3, T1_7); | |
| 356 FF(a, b, c, d, wBuf[R1B8 ], S1_0, T1_8); | |
| 357 FF(d, a, b, c, wBuf[R1B9 ], S1_1, T1_9); | |
| 358 FF(c, d, a, b, wBuf[R1B10], S1_2, T1_10); | |
| 359 FF(b, c, d, a, wBuf[R1B11], S1_3, T1_11); | |
| 360 FF(a, b, c, d, wBuf[R1B12], S1_0, T1_12); | |
| 361 FF(d, a, b, c, wBuf[R1B13], S1_1, T1_13); | |
| 362 FF(c, d, a, b, wBuf[R1B14], S1_2, T1_14); | |
| 363 FF(b, c, d, a, wBuf[R1B15], S1_3, T1_15); | |
| 364 GG(a, b, c, d, wBuf[R2B0 ], S2_0, T2_0); | |
| 365 GG(d, a, b, c, wBuf[R2B1 ], S2_1, T2_1); | |
| 366 GG(c, d, a, b, wBuf[R2B2 ], S2_2, T2_2); | |
| 367 GG(b, c, d, a, wBuf[R2B3 ], S2_3, T2_3); | |
| 368 GG(a, b, c, d, wBuf[R2B4 ], S2_0, T2_4); | |
| 369 GG(d, a, b, c, wBuf[R2B5 ], S2_1, T2_5); | |
| 370 GG(c, d, a, b, wBuf[R2B6 ], S2_2, T2_6); | |
| 371 GG(b, c, d, a, wBuf[R2B7 ], S2_3, T2_7); | |
| 372 GG(a, b, c, d, wBuf[R2B8 ], S2_0, T2_8); | |
| 373 GG(d, a, b, c, wBuf[R2B9 ], S2_1, T2_9); | |
| 374 GG(c, d, a, b, wBuf[R2B10], S2_2, T2_10); | |
| 375 GG(b, c, d, a, wBuf[R2B11], S2_3, T2_11); | |
| 376 GG(a, b, c, d, wBuf[R2B12], S2_0, T2_12); | |
| 377 GG(d, a, b, c, wBuf[R2B13], S2_1, T2_13); | |
| 378 GG(c, d, a, b, wBuf[R2B14], S2_2, T2_14); | |
| 379 GG(b, c, d, a, wBuf[R2B15], S2_3, T2_15); | |
| 380 HH(a, b, c, d, wBuf[R3B0 ], S3_0, T3_0); | |
| 381 HH(d, a, b, c, wBuf[R3B1 ], S3_1, T3_1); | |
| 382 HH(c, d, a, b, wBuf[R3B2 ], S3_2, T3_2); | |
| 383 HH(b, c, d, a, wBuf[R3B3 ], S3_3, T3_3); | |
| 384 HH(a, b, c, d, wBuf[R3B4 ], S3_0, T3_4); | |
| 385 HH(d, a, b, c, wBuf[R3B5 ], S3_1, T3_5); | |
| 386 HH(c, d, a, b, wBuf[R3B6 ], S3_2, T3_6); | |
| 387 HH(b, c, d, a, wBuf[R3B7 ], S3_3, T3_7); | |
| 388 HH(a, b, c, d, wBuf[R3B8 ], S3_0, T3_8); | |
| 389 HH(d, a, b, c, wBuf[R3B9 ], S3_1, T3_9); | |
| 390 HH(c, d, a, b, wBuf[R3B10], S3_2, T3_10); | |
| 391 HH(b, c, d, a, wBuf[R3B11], S3_3, T3_11); | |
| 392 HH(a, b, c, d, wBuf[R3B12], S3_0, T3_12); | |
| 393 HH(d, a, b, c, wBuf[R3B13], S3_1, T3_13); | |
| 394 HH(c, d, a, b, wBuf[R3B14], S3_2, T3_14); | |
| 395 HH(b, c, d, a, wBuf[R3B15], S3_3, T3_15); | |
| 396 II(a, b, c, d, wBuf[R4B0 ], S4_0, T4_0); | |
| 397 II(d, a, b, c, wBuf[R4B1 ], S4_1, T4_1); | |
| 398 II(c, d, a, b, wBuf[R4B2 ], S4_2, T4_2); | |
| 399 II(b, c, d, a, wBuf[R4B3 ], S4_3, T4_3); | |
| 400 II(a, b, c, d, wBuf[R4B4 ], S4_0, T4_4); | |
| 401 II(d, a, b, c, wBuf[R4B5 ], S4_1, T4_5); | |
| 402 II(c, d, a, b, wBuf[R4B6 ], S4_2, T4_6); | |
| 403 II(b, c, d, a, wBuf[R4B7 ], S4_3, T4_7); | |
| 404 II(a, b, c, d, wBuf[R4B8 ], S4_0, T4_8); | |
| 405 II(d, a, b, c, wBuf[R4B9 ], S4_1, T4_9); | |
| 406 II(c, d, a, b, wBuf[R4B10], S4_2, T4_10); | |
| 407 II(b, c, d, a, wBuf[R4B11], S4_3, T4_11); | |
| 408 II(a, b, c, d, wBuf[R4B12], S4_0, T4_12); | |
| 409 II(d, a, b, c, wBuf[R4B13], S4_1, T4_13); | |
| 410 II(c, d, a, b, wBuf[R4B14], S4_2, T4_14); | |
| 411 II(b, c, d, a, wBuf[R4B15], S4_3, T4_15); | |
| 412 cx->cv[0] += a; | |
| 413 cx->cv[1] += b; | |
| 414 cx->cv[2] += c; | |
| 415 cx->cv[3] += d; | |
| 416 } | |
| 417 | |
| 418 void | |
| 419 MD5_Update(MD5Context *cx, const unsigned char *input, unsigned int inputLen) | |
| 420 { | |
| 421 PRUint32 bytesToConsume; | |
| 422 PRUint32 inBufIndex = cx->lsbInput & 63; | |
| 423 const PRUint32 *wBuf; | |
| 424 | |
| 425 /* Add the number of input bytes to the 64-bit input counter. */ | |
| 426 addto64(cx->msbInput, cx->lsbInput, inputLen); | |
| 427 if (inBufIndex) { | |
| 428 /* There is already data in the buffer. Fill with input. */ | |
| 429 bytesToConsume = PR_MIN(inputLen, MD5_BUFFER_SIZE - inBufIndex); | |
| 430 memcpy(&cx->inBuf[inBufIndex], input, bytesToConsume); | |
| 431 if (inBufIndex + bytesToConsume >= MD5_BUFFER_SIZE) { | |
| 432 /* The buffer is filled. Run the compression function.
*/ | |
| 433 #ifndef IS_LITTLE_ENDIAN | |
| 434 md5_prep_state_le(cx); | |
| 435 #endif | |
| 436 md5_compress(cx, cx->u.w); | |
| 437 } | |
| 438 /* Remaining input. */ | |
| 439 inputLen -= bytesToConsume; | |
| 440 input += bytesToConsume; | |
| 441 } | |
| 442 | |
| 443 /* Iterate over 64-byte chunks of the message. */ | |
| 444 while (inputLen >= MD5_BUFFER_SIZE) { | |
| 445 #ifdef IS_LITTLE_ENDIAN | |
| 446 #ifdef NSS_X86_OR_X64 | |
| 447 /* x86 can handle arithmetic on non-word-aligned buffers */ | |
| 448 wBuf = (PRUint32 *)input; | |
| 449 #else | |
| 450 if ((ptrdiff_t)input & 0x3) { | |
| 451 /* buffer not aligned, copy it to force alignment */ | |
| 452 memcpy(cx->inBuf, input, MD5_BUFFER_SIZE); | |
| 453 wBuf = cx->u.w; | |
| 454 } else { | |
| 455 /* buffer is aligned */ | |
| 456 wBuf = (PRUint32 *)input; | |
| 457 } | |
| 458 #endif | |
| 459 #else | |
| 460 md5_prep_buffer_le(cx, input); | |
| 461 wBuf = cx->u.w; | |
| 462 #endif | |
| 463 md5_compress(cx, wBuf); | |
| 464 inputLen -= MD5_BUFFER_SIZE; | |
| 465 input += MD5_BUFFER_SIZE; | |
| 466 } | |
| 467 | |
| 468 /* Tail of message (message bytes mod 64). */ | |
| 469 if (inputLen) | |
| 470 memcpy(cx->inBuf, input, inputLen); | |
| 471 } | |
| 472 | |
| 473 static const unsigned char padbytes[] = { | |
| 474 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 475 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 476 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 477 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 478 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 479 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 480 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 481 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 482 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 483 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 484 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 485 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
| 486 }; | |
| 487 | |
| 488 void | |
| 489 MD5_End(MD5Context *cx, unsigned char *digest, | |
| 490 unsigned int *digestLen, unsigned int maxDigestLen) | |
| 491 { | |
| 492 #ifndef IS_LITTLE_ENDIAN | |
| 493 PRUint32 tmp; | |
| 494 #endif | |
| 495 PRUint32 lowInput, highInput; | |
| 496 PRUint32 inBufIndex = cx->lsbInput & 63; | |
| 497 | |
| 498 if (maxDigestLen < MD5_HASH_LEN) { | |
| 499 PORT_SetError(SEC_ERROR_INVALID_ARGS); | |
| 500 return; | |
| 501 } | |
| 502 | |
| 503 /* Copy out the length of bits input before padding. */ | |
| 504 lowInput = cx->lsbInput; | |
| 505 highInput = (cx->msbInput << 3) | (lowInput >> 29); | |
| 506 lowInput <<= 3; | |
| 507 | |
| 508 if (inBufIndex < MD5_END_BUFFER) { | |
| 509 MD5_Update(cx, padbytes, MD5_END_BUFFER - inBufIndex); | |
| 510 } else { | |
| 511 MD5_Update(cx, padbytes, | |
| 512 MD5_END_BUFFER + MD5_BUFFER_SIZE - inBufIndex); | |
| 513 } | |
| 514 | |
| 515 /* Store the number of bytes input (before padding) in final 64 bits. */ | |
| 516 cx->u.w[14] = lendian(lowInput); | |
| 517 cx->u.w[15] = lendian(highInput); | |
| 518 | |
| 519 /* Final call to compress. */ | |
| 520 #ifndef IS_LITTLE_ENDIAN | |
| 521 md5_prep_state_le(cx); | |
| 522 #endif | |
| 523 md5_compress(cx, cx->u.w); | |
| 524 | |
| 525 /* Copy the resulting values out of the chain variables into return buf.
*/ | |
| 526 if (digestLen) | |
| 527 *digestLen = MD5_HASH_LEN; | |
| 528 #ifndef IS_LITTLE_ENDIAN | |
| 529 cx->cv[0] = lendian(cx->cv[0]); | |
| 530 cx->cv[1] = lendian(cx->cv[1]); | |
| 531 cx->cv[2] = lendian(cx->cv[2]); | |
| 532 cx->cv[3] = lendian(cx->cv[3]); | |
| 533 #endif | |
| 534 memcpy(digest, cx->cv, MD5_HASH_LEN); | |
| 535 } | |
| 536 | |
| 537 void | |
| 538 MD5_EndRaw(MD5Context *cx, unsigned char *digest, | |
| 539 unsigned int *digestLen, unsigned int maxDigestLen) | |
| 540 { | |
| 541 #ifndef IS_LITTLE_ENDIAN | |
| 542 PRUint32 tmp; | |
| 543 #endif | |
| 544 PRUint32 cv[4]; | |
| 545 | |
| 546 if (maxDigestLen < MD5_HASH_LEN) { | |
| 547 PORT_SetError(SEC_ERROR_INVALID_ARGS); | |
| 548 return; | |
| 549 } | |
| 550 | |
| 551 memcpy(cv, cx->cv, sizeof(cv)); | |
| 552 #ifndef IS_LITTLE_ENDIAN | |
| 553 cv[0] = lendian(cv[0]); | |
| 554 cv[1] = lendian(cv[1]); | |
| 555 cv[2] = lendian(cv[2]); | |
| 556 cv[3] = lendian(cv[3]); | |
| 557 #endif | |
| 558 memcpy(digest, cv, MD5_HASH_LEN); | |
| 559 if (digestLen) | |
| 560 *digestLen = MD5_HASH_LEN; | |
| 561 } | |
| 562 | |
| 563 unsigned int | |
| 564 MD5_FlattenSize(MD5Context *cx) | |
| 565 { | |
| 566 return sizeof(*cx); | |
| 567 } | |
| 568 | |
| 569 SECStatus | |
| 570 MD5_Flatten(MD5Context *cx, unsigned char *space) | |
| 571 { | |
| 572 memcpy(space, cx, sizeof(*cx)); | |
| 573 return SECSuccess; | |
| 574 } | |
| 575 | |
| 576 MD5Context * | |
| 577 MD5_Resurrect(unsigned char *space, void *arg) | |
| 578 { | |
| 579 MD5Context *cx = MD5_NewContext(); | |
| 580 if (cx) | |
| 581 memcpy(cx, space, sizeof(*cx)); | |
| 582 return cx; | |
| 583 } | |
| 584 | |
| 585 void MD5_Clone(MD5Context *dest, MD5Context *src) | |
| 586 { | |
| 587 memcpy(dest, src, sizeof *dest); | |
| 588 } | |
| 589 | |
| 590 void | |
| 591 MD5_TraceState(MD5Context *cx) | |
| 592 { | |
| 593 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); | |
| 594 } | |
| OLD | NEW |