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