]>
git.zerfleddert.de Git - proxmark3-svn/blob - common/mbedtls/md5.c
2 * RFC 1321 compliant MD5 implementation
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: GPL-2.0
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 * This file is part of mbed TLS (https://tls.mbed.org)
24 * The MD5 algorithm was designed by Ron Rivest in 1991.
26 * http://www.ietf.org/rfc/rfc1321.txt
29 #if !defined(MBEDTLS_CONFIG_FILE)
30 #include "mbedtls/config.h"
32 #include MBEDTLS_CONFIG_FILE
35 #if defined(MBEDTLS_MD5_C)
37 #include "mbedtls/md5.h"
38 #include "mbedtls/platform_util.h"
42 #if defined(MBEDTLS_SELF_TEST)
43 #if defined(MBEDTLS_PLATFORM_C)
44 #include "mbedtls/platform.h"
47 #define mbedtls_printf printf
48 #endif /* MBEDTLS_PLATFORM_C */
49 #endif /* MBEDTLS_SELF_TEST */
51 #if !defined(MBEDTLS_MD5_ALT)
54 * 32-bit integer manipulation macros (little endian)
57 #define GET_UINT32_LE(n,b,i) \
59 (n) = ( (uint32_t) (b)[(i) ] ) \
60 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
61 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
62 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
67 #define PUT_UINT32_LE(n,b,i) \
69 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
70 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
71 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
72 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
76 void mbedtls_md5_init( mbedtls_md5_context
*ctx
)
78 memset( ctx
, 0, sizeof( mbedtls_md5_context
) );
81 void mbedtls_md5_free( mbedtls_md5_context
*ctx
)
86 mbedtls_platform_zeroize( ctx
, sizeof( mbedtls_md5_context
) );
89 void mbedtls_md5_clone( mbedtls_md5_context
*dst
,
90 const mbedtls_md5_context
*src
)
98 int mbedtls_md5_starts_ret( mbedtls_md5_context
*ctx
)
103 ctx
->state
[0] = 0x67452301;
104 ctx
->state
[1] = 0xEFCDAB89;
105 ctx
->state
[2] = 0x98BADCFE;
106 ctx
->state
[3] = 0x10325476;
111 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
112 void mbedtls_md5_starts( mbedtls_md5_context
*ctx
)
114 mbedtls_md5_starts_ret( ctx
);
118 #if !defined(MBEDTLS_MD5_PROCESS_ALT)
119 int mbedtls_internal_md5_process( mbedtls_md5_context
*ctx
,
120 const unsigned char data
[64] )
122 uint32_t X
[16], A
, B
, C
, D
;
124 GET_UINT32_LE( X
[ 0], data
, 0 );
125 GET_UINT32_LE( X
[ 1], data
, 4 );
126 GET_UINT32_LE( X
[ 2], data
, 8 );
127 GET_UINT32_LE( X
[ 3], data
, 12 );
128 GET_UINT32_LE( X
[ 4], data
, 16 );
129 GET_UINT32_LE( X
[ 5], data
, 20 );
130 GET_UINT32_LE( X
[ 6], data
, 24 );
131 GET_UINT32_LE( X
[ 7], data
, 28 );
132 GET_UINT32_LE( X
[ 8], data
, 32 );
133 GET_UINT32_LE( X
[ 9], data
, 36 );
134 GET_UINT32_LE( X
[10], data
, 40 );
135 GET_UINT32_LE( X
[11], data
, 44 );
136 GET_UINT32_LE( X
[12], data
, 48 );
137 GET_UINT32_LE( X
[13], data
, 52 );
138 GET_UINT32_LE( X
[14], data
, 56 );
139 GET_UINT32_LE( X
[15], data
, 60 );
141 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
143 #define P(a,b,c,d,k,s,t) \
145 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
153 #define F(x,y,z) (z ^ (x & (y ^ z)))
155 P( A
, B
, C
, D
, 0, 7, 0xD76AA478 );
156 P( D
, A
, B
, C
, 1, 12, 0xE8C7B756 );
157 P( C
, D
, A
, B
, 2, 17, 0x242070DB );
158 P( B
, C
, D
, A
, 3, 22, 0xC1BDCEEE );
159 P( A
, B
, C
, D
, 4, 7, 0xF57C0FAF );
160 P( D
, A
, B
, C
, 5, 12, 0x4787C62A );
161 P( C
, D
, A
, B
, 6, 17, 0xA8304613 );
162 P( B
, C
, D
, A
, 7, 22, 0xFD469501 );
163 P( A
, B
, C
, D
, 8, 7, 0x698098D8 );
164 P( D
, A
, B
, C
, 9, 12, 0x8B44F7AF );
165 P( C
, D
, A
, B
, 10, 17, 0xFFFF5BB1 );
166 P( B
, C
, D
, A
, 11, 22, 0x895CD7BE );
167 P( A
, B
, C
, D
, 12, 7, 0x6B901122 );
168 P( D
, A
, B
, C
, 13, 12, 0xFD987193 );
169 P( C
, D
, A
, B
, 14, 17, 0xA679438E );
170 P( B
, C
, D
, A
, 15, 22, 0x49B40821 );
174 #define F(x,y,z) (y ^ (z & (x ^ y)))
176 P( A
, B
, C
, D
, 1, 5, 0xF61E2562 );
177 P( D
, A
, B
, C
, 6, 9, 0xC040B340 );
178 P( C
, D
, A
, B
, 11, 14, 0x265E5A51 );
179 P( B
, C
, D
, A
, 0, 20, 0xE9B6C7AA );
180 P( A
, B
, C
, D
, 5, 5, 0xD62F105D );
181 P( D
, A
, B
, C
, 10, 9, 0x02441453 );
182 P( C
, D
, A
, B
, 15, 14, 0xD8A1E681 );
183 P( B
, C
, D
, A
, 4, 20, 0xE7D3FBC8 );
184 P( A
, B
, C
, D
, 9, 5, 0x21E1CDE6 );
185 P( D
, A
, B
, C
, 14, 9, 0xC33707D6 );
186 P( C
, D
, A
, B
, 3, 14, 0xF4D50D87 );
187 P( B
, C
, D
, A
, 8, 20, 0x455A14ED );
188 P( A
, B
, C
, D
, 13, 5, 0xA9E3E905 );
189 P( D
, A
, B
, C
, 2, 9, 0xFCEFA3F8 );
190 P( C
, D
, A
, B
, 7, 14, 0x676F02D9 );
191 P( B
, C
, D
, A
, 12, 20, 0x8D2A4C8A );
195 #define F(x,y,z) (x ^ y ^ z)
197 P( A
, B
, C
, D
, 5, 4, 0xFFFA3942 );
198 P( D
, A
, B
, C
, 8, 11, 0x8771F681 );
199 P( C
, D
, A
, B
, 11, 16, 0x6D9D6122 );
200 P( B
, C
, D
, A
, 14, 23, 0xFDE5380C );
201 P( A
, B
, C
, D
, 1, 4, 0xA4BEEA44 );
202 P( D
, A
, B
, C
, 4, 11, 0x4BDECFA9 );
203 P( C
, D
, A
, B
, 7, 16, 0xF6BB4B60 );
204 P( B
, C
, D
, A
, 10, 23, 0xBEBFBC70 );
205 P( A
, B
, C
, D
, 13, 4, 0x289B7EC6 );
206 P( D
, A
, B
, C
, 0, 11, 0xEAA127FA );
207 P( C
, D
, A
, B
, 3, 16, 0xD4EF3085 );
208 P( B
, C
, D
, A
, 6, 23, 0x04881D05 );
209 P( A
, B
, C
, D
, 9, 4, 0xD9D4D039 );
210 P( D
, A
, B
, C
, 12, 11, 0xE6DB99E5 );
211 P( C
, D
, A
, B
, 15, 16, 0x1FA27CF8 );
212 P( B
, C
, D
, A
, 2, 23, 0xC4AC5665 );
216 #define F(x,y,z) (y ^ (x | ~z))
218 P( A
, B
, C
, D
, 0, 6, 0xF4292244 );
219 P( D
, A
, B
, C
, 7, 10, 0x432AFF97 );
220 P( C
, D
, A
, B
, 14, 15, 0xAB9423A7 );
221 P( B
, C
, D
, A
, 5, 21, 0xFC93A039 );
222 P( A
, B
, C
, D
, 12, 6, 0x655B59C3 );
223 P( D
, A
, B
, C
, 3, 10, 0x8F0CCC92 );
224 P( C
, D
, A
, B
, 10, 15, 0xFFEFF47D );
225 P( B
, C
, D
, A
, 1, 21, 0x85845DD1 );
226 P( A
, B
, C
, D
, 8, 6, 0x6FA87E4F );
227 P( D
, A
, B
, C
, 15, 10, 0xFE2CE6E0 );
228 P( C
, D
, A
, B
, 6, 15, 0xA3014314 );
229 P( B
, C
, D
, A
, 13, 21, 0x4E0811A1 );
230 P( A
, B
, C
, D
, 4, 6, 0xF7537E82 );
231 P( D
, A
, B
, C
, 11, 10, 0xBD3AF235 );
232 P( C
, D
, A
, B
, 2, 15, 0x2AD7D2BB );
233 P( B
, C
, D
, A
, 9, 21, 0xEB86D391 );
245 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
246 void mbedtls_md5_process( mbedtls_md5_context
*ctx
,
247 const unsigned char data
[64] )
249 mbedtls_internal_md5_process( ctx
, data
);
252 #endif /* !MBEDTLS_MD5_PROCESS_ALT */
257 int mbedtls_md5_update_ret( mbedtls_md5_context
*ctx
,
258 const unsigned char *input
,
268 left
= ctx
->total
[0] & 0x3F;
271 ctx
->total
[0] += (uint32_t) ilen
;
272 ctx
->total
[0] &= 0xFFFFFFFF;
274 if( ctx
->total
[0] < (uint32_t) ilen
)
277 if( left
&& ilen
>= fill
)
279 memcpy( (void *) (ctx
->buffer
+ left
), input
, fill
);
280 if( ( ret
= mbedtls_internal_md5_process( ctx
, ctx
->buffer
) ) != 0 )
290 if( ( ret
= mbedtls_internal_md5_process( ctx
, input
) ) != 0 )
299 memcpy( (void *) (ctx
->buffer
+ left
), input
, ilen
);
305 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
306 void mbedtls_md5_update( mbedtls_md5_context
*ctx
,
307 const unsigned char *input
,
310 mbedtls_md5_update_ret( ctx
, input
, ilen
);
317 int mbedtls_md5_finish_ret( mbedtls_md5_context
*ctx
,
318 unsigned char output
[16] )
325 * Add padding: 0x80 then 0x00 until 8 bytes remain for the length
327 used
= ctx
->total
[0] & 0x3F;
329 ctx
->buffer
[used
++] = 0x80;
333 /* Enough room for padding + length in current block */
334 memset( ctx
->buffer
+ used
, 0, 56 - used
);
338 /* We'll need an extra block */
339 memset( ctx
->buffer
+ used
, 0, 64 - used
);
341 if( ( ret
= mbedtls_internal_md5_process( ctx
, ctx
->buffer
) ) != 0 )
344 memset( ctx
->buffer
, 0, 56 );
350 high
= ( ctx
->total
[0] >> 29 )
351 | ( ctx
->total
[1] << 3 );
352 low
= ( ctx
->total
[0] << 3 );
354 PUT_UINT32_LE( low
, ctx
->buffer
, 56 );
355 PUT_UINT32_LE( high
, ctx
->buffer
, 60 );
357 if( ( ret
= mbedtls_internal_md5_process( ctx
, ctx
->buffer
) ) != 0 )
363 PUT_UINT32_LE( ctx
->state
[0], output
, 0 );
364 PUT_UINT32_LE( ctx
->state
[1], output
, 4 );
365 PUT_UINT32_LE( ctx
->state
[2], output
, 8 );
366 PUT_UINT32_LE( ctx
->state
[3], output
, 12 );
371 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
372 void mbedtls_md5_finish( mbedtls_md5_context
*ctx
,
373 unsigned char output
[16] )
375 mbedtls_md5_finish_ret( ctx
, output
);
379 #endif /* !MBEDTLS_MD5_ALT */
382 * output = MD5( input buffer )
384 int mbedtls_md5_ret( const unsigned char *input
,
386 unsigned char output
[16] )
389 mbedtls_md5_context ctx
;
391 mbedtls_md5_init( &ctx
);
393 if( ( ret
= mbedtls_md5_starts_ret( &ctx
) ) != 0 )
396 if( ( ret
= mbedtls_md5_update_ret( &ctx
, input
, ilen
) ) != 0 )
399 if( ( ret
= mbedtls_md5_finish_ret( &ctx
, output
) ) != 0 )
403 mbedtls_md5_free( &ctx
);
408 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
409 void mbedtls_md5( const unsigned char *input
,
411 unsigned char output
[16] )
413 mbedtls_md5_ret( input
, ilen
, output
);
417 #if defined(MBEDTLS_SELF_TEST)
419 * RFC 1321 test vectors
421 static const unsigned char md5_test_buf
[7][81] =
426 { "message digest" },
427 { "abcdefghijklmnopqrstuvwxyz" },
428 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
429 { "12345678901234567890123456789012345678901234567890123456789012"
430 "345678901234567890" }
433 static const size_t md5_test_buflen
[7] =
435 0, 1, 3, 14, 26, 62, 80
438 static const unsigned char md5_test_sum
[7][16] =
440 { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
441 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
442 { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
443 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
444 { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
445 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
446 { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
447 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
448 { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
449 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
450 { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
451 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
452 { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
453 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }
459 int mbedtls_md5_self_test( int verbose
)
462 unsigned char md5sum
[16];
464 for( i
= 0; i
< 7; i
++ )
467 mbedtls_printf( " MD5 test #%d: ", i
+ 1 );
469 ret
= mbedtls_md5_ret( md5_test_buf
[i
], md5_test_buflen
[i
], md5sum
);
473 if( memcmp( md5sum
, md5_test_sum
[i
], 16 ) != 0 )
480 mbedtls_printf( "passed\n" );
484 mbedtls_printf( "\n" );
490 mbedtls_printf( "failed\n" );
495 #endif /* MBEDTLS_SELF_TEST */
497 #endif /* MBEDTLS_MD5_C */