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