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
33 #if defined(MBEDTLS_MD5_C)
35 #include "mbedtls/md5.h"
39 #if defined(MBEDTLS_SELF_TEST)
40 #if defined(MBEDTLS_PLATFORM_C)
41 #include "mbedtls/platform.h"
44 #define mbedtls_printf printf
45 #endif /* MBEDTLS_PLATFORM_C */
46 #endif /* MBEDTLS_SELF_TEST */
48 #if !defined(MBEDTLS_MD5_ALT)
50 /* Implementation that should never be optimized out by the compiler */
51 static void mbedtls_zeroize( void *v, size_t n ) {
52 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
56 * 32-bit integer manipulation macros (little endian)
59 #define GET_UINT32_LE(n,b,i) \
61 (n) = ( (uint32_t) (b)[(i) ] ) \
62 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
63 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
64 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
69 #define PUT_UINT32_LE(n,b,i) \
71 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
72 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
73 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
74 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
78 void mbedtls_md5_init( mbedtls_md5_context *ctx )
80 memset( ctx, 0, sizeof( mbedtls_md5_context ) );
83 void mbedtls_md5_free( mbedtls_md5_context *ctx )
88 mbedtls_zeroize( ctx, sizeof( mbedtls_md5_context ) );
91 void mbedtls_md5_clone( mbedtls_md5_context *dst,
92 const mbedtls_md5_context *src )
100 void mbedtls_md5_starts( mbedtls_md5_context *ctx )
105 ctx->state[0] = 0x67452301;
106 ctx->state[1] = 0xEFCDAB89;
107 ctx->state[2] = 0x98BADCFE;
108 ctx->state[3] = 0x10325476;
111 #if !defined(MBEDTLS_MD5_PROCESS_ALT)
112 void mbedtls_md5_process( mbedtls_md5_context *ctx, const unsigned char data[64] )
114 uint32_t X[16], A, B, C, D;
116 GET_UINT32_LE( X[ 0], data, 0 );
117 GET_UINT32_LE( X[ 1], data, 4 );
118 GET_UINT32_LE( X[ 2], data, 8 );
119 GET_UINT32_LE( X[ 3], data, 12 );
120 GET_UINT32_LE( X[ 4], data, 16 );
121 GET_UINT32_LE( X[ 5], data, 20 );
122 GET_UINT32_LE( X[ 6], data, 24 );
123 GET_UINT32_LE( X[ 7], data, 28 );
124 GET_UINT32_LE( X[ 8], data, 32 );
125 GET_UINT32_LE( X[ 9], data, 36 );
126 GET_UINT32_LE( X[10], data, 40 );
127 GET_UINT32_LE( X[11], data, 44 );
128 GET_UINT32_LE( X[12], data, 48 );
129 GET_UINT32_LE( X[13], data, 52 );
130 GET_UINT32_LE( X[14], data, 56 );
131 GET_UINT32_LE( X[15], data, 60 );
133 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
135 #define P(a,b,c,d,k,s,t) \
137 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
145 #define F(x,y,z) (z ^ (x & (y ^ z)))
147 P( A, B, C, D, 0, 7, 0xD76AA478 );
148 P( D, A, B, C, 1, 12, 0xE8C7B756 );
149 P( C, D, A, B, 2, 17, 0x242070DB );
150 P( B, C, D, A, 3, 22, 0xC1BDCEEE );
151 P( A, B, C, D, 4, 7, 0xF57C0FAF );
152 P( D, A, B, C, 5, 12, 0x4787C62A );
153 P( C, D, A, B, 6, 17, 0xA8304613 );
154 P( B, C, D, A, 7, 22, 0xFD469501 );
155 P( A, B, C, D, 8, 7, 0x698098D8 );
156 P( D, A, B, C, 9, 12, 0x8B44F7AF );
157 P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
158 P( B, C, D, A, 11, 22, 0x895CD7BE );
159 P( A, B, C, D, 12, 7, 0x6B901122 );
160 P( D, A, B, C, 13, 12, 0xFD987193 );
161 P( C, D, A, B, 14, 17, 0xA679438E );
162 P( B, C, D, A, 15, 22, 0x49B40821 );
166 #define F(x,y,z) (y ^ (z & (x ^ y)))
168 P( A, B, C, D, 1, 5, 0xF61E2562 );
169 P( D, A, B, C, 6, 9, 0xC040B340 );
170 P( C, D, A, B, 11, 14, 0x265E5A51 );
171 P( B, C, D, A, 0, 20, 0xE9B6C7AA );
172 P( A, B, C, D, 5, 5, 0xD62F105D );
173 P( D, A, B, C, 10, 9, 0x02441453 );
174 P( C, D, A, B, 15, 14, 0xD8A1E681 );
175 P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
176 P( A, B, C, D, 9, 5, 0x21E1CDE6 );
177 P( D, A, B, C, 14, 9, 0xC33707D6 );
178 P( C, D, A, B, 3, 14, 0xF4D50D87 );
179 P( B, C, D, A, 8, 20, 0x455A14ED );
180 P( A, B, C, D, 13, 5, 0xA9E3E905 );
181 P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
182 P( C, D, A, B, 7, 14, 0x676F02D9 );
183 P( B, C, D, A, 12, 20, 0x8D2A4C8A );
187 #define F(x,y,z) (x ^ y ^ z)
189 P( A, B, C, D, 5, 4, 0xFFFA3942 );
190 P( D, A, B, C, 8, 11, 0x8771F681 );
191 P( C, D, A, B, 11, 16, 0x6D9D6122 );
192 P( B, C, D, A, 14, 23, 0xFDE5380C );
193 P( A, B, C, D, 1, 4, 0xA4BEEA44 );
194 P( D, A, B, C, 4, 11, 0x4BDECFA9 );
195 P( C, D, A, B, 7, 16, 0xF6BB4B60 );
196 P( B, C, D, A, 10, 23, 0xBEBFBC70 );
197 P( A, B, C, D, 13, 4, 0x289B7EC6 );
198 P( D, A, B, C, 0, 11, 0xEAA127FA );
199 P( C, D, A, B, 3, 16, 0xD4EF3085 );
200 P( B, C, D, A, 6, 23, 0x04881D05 );
201 P( A, B, C, D, 9, 4, 0xD9D4D039 );
202 P( D, A, B, C, 12, 11, 0xE6DB99E5 );
203 P( C, D, A, B, 15, 16, 0x1FA27CF8 );
204 P( B, C, D, A, 2, 23, 0xC4AC5665 );
208 #define F(x,y,z) (y ^ (x | ~z))
210 P( A, B, C, D, 0, 6, 0xF4292244 );
211 P( D, A, B, C, 7, 10, 0x432AFF97 );
212 P( C, D, A, B, 14, 15, 0xAB9423A7 );
213 P( B, C, D, A, 5, 21, 0xFC93A039 );
214 P( A, B, C, D, 12, 6, 0x655B59C3 );
215 P( D, A, B, C, 3, 10, 0x8F0CCC92 );
216 P( C, D, A, B, 10, 15, 0xFFEFF47D );
217 P( B, C, D, A, 1, 21, 0x85845DD1 );
218 P( A, B, C, D, 8, 6, 0x6FA87E4F );
219 P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
220 P( C, D, A, B, 6, 15, 0xA3014314 );
221 P( B, C, D, A, 13, 21, 0x4E0811A1 );
222 P( A, B, C, D, 4, 6, 0xF7537E82 );
223 P( D, A, B, C, 11, 10, 0xBD3AF235 );
224 P( C, D, A, B, 2, 15, 0x2AD7D2BB );
225 P( B, C, D, A, 9, 21, 0xEB86D391 );
234 #endif /* !MBEDTLS_MD5_PROCESS_ALT */
239 void mbedtls_md5_update( mbedtls_md5_context *ctx, const unsigned char *input, size_t ilen )
247 left = ctx->total[0] & 0x3F;
250 ctx->total[0] += (uint32_t) ilen;
251 ctx->total[0] &= 0xFFFFFFFF;
253 if( ctx->total[0] < (uint32_t) ilen )
256 if( left && ilen >= fill )
258 memcpy( (void *) (ctx->buffer + left), input, fill );
259 mbedtls_md5_process( ctx, ctx->buffer );
267 mbedtls_md5_process( ctx, input );
274 memcpy( (void *) (ctx->buffer + left), input, ilen );
278 static const unsigned char md5_padding[64] =
280 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
281 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
282 0, 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
289 void mbedtls_md5_finish( mbedtls_md5_context *ctx, unsigned char output[16] )
293 unsigned char msglen[8];
295 high = ( ctx->total[0] >> 29 )
296 | ( ctx->total[1] << 3 );
297 low = ( ctx->total[0] << 3 );
299 PUT_UINT32_LE( low, msglen, 0 );
300 PUT_UINT32_LE( high, msglen, 4 );
302 last = ctx->total[0] & 0x3F;
303 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
305 mbedtls_md5_update( ctx, md5_padding, padn );
306 mbedtls_md5_update( ctx, msglen, 8 );
308 PUT_UINT32_LE( ctx->state[0], output, 0 );
309 PUT_UINT32_LE( ctx->state[1], output, 4 );
310 PUT_UINT32_LE( ctx->state[2], output, 8 );
311 PUT_UINT32_LE( ctx->state[3], output, 12 );
314 #endif /* !MBEDTLS_MD5_ALT */
317 * output = MD5( input buffer )
319 void mbedtls_md5( const unsigned char *input, size_t ilen, unsigned char output[16] )
321 mbedtls_md5_context ctx;
323 mbedtls_md5_init( &ctx );
324 mbedtls_md5_starts( &ctx );
325 mbedtls_md5_update( &ctx, input, ilen );
326 mbedtls_md5_finish( &ctx, output );
327 mbedtls_md5_free( &ctx );
330 #if defined(MBEDTLS_SELF_TEST)
332 * RFC 1321 test vectors
334 static const unsigned char md5_test_buf[7][81] =
339 { "message digest" },
340 { "abcdefghijklmnopqrstuvwxyz" },
341 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
342 { "12345678901234567890123456789012345678901234567890123456789012" \
343 "345678901234567890" }
346 static const int md5_test_buflen[7] =
348 0, 1, 3, 14, 26, 62, 80
351 static const unsigned char md5_test_sum[7][16] =
353 { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
354 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
355 { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
356 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
357 { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
358 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
359 { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
360 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
361 { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
362 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
363 { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
364 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
365 { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
366 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }
372 int mbedtls_md5_self_test( int verbose )
375 unsigned char md5sum[16];
377 for( i = 0; i < 7; i++ )
380 mbedtls_printf( " MD5 test #%d: ", i + 1 );
382 mbedtls_md5( md5_test_buf[i], md5_test_buflen[i], md5sum );
384 if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 )
387 mbedtls_printf( "failed\n" );
393 mbedtls_printf( "passed\n" );
397 mbedtls_printf( "\n" );
402 #endif /* MBEDTLS_SELF_TEST */
404 #endif /* MBEDTLS_MD5_C */