• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * \file md.c
3  *
4  * \brief Generic message digest wrapper for mbed TLS
5  *
6  * \author Adriaan de Jong <dejong@fox-it.com>
7  *
8  *  Copyright The Mbed TLS Contributors
9  *  SPDX-License-Identifier: Apache-2.0
10  *
11  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
12  *  not use this file except in compliance with the License.
13  *  You may obtain a copy of the License at
14  *
15  *  http://www.apache.org/licenses/LICENSE-2.0
16  *
17  *  Unless required by applicable law or agreed to in writing, software
18  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
19  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  *  See the License for the specific language governing permissions and
21  *  limitations under the License.
22  */
23 
24 #include "common.h"
25 
26 #if defined(MBEDTLS_MD_C)
27 
28 #include "mbedtls/md.h"
29 #include "md_wrap.h"
30 #include "mbedtls/platform_util.h"
31 #include "mbedtls/error.h"
32 
33 #include "mbedtls/md5.h"
34 #include "mbedtls/ripemd160.h"
35 #include "mbedtls/sha1.h"
36 #include "mbedtls/sha256.h"
37 #include "mbedtls/sha512.h"
38 
39 #if defined(MBEDTLS_PLATFORM_C)
40 #include "mbedtls/platform.h"
41 #else
42 #include <stdlib.h>
43 #define mbedtls_calloc    calloc
44 #define mbedtls_free       free
45 #endif
46 
47 #include <string.h>
48 
49 #if defined(MBEDTLS_FS_IO)
50 #include <stdio.h>
51 #endif
52 
53 #if defined(MBEDTLS_MD5_C)
54 const mbedtls_md_info_t mbedtls_md5_info = {
55     "MD5",
56     MBEDTLS_MD_MD5,
57     16,
58     64,
59 };
60 #endif
61 
62 #if defined(MBEDTLS_RIPEMD160_C)
63 const mbedtls_md_info_t mbedtls_ripemd160_info = {
64     "RIPEMD160",
65     MBEDTLS_MD_RIPEMD160,
66     20,
67     64,
68 };
69 #endif
70 
71 #if defined(MBEDTLS_SHA1_C)
72 const mbedtls_md_info_t mbedtls_sha1_info = {
73     "SHA1",
74     MBEDTLS_MD_SHA1,
75     20,
76     64,
77 };
78 #endif
79 
80 #if defined(MBEDTLS_SHA224_C)
81 const mbedtls_md_info_t mbedtls_sha224_info = {
82     "SHA224",
83     MBEDTLS_MD_SHA224,
84     28,
85     64,
86 };
87 #endif
88 
89 #if defined(MBEDTLS_SHA256_C)
90 const mbedtls_md_info_t mbedtls_sha256_info = {
91     "SHA256",
92     MBEDTLS_MD_SHA256,
93     32,
94     64,
95 };
96 #endif
97 
98 #if defined(MBEDTLS_SHA384_C)
99 const mbedtls_md_info_t mbedtls_sha384_info = {
100     "SHA384",
101     MBEDTLS_MD_SHA384,
102     48,
103     128,
104 };
105 #endif
106 
107 #if defined(MBEDTLS_SHA512_C)
108 const mbedtls_md_info_t mbedtls_sha512_info = {
109     "SHA512",
110     MBEDTLS_MD_SHA512,
111     64,
112     128,
113 };
114 #endif
115 
116 /*
117  * Reminder: update profiles in x509_crt.c when adding a new hash!
118  */
119 static const int supported_digests[] = {
120 
121 #if defined(MBEDTLS_SHA512_C)
122         MBEDTLS_MD_SHA512,
123 #endif
124 
125 #if defined(MBEDTLS_SHA384_C)
126         MBEDTLS_MD_SHA384,
127 #endif
128 
129 #if defined(MBEDTLS_SHA256_C)
130         MBEDTLS_MD_SHA256,
131 #endif
132 #if defined(MBEDTLS_SHA224_C)
133         MBEDTLS_MD_SHA224,
134 #endif
135 
136 #if defined(MBEDTLS_SHA1_C)
137         MBEDTLS_MD_SHA1,
138 #endif
139 
140 #if defined(MBEDTLS_RIPEMD160_C)
141         MBEDTLS_MD_RIPEMD160,
142 #endif
143 
144 #if defined(MBEDTLS_MD5_C)
145         MBEDTLS_MD_MD5,
146 #endif
147 
148         MBEDTLS_MD_NONE
149 };
150 
mbedtls_md_list(void)151 const int *mbedtls_md_list( void )
152 {
153     return( supported_digests );
154 }
155 
mbedtls_md_info_from_string(const char * md_name)156 const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name )
157 {
158     if( NULL == md_name )
159         return( NULL );
160 
161     /* Get the appropriate digest information */
162 #if defined(MBEDTLS_MD5_C)
163     if( !strcmp( "MD5", md_name ) )
164         return mbedtls_md_info_from_type( MBEDTLS_MD_MD5 );
165 #endif
166 #if defined(MBEDTLS_RIPEMD160_C)
167     if( !strcmp( "RIPEMD160", md_name ) )
168         return mbedtls_md_info_from_type( MBEDTLS_MD_RIPEMD160 );
169 #endif
170 #if defined(MBEDTLS_SHA1_C)
171     if( !strcmp( "SHA1", md_name ) || !strcmp( "SHA", md_name ) )
172         return mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
173 #endif
174 #if defined(MBEDTLS_SHA224_C)
175     if( !strcmp( "SHA224", md_name ) )
176         return mbedtls_md_info_from_type( MBEDTLS_MD_SHA224 );
177 #endif
178 #if defined(MBEDTLS_SHA256_C)
179     if( !strcmp( "SHA256", md_name ) )
180         return mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 );
181 #endif
182 #if defined(MBEDTLS_SHA384_C)
183     if( !strcmp( "SHA384", md_name ) )
184         return mbedtls_md_info_from_type( MBEDTLS_MD_SHA384 );
185 #endif
186 #if defined(MBEDTLS_SHA512_C)
187     if( !strcmp( "SHA512", md_name ) )
188         return mbedtls_md_info_from_type( MBEDTLS_MD_SHA512 );
189 #endif
190     return( NULL );
191 }
192 
mbedtls_md_info_from_type(mbedtls_md_type_t md_type)193 const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type )
194 {
195     switch( md_type )
196     {
197 #if defined(MBEDTLS_MD5_C)
198         case MBEDTLS_MD_MD5:
199             return( &mbedtls_md5_info );
200 #endif
201 #if defined(MBEDTLS_RIPEMD160_C)
202         case MBEDTLS_MD_RIPEMD160:
203             return( &mbedtls_ripemd160_info );
204 #endif
205 #if defined(MBEDTLS_SHA1_C)
206         case MBEDTLS_MD_SHA1:
207             return( &mbedtls_sha1_info );
208 #endif
209 #if defined(MBEDTLS_SHA224_C)
210         case MBEDTLS_MD_SHA224:
211             return( &mbedtls_sha224_info );
212 #endif
213 #if defined(MBEDTLS_SHA256_C)
214         case MBEDTLS_MD_SHA256:
215             return( &mbedtls_sha256_info );
216 #endif
217 #if defined(MBEDTLS_SHA384_C)
218         case MBEDTLS_MD_SHA384:
219             return( &mbedtls_sha384_info );
220 #endif
221 #if defined(MBEDTLS_SHA512_C)
222         case MBEDTLS_MD_SHA512:
223             return( &mbedtls_sha512_info );
224 #endif
225         default:
226             return( NULL );
227     }
228 }
229 
mbedtls_md_init(mbedtls_md_context_t * ctx)230 void mbedtls_md_init( mbedtls_md_context_t *ctx )
231 {
232     memset( ctx, 0, sizeof( mbedtls_md_context_t ) );
233 }
234 
mbedtls_md_free(mbedtls_md_context_t * ctx)235 void mbedtls_md_free( mbedtls_md_context_t *ctx )
236 {
237     if( ctx == NULL || ctx->md_info == NULL )
238         return;
239 
240     if( ctx->md_ctx != NULL )
241     {
242         switch( ctx->md_info->type )
243         {
244 #if defined(MBEDTLS_MD5_C)
245             case MBEDTLS_MD_MD5:
246                 mbedtls_md5_free( ctx->md_ctx );
247                 break;
248 #endif
249 #if defined(MBEDTLS_RIPEMD160_C)
250             case MBEDTLS_MD_RIPEMD160:
251                 mbedtls_ripemd160_free( ctx->md_ctx );
252                 break;
253 #endif
254 #if defined(MBEDTLS_SHA1_C)
255             case MBEDTLS_MD_SHA1:
256                 mbedtls_sha1_free( ctx->md_ctx );
257                 break;
258 #endif
259 #if defined(MBEDTLS_SHA224_C)
260             case MBEDTLS_MD_SHA224:
261                 mbedtls_sha256_free( ctx->md_ctx );
262                 break;
263 #endif
264 #if defined(MBEDTLS_SHA256_C)
265             case MBEDTLS_MD_SHA256:
266                 mbedtls_sha256_free( ctx->md_ctx );
267                 break;
268 #endif
269 #if defined(MBEDTLS_SHA384_C)
270             case MBEDTLS_MD_SHA384:
271                 mbedtls_sha512_free( ctx->md_ctx );
272                 break;
273 #endif
274 #if defined(MBEDTLS_SHA512_C)
275             case MBEDTLS_MD_SHA512:
276                 mbedtls_sha512_free( ctx->md_ctx );
277                 break;
278 #endif
279             default:
280                 /* Shouldn't happen */
281                 break;
282         }
283         mbedtls_free( ctx->md_ctx );
284     }
285 
286     if( ctx->hmac_ctx != NULL )
287     {
288         mbedtls_platform_zeroize( ctx->hmac_ctx,
289                                   2 * ctx->md_info->block_size );
290         mbedtls_free( ctx->hmac_ctx );
291     }
292 
293     mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md_context_t ) );
294 }
295 
mbedtls_md_clone(mbedtls_md_context_t * dst,const mbedtls_md_context_t * src)296 int mbedtls_md_clone( mbedtls_md_context_t *dst,
297                       const mbedtls_md_context_t *src )
298 {
299     if( dst == NULL || dst->md_info == NULL ||
300         src == NULL || src->md_info == NULL ||
301         dst->md_info != src->md_info )
302     {
303         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
304     }
305 
306     switch( src->md_info->type )
307     {
308 #if defined(MBEDTLS_MD5_C)
309         case MBEDTLS_MD_MD5:
310             mbedtls_md5_clone( dst->md_ctx, src->md_ctx );
311             break;
312 #endif
313 #if defined(MBEDTLS_RIPEMD160_C)
314         case MBEDTLS_MD_RIPEMD160:
315             mbedtls_ripemd160_clone( dst->md_ctx, src->md_ctx );
316             break;
317 #endif
318 #if defined(MBEDTLS_SHA1_C)
319         case MBEDTLS_MD_SHA1:
320             mbedtls_sha1_clone( dst->md_ctx, src->md_ctx );
321             break;
322 #endif
323 #if defined(MBEDTLS_SHA224_C)
324         case MBEDTLS_MD_SHA224:
325             mbedtls_sha256_clone( dst->md_ctx, src->md_ctx );
326             break;
327 #endif
328 #if defined(MBEDTLS_SHA256_C)
329         case MBEDTLS_MD_SHA256:
330             mbedtls_sha256_clone( dst->md_ctx, src->md_ctx );
331             break;
332 #endif
333 #if defined(MBEDTLS_SHA384_C)
334         case MBEDTLS_MD_SHA384:
335             mbedtls_sha512_clone( dst->md_ctx, src->md_ctx );
336             break;
337 #endif
338 #if defined(MBEDTLS_SHA512_C)
339         case MBEDTLS_MD_SHA512:
340             mbedtls_sha512_clone( dst->md_ctx, src->md_ctx );
341             break;
342 #endif
343         default:
344             return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
345     }
346 
347     return( 0 );
348 }
349 
350 #define ALLOC( type )                                                   \
351     do {                                                                \
352         ctx->md_ctx = mbedtls_calloc( 1, sizeof( mbedtls_##type##_context ) ); \
353         if( ctx->md_ctx == NULL )                                       \
354             return( MBEDTLS_ERR_MD_ALLOC_FAILED );                      \
355         mbedtls_##type##_init( ctx->md_ctx );                           \
356     }                                                                   \
357     while( 0 )
358 
mbedtls_md_setup(mbedtls_md_context_t * ctx,const mbedtls_md_info_t * md_info,int hmac)359 int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac )
360 {
361     if( md_info == NULL || ctx == NULL )
362         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
363 
364     ctx->md_info = md_info;
365     ctx->md_ctx = NULL;
366     ctx->hmac_ctx = NULL;
367 
368     switch( md_info->type )
369     {
370 #if defined(MBEDTLS_MD5_C)
371         case MBEDTLS_MD_MD5:
372             ALLOC( md5 );
373             break;
374 #endif
375 #if defined(MBEDTLS_RIPEMD160_C)
376         case MBEDTLS_MD_RIPEMD160:
377             ALLOC( ripemd160 );
378             break;
379 #endif
380 #if defined(MBEDTLS_SHA1_C)
381         case MBEDTLS_MD_SHA1:
382             ALLOC( sha1 );
383             break;
384 #endif
385 #if defined(MBEDTLS_SHA224_C)
386         case MBEDTLS_MD_SHA224:
387             ALLOC( sha256 );
388             break;
389 #endif
390 #if defined(MBEDTLS_SHA256_C)
391         case MBEDTLS_MD_SHA256:
392             ALLOC( sha256 );
393             break;
394 #endif
395 #if defined(MBEDTLS_SHA384_C)
396         case MBEDTLS_MD_SHA384:
397             ALLOC( sha512 );
398             break;
399 #endif
400 #if defined(MBEDTLS_SHA512_C)
401         case MBEDTLS_MD_SHA512:
402             ALLOC( sha512 );
403             break;
404 #endif
405         default:
406             return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
407     }
408 
409     if( hmac != 0 )
410     {
411         ctx->hmac_ctx = mbedtls_calloc( 2, md_info->block_size );
412         if( ctx->hmac_ctx == NULL )
413         {
414             mbedtls_md_free( ctx );
415             return( MBEDTLS_ERR_MD_ALLOC_FAILED );
416         }
417     }
418 
419     return( 0 );
420 }
421 #undef ALLOC
422 
mbedtls_md_starts(mbedtls_md_context_t * ctx)423 int mbedtls_md_starts( mbedtls_md_context_t *ctx )
424 {
425     if( ctx == NULL || ctx->md_info == NULL )
426         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
427 
428     switch( ctx->md_info->type )
429     {
430 #if defined(MBEDTLS_MD5_C)
431         case MBEDTLS_MD_MD5:
432             return( mbedtls_md5_starts( ctx->md_ctx ) );
433 #endif
434 #if defined(MBEDTLS_RIPEMD160_C)
435         case MBEDTLS_MD_RIPEMD160:
436             return( mbedtls_ripemd160_starts( ctx->md_ctx ) );
437 #endif
438 #if defined(MBEDTLS_SHA1_C)
439         case MBEDTLS_MD_SHA1:
440             return( mbedtls_sha1_starts( ctx->md_ctx ) );
441 #endif
442 #if defined(MBEDTLS_SHA224_C)
443         case MBEDTLS_MD_SHA224:
444             return( mbedtls_sha256_starts( ctx->md_ctx, 1 ) );
445 #endif
446 #if defined(MBEDTLS_SHA256_C)
447         case MBEDTLS_MD_SHA256:
448             return( mbedtls_sha256_starts( ctx->md_ctx, 0 ) );
449 #endif
450 #if defined(MBEDTLS_SHA384_C)
451         case MBEDTLS_MD_SHA384:
452             return( mbedtls_sha512_starts( ctx->md_ctx, 1 ) );
453 #endif
454 #if defined(MBEDTLS_SHA512_C)
455         case MBEDTLS_MD_SHA512:
456             return( mbedtls_sha512_starts( ctx->md_ctx, 0 ) );
457 #endif
458         default:
459             return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
460     }
461 }
462 
mbedtls_md_update(mbedtls_md_context_t * ctx,const unsigned char * input,size_t ilen)463 int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
464 {
465     if( ctx == NULL || ctx->md_info == NULL )
466         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
467 
468     switch( ctx->md_info->type )
469     {
470 #if defined(MBEDTLS_MD5_C)
471         case MBEDTLS_MD_MD5:
472             return( mbedtls_md5_update( ctx->md_ctx, input, ilen ) );
473 #endif
474 #if defined(MBEDTLS_RIPEMD160_C)
475         case MBEDTLS_MD_RIPEMD160:
476             return( mbedtls_ripemd160_update( ctx->md_ctx, input, ilen ) );
477 #endif
478 #if defined(MBEDTLS_SHA1_C)
479         case MBEDTLS_MD_SHA1:
480             return( mbedtls_sha1_update( ctx->md_ctx, input, ilen ) );
481 #endif
482 #if defined(MBEDTLS_SHA224_C)
483         case MBEDTLS_MD_SHA224:
484             return( mbedtls_sha256_update( ctx->md_ctx, input, ilen ) );
485 #endif
486 #if defined(MBEDTLS_SHA256_C)
487         case MBEDTLS_MD_SHA256:
488             return( mbedtls_sha256_update( ctx->md_ctx, input, ilen ) );
489 #endif
490 #if defined(MBEDTLS_SHA384_C)
491         case MBEDTLS_MD_SHA384:
492             return( mbedtls_sha512_update( ctx->md_ctx, input, ilen ) );
493 #endif
494 #if defined(MBEDTLS_SHA512_C)
495         case MBEDTLS_MD_SHA512:
496             return( mbedtls_sha512_update( ctx->md_ctx, input, ilen ) );
497 #endif
498         default:
499             return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
500     }
501 }
502 
mbedtls_md_finish(mbedtls_md_context_t * ctx,unsigned char * output)503 int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output )
504 {
505     if( ctx == NULL || ctx->md_info == NULL )
506         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
507 
508     switch( ctx->md_info->type )
509     {
510 #if defined(MBEDTLS_MD5_C)
511         case MBEDTLS_MD_MD5:
512             return( mbedtls_md5_finish( ctx->md_ctx, output ) );
513 #endif
514 #if defined(MBEDTLS_RIPEMD160_C)
515         case MBEDTLS_MD_RIPEMD160:
516             return( mbedtls_ripemd160_finish( ctx->md_ctx, output ) );
517 #endif
518 #if defined(MBEDTLS_SHA1_C)
519         case MBEDTLS_MD_SHA1:
520             return( mbedtls_sha1_finish( ctx->md_ctx, output ) );
521 #endif
522 #if defined(MBEDTLS_SHA224_C)
523         case MBEDTLS_MD_SHA224:
524             return( mbedtls_sha256_finish( ctx->md_ctx, output ) );
525 #endif
526 #if defined(MBEDTLS_SHA256_C)
527         case MBEDTLS_MD_SHA256:
528             return( mbedtls_sha256_finish( ctx->md_ctx, output ) );
529 #endif
530 #if defined(MBEDTLS_SHA384_C)
531         case MBEDTLS_MD_SHA384:
532             return( mbedtls_sha512_finish( ctx->md_ctx, output ) );
533 #endif
534 #if defined(MBEDTLS_SHA512_C)
535         case MBEDTLS_MD_SHA512:
536             return( mbedtls_sha512_finish( ctx->md_ctx, output ) );
537 #endif
538         default:
539             return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
540     }
541 }
542 
mbedtls_md(const mbedtls_md_info_t * md_info,const unsigned char * input,size_t ilen,unsigned char * output)543 int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
544             unsigned char *output )
545 {
546     if( md_info == NULL )
547         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
548 
549     switch( md_info->type )
550     {
551 #if defined(MBEDTLS_MD5_C)
552         case MBEDTLS_MD_MD5:
553             return( mbedtls_md5( input, ilen, output ) );
554 #endif
555 #if defined(MBEDTLS_RIPEMD160_C)
556         case MBEDTLS_MD_RIPEMD160:
557             return( mbedtls_ripemd160( input, ilen, output ) );
558 #endif
559 #if defined(MBEDTLS_SHA1_C)
560         case MBEDTLS_MD_SHA1:
561             return( mbedtls_sha1( input, ilen, output ) );
562 #endif
563 #if defined(MBEDTLS_SHA224_C)
564         case MBEDTLS_MD_SHA224:
565             return( mbedtls_sha256( input, ilen, output, 1 ) );
566 #endif
567 #if defined(MBEDTLS_SHA256_C)
568         case MBEDTLS_MD_SHA256:
569             return( mbedtls_sha256( input, ilen, output, 0 ) );
570 #endif
571 #if defined(MBEDTLS_SHA384_C)
572         case MBEDTLS_MD_SHA384:
573             return( mbedtls_sha512( input, ilen, output, 1 ) );
574 #endif
575 #if defined(MBEDTLS_SHA512_C)
576         case MBEDTLS_MD_SHA512:
577             return( mbedtls_sha512( input, ilen, output, 0 ) );
578 #endif
579         default:
580             return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
581     }
582 }
583 
584 #if defined(MBEDTLS_FS_IO)
mbedtls_md_file(const mbedtls_md_info_t * md_info,const char * path,unsigned char * output)585 int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigned char *output )
586 {
587     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
588     FILE *f;
589     size_t n;
590     mbedtls_md_context_t ctx;
591     unsigned char buf[1024];
592 
593     if( md_info == NULL )
594         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
595 
596     if( ( f = fopen( path, "rb" ) ) == NULL )
597         return( MBEDTLS_ERR_MD_FILE_IO_ERROR );
598 
599     mbedtls_md_init( &ctx );
600 
601     if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 )
602         goto cleanup;
603 
604     if( ( ret = mbedtls_md_starts( &ctx ) ) != 0 )
605         goto cleanup;
606 
607     while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
608         if( ( ret = mbedtls_md_update( &ctx, buf, n ) ) != 0 )
609             goto cleanup;
610 
611     if( ferror( f ) != 0 )
612         ret = MBEDTLS_ERR_MD_FILE_IO_ERROR;
613     else
614         ret = mbedtls_md_finish( &ctx, output );
615 
616 cleanup:
617     mbedtls_platform_zeroize( buf, sizeof( buf ) );
618     fclose( f );
619     mbedtls_md_free( &ctx );
620 
621     return( ret );
622 }
623 #endif /* MBEDTLS_FS_IO */
624 
mbedtls_md_hmac_starts(mbedtls_md_context_t * ctx,const unsigned char * key,size_t keylen)625 int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen )
626 {
627     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
628     unsigned char sum[MBEDTLS_MD_MAX_SIZE];
629     unsigned char *ipad, *opad;
630     size_t i;
631 
632     if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
633         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
634 
635     if( keylen > (size_t) ctx->md_info->block_size )
636     {
637         if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
638             goto cleanup;
639         if( ( ret = mbedtls_md_update( ctx, key, keylen ) ) != 0 )
640             goto cleanup;
641         if( ( ret = mbedtls_md_finish( ctx, sum ) ) != 0 )
642             goto cleanup;
643 
644         keylen = ctx->md_info->size;
645         key = sum;
646     }
647 
648     ipad = (unsigned char *) ctx->hmac_ctx;
649     opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
650 
651     memset( ipad, 0x36, ctx->md_info->block_size );
652     memset( opad, 0x5C, ctx->md_info->block_size );
653 
654     for( i = 0; i < keylen; i++ )
655     {
656         ipad[i] = (unsigned char)( ipad[i] ^ key[i] );
657         opad[i] = (unsigned char)( opad[i] ^ key[i] );
658     }
659 
660     if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
661         goto cleanup;
662     if( ( ret = mbedtls_md_update( ctx, ipad,
663                                    ctx->md_info->block_size ) ) != 0 )
664         goto cleanup;
665 
666 cleanup:
667     mbedtls_platform_zeroize( sum, sizeof( sum ) );
668 
669     return( ret );
670 }
671 
mbedtls_md_hmac_update(mbedtls_md_context_t * ctx,const unsigned char * input,size_t ilen)672 int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
673 {
674     if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
675         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
676 
677     return( mbedtls_md_update( ctx, input, ilen ) );
678 }
679 
mbedtls_md_hmac_finish(mbedtls_md_context_t * ctx,unsigned char * output)680 int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output )
681 {
682     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
683     unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
684     unsigned char *opad;
685 
686     if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
687         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
688 
689     opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
690 
691     if( ( ret = mbedtls_md_finish( ctx, tmp ) ) != 0 )
692         return( ret );
693     if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
694         return( ret );
695     if( ( ret = mbedtls_md_update( ctx, opad,
696                                    ctx->md_info->block_size ) ) != 0 )
697         return( ret );
698     if( ( ret = mbedtls_md_update( ctx, tmp,
699                                    ctx->md_info->size ) ) != 0 )
700         return( ret );
701     return( mbedtls_md_finish( ctx, output ) );
702 }
703 
mbedtls_md_hmac_reset(mbedtls_md_context_t * ctx)704 int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx )
705 {
706     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
707     unsigned char *ipad;
708 
709     if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
710         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
711 
712     ipad = (unsigned char *) ctx->hmac_ctx;
713 
714     if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
715         return( ret );
716     return( mbedtls_md_update( ctx, ipad, ctx->md_info->block_size ) );
717 }
718 
mbedtls_md_hmac(const mbedtls_md_info_t * md_info,const unsigned char * key,size_t keylen,const unsigned char * input,size_t ilen,unsigned char * output)719 int mbedtls_md_hmac( const mbedtls_md_info_t *md_info,
720                      const unsigned char *key, size_t keylen,
721                      const unsigned char *input, size_t ilen,
722                      unsigned char *output )
723 {
724     mbedtls_md_context_t ctx;
725     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
726 
727     if( md_info == NULL )
728         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
729 
730     mbedtls_md_init( &ctx );
731 
732     if( ( ret = mbedtls_md_setup( &ctx, md_info, 1 ) ) != 0 )
733         goto cleanup;
734 
735     if( ( ret = mbedtls_md_hmac_starts( &ctx, key, keylen ) ) != 0 )
736         goto cleanup;
737     if( ( ret = mbedtls_md_hmac_update( &ctx, input, ilen ) ) != 0 )
738         goto cleanup;
739     if( ( ret = mbedtls_md_hmac_finish( &ctx, output ) ) != 0 )
740         goto cleanup;
741 
742 cleanup:
743     mbedtls_md_free( &ctx );
744 
745     return( ret );
746 }
747 
mbedtls_md_process(mbedtls_md_context_t * ctx,const unsigned char * data)748 int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data )
749 {
750     if( ctx == NULL || ctx->md_info == NULL )
751         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
752 
753     switch( ctx->md_info->type )
754     {
755 #if defined(MBEDTLS_MD5_C)
756         case MBEDTLS_MD_MD5:
757             return( mbedtls_internal_md5_process( ctx->md_ctx, data ) );
758 #endif
759 #if defined(MBEDTLS_RIPEMD160_C)
760         case MBEDTLS_MD_RIPEMD160:
761             return( mbedtls_internal_ripemd160_process( ctx->md_ctx, data ) );
762 #endif
763 #if defined(MBEDTLS_SHA1_C)
764         case MBEDTLS_MD_SHA1:
765             return( mbedtls_internal_sha1_process( ctx->md_ctx, data ) );
766 #endif
767 #if defined(MBEDTLS_SHA224_C)
768         case MBEDTLS_MD_SHA224:
769             return( mbedtls_internal_sha256_process( ctx->md_ctx, data ) );
770 #endif
771 #if defined(MBEDTLS_SHA256_C)
772         case MBEDTLS_MD_SHA256:
773             return( mbedtls_internal_sha256_process( ctx->md_ctx, data ) );
774 #endif
775 #if defined(MBEDTLS_SHA384_C)
776         case MBEDTLS_MD_SHA384:
777             return( mbedtls_internal_sha512_process( ctx->md_ctx, data ) );
778 #endif
779 #if defined(MBEDTLS_SHA512_C)
780         case MBEDTLS_MD_SHA512:
781             return( mbedtls_internal_sha512_process( ctx->md_ctx, data ) );
782 #endif
783         default:
784             return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
785     }
786 }
787 
mbedtls_md_get_size(const mbedtls_md_info_t * md_info)788 unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info )
789 {
790     if( md_info == NULL )
791         return( 0 );
792 
793     return md_info->size;
794 }
795 
mbedtls_md_get_type(const mbedtls_md_info_t * md_info)796 mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info )
797 {
798     if( md_info == NULL )
799         return( MBEDTLS_MD_NONE );
800 
801     return md_info->type;
802 }
803 
mbedtls_md_get_name(const mbedtls_md_info_t * md_info)804 const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info )
805 {
806     if( md_info == NULL )
807         return( NULL );
808 
809     return md_info->name;
810 }
811 
812 #endif /* MBEDTLS_MD_C */
813