1 /*
2  * RFC 1321 compliant MD5 implementation,
3  * by Christophe Devine <devine@cr0.net>;
4  * this program is licensed under the GPL.
5  */
6 
7 #include <string.h>
8 
9 #include "md5.h"
10 
11 #define GET_UINT32(n,b,i)                       \
12 {                                               \
13     (n) = ( (uint32) (b)[(i)    ]       )       \
14         | ( (uint32) (b)[(i) + 1] <<  8 )       \
15         | ( (uint32) (b)[(i) + 2] << 16 )       \
16         | ( (uint32) (b)[(i) + 3] << 24 );      \
17 }
18 
19 #define PUT_UINT32(n,b,i)                       \
20 {                                               \
21     (b)[(i)    ] = (uint8) ( (n)       );       \
22     (b)[(i) + 1] = (uint8) ( (n) >>  8 );       \
23     (b)[(i) + 2] = (uint8) ( (n) >> 16 );       \
24     (b)[(i) + 3] = (uint8) ( (n) >> 24 );       \
25 }
26 
md5_starts(md5_context * ctx)27 void md5_starts( md5_context *ctx )
28 {
29     ctx->total[0] = 0;
30     ctx->total[1] = 0;
31 
32     ctx->state[0] = 0x67452301;
33     ctx->state[1] = 0xEFCDAB89;
34     ctx->state[2] = 0x98BADCFE;
35     ctx->state[3] = 0x10325476;
36 }
37 
md5_process(md5_context * ctx,uint8 data[64])38 void md5_process( md5_context *ctx, uint8 data[64] )
39 {
40     uint32 X[16], A, B, C, D;
41 
42     GET_UINT32( X[0],  data,  0 );
43     GET_UINT32( X[1],  data,  4 );
44     GET_UINT32( X[2],  data,  8 );
45     GET_UINT32( X[3],  data, 12 );
46     GET_UINT32( X[4],  data, 16 );
47     GET_UINT32( X[5],  data, 20 );
48     GET_UINT32( X[6],  data, 24 );
49     GET_UINT32( X[7],  data, 28 );
50     GET_UINT32( X[8],  data, 32 );
51     GET_UINT32( X[9],  data, 36 );
52     GET_UINT32( X[10], data, 40 );
53     GET_UINT32( X[11], data, 44 );
54     GET_UINT32( X[12], data, 48 );
55     GET_UINT32( X[13], data, 52 );
56     GET_UINT32( X[14], data, 56 );
57     GET_UINT32( X[15], data, 60 );
58 
59 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
60 
61 #define P(a,b,c,d,k,s,t)                                \
62 {                                                       \
63     a += F(b,c,d) + X[k] + t; a = S(a,s) + b;           \
64 }
65 
66     A = ctx->state[0];
67     B = ctx->state[1];
68     C = ctx->state[2];
69     D = ctx->state[3];
70 
71 #define F(x,y,z) (z ^ (x & (y ^ z)))
72 
73     P( A, B, C, D,  0,  7, 0xD76AA478 );
74     P( D, A, B, C,  1, 12, 0xE8C7B756 );
75     P( C, D, A, B,  2, 17, 0x242070DB );
76     P( B, C, D, A,  3, 22, 0xC1BDCEEE );
77     P( A, B, C, D,  4,  7, 0xF57C0FAF );
78     P( D, A, B, C,  5, 12, 0x4787C62A );
79     P( C, D, A, B,  6, 17, 0xA8304613 );
80     P( B, C, D, A,  7, 22, 0xFD469501 );
81     P( A, B, C, D,  8,  7, 0x698098D8 );
82     P( D, A, B, C,  9, 12, 0x8B44F7AF );
83     P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
84     P( B, C, D, A, 11, 22, 0x895CD7BE );
85     P( A, B, C, D, 12,  7, 0x6B901122 );
86     P( D, A, B, C, 13, 12, 0xFD987193 );
87     P( C, D, A, B, 14, 17, 0xA679438E );
88     P( B, C, D, A, 15, 22, 0x49B40821 );
89 
90 #undef F
91 
92 #define F(x,y,z) (y ^ (z & (x ^ y)))
93 
94     P( A, B, C, D,  1,  5, 0xF61E2562 );
95     P( D, A, B, C,  6,  9, 0xC040B340 );
96     P( C, D, A, B, 11, 14, 0x265E5A51 );
97     P( B, C, D, A,  0, 20, 0xE9B6C7AA );
98     P( A, B, C, D,  5,  5, 0xD62F105D );
99     P( D, A, B, C, 10,  9, 0x02441453 );
100     P( C, D, A, B, 15, 14, 0xD8A1E681 );
101     P( B, C, D, A,  4, 20, 0xE7D3FBC8 );
102     P( A, B, C, D,  9,  5, 0x21E1CDE6 );
103     P( D, A, B, C, 14,  9, 0xC33707D6 );
104     P( C, D, A, B,  3, 14, 0xF4D50D87 );
105     P( B, C, D, A,  8, 20, 0x455A14ED );
106     P( A, B, C, D, 13,  5, 0xA9E3E905 );
107     P( D, A, B, C,  2,  9, 0xFCEFA3F8 );
108     P( C, D, A, B,  7, 14, 0x676F02D9 );
109     P( B, C, D, A, 12, 20, 0x8D2A4C8A );
110 
111 #undef F
112 
113 #define F(x,y,z) (x ^ y ^ z)
114 
115     P( A, B, C, D,  5,  4, 0xFFFA3942 );
116     P( D, A, B, C,  8, 11, 0x8771F681 );
117     P( C, D, A, B, 11, 16, 0x6D9D6122 );
118     P( B, C, D, A, 14, 23, 0xFDE5380C );
119     P( A, B, C, D,  1,  4, 0xA4BEEA44 );
120     P( D, A, B, C,  4, 11, 0x4BDECFA9 );
121     P( C, D, A, B,  7, 16, 0xF6BB4B60 );
122     P( B, C, D, A, 10, 23, 0xBEBFBC70 );
123     P( A, B, C, D, 13,  4, 0x289B7EC6 );
124     P( D, A, B, C,  0, 11, 0xEAA127FA );
125     P( C, D, A, B,  3, 16, 0xD4EF3085 );
126     P( B, C, D, A,  6, 23, 0x04881D05 );
127     P( A, B, C, D,  9,  4, 0xD9D4D039 );
128     P( D, A, B, C, 12, 11, 0xE6DB99E5 );
129     P( C, D, A, B, 15, 16, 0x1FA27CF8 );
130     P( B, C, D, A,  2, 23, 0xC4AC5665 );
131 
132 #undef F
133 
134 #define F(x,y,z) (y ^ (x | ~z))
135 
136     P( A, B, C, D,  0,  6, 0xF4292244 );
137     P( D, A, B, C,  7, 10, 0x432AFF97 );
138     P( C, D, A, B, 14, 15, 0xAB9423A7 );
139     P( B, C, D, A,  5, 21, 0xFC93A039 );
140     P( A, B, C, D, 12,  6, 0x655B59C3 );
141     P( D, A, B, C,  3, 10, 0x8F0CCC92 );
142     P( C, D, A, B, 10, 15, 0xFFEFF47D );
143     P( B, C, D, A,  1, 21, 0x85845DD1 );
144     P( A, B, C, D,  8,  6, 0x6FA87E4F );
145     P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
146     P( C, D, A, B,  6, 15, 0xA3014314 );
147     P( B, C, D, A, 13, 21, 0x4E0811A1 );
148     P( A, B, C, D,  4,  6, 0xF7537E82 );
149     P( D, A, B, C, 11, 10, 0xBD3AF235 );
150     P( C, D, A, B,  2, 15, 0x2AD7D2BB );
151     P( B, C, D, A,  9, 21, 0xEB86D391 );
152 
153 #undef F
154 
155     ctx->state[0] += A;
156     ctx->state[1] += B;
157     ctx->state[2] += C;
158     ctx->state[3] += D;
159 }
160 
md5_update(md5_context * ctx,uint8 * input,uint32 length)161 void md5_update( md5_context *ctx, uint8 *input, uint32 length )
162 {
163     uint32 left, fill;
164 
165     if( ! length ) return;
166 
167     left = ctx->total[0] & 0x3F;
168     fill = 64 - left;
169 
170     ctx->total[0] += length;
171     ctx->total[0] &= 0xFFFFFFFF;
172 
173     if( ctx->total[0] < length )
174         ctx->total[1]++; /* #nocov */
175 
176     if( left && length >= fill )
177     {
178         memcpy( (void *) (ctx->buffer + left),
179                 (void *) input, fill );
180         md5_process( ctx, ctx->buffer );
181         length -= fill;
182         input  += fill;
183         left = 0;
184     }
185 
186     while( length >= 64 )
187     {
188         md5_process( ctx, input );
189         length -= 64;
190         input  += 64;
191     }
192 
193     if( length )
194     {
195         memcpy( (void *) (ctx->buffer + left),
196                 (void *) input, length );
197     }
198 }
199 
200 static uint8 md5_padding[64] =
201 {
202  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
203     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
204     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
205     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
206 };
207 
md5_finish(md5_context * ctx,uint8 digest[16])208 void md5_finish( md5_context *ctx, uint8 digest[16] )
209 {
210     uint32 last, padn;
211     uint32 high, low;
212     uint8 msglen[8];
213 
214     high = ( ctx->total[0] >> 29 )
215          | ( ctx->total[1] <<  3 );
216     low  = ( ctx->total[0] <<  3 );
217 
218     PUT_UINT32( low,  msglen, 0 );
219     PUT_UINT32( high, msglen, 4 );
220 
221     last = ctx->total[0] & 0x3F;
222     padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
223 
224     md5_update( ctx, md5_padding, padn );
225     md5_update( ctx, msglen, 8 );
226 
227     PUT_UINT32( ctx->state[0], digest,  0 );
228     PUT_UINT32( ctx->state[1], digest,  4 );
229     PUT_UINT32( ctx->state[2], digest,  8 );
230     PUT_UINT32( ctx->state[3], digest, 12 );
231 }
232 
233 #ifdef TEST
234 
235 #include <stdlib.h>
236 #include <stdio.h>
237 
238 /*
239  * those are the standard RFC 1321 test vectors
240  */
241 
242 static char *msg[] =
243 {
244     "",
245     "a",
246     "abc",
247     "message digest",
248     "abcdefghijklmnopqrstuvwxyz",
249     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
250     "12345678901234567890123456789012345678901234567890123456789012" \
251         "345678901234567890"
252 };
253 
254 static char *val[] =
255 {
256     "d41d8cd98f00b204e9800998ecf8427e",
257     "0cc175b9c0f1b6a831c399e269772661",
258     "900150983cd24fb0d6963f7d28e17f72",
259     "f96b697d7cb7938d525a2f31aaf161d0",
260     "c3fcd3d76192e4007dfb496cca67e13b",
261     "d174ab98d277d9f5a5611c2c9f419d9f",
262     "57edf4a22be3c955ac49da2e2107b67a"
263 };
264 
main(int argc,char * argv[])265 int main( int argc, char *argv[] )
266 {
267     FILE *f;
268     int i, j;
269     char output[33];
270     md5_context ctx;
271     unsigned char buf[1000];
272     unsigned char md5sum[16];
273 
274     if( argc < 2 )
275     {
276         printf( "\n MD5 Validation Tests:\n\n" );
277 
278         for( i = 0; i < 7; i++ )
279         {
280             printf( " Test %d ", i + 1 );
281 
282             md5_starts( &ctx );
283             md5_update( &ctx, (uint8 *) msg[i], strlen( msg[i] ) );
284             md5_finish( &ctx, md5sum );
285 
286             for( j = 0; j < 16; j++ )
287             {
288                 sprintf( output + j * 2, "%02x", md5sum[j] );
289             }
290 
291             if( memcmp( output, val[i], 32 ) )
292             {
293                 printf( "failed!\n" );
294                 return( 1 );
295             }
296 
297             printf( "passed.\n" );
298         }
299 
300         printf( "\n" );
301     }
302     else
303     {
304         if( ! ( f = fopen( argv[1], "rb" ) ) )
305         {
306             perror( "fopen" );
307             return( 1 );
308         }
309 
310         md5_starts( &ctx );
311 
312         while( ( i = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
313         {
314             md5_update( &ctx, buf, i );
315         }
316 
317         md5_finish( &ctx, md5sum );
318 
319         for( j = 0; j < 16; j++ )
320         {
321             printf( "%02x", md5sum[j] );
322         }
323 
324         printf( "  %s\n", argv[1] );
325     }
326 
327     return( 0 );
328 }
329 
330 #endif
331