2 * RFC 1321 compliant MD5 implementation
4 * Copyright (C) 2006-2007 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, see <http://www.gnu.org/licenses/>.
20 * The MD5 algorithm was designed by Ron Rivest in 1991.
22 * http://www.ietf.org/rfc/rfc1321.txt
27 * Taken from the XySSL project at www.xyssl.org under terms of the
28 * GPL. This is from version 0.9 of the library, and has been modified
29 * as following, which may be helpful for future updates:
30 * * remove "xyssl/config.h" include
31 * * change include from "xyssl/md5.h" to "md5.h"
32 * * removal of HMAC code
33 * * removal of SELF_TEST code
34 * * removal of ipad and opad from the md5_context struct in md5.h
35 * * change of md5_file prototype from
36 * int md5_file( char *path, unsigned char *output )
38 * int md5_file( const char *path, unsigned char *output )
39 * * use a dynamically-allocated buffer in md5_file, and increase the size
40 * for performance reasons
41 * * various static/inline changes
43 * NOTE: XySSL has been renamed to PolarSSL, which is available at
44 * www.polarssl.org. If we update, we should get it from there.
54 * 32-bit integer manipulation macros (little endian)
57 #define GET_ULONG_LE(n,b,i) \
59 (n) = ( (unsigned long) (b)[(i) ] ) \
60 | ( (unsigned long) (b)[(i) + 1] << 8 ) \
61 | ( (unsigned long) (b)[(i) + 2] << 16 ) \
62 | ( (unsigned long) (b)[(i) + 3] << 24 ); \
67 #define PUT_ULONG_LE(n,b,i) \
69 (b)[(i) ] = (unsigned char) ( (n) ); \
70 (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
71 (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
72 (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
79 static inline void md5_starts( md5_context
*ctx
)
84 ctx
->state
[0] = 0x67452301;
85 ctx
->state
[1] = 0xEFCDAB89;
86 ctx
->state
[2] = 0x98BADCFE;
87 ctx
->state
[3] = 0x10325476;
90 static inline void md5_process( md5_context
*ctx
, unsigned char data
[64] )
92 unsigned long X
[16], A
, B
, C
, D
;
94 GET_ULONG_LE( X
[ 0], data
, 0 );
95 GET_ULONG_LE( X
[ 1], data
, 4 );
96 GET_ULONG_LE( X
[ 2], data
, 8 );
97 GET_ULONG_LE( X
[ 3], data
, 12 );
98 GET_ULONG_LE( X
[ 4], data
, 16 );
99 GET_ULONG_LE( X
[ 5], data
, 20 );
100 GET_ULONG_LE( X
[ 6], data
, 24 );
101 GET_ULONG_LE( X
[ 7], data
, 28 );
102 GET_ULONG_LE( X
[ 8], data
, 32 );
103 GET_ULONG_LE( X
[ 9], data
, 36 );
104 GET_ULONG_LE( X
[10], data
, 40 );
105 GET_ULONG_LE( X
[11], data
, 44 );
106 GET_ULONG_LE( X
[12], data
, 48 );
107 GET_ULONG_LE( X
[13], data
, 52 );
108 GET_ULONG_LE( X
[14], data
, 56 );
109 GET_ULONG_LE( X
[15], data
, 60 );
111 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
113 #define P(a,b,c,d,k,s,t) \
115 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
123 #define F(x,y,z) (z ^ (x & (y ^ z)))
125 P( A
, B
, C
, D
, 0, 7, 0xD76AA478 );
126 P( D
, A
, B
, C
, 1, 12, 0xE8C7B756 );
127 P( C
, D
, A
, B
, 2, 17, 0x242070DB );
128 P( B
, C
, D
, A
, 3, 22, 0xC1BDCEEE );
129 P( A
, B
, C
, D
, 4, 7, 0xF57C0FAF );
130 P( D
, A
, B
, C
, 5, 12, 0x4787C62A );
131 P( C
, D
, A
, B
, 6, 17, 0xA8304613 );
132 P( B
, C
, D
, A
, 7, 22, 0xFD469501 );
133 P( A
, B
, C
, D
, 8, 7, 0x698098D8 );
134 P( D
, A
, B
, C
, 9, 12, 0x8B44F7AF );
135 P( C
, D
, A
, B
, 10, 17, 0xFFFF5BB1 );
136 P( B
, C
, D
, A
, 11, 22, 0x895CD7BE );
137 P( A
, B
, C
, D
, 12, 7, 0x6B901122 );
138 P( D
, A
, B
, C
, 13, 12, 0xFD987193 );
139 P( C
, D
, A
, B
, 14, 17, 0xA679438E );
140 P( B
, C
, D
, A
, 15, 22, 0x49B40821 );
144 #define F(x,y,z) (y ^ (z & (x ^ y)))
146 P( A
, B
, C
, D
, 1, 5, 0xF61E2562 );
147 P( D
, A
, B
, C
, 6, 9, 0xC040B340 );
148 P( C
, D
, A
, B
, 11, 14, 0x265E5A51 );
149 P( B
, C
, D
, A
, 0, 20, 0xE9B6C7AA );
150 P( A
, B
, C
, D
, 5, 5, 0xD62F105D );
151 P( D
, A
, B
, C
, 10, 9, 0x02441453 );
152 P( C
, D
, A
, B
, 15, 14, 0xD8A1E681 );
153 P( B
, C
, D
, A
, 4, 20, 0xE7D3FBC8 );
154 P( A
, B
, C
, D
, 9, 5, 0x21E1CDE6 );
155 P( D
, A
, B
, C
, 14, 9, 0xC33707D6 );
156 P( C
, D
, A
, B
, 3, 14, 0xF4D50D87 );
157 P( B
, C
, D
, A
, 8, 20, 0x455A14ED );
158 P( A
, B
, C
, D
, 13, 5, 0xA9E3E905 );
159 P( D
, A
, B
, C
, 2, 9, 0xFCEFA3F8 );
160 P( C
, D
, A
, B
, 7, 14, 0x676F02D9 );
161 P( B
, C
, D
, A
, 12, 20, 0x8D2A4C8A );
165 #define F(x,y,z) (x ^ y ^ z)
167 P( A
, B
, C
, D
, 5, 4, 0xFFFA3942 );
168 P( D
, A
, B
, C
, 8, 11, 0x8771F681 );
169 P( C
, D
, A
, B
, 11, 16, 0x6D9D6122 );
170 P( B
, C
, D
, A
, 14, 23, 0xFDE5380C );
171 P( A
, B
, C
, D
, 1, 4, 0xA4BEEA44 );
172 P( D
, A
, B
, C
, 4, 11, 0x4BDECFA9 );
173 P( C
, D
, A
, B
, 7, 16, 0xF6BB4B60 );
174 P( B
, C
, D
, A
, 10, 23, 0xBEBFBC70 );
175 P( A
, B
, C
, D
, 13, 4, 0x289B7EC6 );
176 P( D
, A
, B
, C
, 0, 11, 0xEAA127FA );
177 P( C
, D
, A
, B
, 3, 16, 0xD4EF3085 );
178 P( B
, C
, D
, A
, 6, 23, 0x04881D05 );
179 P( A
, B
, C
, D
, 9, 4, 0xD9D4D039 );
180 P( D
, A
, B
, C
, 12, 11, 0xE6DB99E5 );
181 P( C
, D
, A
, B
, 15, 16, 0x1FA27CF8 );
182 P( B
, C
, D
, A
, 2, 23, 0xC4AC5665 );
186 #define F(x,y,z) (y ^ (x | ~z))
188 P( A
, B
, C
, D
, 0, 6, 0xF4292244 );
189 P( D
, A
, B
, C
, 7, 10, 0x432AFF97 );
190 P( C
, D
, A
, B
, 14, 15, 0xAB9423A7 );
191 P( B
, C
, D
, A
, 5, 21, 0xFC93A039 );
192 P( A
, B
, C
, D
, 12, 6, 0x655B59C3 );
193 P( D
, A
, B
, C
, 3, 10, 0x8F0CCC92 );
194 P( C
, D
, A
, B
, 10, 15, 0xFFEFF47D );
195 P( B
, C
, D
, A
, 1, 21, 0x85845DD1 );
196 P( A
, B
, C
, D
, 8, 6, 0x6FA87E4F );
197 P( D
, A
, B
, C
, 15, 10, 0xFE2CE6E0 );
198 P( C
, D
, A
, B
, 6, 15, 0xA3014314 );
199 P( B
, C
, D
, A
, 13, 21, 0x4E0811A1 );
200 P( A
, B
, C
, D
, 4, 6, 0xF7537E82 );
201 P( D
, A
, B
, C
, 11, 10, 0xBD3AF235 );
202 P( C
, D
, A
, B
, 2, 15, 0x2AD7D2BB );
203 P( B
, C
, D
, A
, 9, 21, 0xEB86D391 );
216 static inline void md5_update( md5_context
*ctx
, unsigned char *input
, int ilen
)
224 left
= ctx
->total
[0] & 0x3F;
227 ctx
->total
[0] += ilen
;
228 ctx
->total
[0] &= 0xFFFFFFFF;
230 if( ctx
->total
[0] < (unsigned long) ilen
)
233 if( left
&& ilen
>= fill
)
235 memcpy( (void *) (ctx
->buffer
+ left
),
236 (void *) input
, fill
);
237 md5_process( ctx
, ctx
->buffer
);
245 md5_process( ctx
, input
);
252 memcpy( (void *) (ctx
->buffer
+ left
),
253 (void *) input
, ilen
);
257 static unsigned char md5_padding
[64] =
259 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
260 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
261 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
262 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
268 static inline void md5_finish( md5_context
*ctx
, unsigned char output
[16] )
270 unsigned long last
, padn
;
271 unsigned long high
, low
;
272 unsigned char msglen
[8];
274 high
= ( ctx
->total
[0] >> 29 )
275 | ( ctx
->total
[1] << 3 );
276 low
= ( ctx
->total
[0] << 3 );
278 PUT_ULONG_LE( low
, msglen
, 0 );
279 PUT_ULONG_LE( high
, msglen
, 4 );
281 last
= ctx
->total
[0] & 0x3F;
282 padn
= ( last
< 56 ) ? ( 56 - last
) : ( 120 - last
);
284 md5_update( ctx
, (unsigned char *) md5_padding
, padn
);
285 md5_update( ctx
, msglen
, 8 );
287 PUT_ULONG_LE( ctx
->state
[0], output
, 0 );
288 PUT_ULONG_LE( ctx
->state
[1], output
, 4 );
289 PUT_ULONG_LE( ctx
->state
[2], output
, 8 );
290 PUT_ULONG_LE( ctx
->state
[3], output
, 12 );
294 * output = MD5( input buffer )
296 void md5( unsigned char *input
, int ilen
, unsigned char output
[16] )
301 md5_update( &ctx
, input
, ilen
);
302 md5_finish( &ctx
, output
);
304 memset( &ctx
, 0, sizeof( md5_context
) );
308 * output = MD5( file contents )
310 int md5_file( const char *path
, unsigned char output
[16] )
317 if( ( buf
= calloc(8192, sizeof(unsigned char)) ) == NULL
)
320 if( ( f
= fopen( path
, "rb" ) ) == NULL
) {
327 while( ( n
= fread( buf
, 1, sizeof( buf
), f
) ) > 0 )
328 md5_update( &ctx
, buf
, (int) n
);
330 md5_finish( &ctx
, output
);
332 memset( &ctx
, 0, sizeof( md5_context
) );
335 if( ferror( f
) != 0 )