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