security/nss/lib/freebl/md5.c

changeset 0
6474c204b198
     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 +}

mercurial