1/*
2   MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
3 */
4
5/*
6   Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
7   rights reserved.
8
9   License to copy and use this software is granted provided that it
10   is identified as the "RSA Data Security, Inc. MD5 Message-Digest
11   Algorithm" in all material mentioning or referencing this software
12   or this function.
13
14   License is also granted to make and use derivative works provided
15   that such works are identified as "derived from the RSA Data
16   Security, Inc. MD5 Message-Digest Algorithm" in all material
17   mentioning or referencing the derived work.
18
19   RSA Data Security, Inc. makes no representations concerning either
20   the merchantability of this software or the suitability of this
21   software for any particular purpose. It is provided "as is"
22   without express or implied warranty of any kind.
23
24   These notices must be retained in any copies of any part of this
25   documentation and/or software.
26
27 */
28
29#include "global.h"
30#include "md5.h"
31
32/*
33   Constants for MD5Transform routine.
34 */
35#define S11 7
36#define S12 12
37#define S13 17
38#define S14 22
39#define S21 5
40#define S22 9
41#define S23 14
42#define S24 20
43#define S31 4
44#define S32 11
45#define S33 16
46#define S34 23
47#define S41 6
48#define S42 10
49#define S43 15
50#define S44 21
51
52static void MD5Transform PROTO_LIST( ( UINT4[4],
53                                       unsigned char[64] ) );
54static void Encode PROTO_LIST( ( unsigned char *,
55                                 UINT4 *,
56                                 unsigned int ) );
57
58static void Decode PROTO_LIST( ( UINT4 *,
59                                 unsigned char *,
60                                 unsigned int ) );
61
62static void MD5_memcpy PROTO_LIST( ( POINTER,
63                                     POINTER,
64                                     unsigned int ) );
65static void MD5_memset PROTO_LIST( ( POINTER,
66                                     int,
67                                     unsigned int ) );
68
69static unsigned char PADDING[64] = {
70    0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
71    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
72    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
73};
74
75/*
76   F, G, H and I are basic MD5 functions.
77 */
78#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
79#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
80#define H(x, y, z) ((x) ^ (y) ^ (z))
81#define I(x, y, z) ((y) ^ ((x) | (~z)))
82
83/*
84   ROTATE_LEFT rotates x left n bits.
85 */
86#define ROTATE_LEFT(x, n) (((x) <<(n)) | ((x) >> (32-(n))))
87
88/*
89   FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
90   Rotation is separate from addition to prevent recomputation.
91 */
92#define FF(a, b, c, d, x, s, ac) { \
93 (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
94 (a) = ROTATE_LEFT ((a), (s)); \
95 (a) += (b); \
96  }
97
98#define GG(a, b, c, d, x, s, ac) { \
99 (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
100 (a) = ROTATE_LEFT ((a), (s)); \
101 (a) += (b); \
102  }
103
104#define HH(a, b, c, d, x, s, ac) { \
105 (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
106 (a) = ROTATE_LEFT ((a), (s)); \
107 (a) += (b); \
108  }
109
110#define II(a, b, c, d, x, s, ac) { \
111 (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
112 (a) = ROTATE_LEFT ((a), (s)); \
113 (a) += (b); \
114  }
115
116/*
117   MD5 initialization. Begins an MD5 operation, writing a new context.
118 */
119void
120MD5Init( context )
121     MD5_CTX *context;          /* context */
122{
123    context->count[0] = context->count[1] = 0;
124
125    /*
126       Load magic initialization constants.
127     */
128    context->state[0] = 0x67452301;
129    context->state[1] = 0xefcdab89;
130    context->state[2] = 0x98badcfe;
131    context->state[3] = 0x10325476;
132}
133
134/*
135   MD5 block update operation. Continues an MD5 message-digest
136   operation, processing another message block, and updating the
137   context.
138 */
139
140void
141MD5Update( context,
142           input,
143           inputLen )
144     MD5_CTX *context;          /* context */
145     unsigned char *input;      /* input block */
146     unsigned int inputLen;     /* length of input block */
147{
148    unsigned int i,
149      index_1,
150      partLen;
151
152    /*
153       Compute number of bytes mod 64
154     */
155    index_1 = ( unsigned int )( ( context->count[0] >> 3 ) & 0x3F );
156
157    /*
158       Update number of bits
159     */
160    if( ( context->count[0] +=
161          ( ( UINT4 ) inputLen << 3 ) ) < ( ( UINT4 ) inputLen << 3 ) )
162        context->count[1]++;
163
164    context->count[1] += ( ( UINT4 ) inputLen >> 29 );
165
166    partLen = 64 - index_1;
167
168    /*
169       Transform as many times as possible.
170     */
171    if( inputLen >= partLen ) {
172
173        MD5_memcpy
174            ( ( POINTER ) & context->buffer[index_1], ( POINTER ) input,
175              partLen );
176        MD5Transform( context->state, context->buffer );
177
178        for( i = partLen; i + 63 < inputLen; i += 64 )
179            MD5Transform( context->state, &input[i] );
180
181        index_1 = 0;
182    } else
183        i = 0;
184
185    /*
186       Buffer remaining input
187     */
188    MD5_memcpy
189        ( ( POINTER ) & context->buffer[index_1], ( POINTER ) & input[i],
190          inputLen - i );
191
192}
193
194/*
195   MD5 finalization. Ends an MD5 message-digest operation, writing the
196   the message digest and zeroizing the context.
197 */
198
199void
200MD5Final( digest,
201          context )
202     unsigned char digest[16];  /* message digest */
203     MD5_CTX *context;          /* context */
204{
205
206    unsigned char bits[8];
207    unsigned int index_1,
208      padLen;
209
210    /*
211       Save number of bits
212     */
213    Encode( bits, context->count, 8 );
214
215    /*
216       Pad out to 56 mod 64.
217     */
218    index_1 = ( unsigned int )( ( context->count[0] >> 3 ) & 0x3f );
219
220    padLen = ( index_1 < 56 ) ? ( 56 - index_1 ) : ( 120 - index_1 );
221
222    MD5Update( context, PADDING, padLen );
223
224    /*
225       Append length (before padding)
226     */
227    MD5Update( context, bits, 8 );
228
229    /*
230       Store state in digest
231     */
232    Encode( digest, context->state, 16 );
233
234    /*
235       Zeroize sensitive information.
236     */
237    MD5_memset( ( POINTER ) context, 0, sizeof( *context ) );
238
239}
240
241/*
242   MD5 basic transformation. Transforms state based on block.
243 */
244static void
245MD5Transform( state,
246              block )
247     UINT4 state[4];
248     unsigned char block[64];
249{
250    UINT4 a = state[0],
251      b = state[1],
252      c = state[2],
253      d = state[3],
254      x[16];
255
256    Decode( x, block, 64 );
257
258    /*
259       Round 1
260     */
261    FF( a, b, c, d, x[0], S11, 0xd76aa478 );    /* 1 */
262    FF( d, a, b, c, x[1], S12, 0xe8c7b756 );    /* 2 */
263    FF( c, d, a, b, x[2], S13, 0x242070db );    /* 3 */
264    FF( b, c, d, a, x[3], S14, 0xc1bdceee );    /* 4 */
265    FF( a, b, c, d, x[4], S11, 0xf57c0faf );    /* 5 */
266    FF( d, a, b, c, x[5], S12, 0x4787c62a );    /* 6 */
267    FF( c, d, a, b, x[6], S13, 0xa8304613 );    /* 7 */
268    FF( b, c, d, a, x[7], S14, 0xfd469501 );    /* 8 */
269    FF( a, b, c, d, x[8], S11, 0x698098d8 );    /* 9 */
270    FF( d, a, b, c, x[9], S12, 0x8b44f7af );    /* 10 */
271    FF( c, d, a, b, x[10], S13, 0xffff5bb1 );   /* 11 */
272    FF( b, c, d, a, x[11], S14, 0x895cd7be );   /* 12 */
273    FF( a, b, c, d, x[12], S11, 0x6b901122 );   /* 13 */
274    FF( d, a, b, c, x[13], S12, 0xfd987193 );   /* 14 */
275    FF( c, d, a, b, x[14], S13, 0xa679438e );   /* 15 */
276    FF( b, c, d, a, x[15], S14, 0x49b40821 );   /* 16 */
277
278    /*
279       Round 2
280     */
281    GG( a, b, c, d, x[1], S21, 0xf61e2562 );    /* 17 */
282    GG( d, a, b, c, x[6], S22, 0xc040b340 );    /* 18 */
283    GG( c, d, a, b, x[11], S23, 0x265e5a51 );   /* 19 */
284    GG( b, c, d, a, x[0], S24, 0xe9b6c7aa );    /* 20 */
285    GG( a, b, c, d, x[5], S21, 0xd62f105d );    /* 21 */
286    GG( d, a, b, c, x[10], S22, 0x2441453 );    /* 22 */
287    GG( c, d, a, b, x[15], S23, 0xd8a1e681 );   /* 23 */
288    GG( b, c, d, a, x[4], S24, 0xe7d3fbc8 );    /* 24 */
289    GG( a, b, c, d, x[9], S21, 0x21e1cde6 );    /* 25 */
290    GG( d, a, b, c, x[14], S22, 0xc33707d6 );   /* 26 */
291    GG( c, d, a, b, x[3], S23, 0xf4d50d87 );    /* 27 */
292    GG( b, c, d, a, x[8], S24, 0x455a14ed );    /* 28 */
293    GG( a, b, c, d, x[13], S21, 0xa9e3e905 );   /* 29 */
294    GG( d, a, b, c, x[2], S22, 0xfcefa3f8 );    /* 30 */
295    GG( c, d, a, b, x[7], S23, 0x676f02d9 );    /* 31 */
296    GG( b, c, d, a, x[12], S24, 0x8d2a4c8a );   /* 32 */
297
298    /*
299       Round 3
300     */
301    HH( a, b, c, d, x[5], S31, 0xfffa3942 );    /* 33 */
302    HH( d, a, b, c, x[8], S32, 0x8771f681 );    /* 34 */
303    HH( c, d, a, b, x[11], S33, 0x6d9d6122 );   /* 35 */
304    HH( b, c, d, a, x[14], S34, 0xfde5380c );   /* 36 */
305    HH( a, b, c, d, x[1], S31, 0xa4beea44 );    /* 37 */
306    HH( d, a, b, c, x[4], S32, 0x4bdecfa9 );    /* 38 */
307    HH( c, d, a, b, x[7], S33, 0xf6bb4b60 );    /* 39 */
308    HH( b, c, d, a, x[10], S34, 0xbebfbc70 );   /* 40 */
309    HH( a, b, c, d, x[13], S31, 0x289b7ec6 );   /* 41 */
310    HH( d, a, b, c, x[0], S32, 0xeaa127fa );    /* 42 */
311    HH( c, d, a, b, x[3], S33, 0xd4ef3085 );    /* 43 */
312    HH( b, c, d, a, x[6], S34, 0x4881d05 ); /* 44 */
313    HH( a, b, c, d, x[9], S31, 0xd9d4d039 );    /* 45 */
314    HH( d, a, b, c, x[12], S32, 0xe6db99e5 );   /* 46 */
315    HH( c, d, a, b, x[15], S33, 0x1fa27cf8 );   /* 47 */
316    HH( b, c, d, a, x[2], S34, 0xc4ac5665 );    /* 48 */
317
318    /*
319       Round 4
320     */
321    II( a, b, c, d, x[0], S41, 0xf4292244 );    /* 49 */
322    II( d, a, b, c, x[7], S42, 0x432aff97 );    /* 50 */
323    II( c, d, a, b, x[14], S43, 0xab9423a7 );   /* 51 */
324    II( b, c, d, a, x[5], S44, 0xfc93a039 );    /* 52 */
325    II( a, b, c, d, x[12], S41, 0x655b59c3 );   /* 53 */
326    II( d, a, b, c, x[3], S42, 0x8f0ccc92 );    /* 54 */
327    II( c, d, a, b, x[10], S43, 0xffeff47d );   /* 55 */
328    II( b, c, d, a, x[1], S44, 0x85845dd1 );    /* 56 */
329    II( a, b, c, d, x[8], S41, 0x6fa87e4f );    /* 57 */
330    II( d, a, b, c, x[15], S42, 0xfe2ce6e0 );   /* 58 */
331    II( c, d, a, b, x[6], S43, 0xa3014314 );    /* 59 */
332    II( b, c, d, a, x[13], S44, 0x4e0811a1 );   /* 60 */
333    II( a, b, c, d, x[4], S41, 0xf7537e82 );    /* 61 */
334    II( d, a, b, c, x[11], S42, 0xbd3af235 );   /* 62 */
335    II( c, d, a, b, x[2], S43, 0x2ad7d2bb );    /* 63 */
336    II( b, c, d, a, x[9], S44, 0xeb86d391 );    /* 64 */
337
338    state[0] += a;
339    state[1] += b;
340    state[2] += c;
341    state[3] += d;
342
343    /*
344       Zeroize sensitive information.
345     */
346    MD5_memset( ( POINTER ) x, 0, sizeof( x ) );
347
348}
349
350/*
351   Encodes input (UINT4) into output (unsigned char). Assumes len is
352   a multiple of 4.
353 */
354static void
355Encode( output,
356        input,
357        len )
358     unsigned char *output;
359     UINT4 *input;
360     unsigned int len;
361{
362    unsigned int i,
363      j;
364
365    for( i = 0, j = 0; j < len; i++, j += 4 ) {
366        output[j] = ( unsigned char )( input[i] & 0xff );
367        output[j + 1] = ( unsigned char )( ( input[i] >> 8 ) & 0xff );
368        output[j + 2] = ( unsigned char )( ( input[i] >> 16 ) & 0xff );
369        output[j + 3] = ( unsigned char )( ( input[i] >> 24 ) & 0xff );
370    }
371
372}
373
374/*
375   Decodes input (unsigned char) into output (UINT4). Assumes len is
376   a multiple of 4.
377 */
378
379static void
380Decode( output,
381        input,
382        len )
383     UINT4 *output;
384     unsigned char *input;
385     unsigned int len;
386{
387    unsigned int i,
388      j;
389
390    for( i = 0, j = 0; j < len; i++, j += 4 )
391        output[i] =
392            ( ( UINT4 ) input[j] ) | ( ( ( UINT4 ) input[j + 1] ) << 8 ) |
393            ( ( ( UINT4 ) input[j + 2] ) << 16 ) |
394            ( ( ( UINT4 ) input[j + 3] ) << 24 );
395}
396
397/*
398   Note: Replace &quot;for loop&quot; with standard memcpy if possible.
399 */
400static void
401MD5_memcpy( output,
402            input,
403            len )
404     POINTER output;
405     POINTER input;
406     unsigned int len;
407{
408    unsigned int i;
409
410    for( i = 0; i < len; i++ )
411        output[i] = input[i];
412
413}
414
415/*
416   Note: Replace &quot;for loop&quot; with standard memset if possible.
417 */
418static void
419MD5_memset( output,
420            value,
421            len )
422     POINTER output;
423     int value;
424     unsigned int len;
425{
426    unsigned int i;
427
428    for( i = 0; i < len; i++ )
429        ( ( char * )output )[i] = ( char )value;
430
431}
432