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 /* Modified October 3, 2003, to remove testing code, and add
8    include of "types.h".
9 
10    -Xodnizel
11 */
12 
13 #include <string.h>
14 #include "inttypes.h"
15 #include "md5.h"
16 
17 #define GET_UINT32(n,b,i)                       \
18 {                                               \
19     (n) = ( (uint32_t) (b)[(i) + 3] << 24 )       \
20         | ( (uint32_t) (b)[(i) + 2] << 16 )       \
21         | ( (uint32_t) (b)[(i) + 1] <<  8 )       \
22         | ( (uint32_t) (b)[(i)    ]       );      \
23 }
24 
25 #define PUT_UINT32(n,b,i)                       \
26 {                                               \
27     (b)[(i)    ] = (uint8_t) ( (n)       );       \
28     (b)[(i) + 1] = (uint8_t) ( (n) >>  8 );       \
29     (b)[(i) + 2] = (uint8_t) ( (n) >> 16 );       \
30     (b)[(i) + 3] = (uint8_t) ( (n) >> 24 );       \
31 }
32 
sal_md5_starts(struct sal_md5_context * ctx)33 void sal_md5_starts( struct sal_md5_context *ctx )
34 {
35     ctx->total[0] = 0;
36     ctx->total[1] = 0;
37     ctx->state[0] = 0x67452301;
38     ctx->state[1] = 0xEFCDAB89;
39     ctx->state[2] = 0x98BADCFE;
40     ctx->state[3] = 0x10325476;
41 }
42 
sal_md5_process(struct sal_md5_context * ctx,uint8_t data[64])43 void sal_md5_process( struct sal_md5_context *ctx, uint8_t data[64] )
44 {
45     uint32_t A, B, C, D, X[16];
46 
47     GET_UINT32( X[0],  data,  0 );
48     GET_UINT32( X[1],  data,  4 );
49     GET_UINT32( X[2],  data,  8 );
50     GET_UINT32( X[3],  data, 12 );
51     GET_UINT32( X[4],  data, 16 );
52     GET_UINT32( X[5],  data, 20 );
53     GET_UINT32( X[6],  data, 24 );
54     GET_UINT32( X[7],  data, 28 );
55     GET_UINT32( X[8],  data, 32 );
56     GET_UINT32( X[9],  data, 36 );
57     GET_UINT32( X[10], data, 40 );
58     GET_UINT32( X[11], data, 44 );
59     GET_UINT32( X[12], data, 48 );
60     GET_UINT32( X[13], data, 52 );
61     GET_UINT32( X[14], data, 56 );
62     GET_UINT32( X[15], data, 60 );
63 
64 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
65 
66 #define P(a,b,c,d,k,s,t)                                \
67 {                                                       \
68     a += F(b,c,d) + X[k] + t; a = S(a,s) + b;           \
69 }
70 
71     A = ctx->state[0];
72     B = ctx->state[1];
73     C = ctx->state[2];
74     D = ctx->state[3];
75 
76 #define F(x,y,z) (z ^ (x & (y ^ z)))
77 
78     P( A, B, C, D,  0,  7, 0xD76AA478 );
79     P( D, A, B, C,  1, 12, 0xE8C7B756 );
80     P( C, D, A, B,  2, 17, 0x242070DB );
81     P( B, C, D, A,  3, 22, 0xC1BDCEEE );
82     P( A, B, C, D,  4,  7, 0xF57C0FAF );
83     P( D, A, B, C,  5, 12, 0x4787C62A );
84     P( C, D, A, B,  6, 17, 0xA8304613 );
85     P( B, C, D, A,  7, 22, 0xFD469501 );
86     P( A, B, C, D,  8,  7, 0x698098D8 );
87     P( D, A, B, C,  9, 12, 0x8B44F7AF );
88     P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
89     P( B, C, D, A, 11, 22, 0x895CD7BE );
90     P( A, B, C, D, 12,  7, 0x6B901122 );
91     P( D, A, B, C, 13, 12, 0xFD987193 );
92     P( C, D, A, B, 14, 17, 0xA679438E );
93     P( B, C, D, A, 15, 22, 0x49B40821 );
94 
95 #undef F
96 
97 #define F(x,y,z) (y ^ (z & (x ^ y)))
98 
99     P( A, B, C, D,  1,  5, 0xF61E2562 );
100     P( D, A, B, C,  6,  9, 0xC040B340 );
101     P( C, D, A, B, 11, 14, 0x265E5A51 );
102     P( B, C, D, A,  0, 20, 0xE9B6C7AA );
103     P( A, B, C, D,  5,  5, 0xD62F105D );
104     P( D, A, B, C, 10,  9, 0x02441453 );
105     P( C, D, A, B, 15, 14, 0xD8A1E681 );
106     P( B, C, D, A,  4, 20, 0xE7D3FBC8 );
107     P( A, B, C, D,  9,  5, 0x21E1CDE6 );
108     P( D, A, B, C, 14,  9, 0xC33707D6 );
109     P( C, D, A, B,  3, 14, 0xF4D50D87 );
110     P( B, C, D, A,  8, 20, 0x455A14ED );
111     P( A, B, C, D, 13,  5, 0xA9E3E905 );
112     P( D, A, B, C,  2,  9, 0xFCEFA3F8 );
113     P( C, D, A, B,  7, 14, 0x676F02D9 );
114     P( B, C, D, A, 12, 20, 0x8D2A4C8A );
115 
116 #undef F
117 
118 #define F(x,y,z) (x ^ y ^ z)
119 
120     P( A, B, C, D,  5,  4, 0xFFFA3942 );
121     P( D, A, B, C,  8, 11, 0x8771F681 );
122     P( C, D, A, B, 11, 16, 0x6D9D6122 );
123     P( B, C, D, A, 14, 23, 0xFDE5380C );
124     P( A, B, C, D,  1,  4, 0xA4BEEA44 );
125     P( D, A, B, C,  4, 11, 0x4BDECFA9 );
126     P( C, D, A, B,  7, 16, 0xF6BB4B60 );
127     P( B, C, D, A, 10, 23, 0xBEBFBC70 );
128     P( A, B, C, D, 13,  4, 0x289B7EC6 );
129     P( D, A, B, C,  0, 11, 0xEAA127FA );
130     P( C, D, A, B,  3, 16, 0xD4EF3085 );
131     P( B, C, D, A,  6, 23, 0x04881D05 );
132     P( A, B, C, D,  9,  4, 0xD9D4D039 );
133     P( D, A, B, C, 12, 11, 0xE6DB99E5 );
134     P( C, D, A, B, 15, 16, 0x1FA27CF8 );
135     P( B, C, D, A,  2, 23, 0xC4AC5665 );
136 
137 #undef F
138 
139 #define F(x,y,z) (y ^ (x | ~z))
140 
141     P( A, B, C, D,  0,  6, 0xF4292244 );
142     P( D, A, B, C,  7, 10, 0x432AFF97 );
143     P( C, D, A, B, 14, 15, 0xAB9423A7 );
144     P( B, C, D, A,  5, 21, 0xFC93A039 );
145     P( A, B, C, D, 12,  6, 0x655B59C3 );
146     P( D, A, B, C,  3, 10, 0x8F0CCC92 );
147     P( C, D, A, B, 10, 15, 0xFFEFF47D );
148     P( B, C, D, A,  1, 21, 0x85845DD1 );
149     P( A, B, C, D,  8,  6, 0x6FA87E4F );
150     P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
151     P( C, D, A, B,  6, 15, 0xA3014314 );
152     P( B, C, D, A, 13, 21, 0x4E0811A1 );
153     P( A, B, C, D,  4,  6, 0xF7537E82 );
154     P( D, A, B, C, 11, 10, 0xBD3AF235 );
155     P( C, D, A, B,  2, 15, 0x2AD7D2BB );
156     P( B, C, D, A,  9, 21, 0xEB86D391 );
157 
158 #undef F
159 
160     ctx->state[0] += A;
161     ctx->state[1] += B;
162     ctx->state[2] += C;
163     ctx->state[3] += D;
164 }
165 
sal_md5_update(struct sal_md5_context * ctx,uint8_t * input,uint32_t length)166 void sal_md5_update( struct sal_md5_context *ctx, uint8_t *input, uint32_t length )
167 {
168     uint32_t left, fill;
169 
170     if( ! length ) return;
171 
172     left = ( ctx->total[0] >> 3 ) & 0x3F;
173     fill = 64 - left;
174 
175     ctx->total[0] += length <<  3;
176     ctx->total[1] += length >> 29;
177 
178     ctx->total[0] &= 0xFFFFFFFF;
179     ctx->total[1] += ctx->total[0] < ( length << 3 );
180 
181     if( left && length >= fill )
182     {
183         memcpy( (void *) (ctx->buffer + left), (void *) input, fill );
184         sal_md5_process( ctx, ctx->buffer );
185         length -= fill;
186         input  += fill;
187         left = 0;
188     }
189 
190     while( length >= 64 )
191     {
192         sal_md5_process( ctx, input );
193         length -= 64;
194         input  += 64;
195     }
196 
197     if( length )
198     {
199         memcpy( (void *) (ctx->buffer + left), (void *) input, length );
200     }
201 }
202 
203 static uint8_t md5_padding[64] =
204 {
205  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
206     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
207     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
208     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
209 };
210 
sal_md5_finish(struct sal_md5_context * ctx,uint8_t digest[16])211 void sal_md5_finish( struct sal_md5_context *ctx, uint8_t digest[16] )
212 {
213     uint32_t last, padn;
214     uint8_t msglen[8];
215 
216     PUT_UINT32( ctx->total[0], msglen, 0 );
217     PUT_UINT32( ctx->total[1], msglen, 4 );
218 
219     last = ( ctx->total[0] >> 3 ) & 0x3F;
220     padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
221 
222     sal_md5_update( ctx, md5_padding, padn );
223     sal_md5_update( ctx, msglen, 8 );
224 
225     PUT_UINT32( ctx->state[0], digest,  0 );
226     PUT_UINT32( ctx->state[1], digest,  4 );
227     PUT_UINT32( ctx->state[2], digest,  8 );
228     PUT_UINT32( ctx->state[3], digest, 12 );
229 }
230