]> git.sur5r.net Git - freertos/blob - FreeRTOS-Labs/Source/mbedtls/library/md4.c
Add the Labs projects provided in the V10.2.1_191129 zip file.
[freertos] / FreeRTOS-Labs / Source / mbedtls / library / md4.c
1 /*\r
2  *  RFC 1186/1320 compliant MD4 implementation\r
3  *\r
4  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved\r
5  *  SPDX-License-Identifier: Apache-2.0\r
6  *\r
7  *  Licensed under the Apache License, Version 2.0 (the "License"); you may\r
8  *  not use this file except in compliance with the License.\r
9  *  You may obtain a copy of the License at\r
10  *\r
11  *  http://www.apache.org/licenses/LICENSE-2.0\r
12  *\r
13  *  Unless required by applicable law or agreed to in writing, software\r
14  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\r
15  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
16  *  See the License for the specific language governing permissions and\r
17  *  limitations under the License.\r
18  *\r
19  *  This file is part of mbed TLS (https://tls.mbed.org)\r
20  */\r
21 /*\r
22  *  The MD4 algorithm was designed by Ron Rivest in 1990.\r
23  *\r
24  *  http://www.ietf.org/rfc/rfc1186.txt\r
25  *  http://www.ietf.org/rfc/rfc1320.txt\r
26  */\r
27 \r
28 #if !defined(MBEDTLS_CONFIG_FILE)\r
29 #include "mbedtls/config.h"\r
30 #else\r
31 #include MBEDTLS_CONFIG_FILE\r
32 #endif\r
33 \r
34 #if defined(MBEDTLS_MD4_C)\r
35 \r
36 #include "mbedtls/md4.h"\r
37 #include "mbedtls/platform_util.h"\r
38 \r
39 #include <string.h>\r
40 \r
41 #if defined(MBEDTLS_SELF_TEST)\r
42 #if defined(MBEDTLS_PLATFORM_C)\r
43 #include "mbedtls/platform.h"\r
44 #else\r
45 #include <stdio.h>\r
46 #define mbedtls_printf printf\r
47 #endif /* MBEDTLS_PLATFORM_C */\r
48 #endif /* MBEDTLS_SELF_TEST */\r
49 \r
50 #if !defined(MBEDTLS_MD4_ALT)\r
51 \r
52 /*\r
53  * 32-bit integer manipulation macros (little endian)\r
54  */\r
55 #ifndef GET_UINT32_LE\r
56 #define GET_UINT32_LE(n,b,i)                            \\r
57 {                                                       \\r
58     (n) = ( (uint32_t) (b)[(i)    ]       )             \\r
59         | ( (uint32_t) (b)[(i) + 1] <<  8 )             \\r
60         | ( (uint32_t) (b)[(i) + 2] << 16 )             \\r
61         | ( (uint32_t) (b)[(i) + 3] << 24 );            \\r
62 }\r
63 #endif\r
64 \r
65 #ifndef PUT_UINT32_LE\r
66 #define PUT_UINT32_LE(n,b,i)                                    \\r
67 {                                                               \\r
68     (b)[(i)    ] = (unsigned char) ( ( (n)       ) & 0xFF );    \\r
69     (b)[(i) + 1] = (unsigned char) ( ( (n) >>  8 ) & 0xFF );    \\r
70     (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF );    \\r
71     (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF );    \\r
72 }\r
73 #endif\r
74 \r
75 void mbedtls_md4_init( mbedtls_md4_context *ctx )\r
76 {\r
77     memset( ctx, 0, sizeof( mbedtls_md4_context ) );\r
78 }\r
79 \r
80 void mbedtls_md4_free( mbedtls_md4_context *ctx )\r
81 {\r
82     if( ctx == NULL )\r
83         return;\r
84 \r
85     mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md4_context ) );\r
86 }\r
87 \r
88 void mbedtls_md4_clone( mbedtls_md4_context *dst,\r
89                         const mbedtls_md4_context *src )\r
90 {\r
91     *dst = *src;\r
92 }\r
93 \r
94 /*\r
95  * MD4 context setup\r
96  */\r
97 int mbedtls_md4_starts_ret( mbedtls_md4_context *ctx )\r
98 {\r
99     ctx->total[0] = 0;\r
100     ctx->total[1] = 0;\r
101 \r
102     ctx->state[0] = 0x67452301;\r
103     ctx->state[1] = 0xEFCDAB89;\r
104     ctx->state[2] = 0x98BADCFE;\r
105     ctx->state[3] = 0x10325476;\r
106 \r
107     return( 0 );\r
108 }\r
109 \r
110 #if !defined(MBEDTLS_DEPRECATED_REMOVED)\r
111 void mbedtls_md4_starts( mbedtls_md4_context *ctx )\r
112 {\r
113     mbedtls_md4_starts_ret( ctx );\r
114 }\r
115 #endif\r
116 \r
117 #if !defined(MBEDTLS_MD4_PROCESS_ALT)\r
118 int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,\r
119                                   const unsigned char data[64] )\r
120 {\r
121     uint32_t X[16], A, B, C, D;\r
122 \r
123     GET_UINT32_LE( X[ 0], data,  0 );\r
124     GET_UINT32_LE( X[ 1], data,  4 );\r
125     GET_UINT32_LE( X[ 2], data,  8 );\r
126     GET_UINT32_LE( X[ 3], data, 12 );\r
127     GET_UINT32_LE( X[ 4], data, 16 );\r
128     GET_UINT32_LE( X[ 5], data, 20 );\r
129     GET_UINT32_LE( X[ 6], data, 24 );\r
130     GET_UINT32_LE( X[ 7], data, 28 );\r
131     GET_UINT32_LE( X[ 8], data, 32 );\r
132     GET_UINT32_LE( X[ 9], data, 36 );\r
133     GET_UINT32_LE( X[10], data, 40 );\r
134     GET_UINT32_LE( X[11], data, 44 );\r
135     GET_UINT32_LE( X[12], data, 48 );\r
136     GET_UINT32_LE( X[13], data, 52 );\r
137     GET_UINT32_LE( X[14], data, 56 );\r
138     GET_UINT32_LE( X[15], data, 60 );\r
139 \r
140 #define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n))))\r
141 \r
142     A = ctx->state[0];\r
143     B = ctx->state[1];\r
144     C = ctx->state[2];\r
145     D = ctx->state[3];\r
146 \r
147 #define F(x, y, z) (((x) & (y)) | ((~(x)) & (z)))\r
148 #define P(a,b,c,d,x,s)                           \\r
149     do                                           \\r
150     {                                            \\r
151         (a) += F((b),(c),(d)) + (x);             \\r
152         (a) = S((a),(s));                        \\r
153     } while( 0 )\r
154 \r
155 \r
156     P( A, B, C, D, X[ 0],  3 );\r
157     P( D, A, B, C, X[ 1],  7 );\r
158     P( C, D, A, B, X[ 2], 11 );\r
159     P( B, C, D, A, X[ 3], 19 );\r
160     P( A, B, C, D, X[ 4],  3 );\r
161     P( D, A, B, C, X[ 5],  7 );\r
162     P( C, D, A, B, X[ 6], 11 );\r
163     P( B, C, D, A, X[ 7], 19 );\r
164     P( A, B, C, D, X[ 8],  3 );\r
165     P( D, A, B, C, X[ 9],  7 );\r
166     P( C, D, A, B, X[10], 11 );\r
167     P( B, C, D, A, X[11], 19 );\r
168     P( A, B, C, D, X[12],  3 );\r
169     P( D, A, B, C, X[13],  7 );\r
170     P( C, D, A, B, X[14], 11 );\r
171     P( B, C, D, A, X[15], 19 );\r
172 \r
173 #undef P\r
174 #undef F\r
175 \r
176 #define F(x,y,z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))\r
177 #define P(a,b,c,d,x,s)                          \\r
178     do                                          \\r
179     {                                           \\r
180         (a) += F((b),(c),(d)) + (x) + 0x5A827999;       \\r
181         (a) = S((a),(s));                               \\r
182     } while( 0 )\r
183 \r
184     P( A, B, C, D, X[ 0],  3 );\r
185     P( D, A, B, C, X[ 4],  5 );\r
186     P( C, D, A, B, X[ 8],  9 );\r
187     P( B, C, D, A, X[12], 13 );\r
188     P( A, B, C, D, X[ 1],  3 );\r
189     P( D, A, B, C, X[ 5],  5 );\r
190     P( C, D, A, B, X[ 9],  9 );\r
191     P( B, C, D, A, X[13], 13 );\r
192     P( A, B, C, D, X[ 2],  3 );\r
193     P( D, A, B, C, X[ 6],  5 );\r
194     P( C, D, A, B, X[10],  9 );\r
195     P( B, C, D, A, X[14], 13 );\r
196     P( A, B, C, D, X[ 3],  3 );\r
197     P( D, A, B, C, X[ 7],  5 );\r
198     P( C, D, A, B, X[11],  9 );\r
199     P( B, C, D, A, X[15], 13 );\r
200 \r
201 #undef P\r
202 #undef F\r
203 \r
204 #define F(x,y,z) ((x) ^ (y) ^ (z))\r
205 #define P(a,b,c,d,x,s)                                  \\r
206     do                                                  \\r
207     {                                                   \\r
208         (a) += F((b),(c),(d)) + (x) + 0x6ED9EBA1;       \\r
209         (a) = S((a),(s));                               \\r
210     } while( 0 )\r
211 \r
212     P( A, B, C, D, X[ 0],  3 );\r
213     P( D, A, B, C, X[ 8],  9 );\r
214     P( C, D, A, B, X[ 4], 11 );\r
215     P( B, C, D, A, X[12], 15 );\r
216     P( A, B, C, D, X[ 2],  3 );\r
217     P( D, A, B, C, X[10],  9 );\r
218     P( C, D, A, B, X[ 6], 11 );\r
219     P( B, C, D, A, X[14], 15 );\r
220     P( A, B, C, D, X[ 1],  3 );\r
221     P( D, A, B, C, X[ 9],  9 );\r
222     P( C, D, A, B, X[ 5], 11 );\r
223     P( B, C, D, A, X[13], 15 );\r
224     P( A, B, C, D, X[ 3],  3 );\r
225     P( D, A, B, C, X[11],  9 );\r
226     P( C, D, A, B, X[ 7], 11 );\r
227     P( B, C, D, A, X[15], 15 );\r
228 \r
229 #undef F\r
230 #undef P\r
231 \r
232     ctx->state[0] += A;\r
233     ctx->state[1] += B;\r
234     ctx->state[2] += C;\r
235     ctx->state[3] += D;\r
236 \r
237     return( 0 );\r
238 }\r
239 \r
240 #if !defined(MBEDTLS_DEPRECATED_REMOVED)\r
241 void mbedtls_md4_process( mbedtls_md4_context *ctx,\r
242                           const unsigned char data[64] )\r
243 {\r
244     mbedtls_internal_md4_process( ctx, data );\r
245 }\r
246 #endif\r
247 #endif /* !MBEDTLS_MD4_PROCESS_ALT */\r
248 \r
249 /*\r
250  * MD4 process buffer\r
251  */\r
252 int mbedtls_md4_update_ret( mbedtls_md4_context *ctx,\r
253                             const unsigned char *input,\r
254                             size_t ilen )\r
255 {\r
256     int ret;\r
257     size_t fill;\r
258     uint32_t left;\r
259 \r
260     if( ilen == 0 )\r
261         return( 0 );\r
262 \r
263     left = ctx->total[0] & 0x3F;\r
264     fill = 64 - left;\r
265 \r
266     ctx->total[0] += (uint32_t) ilen;\r
267     ctx->total[0] &= 0xFFFFFFFF;\r
268 \r
269     if( ctx->total[0] < (uint32_t) ilen )\r
270         ctx->total[1]++;\r
271 \r
272     if( left && ilen >= fill )\r
273     {\r
274         memcpy( (void *) (ctx->buffer + left),\r
275                 (void *) input, fill );\r
276 \r
277         if( ( ret = mbedtls_internal_md4_process( ctx, ctx->buffer ) ) != 0 )\r
278             return( ret );\r
279 \r
280         input += fill;\r
281         ilen  -= fill;\r
282         left = 0;\r
283     }\r
284 \r
285     while( ilen >= 64 )\r
286     {\r
287         if( ( ret = mbedtls_internal_md4_process( ctx, input ) ) != 0 )\r
288             return( ret );\r
289 \r
290         input += 64;\r
291         ilen  -= 64;\r
292     }\r
293 \r
294     if( ilen > 0 )\r
295     {\r
296         memcpy( (void *) (ctx->buffer + left),\r
297                 (void *) input, ilen );\r
298     }\r
299 \r
300     return( 0 );\r
301 }\r
302 \r
303 #if !defined(MBEDTLS_DEPRECATED_REMOVED)\r
304 void mbedtls_md4_update( mbedtls_md4_context *ctx,\r
305                          const unsigned char *input,\r
306                          size_t ilen )\r
307 {\r
308     mbedtls_md4_update_ret( ctx, input, ilen );\r
309 }\r
310 #endif\r
311 \r
312 static const unsigned char md4_padding[64] =\r
313 {\r
314  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
315     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
316     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
317     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
318 };\r
319 \r
320 /*\r
321  * MD4 final digest\r
322  */\r
323 int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx,\r
324                             unsigned char output[16] )\r
325 {\r
326     int ret;\r
327     uint32_t last, padn;\r
328     uint32_t high, low;\r
329     unsigned char msglen[8];\r
330 \r
331     high = ( ctx->total[0] >> 29 )\r
332          | ( ctx->total[1] <<  3 );\r
333     low  = ( ctx->total[0] <<  3 );\r
334 \r
335     PUT_UINT32_LE( low,  msglen, 0 );\r
336     PUT_UINT32_LE( high, msglen, 4 );\r
337 \r
338     last = ctx->total[0] & 0x3F;\r
339     padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );\r
340 \r
341     ret = mbedtls_md4_update_ret( ctx, (unsigned char *)md4_padding, padn );\r
342     if( ret != 0 )\r
343         return( ret );\r
344 \r
345     if( ( ret = mbedtls_md4_update_ret( ctx, msglen, 8 ) ) != 0 )\r
346         return( ret );\r
347 \r
348 \r
349     PUT_UINT32_LE( ctx->state[0], output,  0 );\r
350     PUT_UINT32_LE( ctx->state[1], output,  4 );\r
351     PUT_UINT32_LE( ctx->state[2], output,  8 );\r
352     PUT_UINT32_LE( ctx->state[3], output, 12 );\r
353 \r
354     return( 0 );\r
355 }\r
356 \r
357 #if !defined(MBEDTLS_DEPRECATED_REMOVED)\r
358 void mbedtls_md4_finish( mbedtls_md4_context *ctx,\r
359                          unsigned char output[16] )\r
360 {\r
361     mbedtls_md4_finish_ret( ctx, output );\r
362 }\r
363 #endif\r
364 \r
365 #endif /* !MBEDTLS_MD4_ALT */\r
366 \r
367 /*\r
368  * output = MD4( input buffer )\r
369  */\r
370 int mbedtls_md4_ret( const unsigned char *input,\r
371                      size_t ilen,\r
372                      unsigned char output[16] )\r
373 {\r
374     int ret;\r
375     mbedtls_md4_context ctx;\r
376 \r
377     mbedtls_md4_init( &ctx );\r
378 \r
379     if( ( ret = mbedtls_md4_starts_ret( &ctx ) ) != 0 )\r
380         goto exit;\r
381 \r
382     if( ( ret = mbedtls_md4_update_ret( &ctx, input, ilen ) ) != 0 )\r
383         goto exit;\r
384 \r
385     if( ( ret = mbedtls_md4_finish_ret( &ctx, output ) ) != 0 )\r
386         goto exit;\r
387 \r
388 exit:\r
389     mbedtls_md4_free( &ctx );\r
390 \r
391     return( ret );\r
392 }\r
393 \r
394 #if !defined(MBEDTLS_DEPRECATED_REMOVED)\r
395 void mbedtls_md4( const unsigned char *input,\r
396                   size_t ilen,\r
397                   unsigned char output[16] )\r
398 {\r
399     mbedtls_md4_ret( input, ilen, output );\r
400 }\r
401 #endif\r
402 \r
403 #if defined(MBEDTLS_SELF_TEST)\r
404 \r
405 /*\r
406  * RFC 1320 test vectors\r
407  */\r
408 static const unsigned char md4_test_str[7][81] =\r
409 {\r
410     { "" },\r
411     { "a" },\r
412     { "abc" },\r
413     { "message digest" },\r
414     { "abcdefghijklmnopqrstuvwxyz" },\r
415     { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },\r
416     { "12345678901234567890123456789012345678901234567890123456789012"\r
417       "345678901234567890" }\r
418 };\r
419 \r
420 static const size_t md4_test_strlen[7] =\r
421 {\r
422     0, 1, 3, 14, 26, 62, 80\r
423 };\r
424 \r
425 static const unsigned char md4_test_sum[7][16] =\r
426 {\r
427     { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,\r
428       0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },\r
429     { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,\r
430       0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },\r
431     { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,\r
432       0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },\r
433     { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,\r
434       0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },\r
435     { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,\r
436       0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },\r
437     { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,\r
438       0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },\r
439     { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,\r
440       0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }\r
441 };\r
442 \r
443 /*\r
444  * Checkup routine\r
445  */\r
446 int mbedtls_md4_self_test( int verbose )\r
447 {\r
448     int i, ret = 0;\r
449     unsigned char md4sum[16];\r
450 \r
451     for( i = 0; i < 7; i++ )\r
452     {\r
453         if( verbose != 0 )\r
454             mbedtls_printf( "  MD4 test #%d: ", i + 1 );\r
455 \r
456         ret = mbedtls_md4_ret( md4_test_str[i], md4_test_strlen[i], md4sum );\r
457         if( ret != 0 )\r
458             goto fail;\r
459 \r
460         if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )\r
461         {\r
462             ret = 1;\r
463             goto fail;\r
464         }\r
465 \r
466         if( verbose != 0 )\r
467             mbedtls_printf( "passed\n" );\r
468     }\r
469 \r
470     if( verbose != 0 )\r
471         mbedtls_printf( "\n" );\r
472 \r
473     return( 0 );\r
474 \r
475 fail:\r
476     if( verbose != 0 )\r
477         mbedtls_printf( "failed\n" );\r
478 \r
479     return( ret );\r
480 }\r
481 \r
482 #endif /* MBEDTLS_SELF_TEST */\r
483 \r
484 #endif /* MBEDTLS_MD4_C */\r