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