2 * RFC 1321 compliant MD5 implementation
4 * Copyright (C) 2001-2003 Christophe Devine
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #define GET_UINT32(n,b,i) \
27 (n) = ( (uint32) (b)[(i) ] ) \
28 | ( (uint32) (b)[(i) + 1] << 8 ) \
29 | ( (uint32) (b)[(i) + 2] << 16 ) \
30 | ( (uint32) (b)[(i) + 3] << 24 ); \
33 #define PUT_UINT32(n,b,i) \
35 (b)[(i) ] = (uint8) ( (n) ); \
36 (b)[(i) + 1] = (uint8) ( (n) >> 8 ); \
37 (b)[(i) + 2] = (uint8) ( (n) >> 16 ); \
38 (b)[(i) + 3] = (uint8) ( (n) >> 24 ); \
41 void md5_starts( md5_context
*ctx
)
46 ctx
->state
[0] = 0x67452301;
47 ctx
->state
[1] = 0xEFCDAB89;
48 ctx
->state
[2] = 0x98BADCFE;
49 ctx
->state
[3] = 0x10325476;
52 void md5_process( md5_context
*ctx
, uint8 data
[64] )
54 uint32 X
[16], A
, B
, C
, D
;
56 GET_UINT32( X
[0], data
, 0 );
57 GET_UINT32( X
[1], data
, 4 );
58 GET_UINT32( X
[2], data
, 8 );
59 GET_UINT32( X
[3], data
, 12 );
60 GET_UINT32( X
[4], data
, 16 );
61 GET_UINT32( X
[5], data
, 20 );
62 GET_UINT32( X
[6], data
, 24 );
63 GET_UINT32( X
[7], data
, 28 );
64 GET_UINT32( X
[8], data
, 32 );
65 GET_UINT32( X
[9], data
, 36 );
66 GET_UINT32( X
[10], data
, 40 );
67 GET_UINT32( X
[11], data
, 44 );
68 GET_UINT32( X
[12], data
, 48 );
69 GET_UINT32( X
[13], data
, 52 );
70 GET_UINT32( X
[14], data
, 56 );
71 GET_UINT32( X
[15], data
, 60 );
73 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
75 #define P(a,b,c,d,k,s,t) \
77 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
85 #define F(x,y,z) (z ^ (x & (y ^ z)))
87 P( A
, B
, C
, D
, 0, 7, 0xD76AA478 );
88 P( D
, A
, B
, C
, 1, 12, 0xE8C7B756 );
89 P( C
, D
, A
, B
, 2, 17, 0x242070DB );
90 P( B
, C
, D
, A
, 3, 22, 0xC1BDCEEE );
91 P( A
, B
, C
, D
, 4, 7, 0xF57C0FAF );
92 P( D
, A
, B
, C
, 5, 12, 0x4787C62A );
93 P( C
, D
, A
, B
, 6, 17, 0xA8304613 );
94 P( B
, C
, D
, A
, 7, 22, 0xFD469501 );
95 P( A
, B
, C
, D
, 8, 7, 0x698098D8 );
96 P( D
, A
, B
, C
, 9, 12, 0x8B44F7AF );
97 P( C
, D
, A
, B
, 10, 17, 0xFFFF5BB1 );
98 P( B
, C
, D
, A
, 11, 22, 0x895CD7BE );
99 P( A
, B
, C
, D
, 12, 7, 0x6B901122 );
100 P( D
, A
, B
, C
, 13, 12, 0xFD987193 );
101 P( C
, D
, A
, B
, 14, 17, 0xA679438E );
102 P( B
, C
, D
, A
, 15, 22, 0x49B40821 );
106 #define F(x,y,z) (y ^ (z & (x ^ y)))
108 P( A
, B
, C
, D
, 1, 5, 0xF61E2562 );
109 P( D
, A
, B
, C
, 6, 9, 0xC040B340 );
110 P( C
, D
, A
, B
, 11, 14, 0x265E5A51 );
111 P( B
, C
, D
, A
, 0, 20, 0xE9B6C7AA );
112 P( A
, B
, C
, D
, 5, 5, 0xD62F105D );
113 P( D
, A
, B
, C
, 10, 9, 0x02441453 );
114 P( C
, D
, A
, B
, 15, 14, 0xD8A1E681 );
115 P( B
, C
, D
, A
, 4, 20, 0xE7D3FBC8 );
116 P( A
, B
, C
, D
, 9, 5, 0x21E1CDE6 );
117 P( D
, A
, B
, C
, 14, 9, 0xC33707D6 );
118 P( C
, D
, A
, B
, 3, 14, 0xF4D50D87 );
119 P( B
, C
, D
, A
, 8, 20, 0x455A14ED );
120 P( A
, B
, C
, D
, 13, 5, 0xA9E3E905 );
121 P( D
, A
, B
, C
, 2, 9, 0xFCEFA3F8 );
122 P( C
, D
, A
, B
, 7, 14, 0x676F02D9 );
123 P( B
, C
, D
, A
, 12, 20, 0x8D2A4C8A );
127 #define F(x,y,z) (x ^ y ^ z)
129 P( A
, B
, C
, D
, 5, 4, 0xFFFA3942 );
130 P( D
, A
, B
, C
, 8, 11, 0x8771F681 );
131 P( C
, D
, A
, B
, 11, 16, 0x6D9D6122 );
132 P( B
, C
, D
, A
, 14, 23, 0xFDE5380C );
133 P( A
, B
, C
, D
, 1, 4, 0xA4BEEA44 );
134 P( D
, A
, B
, C
, 4, 11, 0x4BDECFA9 );
135 P( C
, D
, A
, B
, 7, 16, 0xF6BB4B60 );
136 P( B
, C
, D
, A
, 10, 23, 0xBEBFBC70 );
137 P( A
, B
, C
, D
, 13, 4, 0x289B7EC6 );
138 P( D
, A
, B
, C
, 0, 11, 0xEAA127FA );
139 P( C
, D
, A
, B
, 3, 16, 0xD4EF3085 );
140 P( B
, C
, D
, A
, 6, 23, 0x04881D05 );
141 P( A
, B
, C
, D
, 9, 4, 0xD9D4D039 );
142 P( D
, A
, B
, C
, 12, 11, 0xE6DB99E5 );
143 P( C
, D
, A
, B
, 15, 16, 0x1FA27CF8 );
144 P( B
, C
, D
, A
, 2, 23, 0xC4AC5665 );
148 #define F(x,y,z) (y ^ (x | ~z))
150 P( A
, B
, C
, D
, 0, 6, 0xF4292244 );
151 P( D
, A
, B
, C
, 7, 10, 0x432AFF97 );
152 P( C
, D
, A
, B
, 14, 15, 0xAB9423A7 );
153 P( B
, C
, D
, A
, 5, 21, 0xFC93A039 );
154 P( A
, B
, C
, D
, 12, 6, 0x655B59C3 );
155 P( D
, A
, B
, C
, 3, 10, 0x8F0CCC92 );
156 P( C
, D
, A
, B
, 10, 15, 0xFFEFF47D );
157 P( B
, C
, D
, A
, 1, 21, 0x85845DD1 );
158 P( A
, B
, C
, D
, 8, 6, 0x6FA87E4F );
159 P( D
, A
, B
, C
, 15, 10, 0xFE2CE6E0 );
160 P( C
, D
, A
, B
, 6, 15, 0xA3014314 );
161 P( B
, C
, D
, A
, 13, 21, 0x4E0811A1 );
162 P( A
, B
, C
, D
, 4, 6, 0xF7537E82 );
163 P( D
, A
, B
, C
, 11, 10, 0xBD3AF235 );
164 P( C
, D
, A
, B
, 2, 15, 0x2AD7D2BB );
165 P( B
, C
, D
, A
, 9, 21, 0xEB86D391 );
175 void md5_update( md5_context
*ctx
, uint8
*input
, uint32 length
)
179 if( ! length
) return;
181 left
= ctx
->total
[0] & 0x3F;
184 ctx
->total
[0] += length
;
185 ctx
->total
[0] &= 0xFFFFFFFF;
187 if( ctx
->total
[0] < length
)
190 if( left
&& length
>= fill
)
192 memcpy( (void *) (ctx
->buffer
+ left
),
193 (void *) input
, fill
);
194 md5_process( ctx
, ctx
->buffer
);
200 while( length
>= 64 )
202 md5_process( ctx
, input
);
209 memcpy( (void *) (ctx
->buffer
+ left
),
210 (void *) input
, length
);
214 static uint8 md5_padding
[64] =
216 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
217 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
218 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
219 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
222 void md5_finish( md5_context
*ctx
, uint8 digest
[16] )
228 high
= ( ctx
->total
[0] >> 29 )
229 | ( ctx
->total
[1] << 3 );
230 low
= ( ctx
->total
[0] << 3 );
232 PUT_UINT32( low
, msglen
, 0 );
233 PUT_UINT32( high
, msglen
, 4 );
235 last
= ctx
->total
[0] & 0x3F;
236 padn
= ( last
< 56 ) ? ( 56 - last
) : ( 120 - last
);
238 md5_update( ctx
, md5_padding
, padn
);
239 md5_update( ctx
, msglen
, 8 );
241 PUT_UINT32( ctx
->state
[0], digest
, 0 );
242 PUT_UINT32( ctx
->state
[1], digest
, 4 );
243 PUT_UINT32( ctx
->state
[2], digest
, 8 );
244 PUT_UINT32( ctx
->state
[3], digest
, 12 );