1
/* ***** BEGIN LICENSE BLOCK *****
2
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
4
* The contents of this file are subject to the Mozilla Public License Version
5
* 1.1 (the "License"); you may not use this file except in compliance with
6
* the License. You may obtain a copy of the License at
7
* http://www.mozilla.org/MPL/
9
* Software distributed under the License is distributed on an "AS IS" basis,
10
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11
* for the specific language governing rights and limitations under the
14
* The Original Code is the Netscape security libraries.
16
* The Initial Developer of the Original Code is
17
* Netscape Communications Corporation.
18
* Portions created by the Initial Developer are Copyright (C) 1994-2000
19
* the Initial Developer. All Rights Reserved.
23
* Alternatively, the contents of this file may be used under the terms of
24
* either the GNU General Public License Version 2 or later (the "GPL"), or
25
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26
* in which case the provisions of the GPL or the LGPL are applicable instead
27
* of those above. If you wish to allow use of your version of this file only
28
* under the terms of either the GPL or the LGPL, and not to allow others to
29
* use your version of this file under the terms of the MPL, indicate your
30
* decision by deleting the provisions above and replace them with the notice
31
* and other provisions required by the GPL or the LGPL. If you do not delete
32
* the provisions above, a recipient may use your version of this file under
33
* the terms of any one of the MPL, the GPL or the LGPL.
35
* ***** END LICENSE BLOCK ***** */
45
#define MD5_HASH_LEN 16
46
#define MD5_BUFFER_SIZE 64
47
#define MD5_END_BUFFER (MD5_BUFFER_SIZE - 8)
49
#define CV0_1 0x67452301
50
#define CV0_2 0xefcdab89
51
#define CV0_3 0x98badcfe
52
#define CV0_4 0x10325476
54
#define T1_0 0xd76aa478
55
#define T1_1 0xe8c7b756
56
#define T1_2 0x242070db
57
#define T1_3 0xc1bdceee
58
#define T1_4 0xf57c0faf
59
#define T1_5 0x4787c62a
60
#define T1_6 0xa8304613
61
#define T1_7 0xfd469501
62
#define T1_8 0x698098d8
63
#define T1_9 0x8b44f7af
64
#define T1_10 0xffff5bb1
65
#define T1_11 0x895cd7be
66
#define T1_12 0x6b901122
67
#define T1_13 0xfd987193
68
#define T1_14 0xa679438e
69
#define T1_15 0x49b40821
71
#define T2_0 0xf61e2562
72
#define T2_1 0xc040b340
73
#define T2_2 0x265e5a51
74
#define T2_3 0xe9b6c7aa
75
#define T2_4 0xd62f105d
76
#define T2_5 0x02441453
77
#define T2_6 0xd8a1e681
78
#define T2_7 0xe7d3fbc8
79
#define T2_8 0x21e1cde6
80
#define T2_9 0xc33707d6
81
#define T2_10 0xf4d50d87
82
#define T2_11 0x455a14ed
83
#define T2_12 0xa9e3e905
84
#define T2_13 0xfcefa3f8
85
#define T2_14 0x676f02d9
86
#define T2_15 0x8d2a4c8a
88
#define T3_0 0xfffa3942
89
#define T3_1 0x8771f681
90
#define T3_2 0x6d9d6122
91
#define T3_3 0xfde5380c
92
#define T3_4 0xa4beea44
93
#define T3_5 0x4bdecfa9
94
#define T3_6 0xf6bb4b60
95
#define T3_7 0xbebfbc70
96
#define T3_8 0x289b7ec6
97
#define T3_9 0xeaa127fa
98
#define T3_10 0xd4ef3085
99
#define T3_11 0x04881d05
100
#define T3_12 0xd9d4d039
101
#define T3_13 0xe6db99e5
102
#define T3_14 0x1fa27cf8
103
#define T3_15 0xc4ac5665
105
#define T4_0 0xf4292244
106
#define T4_1 0x432aff97
107
#define T4_2 0xab9423a7
108
#define T4_3 0xfc93a039
109
#define T4_4 0x655b59c3
110
#define T4_5 0x8f0ccc92
111
#define T4_6 0xffeff47d
112
#define T4_7 0x85845dd1
113
#define T4_8 0x6fa87e4f
114
#define T4_9 0xfe2ce6e0
115
#define T4_10 0xa3014314
116
#define T4_11 0x4e0811a1
117
#define T4_12 0xf7537e82
118
#define T4_13 0xbd3af235
119
#define T4_14 0x2ad7d2bb
120
#define T4_15 0xeb86d391
210
struct MD5ContextStr {
223
MD5_Hash(unsigned char *dest, const char *src)
225
return MD5_HashBuf(dest, (unsigned char *)src, PL_strlen(src));
229
MD5_HashBuf(unsigned char *dest, const unsigned char *src, uint32 src_length)
235
MD5_Update(&cx, src, src_length);
236
MD5_End(&cx, dest, &len, MD5_HASH_LEN);
237
/* memset(&cx, 0, sizeof cx); */
244
/* no need to ZAlloc, MD5_Begin will init the context */
245
MD5Context *cx = (MD5Context *)PORT_Alloc(sizeof(MD5Context));
247
PORT_SetError(PR_OUT_OF_MEMORY_ERROR);
254
MD5_DestroyContext(MD5Context *cx, PRBool freeit)
256
/* memset(cx, 0, sizeof *cx); */
263
MD5_Begin(MD5Context *cx)
267
/* memset(cx->inBuf, 0, sizeof(cx->inBuf)); */
274
#define cls(i32, s) (tmp = i32, tmp << s | tmp >> (32 - s))
276
#if defined(SOLARIS) || defined(HPUX)
277
#define addto64(sumhigh, sumlow, addend) \
278
sumlow += addend; sumhigh += (sumlow < addend);
280
#define addto64(sumhigh, sumlow, addend) \
281
sumlow += addend; if (sumlow < addend) ++sumhigh;
284
#define MASK 0x00ff00ff
285
#ifdef IS_LITTLE_ENDIAN
286
#define lendian(i32) \
289
#define lendian(i32) \
290
(tmp = i32 >> 16 | i32 << 16, (tmp & MASK) << 8 | tmp >> 8 & MASK)
293
#ifndef IS_LITTLE_ENDIAN
295
#define lebytes(b4) \
296
((b4)[3] << 24 | (b4)[2] << 16 | (b4)[1] << 8 | (b4)[0])
299
md5_prep_state_le(MD5Context *cx)
302
cx->u.w[0] = lendian(cx->u.w[0]);
303
cx->u.w[1] = lendian(cx->u.w[1]);
304
cx->u.w[2] = lendian(cx->u.w[2]);
305
cx->u.w[3] = lendian(cx->u.w[3]);
306
cx->u.w[4] = lendian(cx->u.w[4]);
307
cx->u.w[5] = lendian(cx->u.w[5]);
308
cx->u.w[6] = lendian(cx->u.w[6]);
309
cx->u.w[7] = lendian(cx->u.w[7]);
310
cx->u.w[8] = lendian(cx->u.w[8]);
311
cx->u.w[9] = lendian(cx->u.w[9]);
312
cx->u.w[10] = lendian(cx->u.w[10]);
313
cx->u.w[11] = lendian(cx->u.w[11]);
314
cx->u.w[12] = lendian(cx->u.w[12]);
315
cx->u.w[13] = lendian(cx->u.w[13]);
316
cx->u.w[14] = lendian(cx->u.w[14]);
317
cx->u.w[15] = lendian(cx->u.w[15]);
321
md5_prep_buffer_le(MD5Context *cx, const PRUint8 *beBuf)
323
cx->u.w[0] = lebytes(&beBuf[0]);
324
cx->u.w[1] = lebytes(&beBuf[4]);
325
cx->u.w[2] = lebytes(&beBuf[8]);
326
cx->u.w[3] = lebytes(&beBuf[12]);
327
cx->u.w[4] = lebytes(&beBuf[16]);
328
cx->u.w[5] = lebytes(&beBuf[20]);
329
cx->u.w[6] = lebytes(&beBuf[24]);
330
cx->u.w[7] = lebytes(&beBuf[28]);
331
cx->u.w[8] = lebytes(&beBuf[32]);
332
cx->u.w[9] = lebytes(&beBuf[36]);
333
cx->u.w[10] = lebytes(&beBuf[40]);
334
cx->u.w[11] = lebytes(&beBuf[44]);
335
cx->u.w[12] = lebytes(&beBuf[48]);
336
cx->u.w[13] = lebytes(&beBuf[52]);
337
cx->u.w[14] = lebytes(&beBuf[56]);
338
cx->u.w[15] = lebytes(&beBuf[60]);
344
((X & Y) | ((~X) & Z))
347
((X & Z) | (Y & (~Z)))
355
#define FF(a, b, c, d, bufint, s, ti) \
356
a = b + cls(a + F(b, c, d) + bufint + ti, s)
358
#define GG(a, b, c, d, bufint, s, ti) \
359
a = b + cls(a + G(b, c, d) + bufint + ti, s)
361
#define HH(a, b, c, d, bufint, s, ti) \
362
a = b + cls(a + H(b, c, d) + bufint + ti, s)
364
#define II(a, b, c, d, bufint, s, ti) \
365
a = b + cls(a + I(b, c, d) + bufint + ti, s)
368
md5_compress(MD5Context *cx, const PRUint32 *wBuf)
376
FF(a, b, c, d, wBuf[R1B0 ], S1_0, T1_0);
377
FF(d, a, b, c, wBuf[R1B1 ], S1_1, T1_1);
378
FF(c, d, a, b, wBuf[R1B2 ], S1_2, T1_2);
379
FF(b, c, d, a, wBuf[R1B3 ], S1_3, T1_3);
380
FF(a, b, c, d, wBuf[R1B4 ], S1_0, T1_4);
381
FF(d, a, b, c, wBuf[R1B5 ], S1_1, T1_5);
382
FF(c, d, a, b, wBuf[R1B6 ], S1_2, T1_6);
383
FF(b, c, d, a, wBuf[R1B7 ], S1_3, T1_7);
384
FF(a, b, c, d, wBuf[R1B8 ], S1_0, T1_8);
385
FF(d, a, b, c, wBuf[R1B9 ], S1_1, T1_9);
386
FF(c, d, a, b, wBuf[R1B10], S1_2, T1_10);
387
FF(b, c, d, a, wBuf[R1B11], S1_3, T1_11);
388
FF(a, b, c, d, wBuf[R1B12], S1_0, T1_12);
389
FF(d, a, b, c, wBuf[R1B13], S1_1, T1_13);
390
FF(c, d, a, b, wBuf[R1B14], S1_2, T1_14);
391
FF(b, c, d, a, wBuf[R1B15], S1_3, T1_15);
392
GG(a, b, c, d, wBuf[R2B0 ], S2_0, T2_0);
393
GG(d, a, b, c, wBuf[R2B1 ], S2_1, T2_1);
394
GG(c, d, a, b, wBuf[R2B2 ], S2_2, T2_2);
395
GG(b, c, d, a, wBuf[R2B3 ], S2_3, T2_3);
396
GG(a, b, c, d, wBuf[R2B4 ], S2_0, T2_4);
397
GG(d, a, b, c, wBuf[R2B5 ], S2_1, T2_5);
398
GG(c, d, a, b, wBuf[R2B6 ], S2_2, T2_6);
399
GG(b, c, d, a, wBuf[R2B7 ], S2_3, T2_7);
400
GG(a, b, c, d, wBuf[R2B8 ], S2_0, T2_8);
401
GG(d, a, b, c, wBuf[R2B9 ], S2_1, T2_9);
402
GG(c, d, a, b, wBuf[R2B10], S2_2, T2_10);
403
GG(b, c, d, a, wBuf[R2B11], S2_3, T2_11);
404
GG(a, b, c, d, wBuf[R2B12], S2_0, T2_12);
405
GG(d, a, b, c, wBuf[R2B13], S2_1, T2_13);
406
GG(c, d, a, b, wBuf[R2B14], S2_2, T2_14);
407
GG(b, c, d, a, wBuf[R2B15], S2_3, T2_15);
408
HH(a, b, c, d, wBuf[R3B0 ], S3_0, T3_0);
409
HH(d, a, b, c, wBuf[R3B1 ], S3_1, T3_1);
410
HH(c, d, a, b, wBuf[R3B2 ], S3_2, T3_2);
411
HH(b, c, d, a, wBuf[R3B3 ], S3_3, T3_3);
412
HH(a, b, c, d, wBuf[R3B4 ], S3_0, T3_4);
413
HH(d, a, b, c, wBuf[R3B5 ], S3_1, T3_5);
414
HH(c, d, a, b, wBuf[R3B6 ], S3_2, T3_6);
415
HH(b, c, d, a, wBuf[R3B7 ], S3_3, T3_7);
416
HH(a, b, c, d, wBuf[R3B8 ], S3_0, T3_8);
417
HH(d, a, b, c, wBuf[R3B9 ], S3_1, T3_9);
418
HH(c, d, a, b, wBuf[R3B10], S3_2, T3_10);
419
HH(b, c, d, a, wBuf[R3B11], S3_3, T3_11);
420
HH(a, b, c, d, wBuf[R3B12], S3_0, T3_12);
421
HH(d, a, b, c, wBuf[R3B13], S3_1, T3_13);
422
HH(c, d, a, b, wBuf[R3B14], S3_2, T3_14);
423
HH(b, c, d, a, wBuf[R3B15], S3_3, T3_15);
424
II(a, b, c, d, wBuf[R4B0 ], S4_0, T4_0);
425
II(d, a, b, c, wBuf[R4B1 ], S4_1, T4_1);
426
II(c, d, a, b, wBuf[R4B2 ], S4_2, T4_2);
427
II(b, c, d, a, wBuf[R4B3 ], S4_3, T4_3);
428
II(a, b, c, d, wBuf[R4B4 ], S4_0, T4_4);
429
II(d, a, b, c, wBuf[R4B5 ], S4_1, T4_5);
430
II(c, d, a, b, wBuf[R4B6 ], S4_2, T4_6);
431
II(b, c, d, a, wBuf[R4B7 ], S4_3, T4_7);
432
II(a, b, c, d, wBuf[R4B8 ], S4_0, T4_8);
433
II(d, a, b, c, wBuf[R4B9 ], S4_1, T4_9);
434
II(c, d, a, b, wBuf[R4B10], S4_2, T4_10);
435
II(b, c, d, a, wBuf[R4B11], S4_3, T4_11);
436
II(a, b, c, d, wBuf[R4B12], S4_0, T4_12);
437
II(d, a, b, c, wBuf[R4B13], S4_1, T4_13);
438
II(c, d, a, b, wBuf[R4B14], S4_2, T4_14);
439
II(b, c, d, a, wBuf[R4B15], S4_3, T4_15);
447
MD5_Update(MD5Context *cx, const unsigned char *input, unsigned int inputLen)
449
PRUint32 bytesToConsume;
450
PRUint32 inBufIndex = cx->lsbInput & 63;
451
const PRUint32 *wBuf;
453
/* Add the number of input bytes to the 64-bit input counter. */
454
addto64(cx->msbInput, cx->lsbInput, inputLen);
456
/* There is already data in the buffer. Fill with input. */
457
bytesToConsume = PR_MIN(inputLen, MD5_BUFFER_SIZE - inBufIndex);
458
memcpy(&cx->inBuf[inBufIndex], input, bytesToConsume);
459
if (inBufIndex + bytesToConsume >= MD5_BUFFER_SIZE) {
460
/* The buffer is filled. Run the compression function. */
461
#ifndef IS_LITTLE_ENDIAN
462
md5_prep_state_le(cx);
464
md5_compress(cx, cx->u.w);
466
/* Remaining input. */
467
inputLen -= bytesToConsume;
468
input += bytesToConsume;
471
/* Iterate over 64-byte chunks of the message. */
472
while (inputLen >= MD5_BUFFER_SIZE) {
473
#ifdef IS_LITTLE_ENDIAN
475
/* x86 can handle arithmetic on non-word-aligned buffers */
476
wBuf = (PRUint32 *)input;
478
if ((ptrdiff_t)input & 0x3) {
479
/* buffer not aligned, copy it to force alignment */
480
memcpy(cx->inBuf, input, MD5_BUFFER_SIZE);
483
/* buffer is aligned */
484
wBuf = (PRUint32 *)input;
488
md5_prep_buffer_le(cx, input);
491
md5_compress(cx, wBuf);
492
inputLen -= MD5_BUFFER_SIZE;
493
input += MD5_BUFFER_SIZE;
496
/* Tail of message (message bytes mod 64). */
498
memcpy(cx->inBuf, input, inputLen);
501
static const unsigned char padbytes[] = {
502
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
503
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
504
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
505
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
506
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
507
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
508
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
509
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
510
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
511
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
512
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
513
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
517
MD5_End(MD5Context *cx, unsigned char *digest,
518
unsigned int *digestLen, unsigned int maxDigestLen)
520
#ifndef IS_LITTLE_ENDIAN
523
PRUint32 lowInput, highInput;
524
PRUint32 inBufIndex = cx->lsbInput & 63;
526
if (maxDigestLen < MD5_HASH_LEN) {
527
PORT_SetError(SEC_ERROR_INVALID_ARGS);
531
/* Copy out the length of bits input before padding. */
532
lowInput = cx->lsbInput;
533
highInput = (cx->msbInput << 3) | (lowInput >> 29);
536
if (inBufIndex < MD5_END_BUFFER) {
537
MD5_Update(cx, padbytes, MD5_END_BUFFER - inBufIndex);
539
MD5_Update(cx, padbytes,
540
MD5_END_BUFFER + MD5_BUFFER_SIZE - inBufIndex);
543
/* Store the number of bytes input (before padding) in final 64 bits. */
544
cx->u.w[14] = lendian(lowInput);
545
cx->u.w[15] = lendian(highInput);
547
/* Final call to compress. */
548
#ifndef IS_LITTLE_ENDIAN
549
md5_prep_state_le(cx);
551
md5_compress(cx, cx->u.w);
553
/* Copy the resulting values out of the chain variables into return buf. */
554
*digestLen = MD5_HASH_LEN;
555
#ifndef IS_LITTLE_ENDIAN
556
cx->cv[0] = lendian(cx->cv[0]);
557
cx->cv[1] = lendian(cx->cv[1]);
558
cx->cv[2] = lendian(cx->cv[2]);
559
cx->cv[3] = lendian(cx->cv[3]);
561
memcpy(digest, cx->cv, MD5_HASH_LEN);
565
MD5_FlattenSize(MD5Context *cx)
571
MD5_Flatten(MD5Context *cx, unsigned char *space)
573
memcpy(space, cx, sizeof(*cx));
578
MD5_Resurrect(unsigned char *space, void *arg)
580
MD5Context *cx = MD5_NewContext();
582
memcpy(cx, space, sizeof(*cx));
586
void MD5_Clone(MD5Context *dest, MD5Context *src)
588
memcpy(dest, src, sizeof *dest);
592
MD5_TraceState(MD5Context *cx)
594
PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);