1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/lib/freebl/md5.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,594 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#ifdef FREEBL_NO_DEPEND 1.9 +#include "stubs.h" 1.10 +#endif 1.11 + 1.12 +#include "prerr.h" 1.13 +#include "secerr.h" 1.14 + 1.15 +#include "prtypes.h" 1.16 +#include "prlong.h" 1.17 + 1.18 +#include "blapi.h" 1.19 + 1.20 +#define MD5_HASH_LEN 16 1.21 +#define MD5_BUFFER_SIZE 64 1.22 +#define MD5_END_BUFFER (MD5_BUFFER_SIZE - 8) 1.23 + 1.24 +#define CV0_1 0x67452301 1.25 +#define CV0_2 0xefcdab89 1.26 +#define CV0_3 0x98badcfe 1.27 +#define CV0_4 0x10325476 1.28 + 1.29 +#define T1_0 0xd76aa478 1.30 +#define T1_1 0xe8c7b756 1.31 +#define T1_2 0x242070db 1.32 +#define T1_3 0xc1bdceee 1.33 +#define T1_4 0xf57c0faf 1.34 +#define T1_5 0x4787c62a 1.35 +#define T1_6 0xa8304613 1.36 +#define T1_7 0xfd469501 1.37 +#define T1_8 0x698098d8 1.38 +#define T1_9 0x8b44f7af 1.39 +#define T1_10 0xffff5bb1 1.40 +#define T1_11 0x895cd7be 1.41 +#define T1_12 0x6b901122 1.42 +#define T1_13 0xfd987193 1.43 +#define T1_14 0xa679438e 1.44 +#define T1_15 0x49b40821 1.45 + 1.46 +#define T2_0 0xf61e2562 1.47 +#define T2_1 0xc040b340 1.48 +#define T2_2 0x265e5a51 1.49 +#define T2_3 0xe9b6c7aa 1.50 +#define T2_4 0xd62f105d 1.51 +#define T2_5 0x02441453 1.52 +#define T2_6 0xd8a1e681 1.53 +#define T2_7 0xe7d3fbc8 1.54 +#define T2_8 0x21e1cde6 1.55 +#define T2_9 0xc33707d6 1.56 +#define T2_10 0xf4d50d87 1.57 +#define T2_11 0x455a14ed 1.58 +#define T2_12 0xa9e3e905 1.59 +#define T2_13 0xfcefa3f8 1.60 +#define T2_14 0x676f02d9 1.61 +#define T2_15 0x8d2a4c8a 1.62 + 1.63 +#define T3_0 0xfffa3942 1.64 +#define T3_1 0x8771f681 1.65 +#define T3_2 0x6d9d6122 1.66 +#define T3_3 0xfde5380c 1.67 +#define T3_4 0xa4beea44 1.68 +#define T3_5 0x4bdecfa9 1.69 +#define T3_6 0xf6bb4b60 1.70 +#define T3_7 0xbebfbc70 1.71 +#define T3_8 0x289b7ec6 1.72 +#define T3_9 0xeaa127fa 1.73 +#define T3_10 0xd4ef3085 1.74 +#define T3_11 0x04881d05 1.75 +#define T3_12 0xd9d4d039 1.76 +#define T3_13 0xe6db99e5 1.77 +#define T3_14 0x1fa27cf8 1.78 +#define T3_15 0xc4ac5665 1.79 + 1.80 +#define T4_0 0xf4292244 1.81 +#define T4_1 0x432aff97 1.82 +#define T4_2 0xab9423a7 1.83 +#define T4_3 0xfc93a039 1.84 +#define T4_4 0x655b59c3 1.85 +#define T4_5 0x8f0ccc92 1.86 +#define T4_6 0xffeff47d 1.87 +#define T4_7 0x85845dd1 1.88 +#define T4_8 0x6fa87e4f 1.89 +#define T4_9 0xfe2ce6e0 1.90 +#define T4_10 0xa3014314 1.91 +#define T4_11 0x4e0811a1 1.92 +#define T4_12 0xf7537e82 1.93 +#define T4_13 0xbd3af235 1.94 +#define T4_14 0x2ad7d2bb 1.95 +#define T4_15 0xeb86d391 1.96 + 1.97 +#define R1B0 0 1.98 +#define R1B1 1 1.99 +#define R1B2 2 1.100 +#define R1B3 3 1.101 +#define R1B4 4 1.102 +#define R1B5 5 1.103 +#define R1B6 6 1.104 +#define R1B7 7 1.105 +#define R1B8 8 1.106 +#define R1B9 9 1.107 +#define R1B10 10 1.108 +#define R1B11 11 1.109 +#define R1B12 12 1.110 +#define R1B13 13 1.111 +#define R1B14 14 1.112 +#define R1B15 15 1.113 + 1.114 +#define R2B0 1 1.115 +#define R2B1 6 1.116 +#define R2B2 11 1.117 +#define R2B3 0 1.118 +#define R2B4 5 1.119 +#define R2B5 10 1.120 +#define R2B6 15 1.121 +#define R2B7 4 1.122 +#define R2B8 9 1.123 +#define R2B9 14 1.124 +#define R2B10 3 1.125 +#define R2B11 8 1.126 +#define R2B12 13 1.127 +#define R2B13 2 1.128 +#define R2B14 7 1.129 +#define R2B15 12 1.130 + 1.131 +#define R3B0 5 1.132 +#define R3B1 8 1.133 +#define R3B2 11 1.134 +#define R3B3 14 1.135 +#define R3B4 1 1.136 +#define R3B5 4 1.137 +#define R3B6 7 1.138 +#define R3B7 10 1.139 +#define R3B8 13 1.140 +#define R3B9 0 1.141 +#define R3B10 3 1.142 +#define R3B11 6 1.143 +#define R3B12 9 1.144 +#define R3B13 12 1.145 +#define R3B14 15 1.146 +#define R3B15 2 1.147 + 1.148 +#define R4B0 0 1.149 +#define R4B1 7 1.150 +#define R4B2 14 1.151 +#define R4B3 5 1.152 +#define R4B4 12 1.153 +#define R4B5 3 1.154 +#define R4B6 10 1.155 +#define R4B7 1 1.156 +#define R4B8 8 1.157 +#define R4B9 15 1.158 +#define R4B10 6 1.159 +#define R4B11 13 1.160 +#define R4B12 4 1.161 +#define R4B13 11 1.162 +#define R4B14 2 1.163 +#define R4B15 9 1.164 + 1.165 +#define S1_0 7 1.166 +#define S1_1 12 1.167 +#define S1_2 17 1.168 +#define S1_3 22 1.169 + 1.170 +#define S2_0 5 1.171 +#define S2_1 9 1.172 +#define S2_2 14 1.173 +#define S2_3 20 1.174 + 1.175 +#define S3_0 4 1.176 +#define S3_1 11 1.177 +#define S3_2 16 1.178 +#define S3_3 23 1.179 + 1.180 +#define S4_0 6 1.181 +#define S4_1 10 1.182 +#define S4_2 15 1.183 +#define S4_3 21 1.184 + 1.185 +struct MD5ContextStr { 1.186 + PRUint32 lsbInput; 1.187 + PRUint32 msbInput; 1.188 + PRUint32 cv[4]; 1.189 + union { 1.190 + PRUint8 b[64]; 1.191 + PRUint32 w[16]; 1.192 + } u; 1.193 +}; 1.194 + 1.195 +#define inBuf u.b 1.196 + 1.197 +SECStatus 1.198 +MD5_Hash(unsigned char *dest, const char *src) 1.199 +{ 1.200 + return MD5_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src)); 1.201 +} 1.202 + 1.203 +SECStatus 1.204 +MD5_HashBuf(unsigned char *dest, const unsigned char *src, PRUint32 src_length) 1.205 +{ 1.206 + unsigned int len; 1.207 + MD5Context cx; 1.208 + 1.209 + MD5_Begin(&cx); 1.210 + MD5_Update(&cx, src, src_length); 1.211 + MD5_End(&cx, dest, &len, MD5_HASH_LEN); 1.212 + memset(&cx, 0, sizeof cx); 1.213 + return SECSuccess; 1.214 +} 1.215 + 1.216 +MD5Context * 1.217 +MD5_NewContext(void) 1.218 +{ 1.219 + /* no need to ZAlloc, MD5_Begin will init the context */ 1.220 + MD5Context *cx = (MD5Context *)PORT_Alloc(sizeof(MD5Context)); 1.221 + if (cx == NULL) { 1.222 + PORT_SetError(PR_OUT_OF_MEMORY_ERROR); 1.223 + return NULL; 1.224 + } 1.225 + return cx; 1.226 +} 1.227 + 1.228 +void 1.229 +MD5_DestroyContext(MD5Context *cx, PRBool freeit) 1.230 +{ 1.231 + memset(cx, 0, sizeof *cx); 1.232 + if (freeit) { 1.233 + PORT_Free(cx); 1.234 + } 1.235 +} 1.236 + 1.237 +void 1.238 +MD5_Begin(MD5Context *cx) 1.239 +{ 1.240 + cx->lsbInput = 0; 1.241 + cx->msbInput = 0; 1.242 +/* memset(cx->inBuf, 0, sizeof(cx->inBuf)); */ 1.243 + cx->cv[0] = CV0_1; 1.244 + cx->cv[1] = CV0_2; 1.245 + cx->cv[2] = CV0_3; 1.246 + cx->cv[3] = CV0_4; 1.247 +} 1.248 + 1.249 +#define cls(i32, s) (tmp = i32, tmp << s | tmp >> (32 - s)) 1.250 + 1.251 +#if defined(SOLARIS) || defined(HPUX) 1.252 +#define addto64(sumhigh, sumlow, addend) \ 1.253 + sumlow += addend; sumhigh += (sumlow < addend); 1.254 +#else 1.255 +#define addto64(sumhigh, sumlow, addend) \ 1.256 + sumlow += addend; if (sumlow < addend) ++sumhigh; 1.257 +#endif 1.258 + 1.259 +#define MASK 0x00ff00ff 1.260 +#ifdef IS_LITTLE_ENDIAN 1.261 +#define lendian(i32) \ 1.262 + (i32) 1.263 +#else 1.264 +#define lendian(i32) \ 1.265 + (tmp = i32 >> 16 | i32 << 16, (tmp & MASK) << 8 | tmp >> 8 & MASK) 1.266 +#endif 1.267 + 1.268 +#ifndef IS_LITTLE_ENDIAN 1.269 + 1.270 +#define lebytes(b4) \ 1.271 + ((b4)[3] << 24 | (b4)[2] << 16 | (b4)[1] << 8 | (b4)[0]) 1.272 + 1.273 +static void 1.274 +md5_prep_state_le(MD5Context *cx) 1.275 +{ 1.276 + PRUint32 tmp; 1.277 + cx->u.w[0] = lendian(cx->u.w[0]); 1.278 + cx->u.w[1] = lendian(cx->u.w[1]); 1.279 + cx->u.w[2] = lendian(cx->u.w[2]); 1.280 + cx->u.w[3] = lendian(cx->u.w[3]); 1.281 + cx->u.w[4] = lendian(cx->u.w[4]); 1.282 + cx->u.w[5] = lendian(cx->u.w[5]); 1.283 + cx->u.w[6] = lendian(cx->u.w[6]); 1.284 + cx->u.w[7] = lendian(cx->u.w[7]); 1.285 + cx->u.w[8] = lendian(cx->u.w[8]); 1.286 + cx->u.w[9] = lendian(cx->u.w[9]); 1.287 + cx->u.w[10] = lendian(cx->u.w[10]); 1.288 + cx->u.w[11] = lendian(cx->u.w[11]); 1.289 + cx->u.w[12] = lendian(cx->u.w[12]); 1.290 + cx->u.w[13] = lendian(cx->u.w[13]); 1.291 + cx->u.w[14] = lendian(cx->u.w[14]); 1.292 + cx->u.w[15] = lendian(cx->u.w[15]); 1.293 +} 1.294 + 1.295 +static void 1.296 +md5_prep_buffer_le(MD5Context *cx, const PRUint8 *beBuf) 1.297 +{ 1.298 + cx->u.w[0] = lebytes(&beBuf[0]); 1.299 + cx->u.w[1] = lebytes(&beBuf[4]); 1.300 + cx->u.w[2] = lebytes(&beBuf[8]); 1.301 + cx->u.w[3] = lebytes(&beBuf[12]); 1.302 + cx->u.w[4] = lebytes(&beBuf[16]); 1.303 + cx->u.w[5] = lebytes(&beBuf[20]); 1.304 + cx->u.w[6] = lebytes(&beBuf[24]); 1.305 + cx->u.w[7] = lebytes(&beBuf[28]); 1.306 + cx->u.w[8] = lebytes(&beBuf[32]); 1.307 + cx->u.w[9] = lebytes(&beBuf[36]); 1.308 + cx->u.w[10] = lebytes(&beBuf[40]); 1.309 + cx->u.w[11] = lebytes(&beBuf[44]); 1.310 + cx->u.w[12] = lebytes(&beBuf[48]); 1.311 + cx->u.w[13] = lebytes(&beBuf[52]); 1.312 + cx->u.w[14] = lebytes(&beBuf[56]); 1.313 + cx->u.w[15] = lebytes(&beBuf[60]); 1.314 +} 1.315 +#endif 1.316 + 1.317 + 1.318 +#define F(X, Y, Z) \ 1.319 + ((X & Y) | ((~X) & Z)) 1.320 + 1.321 +#define G(X, Y, Z) \ 1.322 + ((X & Z) | (Y & (~Z))) 1.323 + 1.324 +#define H(X, Y, Z) \ 1.325 + (X ^ Y ^ Z) 1.326 + 1.327 +#define I(X, Y, Z) \ 1.328 + (Y ^ (X | (~Z))) 1.329 + 1.330 +#define FF(a, b, c, d, bufint, s, ti) \ 1.331 + a = b + cls(a + F(b, c, d) + bufint + ti, s) 1.332 + 1.333 +#define GG(a, b, c, d, bufint, s, ti) \ 1.334 + a = b + cls(a + G(b, c, d) + bufint + ti, s) 1.335 + 1.336 +#define HH(a, b, c, d, bufint, s, ti) \ 1.337 + a = b + cls(a + H(b, c, d) + bufint + ti, s) 1.338 + 1.339 +#define II(a, b, c, d, bufint, s, ti) \ 1.340 + a = b + cls(a + I(b, c, d) + bufint + ti, s) 1.341 + 1.342 +static void 1.343 +md5_compress(MD5Context *cx, const PRUint32 *wBuf) 1.344 +{ 1.345 + PRUint32 a, b, c, d; 1.346 + PRUint32 tmp; 1.347 + a = cx->cv[0]; 1.348 + b = cx->cv[1]; 1.349 + c = cx->cv[2]; 1.350 + d = cx->cv[3]; 1.351 + FF(a, b, c, d, wBuf[R1B0 ], S1_0, T1_0); 1.352 + FF(d, a, b, c, wBuf[R1B1 ], S1_1, T1_1); 1.353 + FF(c, d, a, b, wBuf[R1B2 ], S1_2, T1_2); 1.354 + FF(b, c, d, a, wBuf[R1B3 ], S1_3, T1_3); 1.355 + FF(a, b, c, d, wBuf[R1B4 ], S1_0, T1_4); 1.356 + FF(d, a, b, c, wBuf[R1B5 ], S1_1, T1_5); 1.357 + FF(c, d, a, b, wBuf[R1B6 ], S1_2, T1_6); 1.358 + FF(b, c, d, a, wBuf[R1B7 ], S1_3, T1_7); 1.359 + FF(a, b, c, d, wBuf[R1B8 ], S1_0, T1_8); 1.360 + FF(d, a, b, c, wBuf[R1B9 ], S1_1, T1_9); 1.361 + FF(c, d, a, b, wBuf[R1B10], S1_2, T1_10); 1.362 + FF(b, c, d, a, wBuf[R1B11], S1_3, T1_11); 1.363 + FF(a, b, c, d, wBuf[R1B12], S1_0, T1_12); 1.364 + FF(d, a, b, c, wBuf[R1B13], S1_1, T1_13); 1.365 + FF(c, d, a, b, wBuf[R1B14], S1_2, T1_14); 1.366 + FF(b, c, d, a, wBuf[R1B15], S1_3, T1_15); 1.367 + GG(a, b, c, d, wBuf[R2B0 ], S2_0, T2_0); 1.368 + GG(d, a, b, c, wBuf[R2B1 ], S2_1, T2_1); 1.369 + GG(c, d, a, b, wBuf[R2B2 ], S2_2, T2_2); 1.370 + GG(b, c, d, a, wBuf[R2B3 ], S2_3, T2_3); 1.371 + GG(a, b, c, d, wBuf[R2B4 ], S2_0, T2_4); 1.372 + GG(d, a, b, c, wBuf[R2B5 ], S2_1, T2_5); 1.373 + GG(c, d, a, b, wBuf[R2B6 ], S2_2, T2_6); 1.374 + GG(b, c, d, a, wBuf[R2B7 ], S2_3, T2_7); 1.375 + GG(a, b, c, d, wBuf[R2B8 ], S2_0, T2_8); 1.376 + GG(d, a, b, c, wBuf[R2B9 ], S2_1, T2_9); 1.377 + GG(c, d, a, b, wBuf[R2B10], S2_2, T2_10); 1.378 + GG(b, c, d, a, wBuf[R2B11], S2_3, T2_11); 1.379 + GG(a, b, c, d, wBuf[R2B12], S2_0, T2_12); 1.380 + GG(d, a, b, c, wBuf[R2B13], S2_1, T2_13); 1.381 + GG(c, d, a, b, wBuf[R2B14], S2_2, T2_14); 1.382 + GG(b, c, d, a, wBuf[R2B15], S2_3, T2_15); 1.383 + HH(a, b, c, d, wBuf[R3B0 ], S3_0, T3_0); 1.384 + HH(d, a, b, c, wBuf[R3B1 ], S3_1, T3_1); 1.385 + HH(c, d, a, b, wBuf[R3B2 ], S3_2, T3_2); 1.386 + HH(b, c, d, a, wBuf[R3B3 ], S3_3, T3_3); 1.387 + HH(a, b, c, d, wBuf[R3B4 ], S3_0, T3_4); 1.388 + HH(d, a, b, c, wBuf[R3B5 ], S3_1, T3_5); 1.389 + HH(c, d, a, b, wBuf[R3B6 ], S3_2, T3_6); 1.390 + HH(b, c, d, a, wBuf[R3B7 ], S3_3, T3_7); 1.391 + HH(a, b, c, d, wBuf[R3B8 ], S3_0, T3_8); 1.392 + HH(d, a, b, c, wBuf[R3B9 ], S3_1, T3_9); 1.393 + HH(c, d, a, b, wBuf[R3B10], S3_2, T3_10); 1.394 + HH(b, c, d, a, wBuf[R3B11], S3_3, T3_11); 1.395 + HH(a, b, c, d, wBuf[R3B12], S3_0, T3_12); 1.396 + HH(d, a, b, c, wBuf[R3B13], S3_1, T3_13); 1.397 + HH(c, d, a, b, wBuf[R3B14], S3_2, T3_14); 1.398 + HH(b, c, d, a, wBuf[R3B15], S3_3, T3_15); 1.399 + II(a, b, c, d, wBuf[R4B0 ], S4_0, T4_0); 1.400 + II(d, a, b, c, wBuf[R4B1 ], S4_1, T4_1); 1.401 + II(c, d, a, b, wBuf[R4B2 ], S4_2, T4_2); 1.402 + II(b, c, d, a, wBuf[R4B3 ], S4_3, T4_3); 1.403 + II(a, b, c, d, wBuf[R4B4 ], S4_0, T4_4); 1.404 + II(d, a, b, c, wBuf[R4B5 ], S4_1, T4_5); 1.405 + II(c, d, a, b, wBuf[R4B6 ], S4_2, T4_6); 1.406 + II(b, c, d, a, wBuf[R4B7 ], S4_3, T4_7); 1.407 + II(a, b, c, d, wBuf[R4B8 ], S4_0, T4_8); 1.408 + II(d, a, b, c, wBuf[R4B9 ], S4_1, T4_9); 1.409 + II(c, d, a, b, wBuf[R4B10], S4_2, T4_10); 1.410 + II(b, c, d, a, wBuf[R4B11], S4_3, T4_11); 1.411 + II(a, b, c, d, wBuf[R4B12], S4_0, T4_12); 1.412 + II(d, a, b, c, wBuf[R4B13], S4_1, T4_13); 1.413 + II(c, d, a, b, wBuf[R4B14], S4_2, T4_14); 1.414 + II(b, c, d, a, wBuf[R4B15], S4_3, T4_15); 1.415 + cx->cv[0] += a; 1.416 + cx->cv[1] += b; 1.417 + cx->cv[2] += c; 1.418 + cx->cv[3] += d; 1.419 +} 1.420 + 1.421 +void 1.422 +MD5_Update(MD5Context *cx, const unsigned char *input, unsigned int inputLen) 1.423 +{ 1.424 + PRUint32 bytesToConsume; 1.425 + PRUint32 inBufIndex = cx->lsbInput & 63; 1.426 + const PRUint32 *wBuf; 1.427 + 1.428 + /* Add the number of input bytes to the 64-bit input counter. */ 1.429 + addto64(cx->msbInput, cx->lsbInput, inputLen); 1.430 + if (inBufIndex) { 1.431 + /* There is already data in the buffer. Fill with input. */ 1.432 + bytesToConsume = PR_MIN(inputLen, MD5_BUFFER_SIZE - inBufIndex); 1.433 + memcpy(&cx->inBuf[inBufIndex], input, bytesToConsume); 1.434 + if (inBufIndex + bytesToConsume >= MD5_BUFFER_SIZE) { 1.435 + /* The buffer is filled. Run the compression function. */ 1.436 +#ifndef IS_LITTLE_ENDIAN 1.437 + md5_prep_state_le(cx); 1.438 +#endif 1.439 + md5_compress(cx, cx->u.w); 1.440 + } 1.441 + /* Remaining input. */ 1.442 + inputLen -= bytesToConsume; 1.443 + input += bytesToConsume; 1.444 + } 1.445 + 1.446 + /* Iterate over 64-byte chunks of the message. */ 1.447 + while (inputLen >= MD5_BUFFER_SIZE) { 1.448 +#ifdef IS_LITTLE_ENDIAN 1.449 +#ifdef NSS_X86_OR_X64 1.450 + /* x86 can handle arithmetic on non-word-aligned buffers */ 1.451 + wBuf = (PRUint32 *)input; 1.452 +#else 1.453 + if ((ptrdiff_t)input & 0x3) { 1.454 + /* buffer not aligned, copy it to force alignment */ 1.455 + memcpy(cx->inBuf, input, MD5_BUFFER_SIZE); 1.456 + wBuf = cx->u.w; 1.457 + } else { 1.458 + /* buffer is aligned */ 1.459 + wBuf = (PRUint32 *)input; 1.460 + } 1.461 +#endif 1.462 +#else 1.463 + md5_prep_buffer_le(cx, input); 1.464 + wBuf = cx->u.w; 1.465 +#endif 1.466 + md5_compress(cx, wBuf); 1.467 + inputLen -= MD5_BUFFER_SIZE; 1.468 + input += MD5_BUFFER_SIZE; 1.469 + } 1.470 + 1.471 + /* Tail of message (message bytes mod 64). */ 1.472 + if (inputLen) 1.473 + memcpy(cx->inBuf, input, inputLen); 1.474 +} 1.475 + 1.476 +static const unsigned char padbytes[] = { 1.477 + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1.478 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1.479 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1.480 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1.481 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1.482 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1.483 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1.484 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1.485 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1.486 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1.487 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1.488 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 1.489 +}; 1.490 + 1.491 +void 1.492 +MD5_End(MD5Context *cx, unsigned char *digest, 1.493 + unsigned int *digestLen, unsigned int maxDigestLen) 1.494 +{ 1.495 +#ifndef IS_LITTLE_ENDIAN 1.496 + PRUint32 tmp; 1.497 +#endif 1.498 + PRUint32 lowInput, highInput; 1.499 + PRUint32 inBufIndex = cx->lsbInput & 63; 1.500 + 1.501 + if (maxDigestLen < MD5_HASH_LEN) { 1.502 + PORT_SetError(SEC_ERROR_INVALID_ARGS); 1.503 + return; 1.504 + } 1.505 + 1.506 + /* Copy out the length of bits input before padding. */ 1.507 + lowInput = cx->lsbInput; 1.508 + highInput = (cx->msbInput << 3) | (lowInput >> 29); 1.509 + lowInput <<= 3; 1.510 + 1.511 + if (inBufIndex < MD5_END_BUFFER) { 1.512 + MD5_Update(cx, padbytes, MD5_END_BUFFER - inBufIndex); 1.513 + } else { 1.514 + MD5_Update(cx, padbytes, 1.515 + MD5_END_BUFFER + MD5_BUFFER_SIZE - inBufIndex); 1.516 + } 1.517 + 1.518 + /* Store the number of bytes input (before padding) in final 64 bits. */ 1.519 + cx->u.w[14] = lendian(lowInput); 1.520 + cx->u.w[15] = lendian(highInput); 1.521 + 1.522 + /* Final call to compress. */ 1.523 +#ifndef IS_LITTLE_ENDIAN 1.524 + md5_prep_state_le(cx); 1.525 +#endif 1.526 + md5_compress(cx, cx->u.w); 1.527 + 1.528 + /* Copy the resulting values out of the chain variables into return buf. */ 1.529 + if (digestLen) 1.530 + *digestLen = MD5_HASH_LEN; 1.531 +#ifndef IS_LITTLE_ENDIAN 1.532 + cx->cv[0] = lendian(cx->cv[0]); 1.533 + cx->cv[1] = lendian(cx->cv[1]); 1.534 + cx->cv[2] = lendian(cx->cv[2]); 1.535 + cx->cv[3] = lendian(cx->cv[3]); 1.536 +#endif 1.537 + memcpy(digest, cx->cv, MD5_HASH_LEN); 1.538 +} 1.539 + 1.540 +void 1.541 +MD5_EndRaw(MD5Context *cx, unsigned char *digest, 1.542 + unsigned int *digestLen, unsigned int maxDigestLen) 1.543 +{ 1.544 +#ifndef IS_LITTLE_ENDIAN 1.545 + PRUint32 tmp; 1.546 +#endif 1.547 + PRUint32 cv[4]; 1.548 + 1.549 + if (maxDigestLen < MD5_HASH_LEN) { 1.550 + PORT_SetError(SEC_ERROR_INVALID_ARGS); 1.551 + return; 1.552 + } 1.553 + 1.554 + memcpy(cv, cx->cv, sizeof(cv)); 1.555 +#ifndef IS_LITTLE_ENDIAN 1.556 + cv[0] = lendian(cv[0]); 1.557 + cv[1] = lendian(cv[1]); 1.558 + cv[2] = lendian(cv[2]); 1.559 + cv[3] = lendian(cv[3]); 1.560 +#endif 1.561 + memcpy(digest, cv, MD5_HASH_LEN); 1.562 + if (digestLen) 1.563 + *digestLen = MD5_HASH_LEN; 1.564 +} 1.565 + 1.566 +unsigned int 1.567 +MD5_FlattenSize(MD5Context *cx) 1.568 +{ 1.569 + return sizeof(*cx); 1.570 +} 1.571 + 1.572 +SECStatus 1.573 +MD5_Flatten(MD5Context *cx, unsigned char *space) 1.574 +{ 1.575 + memcpy(space, cx, sizeof(*cx)); 1.576 + return SECSuccess; 1.577 +} 1.578 + 1.579 +MD5Context * 1.580 +MD5_Resurrect(unsigned char *space, void *arg) 1.581 +{ 1.582 + MD5Context *cx = MD5_NewContext(); 1.583 + if (cx) 1.584 + memcpy(cx, space, sizeof(*cx)); 1.585 + return cx; 1.586 +} 1.587 + 1.588 +void MD5_Clone(MD5Context *dest, MD5Context *src) 1.589 +{ 1.590 + memcpy(dest, src, sizeof *dest); 1.591 +} 1.592 + 1.593 +void 1.594 +MD5_TraceState(MD5Context *cx) 1.595 +{ 1.596 + PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); 1.597 +}