1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <assert.h>
5 #include "aes_core.h"
6
7 #ifndef uint32_t
8 #define uint32_t unsigned int
9 #endif
10
11 /**
12 * \brief MD5 context structure
13 */
14 typedef struct
15 {
16 uint32_t total[2]; /*!< number of bytes processed */
17 uint32_t state[4]; /*!< intermediate digest state */
18 unsigned char buffer[64]; /*!< data block being processed */
19 }
20 RK_MD5_CTX;
21
22 /* Implementation that should never be optimized out by the compiler */
mbedtls_zeroize(void * v,size_t n)23 static void mbedtls_zeroize( void *v, size_t n ) {
24 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
25 }
26
27 /*
28 * 32-bit integer manipulation macros (little endian)
29 */
30 #ifndef GET_UINT32_LE
31 #define GET_UINT32_LE(n,b,i) \
32 { \
33 (n) = ( (uint32_t) (b)[(i) ] ) \
34 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
35 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
36 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
37 }
38 #endif
39
40 #ifndef PUT_UINT32_LE
41 #define PUT_UINT32_LE(n,b,i) \
42 { \
43 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
44 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
45 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
46 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
47 }
48 #endif
49
mbedtls_md5_init(RK_MD5_CTX * ctx)50 void mbedtls_md5_init( RK_MD5_CTX *ctx )
51 {
52 memset( ctx, 0, sizeof( RK_MD5_CTX ) );
53 }
54
mbedtls_md5_free(RK_MD5_CTX * ctx)55 void mbedtls_md5_free( RK_MD5_CTX *ctx )
56 {
57 if( ctx == NULL )
58 return;
59
60 mbedtls_zeroize( ctx, sizeof( RK_MD5_CTX ) );
61 }
62
mbedtls_md5_clone(RK_MD5_CTX * dst,const RK_MD5_CTX * src)63 void mbedtls_md5_clone( RK_MD5_CTX *dst,
64 const RK_MD5_CTX *src )
65 {
66 *dst = *src;
67 }
68
69 /*
70 * MD5 context setup
71 */
mbedtls_md5_starts(RK_MD5_CTX * ctx)72 void mbedtls_md5_starts( RK_MD5_CTX *ctx )
73 {
74 ctx->total[0] = 0;
75 ctx->total[1] = 0;
76
77 ctx->state[0] = 0x67452301;
78 ctx->state[1] = 0xEFCDAB89;
79 ctx->state[2] = 0x98BADCFE;
80 ctx->state[3] = 0x10325476;
81 }
82
83 #if !defined(MBEDTLS_MD5_PROCESS_ALT)
mbedtls_md5_process(RK_MD5_CTX * ctx,const unsigned char data[64])84 void mbedtls_md5_process( RK_MD5_CTX *ctx, const unsigned char data[64] )
85 {
86 uint32_t X[16], A, B, C, D;
87
88 GET_UINT32_LE( X[ 0], data, 0 );
89 GET_UINT32_LE( X[ 1], data, 4 );
90 GET_UINT32_LE( X[ 2], data, 8 );
91 GET_UINT32_LE( X[ 3], data, 12 );
92 GET_UINT32_LE( X[ 4], data, 16 );
93 GET_UINT32_LE( X[ 5], data, 20 );
94 GET_UINT32_LE( X[ 6], data, 24 );
95 GET_UINT32_LE( X[ 7], data, 28 );
96 GET_UINT32_LE( X[ 8], data, 32 );
97 GET_UINT32_LE( X[ 9], data, 36 );
98 GET_UINT32_LE( X[10], data, 40 );
99 GET_UINT32_LE( X[11], data, 44 );
100 GET_UINT32_LE( X[12], data, 48 );
101 GET_UINT32_LE( X[13], data, 52 );
102 GET_UINT32_LE( X[14], data, 56 );
103 GET_UINT32_LE( X[15], data, 60 );
104
105 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
106
107 #define P(a,b,c,d,k,s,t) \
108 { \
109 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
110 }
111
112 A = ctx->state[0];
113 B = ctx->state[1];
114 C = ctx->state[2];
115 D = ctx->state[3];
116
117 #define F(x,y,z) (z ^ (x & (y ^ z)))
118
119 P( A, B, C, D, 0, 7, 0xD76AA478 );
120 P( D, A, B, C, 1, 12, 0xE8C7B756 );
121 P( C, D, A, B, 2, 17, 0x242070DB );
122 P( B, C, D, A, 3, 22, 0xC1BDCEEE );
123 P( A, B, C, D, 4, 7, 0xF57C0FAF );
124 P( D, A, B, C, 5, 12, 0x4787C62A );
125 P( C, D, A, B, 6, 17, 0xA8304613 );
126 P( B, C, D, A, 7, 22, 0xFD469501 );
127 P( A, B, C, D, 8, 7, 0x698098D8 );
128 P( D, A, B, C, 9, 12, 0x8B44F7AF );
129 P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
130 P( B, C, D, A, 11, 22, 0x895CD7BE );
131 P( A, B, C, D, 12, 7, 0x6B901122 );
132 P( D, A, B, C, 13, 12, 0xFD987193 );
133 P( C, D, A, B, 14, 17, 0xA679438E );
134 P( B, C, D, A, 15, 22, 0x49B40821 );
135
136 #undef F
137
138 #define F(x,y,z) (y ^ (z & (x ^ y)))
139
140 P( A, B, C, D, 1, 5, 0xF61E2562 );
141 P( D, A, B, C, 6, 9, 0xC040B340 );
142 P( C, D, A, B, 11, 14, 0x265E5A51 );
143 P( B, C, D, A, 0, 20, 0xE9B6C7AA );
144 P( A, B, C, D, 5, 5, 0xD62F105D );
145 P( D, A, B, C, 10, 9, 0x02441453 );
146 P( C, D, A, B, 15, 14, 0xD8A1E681 );
147 P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
148 P( A, B, C, D, 9, 5, 0x21E1CDE6 );
149 P( D, A, B, C, 14, 9, 0xC33707D6 );
150 P( C, D, A, B, 3, 14, 0xF4D50D87 );
151 P( B, C, D, A, 8, 20, 0x455A14ED );
152 P( A, B, C, D, 13, 5, 0xA9E3E905 );
153 P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
154 P( C, D, A, B, 7, 14, 0x676F02D9 );
155 P( B, C, D, A, 12, 20, 0x8D2A4C8A );
156
157 #undef F
158
159 #define F(x,y,z) (x ^ y ^ z)
160
161 P( A, B, C, D, 5, 4, 0xFFFA3942 );
162 P( D, A, B, C, 8, 11, 0x8771F681 );
163 P( C, D, A, B, 11, 16, 0x6D9D6122 );
164 P( B, C, D, A, 14, 23, 0xFDE5380C );
165 P( A, B, C, D, 1, 4, 0xA4BEEA44 );
166 P( D, A, B, C, 4, 11, 0x4BDECFA9 );
167 P( C, D, A, B, 7, 16, 0xF6BB4B60 );
168 P( B, C, D, A, 10, 23, 0xBEBFBC70 );
169 P( A, B, C, D, 13, 4, 0x289B7EC6 );
170 P( D, A, B, C, 0, 11, 0xEAA127FA );
171 P( C, D, A, B, 3, 16, 0xD4EF3085 );
172 P( B, C, D, A, 6, 23, 0x04881D05 );
173 P( A, B, C, D, 9, 4, 0xD9D4D039 );
174 P( D, A, B, C, 12, 11, 0xE6DB99E5 );
175 P( C, D, A, B, 15, 16, 0x1FA27CF8 );
176 P( B, C, D, A, 2, 23, 0xC4AC5665 );
177
178 #undef F
179
180 #define F(x,y,z) (y ^ (x | ~z))
181
182 P( A, B, C, D, 0, 6, 0xF4292244 );
183 P( D, A, B, C, 7, 10, 0x432AFF97 );
184 P( C, D, A, B, 14, 15, 0xAB9423A7 );
185 P( B, C, D, A, 5, 21, 0xFC93A039 );
186 P( A, B, C, D, 12, 6, 0x655B59C3 );
187 P( D, A, B, C, 3, 10, 0x8F0CCC92 );
188 P( C, D, A, B, 10, 15, 0xFFEFF47D );
189 P( B, C, D, A, 1, 21, 0x85845DD1 );
190 P( A, B, C, D, 8, 6, 0x6FA87E4F );
191 P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
192 P( C, D, A, B, 6, 15, 0xA3014314 );
193 P( B, C, D, A, 13, 21, 0x4E0811A1 );
194 P( A, B, C, D, 4, 6, 0xF7537E82 );
195 P( D, A, B, C, 11, 10, 0xBD3AF235 );
196 P( C, D, A, B, 2, 15, 0x2AD7D2BB );
197 P( B, C, D, A, 9, 21, 0xEB86D391 );
198
199 #undef F
200
201 ctx->state[0] += A;
202 ctx->state[1] += B;
203 ctx->state[2] += C;
204 ctx->state[3] += D;
205 }
206
207 /*
208 * MD5 process buffer
209 */
mbedtls_md5_update(RK_MD5_CTX * ctx,const unsigned char * input,size_t ilen)210 void mbedtls_md5_update( RK_MD5_CTX *ctx, const unsigned char *input, size_t ilen )
211 {
212 size_t fill;
213 uint32_t left;
214
215 if( ilen == 0 )
216 return;
217
218 left = ctx->total[0] & 0x3F;
219 fill = 64 - left;
220
221 ctx->total[0] += (uint32_t) ilen;
222 ctx->total[0] &= 0xFFFFFFFF;
223
224 if( ctx->total[0] < (uint32_t) ilen )
225 ctx->total[1]++;
226
227 if( left && ilen >= fill )
228 {
229 memcpy( (void *) (ctx->buffer + left), input, fill );
230 mbedtls_md5_process( ctx, ctx->buffer );
231 input += fill;
232 ilen -= fill;
233 left = 0;
234 }
235
236 while( ilen >= 64 )
237 {
238 mbedtls_md5_process( ctx, input );
239 input += 64;
240 ilen -= 64;
241 }
242
243 if( ilen > 0 )
244 {
245 memcpy( (void *) (ctx->buffer + left), input, ilen );
246 }
247 }
248
249 static const unsigned char md5_padding[64] =
250 {
251 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
252 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
253 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
254 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
255 };
256
257 /*
258 * MD5 final digest
259 */
mbedtls_md5_finish(RK_MD5_CTX * ctx,unsigned char output[16])260 void mbedtls_md5_finish( RK_MD5_CTX *ctx, unsigned char output[16] )
261 {
262 uint32_t last, padn;
263 uint32_t high, low;
264 unsigned char msglen[8];
265
266 high = ( ctx->total[0] >> 29 )
267 | ( ctx->total[1] << 3 );
268 low = ( ctx->total[0] << 3 );
269
270 PUT_UINT32_LE( low, msglen, 0 );
271 PUT_UINT32_LE( high, msglen, 4 );
272
273 last = ctx->total[0] & 0x3F;
274 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
275
276 mbedtls_md5_update( ctx, md5_padding, padn );
277 mbedtls_md5_update( ctx, msglen, 8 );
278
279 PUT_UINT32_LE( ctx->state[0], output, 0 );
280 PUT_UINT32_LE( ctx->state[1], output, 4 );
281 PUT_UINT32_LE( ctx->state[2], output, 8 );
282 PUT_UINT32_LE( ctx->state[3], output, 12 );
283 }
284
285 #endif /* !MBEDTLS_MD5_ALT */
286
287 /*
288 * output = MD5( input buffer )
289 */
rk_hash_md5(const unsigned char * in,unsigned int in_len,unsigned char * out,unsigned int * out_len)290 int rk_hash_md5(const unsigned char *in, unsigned int in_len,
291 unsigned char *out, unsigned int *out_len)
292 {
293 RK_MD5_CTX ctx;
294
295 if (in == NULL && in_len != 0)
296 return -1;
297
298 if(out == NULL || out_len == NULL)
299 return -1;
300
301 mbedtls_md5_init( &ctx );
302 mbedtls_md5_starts( &ctx );
303 mbedtls_md5_update( &ctx, in, in_len );
304 mbedtls_md5_finish( &ctx, out );
305 mbedtls_md5_free( &ctx );
306 *out_len = 16;
307 return 0;
308 }
309
310
311