]> git.sur5r.net Git - freertos/blob - FreeRTOS-Labs/Source/mbedtls/library/md.c
Add the Labs projects provided in the V10.2.1_191129 zip file.
[freertos] / FreeRTOS-Labs / Source / mbedtls / library / md.c
1 /**\r
2  * \file mbedtls_md.c\r
3  *\r
4  * \brief Generic message digest wrapper for mbed TLS\r
5  *\r
6  * \author Adriaan de Jong <dejong@fox-it.com>\r
7  *\r
8  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved\r
9  *  SPDX-License-Identifier: Apache-2.0\r
10  *\r
11  *  Licensed under the Apache License, Version 2.0 (the "License"); you may\r
12  *  not use this file except in compliance with the License.\r
13  *  You may obtain a copy of the License at\r
14  *\r
15  *  http://www.apache.org/licenses/LICENSE-2.0\r
16  *\r
17  *  Unless required by applicable law or agreed to in writing, software\r
18  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\r
19  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
20  *  See the License for the specific language governing permissions and\r
21  *  limitations under the License.\r
22  *\r
23  *  This file is part of mbed TLS (https://tls.mbed.org)\r
24  */\r
25 \r
26 #if !defined(MBEDTLS_CONFIG_FILE)\r
27 #include "mbedtls/config.h"\r
28 #else\r
29 #include MBEDTLS_CONFIG_FILE\r
30 #endif\r
31 \r
32 #if defined(MBEDTLS_MD_C)\r
33 \r
34 #include "mbedtls/md.h"\r
35 #include "mbedtls/md_internal.h"\r
36 #include "mbedtls/platform_util.h"\r
37 \r
38 #if defined(MBEDTLS_PLATFORM_C)\r
39 #include "mbedtls/platform.h"\r
40 #else\r
41 #include <stdlib.h>\r
42 #define mbedtls_calloc    calloc\r
43 #define mbedtls_free       free\r
44 #endif\r
45 \r
46 #include <string.h>\r
47 \r
48 #if defined(MBEDTLS_FS_IO)\r
49 #include <stdio.h>\r
50 #endif\r
51 \r
52 /*\r
53  * Reminder: update profiles in x509_crt.c when adding a new hash!\r
54  */\r
55 static const int supported_digests[] = {\r
56 \r
57 #if defined(MBEDTLS_SHA512_C)\r
58         MBEDTLS_MD_SHA512,\r
59         MBEDTLS_MD_SHA384,\r
60 #endif\r
61 \r
62 #if defined(MBEDTLS_SHA256_C)\r
63         MBEDTLS_MD_SHA256,\r
64         MBEDTLS_MD_SHA224,\r
65 #endif\r
66 \r
67 #if defined(MBEDTLS_SHA1_C)\r
68         MBEDTLS_MD_SHA1,\r
69 #endif\r
70 \r
71 #if defined(MBEDTLS_RIPEMD160_C)\r
72         MBEDTLS_MD_RIPEMD160,\r
73 #endif\r
74 \r
75 #if defined(MBEDTLS_MD5_C)\r
76         MBEDTLS_MD_MD5,\r
77 #endif\r
78 \r
79 #if defined(MBEDTLS_MD4_C)\r
80         MBEDTLS_MD_MD4,\r
81 #endif\r
82 \r
83 #if defined(MBEDTLS_MD2_C)\r
84         MBEDTLS_MD_MD2,\r
85 #endif\r
86 \r
87         MBEDTLS_MD_NONE\r
88 };\r
89 \r
90 const int *mbedtls_md_list( void )\r
91 {\r
92     return( supported_digests );\r
93 }\r
94 \r
95 const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name )\r
96 {\r
97     if( NULL == md_name )\r
98         return( NULL );\r
99 \r
100     /* Get the appropriate digest information */\r
101 #if defined(MBEDTLS_MD2_C)\r
102     if( !strcmp( "MD2", md_name ) )\r
103         return mbedtls_md_info_from_type( MBEDTLS_MD_MD2 );\r
104 #endif\r
105 #if defined(MBEDTLS_MD4_C)\r
106     if( !strcmp( "MD4", md_name ) )\r
107         return mbedtls_md_info_from_type( MBEDTLS_MD_MD4 );\r
108 #endif\r
109 #if defined(MBEDTLS_MD5_C)\r
110     if( !strcmp( "MD5", md_name ) )\r
111         return mbedtls_md_info_from_type( MBEDTLS_MD_MD5 );\r
112 #endif\r
113 #if defined(MBEDTLS_RIPEMD160_C)\r
114     if( !strcmp( "RIPEMD160", md_name ) )\r
115         return mbedtls_md_info_from_type( MBEDTLS_MD_RIPEMD160 );\r
116 #endif\r
117 #if defined(MBEDTLS_SHA1_C)\r
118     if( !strcmp( "SHA1", md_name ) || !strcmp( "SHA", md_name ) )\r
119         return mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );\r
120 #endif\r
121 #if defined(MBEDTLS_SHA256_C)\r
122     if( !strcmp( "SHA224", md_name ) )\r
123         return mbedtls_md_info_from_type( MBEDTLS_MD_SHA224 );\r
124     if( !strcmp( "SHA256", md_name ) )\r
125         return mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 );\r
126 #endif\r
127 #if defined(MBEDTLS_SHA512_C)\r
128     if( !strcmp( "SHA384", md_name ) )\r
129         return mbedtls_md_info_from_type( MBEDTLS_MD_SHA384 );\r
130     if( !strcmp( "SHA512", md_name ) )\r
131         return mbedtls_md_info_from_type( MBEDTLS_MD_SHA512 );\r
132 #endif\r
133     return( NULL );\r
134 }\r
135 \r
136 const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type )\r
137 {\r
138     switch( md_type )\r
139     {\r
140 #if defined(MBEDTLS_MD2_C)\r
141         case MBEDTLS_MD_MD2:\r
142             return( &mbedtls_md2_info );\r
143 #endif\r
144 #if defined(MBEDTLS_MD4_C)\r
145         case MBEDTLS_MD_MD4:\r
146             return( &mbedtls_md4_info );\r
147 #endif\r
148 #if defined(MBEDTLS_MD5_C)\r
149         case MBEDTLS_MD_MD5:\r
150             return( &mbedtls_md5_info );\r
151 #endif\r
152 #if defined(MBEDTLS_RIPEMD160_C)\r
153         case MBEDTLS_MD_RIPEMD160:\r
154             return( &mbedtls_ripemd160_info );\r
155 #endif\r
156 #if defined(MBEDTLS_SHA1_C)\r
157         case MBEDTLS_MD_SHA1:\r
158             return( &mbedtls_sha1_info );\r
159 #endif\r
160 #if defined(MBEDTLS_SHA256_C)\r
161         case MBEDTLS_MD_SHA224:\r
162             return( &mbedtls_sha224_info );\r
163         case MBEDTLS_MD_SHA256:\r
164             return( &mbedtls_sha256_info );\r
165 #endif\r
166 #if defined(MBEDTLS_SHA512_C)\r
167         case MBEDTLS_MD_SHA384:\r
168             return( &mbedtls_sha384_info );\r
169         case MBEDTLS_MD_SHA512:\r
170             return( &mbedtls_sha512_info );\r
171 #endif\r
172         default:\r
173             return( NULL );\r
174     }\r
175 }\r
176 \r
177 void mbedtls_md_init( mbedtls_md_context_t *ctx )\r
178 {\r
179     memset( ctx, 0, sizeof( mbedtls_md_context_t ) );\r
180 }\r
181 \r
182 void mbedtls_md_free( mbedtls_md_context_t *ctx )\r
183 {\r
184     if( ctx == NULL || ctx->md_info == NULL )\r
185         return;\r
186 \r
187     if( ctx->md_ctx != NULL )\r
188         ctx->md_info->ctx_free_func( ctx->md_ctx );\r
189 \r
190     if( ctx->hmac_ctx != NULL )\r
191     {\r
192         mbedtls_platform_zeroize( ctx->hmac_ctx,\r
193                                   2 * ctx->md_info->block_size );\r
194         mbedtls_free( ctx->hmac_ctx );\r
195     }\r
196 \r
197     mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md_context_t ) );\r
198 }\r
199 \r
200 int mbedtls_md_clone( mbedtls_md_context_t *dst,\r
201                       const mbedtls_md_context_t *src )\r
202 {\r
203     if( dst == NULL || dst->md_info == NULL ||\r
204         src == NULL || src->md_info == NULL ||\r
205         dst->md_info != src->md_info )\r
206     {\r
207         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );\r
208     }\r
209 \r
210     dst->md_info->clone_func( dst->md_ctx, src->md_ctx );\r
211 \r
212     return( 0 );\r
213 }\r
214 \r
215 #if ! defined(MBEDTLS_DEPRECATED_REMOVED)\r
216 int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info )\r
217 {\r
218     return mbedtls_md_setup( ctx, md_info, 1 );\r
219 }\r
220 #endif\r
221 \r
222 int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac )\r
223 {\r
224     if( md_info == NULL || ctx == NULL )\r
225         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );\r
226 \r
227     if( ( ctx->md_ctx = md_info->ctx_alloc_func() ) == NULL )\r
228         return( MBEDTLS_ERR_MD_ALLOC_FAILED );\r
229 \r
230     if( hmac != 0 )\r
231     {\r
232         ctx->hmac_ctx = mbedtls_calloc( 2, md_info->block_size );\r
233         if( ctx->hmac_ctx == NULL )\r
234         {\r
235             md_info->ctx_free_func( ctx->md_ctx );\r
236             return( MBEDTLS_ERR_MD_ALLOC_FAILED );\r
237         }\r
238     }\r
239 \r
240     ctx->md_info = md_info;\r
241 \r
242     return( 0 );\r
243 }\r
244 \r
245 int mbedtls_md_starts( mbedtls_md_context_t *ctx )\r
246 {\r
247     if( ctx == NULL || ctx->md_info == NULL )\r
248         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );\r
249 \r
250     return( ctx->md_info->starts_func( ctx->md_ctx ) );\r
251 }\r
252 \r
253 int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )\r
254 {\r
255     if( ctx == NULL || ctx->md_info == NULL )\r
256         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );\r
257 \r
258     return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) );\r
259 }\r
260 \r
261 int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output )\r
262 {\r
263     if( ctx == NULL || ctx->md_info == NULL )\r
264         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );\r
265 \r
266     return( ctx->md_info->finish_func( ctx->md_ctx, output ) );\r
267 }\r
268 \r
269 int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,\r
270             unsigned char *output )\r
271 {\r
272     if( md_info == NULL )\r
273         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );\r
274 \r
275     return( md_info->digest_func( input, ilen, output ) );\r
276 }\r
277 \r
278 #if defined(MBEDTLS_FS_IO)\r
279 int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigned char *output )\r
280 {\r
281     int ret;\r
282     FILE *f;\r
283     size_t n;\r
284     mbedtls_md_context_t ctx;\r
285     unsigned char buf[1024];\r
286 \r
287     if( md_info == NULL )\r
288         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );\r
289 \r
290     if( ( f = fopen( path, "rb" ) ) == NULL )\r
291         return( MBEDTLS_ERR_MD_FILE_IO_ERROR );\r
292 \r
293     mbedtls_md_init( &ctx );\r
294 \r
295     if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 )\r
296         goto cleanup;\r
297 \r
298     if( ( ret = md_info->starts_func( ctx.md_ctx ) ) != 0 )\r
299         goto cleanup;\r
300 \r
301     while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )\r
302         if( ( ret = md_info->update_func( ctx.md_ctx, buf, n ) ) != 0 )\r
303             goto cleanup;\r
304 \r
305     if( ferror( f ) != 0 )\r
306         ret = MBEDTLS_ERR_MD_FILE_IO_ERROR;\r
307     else\r
308         ret = md_info->finish_func( ctx.md_ctx, output );\r
309 \r
310 cleanup:\r
311     mbedtls_platform_zeroize( buf, sizeof( buf ) );\r
312     fclose( f );\r
313     mbedtls_md_free( &ctx );\r
314 \r
315     return( ret );\r
316 }\r
317 #endif /* MBEDTLS_FS_IO */\r
318 \r
319 int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen )\r
320 {\r
321     int ret;\r
322     unsigned char sum[MBEDTLS_MD_MAX_SIZE];\r
323     unsigned char *ipad, *opad;\r
324     size_t i;\r
325 \r
326     if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )\r
327         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );\r
328 \r
329     if( keylen > (size_t) ctx->md_info->block_size )\r
330     {\r
331         if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )\r
332             goto cleanup;\r
333         if( ( ret = ctx->md_info->update_func( ctx->md_ctx, key, keylen ) ) != 0 )\r
334             goto cleanup;\r
335         if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, sum ) ) != 0 )\r
336             goto cleanup;\r
337 \r
338         keylen = ctx->md_info->size;\r
339         key = sum;\r
340     }\r
341 \r
342     ipad = (unsigned char *) ctx->hmac_ctx;\r
343     opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;\r
344 \r
345     memset( ipad, 0x36, ctx->md_info->block_size );\r
346     memset( opad, 0x5C, ctx->md_info->block_size );\r
347 \r
348     for( i = 0; i < keylen; i++ )\r
349     {\r
350         ipad[i] = (unsigned char)( ipad[i] ^ key[i] );\r
351         opad[i] = (unsigned char)( opad[i] ^ key[i] );\r
352     }\r
353 \r
354     if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )\r
355         goto cleanup;\r
356     if( ( ret = ctx->md_info->update_func( ctx->md_ctx, ipad,\r
357                                            ctx->md_info->block_size ) ) != 0 )\r
358         goto cleanup;\r
359 \r
360 cleanup:\r
361     mbedtls_platform_zeroize( sum, sizeof( sum ) );\r
362 \r
363     return( ret );\r
364 }\r
365 \r
366 int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )\r
367 {\r
368     if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )\r
369         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );\r
370 \r
371     return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) );\r
372 }\r
373 \r
374 int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output )\r
375 {\r
376     int ret;\r
377     unsigned char tmp[MBEDTLS_MD_MAX_SIZE];\r
378     unsigned char *opad;\r
379 \r
380     if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )\r
381         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );\r
382 \r
383     opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;\r
384 \r
385     if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, tmp ) ) != 0 )\r
386         return( ret );\r
387     if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )\r
388         return( ret );\r
389     if( ( ret = ctx->md_info->update_func( ctx->md_ctx, opad,\r
390                                            ctx->md_info->block_size ) ) != 0 )\r
391         return( ret );\r
392     if( ( ret = ctx->md_info->update_func( ctx->md_ctx, tmp,\r
393                                            ctx->md_info->size ) ) != 0 )\r
394         return( ret );\r
395     return( ctx->md_info->finish_func( ctx->md_ctx, output ) );\r
396 }\r
397 \r
398 int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx )\r
399 {\r
400     int ret;\r
401     unsigned char *ipad;\r
402 \r
403     if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )\r
404         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );\r
405 \r
406     ipad = (unsigned char *) ctx->hmac_ctx;\r
407 \r
408     if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )\r
409         return( ret );\r
410     return( ctx->md_info->update_func( ctx->md_ctx, ipad,\r
411                                        ctx->md_info->block_size ) );\r
412 }\r
413 \r
414 int mbedtls_md_hmac( const mbedtls_md_info_t *md_info,\r
415                      const unsigned char *key, size_t keylen,\r
416                      const unsigned char *input, size_t ilen,\r
417                      unsigned char *output )\r
418 {\r
419     mbedtls_md_context_t ctx;\r
420     int ret;\r
421 \r
422     if( md_info == NULL )\r
423         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );\r
424 \r
425     mbedtls_md_init( &ctx );\r
426 \r
427     if( ( ret = mbedtls_md_setup( &ctx, md_info, 1 ) ) != 0 )\r
428         goto cleanup;\r
429 \r
430     if( ( ret = mbedtls_md_hmac_starts( &ctx, key, keylen ) ) != 0 )\r
431         goto cleanup;\r
432     if( ( ret = mbedtls_md_hmac_update( &ctx, input, ilen ) ) != 0 )\r
433         goto cleanup;\r
434     if( ( ret = mbedtls_md_hmac_finish( &ctx, output ) ) != 0 )\r
435         goto cleanup;\r
436 \r
437 cleanup:\r
438     mbedtls_md_free( &ctx );\r
439 \r
440     return( ret );\r
441 }\r
442 \r
443 int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data )\r
444 {\r
445     if( ctx == NULL || ctx->md_info == NULL )\r
446         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );\r
447 \r
448     return( ctx->md_info->process_func( ctx->md_ctx, data ) );\r
449 }\r
450 \r
451 unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info )\r
452 {\r
453     if( md_info == NULL )\r
454         return( 0 );\r
455 \r
456     return md_info->size;\r
457 }\r
458 \r
459 mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info )\r
460 {\r
461     if( md_info == NULL )\r
462         return( MBEDTLS_MD_NONE );\r
463 \r
464     return md_info->type;\r
465 }\r
466 \r
467 const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info )\r
468 {\r
469     if( md_info == NULL )\r
470         return( NULL );\r
471 \r
472     return md_info->name;\r
473 }\r
474 \r
475 #endif /* MBEDTLS_MD_C */\r