f7183893e837b331b3a7a02d67cafec88869fd49
2 ** Copyright 1998 - 2000 Double Precision, Inc.
3 ** See COPYING for distribution information.
12 #define MD5_BYTE unsigned char
14 #define MD5_ROL(w,n) \
15 ( (w) << (n) | ( (w) >> (32-(n)) ) )
17 static MD5_WORD T
[64]={
18 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
19 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
20 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
21 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
22 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
23 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8,
24 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
25 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
26 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
27 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
28 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05,
29 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
30 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
31 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
32 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
33 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391};
35 void md5_context_init(struct MD5_CONTEXT
*c
)
37 if (sizeof(MD5_WORD
) != 4) abort();
47 void md5_context_hash(struct MD5_CONTEXT
*c
,
48 const unsigned char blk
[MD5_BLOCK_SIZE
])
55 for (i
=j
=0; i
<16; i
++)
57 MD5_WORD w
=(MD5_WORD
)blk
[j
++];
59 w
|= (MD5_WORD
)blk
[j
++] << 8;
60 w
|= (MD5_WORD
)blk
[j
++] << 16;
61 w
|= (MD5_WORD
)blk
[j
++] << 24;
65 #define F(X,Y,Z) ( ((X) & (Y)) | ( (~(X)) & (Z)))
66 #define G(X,Y,Z) ( ((X) & (Z)) | ( (Y) & (~(Z))))
67 #define H(X,Y,Z) ( (X) ^ (Y) ^ (Z) )
68 #define I(X,Y,Z) ( (Y) ^ ( (X) | (~(Z))))
75 #define ROUND1(a,b,c,d,k,s,i) \
76 { zz=(a + F(b,c,d) + x[k] + T[i]); a=b+MD5_ROL(zz,s); }
78 ROUND1(A
,B
,C
,D
,0,7,0);
79 ROUND1(D
,A
,B
,C
,1,12,1);
80 ROUND1(C
,D
,A
,B
,2,17,2);
81 ROUND1(B
,C
,D
,A
,3,22,3);
82 ROUND1(A
,B
,C
,D
,4,7,4);
83 ROUND1(D
,A
,B
,C
,5,12,5);
84 ROUND1(C
,D
,A
,B
,6,17,6);
85 ROUND1(B
,C
,D
,A
,7,22,7);
86 ROUND1(A
,B
,C
,D
,8,7,8);
87 ROUND1(D
,A
,B
,C
,9,12,9);
88 ROUND1(C
,D
,A
,B
,10,17,10);
89 ROUND1(B
,C
,D
,A
,11,22,11);
90 ROUND1(A
,B
,C
,D
,12,7,12);
91 ROUND1(D
,A
,B
,C
,13,12,13);
92 ROUND1(C
,D
,A
,B
,14,17,14);
93 ROUND1(B
,C
,D
,A
,15,22,15);
95 #define ROUND2(a,b,c,d,k,s,i) \
96 { zz=(a + G(b,c,d) + x[k] + T[i]); a = b + MD5_ROL(zz,s); }
98 ROUND2(A
,B
,C
,D
,1,5,16);
99 ROUND2(D
,A
,B
,C
,6,9,17);
100 ROUND2(C
,D
,A
,B
,11,14,18);
101 ROUND2(B
,C
,D
,A
,0,20,19);
102 ROUND2(A
,B
,C
,D
,5,5,20);
103 ROUND2(D
,A
,B
,C
,10,9,21);
104 ROUND2(C
,D
,A
,B
,15,14,22);
105 ROUND2(B
,C
,D
,A
,4,20,23);
106 ROUND2(A
,B
,C
,D
,9,5,24);
107 ROUND2(D
,A
,B
,C
,14,9,25);
108 ROUND2(C
,D
,A
,B
,3,14,26);
109 ROUND2(B
,C
,D
,A
,8,20,27);
110 ROUND2(A
,B
,C
,D
,13,5,28);
111 ROUND2(D
,A
,B
,C
,2,9,29);
112 ROUND2(C
,D
,A
,B
,7,14,30);
113 ROUND2(B
,C
,D
,A
,12,20,31);
115 #define ROUND3(a,b,c,d,k,s,i) \
116 { zz=(a + H(b,c,d) + x[k] + T[i]); a = b + MD5_ROL(zz,s); }
118 ROUND3(A
,B
,C
,D
,5,4,32);
119 ROUND3(D
,A
,B
,C
,8,11,33);
120 ROUND3(C
,D
,A
,B
,11,16,34);
121 ROUND3(B
,C
,D
,A
,14,23,35);
122 ROUND3(A
,B
,C
,D
,1,4,36);
123 ROUND3(D
,A
,B
,C
,4,11,37);
124 ROUND3(C
,D
,A
,B
,7,16,38);
125 ROUND3(B
,C
,D
,A
,10,23,39);
126 ROUND3(A
,B
,C
,D
,13,4,40);
127 ROUND3(D
,A
,B
,C
,0,11,41);
128 ROUND3(C
,D
,A
,B
,3,16,42);
129 ROUND3(B
,C
,D
,A
,6,23,43);
130 ROUND3(A
,B
,C
,D
,9,4,44);
131 ROUND3(D
,A
,B
,C
,12,11,45);
132 ROUND3(C
,D
,A
,B
,15,16,46);
133 ROUND3(B
,C
,D
,A
,2,23,47);
135 #define ROUND4(a,b,c,d,k,s,i) \
136 { zz=(a + I(b,c,d) + x[k] + T[i]); a = b + MD5_ROL(zz,s); }
138 ROUND4(A
,B
,C
,D
,0,6,48);
139 ROUND4(D
,A
,B
,C
,7,10,49);
140 ROUND4(C
,D
,A
,B
,14,15,50);
141 ROUND4(B
,C
,D
,A
,5,21,51);
142 ROUND4(A
,B
,C
,D
,12,6,52);
143 ROUND4(D
,A
,B
,C
,3,10,53);
144 ROUND4(C
,D
,A
,B
,10,15,54);
145 ROUND4(B
,C
,D
,A
,1,21,55);
146 ROUND4(A
,B
,C
,D
,8,6,56);
147 ROUND4(D
,A
,B
,C
,15,10,57);
148 ROUND4(C
,D
,A
,B
,6,15,58);
149 ROUND4(B
,C
,D
,A
,13,21,59);
150 ROUND4(A
,B
,C
,D
,4,6,60);
151 ROUND4(D
,A
,B
,C
,11,10,61);
152 ROUND4(C
,D
,A
,B
,2,15,62);
153 ROUND4(B
,C
,D
,A
,9,21,63);
161 void md5_context_hashstream(struct MD5_CONTEXT
*c
, const void *p
, unsigned l
)
163 const unsigned char *cp
=(const unsigned char *)p
;
168 if (c
->blk_ptr
== 0 && l
>= MD5_BLOCK_SIZE
)
170 md5_context_hash(c
, cp
);
171 cp
+= MD5_BLOCK_SIZE
;
177 if (ll
> MD5_BLOCK_SIZE
- c
->blk_ptr
)
178 ll
=MD5_BLOCK_SIZE
- c
->blk_ptr
;
179 memcpy(c
->blk
+ c
->blk_ptr
, cp
, ll
);
183 if (c
->blk_ptr
>= MD5_BLOCK_SIZE
)
185 md5_context_hash(c
, c
->blk
);
191 void md5_context_endstream(struct MD5_CONTEXT
*c
, unsigned long ll
)
193 unsigned char buf
[8];
195 static unsigned char zero
[MD5_BLOCK_SIZE
-8];
199 md5_context_hashstream(c
, buf
, 1);
200 while (c
->blk_ptr
!= MD5_BLOCK_SIZE
- 8)
202 if (c
->blk_ptr
> MD5_BLOCK_SIZE
- 8)
204 md5_context_hashstream(c
, zero
,
205 MD5_BLOCK_SIZE
- c
->blk_ptr
);
208 md5_context_hashstream(c
, zero
,
209 MD5_BLOCK_SIZE
- 8 - c
->blk_ptr
);
234 md5_context_hashstream(c
, buf
, 8);
237 void md5_context_digest(struct MD5_CONTEXT
*c
, MD5_DIGEST d
)
242 #define PUT(c) (w=(c), *dp++ = w, w >>= 8, *dp++ = w, w >>= 8, *dp++ = w, w >>= 8, *dp++ = w)
251 void md5_context_restore(struct MD5_CONTEXT
*c
, const MD5_DIGEST d
)
253 const unsigned char *dp
=(unsigned char *)d
+MD5_DIGEST_SIZE
;
257 w=*--dp; w=(w << 8) | *--dp; w=(w << 8) | *--dp; w=(w << 8) | *--dp;
270 void md5_digest(const void *msg
, unsigned int len
, MD5_DIGEST d
)
272 struct MD5_CONTEXT c
;
274 md5_context_init(&c
);
275 md5_context_hashstream(&c
, msg
, len
);
276 md5_context_endstream(&c
, len
);
277 md5_context_digest(&c
, d
);