1 /*
2 * RFC 1321 compliant MD5 implementation
3 *
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: Apache-2.0
6 *
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
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
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.
18 *
19 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
21 /*
22 * The MD5 algorithm was designed by Ron Rivest in 1991.
23 *
24 * http://www.ietf.org/rfc/rfc1321.txt
25 */
26
27 #if !defined(MBEDTLS_CONFIG_FILE)
28 #include "mbedtls/config.h"
29 #else
30 #include MBEDTLS_CONFIG_FILE
31 #endif
32
33 #if defined(MBEDTLS_MD5_C)
34
35 #include "mbedtls/md5.h"
36
37 #include <string.h>
38
39 #if defined(MBEDTLS_SELF_TEST)
40 #if defined(MBEDTLS_PLATFORM_C)
41 #include "mbedtls/platform.h"
42 #else
43 #include <stdio.h>
44 #define mbedtls_printf printf
45 #endif /* MBEDTLS_PLATFORM_C */
46 #endif /* MBEDTLS_SELF_TEST */
47
48 #if !defined(MBEDTLS_MD5_ALT)
49
50 /* Implementation that should never be optimized out by the compiler */
mbedtls_zeroize(void * v,size_t n)51 static void mbedtls_zeroize( void *v, size_t n ) {
52 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
53 }
54
55 /*
56 * 32-bit integer manipulation macros (little endian)
57 */
58 #ifndef GET_UINT32_LE
59 #define GET_UINT32_LE(n,b,i) \
60 { \
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 ); \
65 }
66 #endif
67
68 #ifndef PUT_UINT32_LE
69 #define PUT_UINT32_LE(n,b,i) \
70 { \
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 ); \
75 }
76 #endif
77
mbedtls_md5_init(mbedtls_md5_context * ctx)78 void mbedtls_md5_init( mbedtls_md5_context *ctx )
79 {
80 memset( ctx, 0, sizeof( mbedtls_md5_context ) );
81 }
82
mbedtls_md5_free(mbedtls_md5_context * ctx)83 void mbedtls_md5_free( mbedtls_md5_context *ctx )
84 {
85 if( ctx == NULL )
86 return;
87
88 mbedtls_zeroize( ctx, sizeof( mbedtls_md5_context ) );
89 }
90
mbedtls_md5_clone(mbedtls_md5_context * dst,const mbedtls_md5_context * src)91 void mbedtls_md5_clone( mbedtls_md5_context *dst,
92 const mbedtls_md5_context *src )
93 {
94 *dst = *src;
95 }
96
97 /*
98 * MD5 context setup
99 */
mbedtls_md5_starts(mbedtls_md5_context * ctx)100 void mbedtls_md5_starts( mbedtls_md5_context *ctx )
101 {
102 ctx->total[0] = 0;
103 ctx->total[1] = 0;
104
105 ctx->state[0] = 0x67452301;
106 ctx->state[1] = 0xEFCDAB89;
107 ctx->state[2] = 0x98BADCFE;
108 ctx->state[3] = 0x10325476;
109 }
110
111 #if !defined(MBEDTLS_MD5_PROCESS_ALT)
mbedtls_md5_process(mbedtls_md5_context * ctx,const unsigned char data[64])112 void mbedtls_md5_process( mbedtls_md5_context *ctx, const unsigned char data[64] )
113 {
114 uint32_t X[16], A, B, C, D;
115
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 );
132
133 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
134
135 #define P(a,b,c,d,k,s,t) \
136 { \
137 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
138 }
139
140 A = ctx->state[0];
141 B = ctx->state[1];
142 C = ctx->state[2];
143 D = ctx->state[3];
144
145 #define F(x,y,z) (z ^ (x & (y ^ z)))
146
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 );
163
164 #undef F
165
166 #define F(x,y,z) (y ^ (z & (x ^ y)))
167
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 );
184
185 #undef F
186
187 #define F(x,y,z) (x ^ y ^ z)
188
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 );
205
206 #undef F
207
208 #define F(x,y,z) (y ^ (x | ~z))
209
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 );
226
227 #undef F
228
229 ctx->state[0] += A;
230 ctx->state[1] += B;
231 ctx->state[2] += C;
232 ctx->state[3] += D;
233 }
234 #endif /* !MBEDTLS_MD5_PROCESS_ALT */
235
236 /*
237 * MD5 process buffer
238 */
mbedtls_md5_update(mbedtls_md5_context * ctx,const unsigned char * input,size_t ilen)239 void mbedtls_md5_update( mbedtls_md5_context *ctx, const unsigned char *input, size_t ilen )
240 {
241 size_t fill;
242 uint32_t left;
243
244 if( ilen == 0 )
245 return;
246
247 left = ctx->total[0] & 0x3F;
248 fill = 64 - left;
249
250 ctx->total[0] += (uint32_t) ilen;
251 ctx->total[0] &= 0xFFFFFFFF;
252
253 if( ctx->total[0] < (uint32_t) ilen )
254 ctx->total[1]++;
255
256 if( left && ilen >= fill )
257 {
258 memcpy( (void *) (ctx->buffer + left), input, fill );
259 mbedtls_md5_process( ctx, ctx->buffer );
260 input += fill;
261 ilen -= fill;
262 left = 0;
263 }
264
265 while( ilen >= 64 )
266 {
267 mbedtls_md5_process( ctx, input );
268 input += 64;
269 ilen -= 64;
270 }
271
272 if( ilen > 0 )
273 {
274 memcpy( (void *) (ctx->buffer + left), input, ilen );
275 }
276 }
277
278 static const unsigned char md5_padding[64] =
279 {
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
284 };
285
286 /*
287 * MD5 final digest
288 */
mbedtls_md5_finish(mbedtls_md5_context * ctx,unsigned char output[16])289 void mbedtls_md5_finish( mbedtls_md5_context *ctx, unsigned char output[16] )
290 {
291 uint32_t last, padn;
292 uint32_t high, low;
293 unsigned char msglen[8];
294
295 high = ( ctx->total[0] >> 29 )
296 | ( ctx->total[1] << 3 );
297 low = ( ctx->total[0] << 3 );
298
299 PUT_UINT32_LE( low, msglen, 0 );
300 PUT_UINT32_LE( high, msglen, 4 );
301
302 last = ctx->total[0] & 0x3F;
303 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
304
305 mbedtls_md5_update( ctx, md5_padding, padn );
306 mbedtls_md5_update( ctx, msglen, 8 );
307
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 );
312 }
313
314 #endif /* !MBEDTLS_MD5_ALT */
315
316 /*
317 * output = MD5( input buffer )
318 */
mbedtls_md5(const unsigned char * input,size_t ilen,unsigned char output[16])319 void mbedtls_md5( const unsigned char *input, size_t ilen, unsigned char output[16] )
320 {
321 mbedtls_md5_context ctx;
322
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 );
328 }
329
330 #if defined(MBEDTLS_SELF_TEST)
331 /*
332 * RFC 1321 test vectors
333 */
334 static const unsigned char md5_test_buf[7][81] =
335 {
336 { "" },
337 { "a" },
338 { "abc" },
339 { "message digest" },
340 { "abcdefghijklmnopqrstuvwxyz" },
341 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
342 { "12345678901234567890123456789012345678901234567890123456789012" \
343 "345678901234567890" }
344 };
345
346 static const int md5_test_buflen[7] =
347 {
348 0, 1, 3, 14, 26, 62, 80
349 };
350
351 static const unsigned char md5_test_sum[7][16] =
352 {
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 }
367 };
368
369 /*
370 * Checkup routine
371 */
mbedtls_md5_self_test(int verbose)372 int mbedtls_md5_self_test( int verbose )
373 {
374 int i;
375 unsigned char md5sum[16];
376
377 for( i = 0; i < 7; i++ )
378 {
379 if( verbose != 0 )
380 mbedtls_printf( " MD5 test #%d: ", i + 1 );
381
382 mbedtls_md5( md5_test_buf[i], md5_test_buflen[i], md5sum );
383
384 if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 )
385 {
386 if( verbose != 0 )
387 mbedtls_printf( "failed\n" );
388
389 return( 1 );
390 }
391
392 if( verbose != 0 )
393 mbedtls_printf( "passed\n" );
394 }
395
396 if( verbose != 0 )
397 mbedtls_printf( "\n" );
398
399 return( 0 );
400 }
401
402 #endif /* MBEDTLS_SELF_TEST */
403
404 #endif /* MBEDTLS_MD5_C */
405