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