2 ** Copyright 1998 - 2000 Double Precision, Inc.
3 ** See COPYING for distribution information.
11 static const char rcsid
[]="$Id: md5.c,v 1.7 2000/07/30 01:08:09 mrsam Exp $";
13 #define MD5_BYTE unsigned char
15 #define MD5_ROL(w,n) \
16 ( (w) << (n) | ( (w) >> (32-(n)) ) )
18 static MD5_WORD T
[64]={
19 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
20 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
21 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
22 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
23 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
24 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8,
25 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
26 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
27 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
28 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
29 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05,
30 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
31 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
32 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
33 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
34 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391};
36 void md5_context_init(struct MD5_CONTEXT
*c
)
38 if (sizeof(MD5_WORD
) != 4) abort();
48 void md5_context_hash(struct MD5_CONTEXT
*c
,
49 const unsigned char blk
[MD5_BLOCK_SIZE
])
56 for (i
=j
=0; i
<16; i
++)
58 MD5_WORD w
=(MD5_WORD
)blk
[j
++];
60 w
|= (MD5_WORD
)blk
[j
++] << 8;
61 w
|= (MD5_WORD
)blk
[j
++] << 16;
62 w
|= (MD5_WORD
)blk
[j
++] << 24;
66 #define F(X,Y,Z) ( ((X) & (Y)) | ( (~(X)) & (Z)))
67 #define G(X,Y,Z) ( ((X) & (Z)) | ( (Y) & (~(Z))))
68 #define H(X,Y,Z) ( (X) ^ (Y) ^ (Z) )
69 #define I(X,Y,Z) ( (Y) ^ ( (X) | (~(Z))))
76 #define ROUND1(a,b,c,d,k,s,i) \
77 { zz=(a + F(b,c,d) + x[k] + T[i]); a=b+MD5_ROL(zz,s); }
79 ROUND1(A
,B
,C
,D
,0,7,0);
80 ROUND1(D
,A
,B
,C
,1,12,1);
81 ROUND1(C
,D
,A
,B
,2,17,2);
82 ROUND1(B
,C
,D
,A
,3,22,3);
83 ROUND1(A
,B
,C
,D
,4,7,4);
84 ROUND1(D
,A
,B
,C
,5,12,5);
85 ROUND1(C
,D
,A
,B
,6,17,6);
86 ROUND1(B
,C
,D
,A
,7,22,7);
87 ROUND1(A
,B
,C
,D
,8,7,8);
88 ROUND1(D
,A
,B
,C
,9,12,9);
89 ROUND1(C
,D
,A
,B
,10,17,10);
90 ROUND1(B
,C
,D
,A
,11,22,11);
91 ROUND1(A
,B
,C
,D
,12,7,12);
92 ROUND1(D
,A
,B
,C
,13,12,13);
93 ROUND1(C
,D
,A
,B
,14,17,14);
94 ROUND1(B
,C
,D
,A
,15,22,15);
96 #define ROUND2(a,b,c,d,k,s,i) \
97 { zz=(a + G(b,c,d) + x[k] + T[i]); a = b + MD5_ROL(zz,s); }
99 ROUND2(A
,B
,C
,D
,1,5,16);
100 ROUND2(D
,A
,B
,C
,6,9,17);
101 ROUND2(C
,D
,A
,B
,11,14,18);
102 ROUND2(B
,C
,D
,A
,0,20,19);
103 ROUND2(A
,B
,C
,D
,5,5,20);
104 ROUND2(D
,A
,B
,C
,10,9,21);
105 ROUND2(C
,D
,A
,B
,15,14,22);
106 ROUND2(B
,C
,D
,A
,4,20,23);
107 ROUND2(A
,B
,C
,D
,9,5,24);
108 ROUND2(D
,A
,B
,C
,14,9,25);
109 ROUND2(C
,D
,A
,B
,3,14,26);
110 ROUND2(B
,C
,D
,A
,8,20,27);
111 ROUND2(A
,B
,C
,D
,13,5,28);
112 ROUND2(D
,A
,B
,C
,2,9,29);
113 ROUND2(C
,D
,A
,B
,7,14,30);
114 ROUND2(B
,C
,D
,A
,12,20,31);
116 #define ROUND3(a,b,c,d,k,s,i) \
117 { zz=(a + H(b,c,d) + x[k] + T[i]); a = b + MD5_ROL(zz,s); }
119 ROUND3(A
,B
,C
,D
,5,4,32);
120 ROUND3(D
,A
,B
,C
,8,11,33);
121 ROUND3(C
,D
,A
,B
,11,16,34);
122 ROUND3(B
,C
,D
,A
,14,23,35);
123 ROUND3(A
,B
,C
,D
,1,4,36);
124 ROUND3(D
,A
,B
,C
,4,11,37);
125 ROUND3(C
,D
,A
,B
,7,16,38);
126 ROUND3(B
,C
,D
,A
,10,23,39);
127 ROUND3(A
,B
,C
,D
,13,4,40);
128 ROUND3(D
,A
,B
,C
,0,11,41);
129 ROUND3(C
,D
,A
,B
,3,16,42);
130 ROUND3(B
,C
,D
,A
,6,23,43);
131 ROUND3(A
,B
,C
,D
,9,4,44);
132 ROUND3(D
,A
,B
,C
,12,11,45);
133 ROUND3(C
,D
,A
,B
,15,16,46);
134 ROUND3(B
,C
,D
,A
,2,23,47);
136 #define ROUND4(a,b,c,d,k,s,i) \
137 { zz=(a + I(b,c,d) + x[k] + T[i]); a = b + MD5_ROL(zz,s); }
139 ROUND4(A
,B
,C
,D
,0,6,48);
140 ROUND4(D
,A
,B
,C
,7,10,49);
141 ROUND4(C
,D
,A
,B
,14,15,50);
142 ROUND4(B
,C
,D
,A
,5,21,51);
143 ROUND4(A
,B
,C
,D
,12,6,52);
144 ROUND4(D
,A
,B
,C
,3,10,53);
145 ROUND4(C
,D
,A
,B
,10,15,54);
146 ROUND4(B
,C
,D
,A
,1,21,55);
147 ROUND4(A
,B
,C
,D
,8,6,56);
148 ROUND4(D
,A
,B
,C
,15,10,57);
149 ROUND4(C
,D
,A
,B
,6,15,58);
150 ROUND4(B
,C
,D
,A
,13,21,59);
151 ROUND4(A
,B
,C
,D
,4,6,60);
152 ROUND4(D
,A
,B
,C
,11,10,61);
153 ROUND4(C
,D
,A
,B
,2,15,62);
154 ROUND4(B
,C
,D
,A
,9,21,63);
162 void md5_context_hashstream(struct MD5_CONTEXT
*c
, const void *p
, unsigned l
)
164 const unsigned char *cp
=(const unsigned char *)p
;
169 if (c
->blk_ptr
== 0 && l
>= MD5_BLOCK_SIZE
)
171 md5_context_hash(c
, cp
);
172 cp
+= MD5_BLOCK_SIZE
;
178 if (ll
> MD5_BLOCK_SIZE
- c
->blk_ptr
)
179 ll
=MD5_BLOCK_SIZE
- c
->blk_ptr
;
180 memcpy(c
->blk
+ c
->blk_ptr
, cp
, ll
);
184 if (c
->blk_ptr
>= MD5_BLOCK_SIZE
)
186 md5_context_hash(c
, c
->blk
);
192 void md5_context_endstream(struct MD5_CONTEXT
*c
, unsigned long ll
)
194 unsigned char buf
[8];
196 static unsigned char zero
[MD5_BLOCK_SIZE
-8];
200 md5_context_hashstream(c
, buf
, 1);
201 while (c
->blk_ptr
!= MD5_BLOCK_SIZE
- 8)
203 if (c
->blk_ptr
> MD5_BLOCK_SIZE
- 8)
205 md5_context_hashstream(c
, zero
,
206 MD5_BLOCK_SIZE
- c
->blk_ptr
);
209 md5_context_hashstream(c
, zero
,
210 MD5_BLOCK_SIZE
- 8 - c
->blk_ptr
);
235 md5_context_hashstream(c
, buf
, 8);
238 void md5_context_digest(struct MD5_CONTEXT
*c
, MD5_DIGEST d
)
243 #define PUT(c) (w=(c), *dp++ = w, w >>= 8, *dp++ = w, w >>= 8, *dp++ = w, w >>= 8, *dp++ = w)
252 void md5_context_restore(struct MD5_CONTEXT
*c
, const MD5_DIGEST d
)
254 const unsigned char *dp
=(unsigned char *)d
+MD5_DIGEST_SIZE
;
258 w=*--dp; w=(w << 8) | *--dp; w=(w << 8) | *--dp; w=(w << 8) | *--dp;
271 void md5_digest(const void *msg
, unsigned int len
, MD5_DIGEST d
)
273 struct MD5_CONTEXT c
;
275 md5_context_init(&c
);
276 md5_context_hashstream(&c
, msg
, len
);
277 md5_context_endstream(&c
, len
);
278 md5_context_digest(&c
, d
);