2 * RFC 1321 compliant MD5 implementation
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: Apache-2.0
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 * This file is part of mbed TLS (https://tls.mbed.org)
22 * The MD5 algorithm was designed by Ron Rivest in 1991.
24 * http://www.ietf.org/rfc/rfc1321.txt
27 #if !defined(MBEDTLS_CONFIG_FILE)
28 //#include "mbedtls/config.h"
30 #include MBEDTLS_CONFIG_FILE
35 #if defined(MBEDTLS_MD5_C)
41 #if defined(MBEDTLS_SELF_TEST)
42 #if defined(MBEDTLS_PLATFORM_C)
43 #include "mbedtls/platform.h"
46 #define mbedtls_printf printf
47 #endif /* MBEDTLS_PLATFORM_C */
48 #endif /* MBEDTLS_SELF_TEST */
50 #if !defined(MBEDTLS_MD5_ALT)
52 /* Implementation that should never be optimized out by the compiler */
53 static void mbedtls_zeroize( void *v
, size_t n
) {
54 volatile unsigned char *p
= v
; while( n
-- ) *p
++ = 0;
58 * 32-bit integer manipulation macros (little endian)
61 #define GET_UINT32_LE(n,b,i) \
63 (n) = ( (uint32_t) (b)[(i) ] ) \
64 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
65 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
66 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
71 #define PUT_UINT32_LE(n,b,i) \
73 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
74 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
75 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
76 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
80 void mbedtls_md5_init( mbedtls_md5_context
*ctx
)
82 memset( ctx
, 0, sizeof( mbedtls_md5_context
) );
85 void mbedtls_md5_free( mbedtls_md5_context
*ctx
)
90 mbedtls_zeroize( ctx
, sizeof( mbedtls_md5_context
) );
93 void mbedtls_md5_clone( mbedtls_md5_context
*dst
,
94 const mbedtls_md5_context
*src
)
102 void mbedtls_md5_starts( mbedtls_md5_context
*ctx
)
107 ctx
->state
[0] = 0x67452301;
108 ctx
->state
[1] = 0xEFCDAB89;
109 ctx
->state
[2] = 0x98BADCFE;
110 ctx
->state
[3] = 0x10325476;
113 #if !defined(MBEDTLS_MD5_PROCESS_ALT)
114 void mbedtls_md5_process( mbedtls_md5_context
*ctx
, const unsigned char data
[64] )
116 uint32_t X
[16], A
, B
, C
, D
;
118 GET_UINT32_LE( X
[ 0], data
, 0 );
119 GET_UINT32_LE( X
[ 1], data
, 4 );
120 GET_UINT32_LE( X
[ 2], data
, 8 );
121 GET_UINT32_LE( X
[ 3], data
, 12 );
122 GET_UINT32_LE( X
[ 4], data
, 16 );
123 GET_UINT32_LE( X
[ 5], data
, 20 );
124 GET_UINT32_LE( X
[ 6], data
, 24 );
125 GET_UINT32_LE( X
[ 7], data
, 28 );
126 GET_UINT32_LE( X
[ 8], data
, 32 );
127 GET_UINT32_LE( X
[ 9], data
, 36 );
128 GET_UINT32_LE( X
[10], data
, 40 );
129 GET_UINT32_LE( X
[11], data
, 44 );
130 GET_UINT32_LE( X
[12], data
, 48 );
131 GET_UINT32_LE( X
[13], data
, 52 );
132 GET_UINT32_LE( X
[14], data
, 56 );
133 GET_UINT32_LE( X
[15], data
, 60 );
135 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
137 #define P(a,b,c,d,k,s,t) \
139 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
147 #define F(x,y,z) (z ^ (x & (y ^ z)))
149 P( A
, B
, C
, D
, 0, 7, 0xD76AA478 );
150 P( D
, A
, B
, C
, 1, 12, 0xE8C7B756 );
151 P( C
, D
, A
, B
, 2, 17, 0x242070DB );
152 P( B
, C
, D
, A
, 3, 22, 0xC1BDCEEE );
153 P( A
, B
, C
, D
, 4, 7, 0xF57C0FAF );
154 P( D
, A
, B
, C
, 5, 12, 0x4787C62A );
155 P( C
, D
, A
, B
, 6, 17, 0xA8304613 );
156 P( B
, C
, D
, A
, 7, 22, 0xFD469501 );
157 P( A
, B
, C
, D
, 8, 7, 0x698098D8 );
158 P( D
, A
, B
, C
, 9, 12, 0x8B44F7AF );
159 P( C
, D
, A
, B
, 10, 17, 0xFFFF5BB1 );
160 P( B
, C
, D
, A
, 11, 22, 0x895CD7BE );
161 P( A
, B
, C
, D
, 12, 7, 0x6B901122 );
162 P( D
, A
, B
, C
, 13, 12, 0xFD987193 );
163 P( C
, D
, A
, B
, 14, 17, 0xA679438E );
164 P( B
, C
, D
, A
, 15, 22, 0x49B40821 );
168 #define F(x,y,z) (y ^ (z & (x ^ y)))
170 P( A
, B
, C
, D
, 1, 5, 0xF61E2562 );
171 P( D
, A
, B
, C
, 6, 9, 0xC040B340 );
172 P( C
, D
, A
, B
, 11, 14, 0x265E5A51 );
173 P( B
, C
, D
, A
, 0, 20, 0xE9B6C7AA );
174 P( A
, B
, C
, D
, 5, 5, 0xD62F105D );
175 P( D
, A
, B
, C
, 10, 9, 0x02441453 );
176 P( C
, D
, A
, B
, 15, 14, 0xD8A1E681 );
177 P( B
, C
, D
, A
, 4, 20, 0xE7D3FBC8 );
178 P( A
, B
, C
, D
, 9, 5, 0x21E1CDE6 );
179 P( D
, A
, B
, C
, 14, 9, 0xC33707D6 );
180 P( C
, D
, A
, B
, 3, 14, 0xF4D50D87 );
181 P( B
, C
, D
, A
, 8, 20, 0x455A14ED );
182 P( A
, B
, C
, D
, 13, 5, 0xA9E3E905 );
183 P( D
, A
, B
, C
, 2, 9, 0xFCEFA3F8 );
184 P( C
, D
, A
, B
, 7, 14, 0x676F02D9 );
185 P( B
, C
, D
, A
, 12, 20, 0x8D2A4C8A );
189 #define F(x,y,z) (x ^ y ^ z)
191 P( A
, B
, C
, D
, 5, 4, 0xFFFA3942 );
192 P( D
, A
, B
, C
, 8, 11, 0x8771F681 );
193 P( C
, D
, A
, B
, 11, 16, 0x6D9D6122 );
194 P( B
, C
, D
, A
, 14, 23, 0xFDE5380C );
195 P( A
, B
, C
, D
, 1, 4, 0xA4BEEA44 );
196 P( D
, A
, B
, C
, 4, 11, 0x4BDECFA9 );
197 P( C
, D
, A
, B
, 7, 16, 0xF6BB4B60 );
198 P( B
, C
, D
, A
, 10, 23, 0xBEBFBC70 );
199 P( A
, B
, C
, D
, 13, 4, 0x289B7EC6 );
200 P( D
, A
, B
, C
, 0, 11, 0xEAA127FA );
201 P( C
, D
, A
, B
, 3, 16, 0xD4EF3085 );
202 P( B
, C
, D
, A
, 6, 23, 0x04881D05 );
203 P( A
, B
, C
, D
, 9, 4, 0xD9D4D039 );
204 P( D
, A
, B
, C
, 12, 11, 0xE6DB99E5 );
205 P( C
, D
, A
, B
, 15, 16, 0x1FA27CF8 );
206 P( B
, C
, D
, A
, 2, 23, 0xC4AC5665 );
210 #define F(x,y,z) (y ^ (x | ~z))
212 P( A
, B
, C
, D
, 0, 6, 0xF4292244 );
213 P( D
, A
, B
, C
, 7, 10, 0x432AFF97 );
214 P( C
, D
, A
, B
, 14, 15, 0xAB9423A7 );
215 P( B
, C
, D
, A
, 5, 21, 0xFC93A039 );
216 P( A
, B
, C
, D
, 12, 6, 0x655B59C3 );
217 P( D
, A
, B
, C
, 3, 10, 0x8F0CCC92 );
218 P( C
, D
, A
, B
, 10, 15, 0xFFEFF47D );
219 P( B
, C
, D
, A
, 1, 21, 0x85845DD1 );
220 P( A
, B
, C
, D
, 8, 6, 0x6FA87E4F );
221 P( D
, A
, B
, C
, 15, 10, 0xFE2CE6E0 );
222 P( C
, D
, A
, B
, 6, 15, 0xA3014314 );
223 P( B
, C
, D
, A
, 13, 21, 0x4E0811A1 );
224 P( A
, B
, C
, D
, 4, 6, 0xF7537E82 );
225 P( D
, A
, B
, C
, 11, 10, 0xBD3AF235 );
226 P( C
, D
, A
, B
, 2, 15, 0x2AD7D2BB );
227 P( B
, C
, D
, A
, 9, 21, 0xEB86D391 );
236 #endif /* !MBEDTLS_MD5_PROCESS_ALT */
241 void mbedtls_md5_update( mbedtls_md5_context
*ctx
, const unsigned char *input
, size_t ilen
)
249 left
= ctx
->total
[0] & 0x3F;
252 ctx
->total
[0] += (uint32_t) ilen
;
253 ctx
->total
[0] &= 0xFFFFFFFF;
255 if( ctx
->total
[0] < (uint32_t) ilen
)
258 if( left
&& ilen
>= fill
)
260 memcpy( (void *) (ctx
->buffer
+ left
), input
, fill
);
261 mbedtls_md5_process( ctx
, ctx
->buffer
);
269 mbedtls_md5_process( ctx
, input
);
276 memcpy( (void *) (ctx
->buffer
+ left
), input
, ilen
);
280 static const unsigned char md5_padding
[64] =
282 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
283 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
284 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
285 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
291 void mbedtls_md5_finish( mbedtls_md5_context
*ctx
, unsigned char output
[16] )
295 unsigned char msglen
[8];
297 high
= ( ctx
->total
[0] >> 29 )
298 | ( ctx
->total
[1] << 3 );
299 low
= ( ctx
->total
[0] << 3 );
301 PUT_UINT32_LE( low
, msglen
, 0 );
302 PUT_UINT32_LE( high
, msglen
, 4 );
304 last
= ctx
->total
[0] & 0x3F;
305 padn
= ( last
< 56 ) ? ( 56 - last
) : ( 120 - last
);
307 mbedtls_md5_update( ctx
, md5_padding
, padn
);
308 mbedtls_md5_update( ctx
, msglen
, 8 );
310 PUT_UINT32_LE( ctx
->state
[0], output
, 0 );
311 PUT_UINT32_LE( ctx
->state
[1], output
, 4 );
312 PUT_UINT32_LE( ctx
->state
[2], output
, 8 );
313 PUT_UINT32_LE( ctx
->state
[3], output
, 12 );
316 #endif /* !MBEDTLS_MD5_ALT */
319 * output = MD5( input buffer )
321 void mbedtls_md5( const unsigned char *input
, size_t ilen
, unsigned char output
[16] )
323 mbedtls_md5_context ctx
;
325 mbedtls_md5_init( &ctx
);
326 mbedtls_md5_starts( &ctx
);
327 mbedtls_md5_update( &ctx
, input
, ilen
);
328 mbedtls_md5_finish( &ctx
, output
);
329 mbedtls_md5_free( &ctx
);
332 #if defined(MBEDTLS_SELF_TEST)
334 * RFC 1321 test vectors
336 static const unsigned char md5_test_buf
[7][81] =
341 { "message digest" },
342 { "abcdefghijklmnopqrstuvwxyz" },
343 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
344 { "12345678901234567890123456789012345678901234567890123456789012" \
345 "345678901234567890" }
348 static const int md5_test_buflen
[7] =
350 0, 1, 3, 14, 26, 62, 80
353 static const unsigned char md5_test_sum
[7][16] =
355 { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
356 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
357 { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
358 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
359 { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
360 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
361 { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
362 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
363 { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
364 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
365 { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
366 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
367 { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
368 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }
374 int mbedtls_md5_self_test( int verbose
)
377 unsigned char md5sum
[16];
379 for( i
= 0; i
< 7; i
++ )
382 mbedtls_printf( " MD5 test #%d: ", i
+ 1 );
384 mbedtls_md5( md5_test_buf
[i
], md5_test_buflen
[i
], md5sum
);
386 if( memcmp( md5sum
, md5_test_sum
[i
], 16 ) != 0 )
389 mbedtls_printf( "failed\n" );
395 mbedtls_printf( "passed\n" );
399 mbedtls_printf( "\n" );
404 #endif /* MBEDTLS_SELF_TEST */
406 #endif /* MBEDTLS_MD5_C */