blob: 869b177feef16ca29c9a29d06a0f4973bba34680 [file] [log] [blame]
Edison Aic6672fd2018-02-28 15:01:47 +08001// SPDX-License-Identifier: Apache-2.0
Jens Wiklander817466c2018-05-22 13:49:31 +02002/**
3 * \file mbedtls_md.c
4 *
5 * \brief Generic message digest wrapper for mbed TLS
6 *
7 * \author Adriaan de Jong <dejong@fox-it.com>
8 *
9 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Jens Wiklander817466c2018-05-22 13:49:31 +020010 *
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 * This file is part of mbed TLS (https://tls.mbed.org)
24 */
25
26#if !defined(MBEDTLS_CONFIG_FILE)
27#include "mbedtls/config.h"
28#else
29#include MBEDTLS_CONFIG_FILE
30#endif
31
32#if defined(MBEDTLS_MD_C)
33
34#include "mbedtls/md.h"
35#include "mbedtls/md_internal.h"
Jens Wiklander3d3b0592019-03-20 15:30:29 +010036#include "mbedtls/platform_util.h"
Jerome Forissier11fa71b2020-04-20 17:17:56 +020037#include "mbedtls/error.h"
38
39#include "mbedtls/md2.h"
40#include "mbedtls/md4.h"
41#include "mbedtls/md5.h"
42#include "mbedtls/ripemd160.h"
43#include "mbedtls/sha1.h"
44#include "mbedtls/sha256.h"
45#include "mbedtls/sha512.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020046
47#if defined(MBEDTLS_PLATFORM_C)
48#include "mbedtls/platform.h"
49#else
50#include <stdlib.h>
51#define mbedtls_calloc calloc
52#define mbedtls_free free
53#endif
54
55#include <string.h>
56
57#if defined(MBEDTLS_FS_IO)
58#include <stdio.h>
59#endif
60
Jerome Forissier11fa71b2020-04-20 17:17:56 +020061#if defined(MBEDTLS_MD2_C)
62const mbedtls_md_info_t mbedtls_md2_info = {
63 "MD2",
64 MBEDTLS_MD_MD2,
65 16,
66 16,
67};
68#endif
69
70#if defined(MBEDTLS_MD4_C)
71const mbedtls_md_info_t mbedtls_md4_info = {
72 "MD4",
73 MBEDTLS_MD_MD4,
74 16,
75 64,
76};
77#endif
78
79#if defined(MBEDTLS_MD5_C)
80const mbedtls_md_info_t mbedtls_md5_info = {
81 "MD5",
82 MBEDTLS_MD_MD5,
83 16,
84 64,
85};
86#endif
87
88#if defined(MBEDTLS_RIPEMD160_C)
89const mbedtls_md_info_t mbedtls_ripemd160_info = {
90 "RIPEMD160",
91 MBEDTLS_MD_RIPEMD160,
92 20,
93 64,
94};
95#endif
96
97#if defined(MBEDTLS_SHA1_C)
98const mbedtls_md_info_t mbedtls_sha1_info = {
99 "SHA1",
100 MBEDTLS_MD_SHA1,
101 20,
102 64,
103};
104#endif
105
106#if defined(MBEDTLS_SHA256_C)
107const mbedtls_md_info_t mbedtls_sha224_info = {
108 "SHA224",
109 MBEDTLS_MD_SHA224,
110 28,
111 64,
112};
113
114const mbedtls_md_info_t mbedtls_sha256_info = {
115 "SHA256",
116 MBEDTLS_MD_SHA256,
117 32,
118 64,
119};
120#endif
121
122#if defined(MBEDTLS_SHA512_C)
123#if !defined(MBEDTLS_SHA512_NO_SHA384)
124const mbedtls_md_info_t mbedtls_sha384_info = {
125 "SHA384",
126 MBEDTLS_MD_SHA384,
127 48,
128 128,
129};
130#endif
131
132const mbedtls_md_info_t mbedtls_sha512_info = {
133 "SHA512",
134 MBEDTLS_MD_SHA512,
135 64,
136 128,
137};
138#endif
139
Jens Wiklander817466c2018-05-22 13:49:31 +0200140/*
141 * Reminder: update profiles in x509_crt.c when adding a new hash!
142 */
143static const int supported_digests[] = {
144
145#if defined(MBEDTLS_SHA512_C)
146 MBEDTLS_MD_SHA512,
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200147#if !defined(MBEDTLS_SHA512_NO_SHA384)
Jens Wiklander817466c2018-05-22 13:49:31 +0200148 MBEDTLS_MD_SHA384,
149#endif
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200150#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200151
152#if defined(MBEDTLS_SHA256_C)
153 MBEDTLS_MD_SHA256,
154 MBEDTLS_MD_SHA224,
155#endif
156
157#if defined(MBEDTLS_SHA1_C)
158 MBEDTLS_MD_SHA1,
159#endif
160
161#if defined(MBEDTLS_RIPEMD160_C)
162 MBEDTLS_MD_RIPEMD160,
163#endif
164
165#if defined(MBEDTLS_MD5_C)
166 MBEDTLS_MD_MD5,
167#endif
168
169#if defined(MBEDTLS_MD4_C)
170 MBEDTLS_MD_MD4,
171#endif
172
173#if defined(MBEDTLS_MD2_C)
174 MBEDTLS_MD_MD2,
175#endif
176
177 MBEDTLS_MD_NONE
178};
179
180const int *mbedtls_md_list( void )
181{
182 return( supported_digests );
183}
184
185const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name )
186{
187 if( NULL == md_name )
188 return( NULL );
189
190 /* Get the appropriate digest information */
191#if defined(MBEDTLS_MD2_C)
192 if( !strcmp( "MD2", md_name ) )
193 return mbedtls_md_info_from_type( MBEDTLS_MD_MD2 );
194#endif
195#if defined(MBEDTLS_MD4_C)
196 if( !strcmp( "MD4", md_name ) )
197 return mbedtls_md_info_from_type( MBEDTLS_MD_MD4 );
198#endif
199#if defined(MBEDTLS_MD5_C)
200 if( !strcmp( "MD5", md_name ) )
201 return mbedtls_md_info_from_type( MBEDTLS_MD_MD5 );
202#endif
203#if defined(MBEDTLS_RIPEMD160_C)
204 if( !strcmp( "RIPEMD160", md_name ) )
205 return mbedtls_md_info_from_type( MBEDTLS_MD_RIPEMD160 );
206#endif
207#if defined(MBEDTLS_SHA1_C)
208 if( !strcmp( "SHA1", md_name ) || !strcmp( "SHA", md_name ) )
209 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
210#endif
211#if defined(MBEDTLS_SHA256_C)
212 if( !strcmp( "SHA224", md_name ) )
213 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA224 );
214 if( !strcmp( "SHA256", md_name ) )
215 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 );
216#endif
217#if defined(MBEDTLS_SHA512_C)
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200218#if !defined(MBEDTLS_SHA512_NO_SHA384)
Jens Wiklander817466c2018-05-22 13:49:31 +0200219 if( !strcmp( "SHA384", md_name ) )
220 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA384 );
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200221#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200222 if( !strcmp( "SHA512", md_name ) )
223 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA512 );
224#endif
225 return( NULL );
226}
227
228const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type )
229{
230 switch( md_type )
231 {
232#if defined(MBEDTLS_MD2_C)
233 case MBEDTLS_MD_MD2:
234 return( &mbedtls_md2_info );
235#endif
236#if defined(MBEDTLS_MD4_C)
237 case MBEDTLS_MD_MD4:
238 return( &mbedtls_md4_info );
239#endif
240#if defined(MBEDTLS_MD5_C)
241 case MBEDTLS_MD_MD5:
242 return( &mbedtls_md5_info );
243#endif
244#if defined(MBEDTLS_RIPEMD160_C)
245 case MBEDTLS_MD_RIPEMD160:
246 return( &mbedtls_ripemd160_info );
247#endif
248#if defined(MBEDTLS_SHA1_C)
249 case MBEDTLS_MD_SHA1:
250 return( &mbedtls_sha1_info );
251#endif
252#if defined(MBEDTLS_SHA256_C)
253 case MBEDTLS_MD_SHA224:
254 return( &mbedtls_sha224_info );
255 case MBEDTLS_MD_SHA256:
256 return( &mbedtls_sha256_info );
257#endif
258#if defined(MBEDTLS_SHA512_C)
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200259#if !defined(MBEDTLS_SHA512_NO_SHA384)
Jens Wiklander817466c2018-05-22 13:49:31 +0200260 case MBEDTLS_MD_SHA384:
261 return( &mbedtls_sha384_info );
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200262#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200263 case MBEDTLS_MD_SHA512:
264 return( &mbedtls_sha512_info );
265#endif
266 default:
267 return( NULL );
268 }
269}
270
271void mbedtls_md_init( mbedtls_md_context_t *ctx )
272{
273 memset( ctx, 0, sizeof( mbedtls_md_context_t ) );
274}
275
276void mbedtls_md_free( mbedtls_md_context_t *ctx )
277{
278 if( ctx == NULL || ctx->md_info == NULL )
279 return;
280
281 if( ctx->md_ctx != NULL )
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200282 {
283 switch( ctx->md_info->type )
284 {
285#if defined(MBEDTLS_MD2_C)
286 case MBEDTLS_MD_MD2:
287 mbedtls_md2_free( ctx->md_ctx );
288 break;
289#endif
290#if defined(MBEDTLS_MD4_C)
291 case MBEDTLS_MD_MD4:
292 mbedtls_md4_free( ctx->md_ctx );
293 break;
294#endif
295#if defined(MBEDTLS_MD5_C)
296 case MBEDTLS_MD_MD5:
297 mbedtls_md5_free( ctx->md_ctx );
298 break;
299#endif
300#if defined(MBEDTLS_RIPEMD160_C)
301 case MBEDTLS_MD_RIPEMD160:
302 mbedtls_ripemd160_free( ctx->md_ctx );
303 break;
304#endif
305#if defined(MBEDTLS_SHA1_C)
306 case MBEDTLS_MD_SHA1:
307 mbedtls_sha1_free( ctx->md_ctx );
308 break;
309#endif
310#if defined(MBEDTLS_SHA256_C)
311 case MBEDTLS_MD_SHA224:
312 case MBEDTLS_MD_SHA256:
313 mbedtls_sha256_free( ctx->md_ctx );
314 break;
315#endif
316#if defined(MBEDTLS_SHA512_C)
317#if !defined(MBEDTLS_SHA512_NO_SHA384)
318 case MBEDTLS_MD_SHA384:
319#endif
320 case MBEDTLS_MD_SHA512:
321 mbedtls_sha512_free( ctx->md_ctx );
322 break;
323#endif
324 default:
325 /* Shouldn't happen */
326 break;
327 }
328 mbedtls_free( ctx->md_ctx );
329 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200330
331 if( ctx->hmac_ctx != NULL )
332 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100333 mbedtls_platform_zeroize( ctx->hmac_ctx,
334 2 * ctx->md_info->block_size );
Jens Wiklander817466c2018-05-22 13:49:31 +0200335 mbedtls_free( ctx->hmac_ctx );
336 }
337
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100338 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md_context_t ) );
Jens Wiklander817466c2018-05-22 13:49:31 +0200339}
340
341int mbedtls_md_clone( mbedtls_md_context_t *dst,
342 const mbedtls_md_context_t *src )
343{
344 if( dst == NULL || dst->md_info == NULL ||
345 src == NULL || src->md_info == NULL ||
346 dst->md_info != src->md_info )
347 {
348 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
349 }
350
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200351 switch( src->md_info->type )
352 {
353#if defined(MBEDTLS_MD2_C)
354 case MBEDTLS_MD_MD2:
355 mbedtls_md2_clone( dst->md_ctx, src->md_ctx );
356 break;
357#endif
358#if defined(MBEDTLS_MD4_C)
359 case MBEDTLS_MD_MD4:
360 mbedtls_md4_clone( dst->md_ctx, src->md_ctx );
361 break;
362#endif
363#if defined(MBEDTLS_MD5_C)
364 case MBEDTLS_MD_MD5:
365 mbedtls_md5_clone( dst->md_ctx, src->md_ctx );
366 break;
367#endif
368#if defined(MBEDTLS_RIPEMD160_C)
369 case MBEDTLS_MD_RIPEMD160:
370 mbedtls_ripemd160_clone( dst->md_ctx, src->md_ctx );
371 break;
372#endif
373#if defined(MBEDTLS_SHA1_C)
374 case MBEDTLS_MD_SHA1:
375 mbedtls_sha1_clone( dst->md_ctx, src->md_ctx );
376 break;
377#endif
378#if defined(MBEDTLS_SHA256_C)
379 case MBEDTLS_MD_SHA224:
380 case MBEDTLS_MD_SHA256:
381 mbedtls_sha256_clone( dst->md_ctx, src->md_ctx );
382 break;
383#endif
384#if defined(MBEDTLS_SHA512_C)
385#if !defined(MBEDTLS_SHA512_NO_SHA384)
386 case MBEDTLS_MD_SHA384:
387#endif
388 case MBEDTLS_MD_SHA512:
389 mbedtls_sha512_clone( dst->md_ctx, src->md_ctx );
390 break;
391#endif
392 default:
393 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
394 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200395
Edison Ai12484fc2018-12-19 15:36:28 +0800396 if( dst->hmac_ctx != NULL && src->hmac_ctx != NULL )
397 memcpy( dst->hmac_ctx, src->hmac_ctx, 2 * src->md_info->block_size );
398
Jens Wiklander817466c2018-05-22 13:49:31 +0200399 return( 0 );
400}
401
402#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
403int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info )
404{
405 return mbedtls_md_setup( ctx, md_info, 1 );
406}
407#endif
408
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200409#define ALLOC( type ) \
410 do { \
411 ctx->md_ctx = mbedtls_calloc( 1, sizeof( mbedtls_##type##_context ) ); \
412 if( ctx->md_ctx == NULL ) \
413 return( MBEDTLS_ERR_MD_ALLOC_FAILED ); \
414 mbedtls_##type##_init( ctx->md_ctx ); \
415 } \
416 while( 0 )
417
Jens Wiklander817466c2018-05-22 13:49:31 +0200418int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac )
419{
420 if( md_info == NULL || ctx == NULL )
421 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
422
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200423 switch( md_info->type )
424 {
425#if defined(MBEDTLS_MD2_C)
426 case MBEDTLS_MD_MD2:
427 ALLOC( md2 );
428 break;
429#endif
430#if defined(MBEDTLS_MD4_C)
431 case MBEDTLS_MD_MD4:
432 ALLOC( md4 );
433 break;
434#endif
435#if defined(MBEDTLS_MD5_C)
436 case MBEDTLS_MD_MD5:
437 ALLOC( md5 );
438 break;
439#endif
440#if defined(MBEDTLS_RIPEMD160_C)
441 case MBEDTLS_MD_RIPEMD160:
442 ALLOC( ripemd160 );
443 break;
444#endif
445#if defined(MBEDTLS_SHA1_C)
446 case MBEDTLS_MD_SHA1:
447 ALLOC( sha1 );
448 break;
449#endif
450#if defined(MBEDTLS_SHA256_C)
451 case MBEDTLS_MD_SHA224:
452 case MBEDTLS_MD_SHA256:
453 ALLOC( sha256 );
454 break;
455#endif
456#if defined(MBEDTLS_SHA512_C)
457#if !defined(MBEDTLS_SHA512_NO_SHA384)
458 case MBEDTLS_MD_SHA384:
459#endif
460 case MBEDTLS_MD_SHA512:
461 ALLOC( sha512 );
462 break;
463#endif
464 default:
465 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
466 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200467
468 if( hmac != 0 )
469 {
470 ctx->hmac_ctx = mbedtls_calloc( 2, md_info->block_size );
471 if( ctx->hmac_ctx == NULL )
472 {
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200473 mbedtls_md_free( ctx );
Jens Wiklander817466c2018-05-22 13:49:31 +0200474 return( MBEDTLS_ERR_MD_ALLOC_FAILED );
475 }
476 }
477
478 ctx->md_info = md_info;
479
480 return( 0 );
481}
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200482#undef ALLOC
Jens Wiklander817466c2018-05-22 13:49:31 +0200483
484int mbedtls_md_starts( mbedtls_md_context_t *ctx )
485{
486 if( ctx == NULL || ctx->md_info == NULL )
487 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
488
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200489 switch( ctx->md_info->type )
490 {
491#if defined(MBEDTLS_MD2_C)
492 case MBEDTLS_MD_MD2:
493 return( mbedtls_md2_starts_ret( ctx->md_ctx ) );
494#endif
495#if defined(MBEDTLS_MD4_C)
496 case MBEDTLS_MD_MD4:
497 return( mbedtls_md4_starts_ret( ctx->md_ctx ) );
498#endif
499#if defined(MBEDTLS_MD5_C)
500 case MBEDTLS_MD_MD5:
501 return( mbedtls_md5_starts_ret( ctx->md_ctx ) );
502#endif
503#if defined(MBEDTLS_RIPEMD160_C)
504 case MBEDTLS_MD_RIPEMD160:
505 return( mbedtls_ripemd160_starts_ret( ctx->md_ctx ) );
506#endif
507#if defined(MBEDTLS_SHA1_C)
508 case MBEDTLS_MD_SHA1:
509 return( mbedtls_sha1_starts_ret( ctx->md_ctx ) );
510#endif
511#if defined(MBEDTLS_SHA256_C)
512 case MBEDTLS_MD_SHA224:
513 return( mbedtls_sha256_starts_ret( ctx->md_ctx, 1 ) );
514 case MBEDTLS_MD_SHA256:
515 return( mbedtls_sha256_starts_ret( ctx->md_ctx, 0 ) );
516#endif
517#if defined(MBEDTLS_SHA512_C)
518#if !defined(MBEDTLS_SHA512_NO_SHA384)
519 case MBEDTLS_MD_SHA384:
520 return( mbedtls_sha512_starts_ret( ctx->md_ctx, 1 ) );
521#endif
522 case MBEDTLS_MD_SHA512:
523 return( mbedtls_sha512_starts_ret( ctx->md_ctx, 0 ) );
524#endif
525 default:
526 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
527 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200528}
529
530int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
531{
532 if( ctx == NULL || ctx->md_info == NULL )
533 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
534
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200535 switch( ctx->md_info->type )
536 {
537#if defined(MBEDTLS_MD2_C)
538 case MBEDTLS_MD_MD2:
539 return( mbedtls_md2_update_ret( ctx->md_ctx, input, ilen ) );
540#endif
541#if defined(MBEDTLS_MD4_C)
542 case MBEDTLS_MD_MD4:
543 return( mbedtls_md4_update_ret( ctx->md_ctx, input, ilen ) );
544#endif
545#if defined(MBEDTLS_MD5_C)
546 case MBEDTLS_MD_MD5:
547 return( mbedtls_md5_update_ret( ctx->md_ctx, input, ilen ) );
548#endif
549#if defined(MBEDTLS_RIPEMD160_C)
550 case MBEDTLS_MD_RIPEMD160:
551 return( mbedtls_ripemd160_update_ret( ctx->md_ctx, input, ilen ) );
552#endif
553#if defined(MBEDTLS_SHA1_C)
554 case MBEDTLS_MD_SHA1:
555 return( mbedtls_sha1_update_ret( ctx->md_ctx, input, ilen ) );
556#endif
557#if defined(MBEDTLS_SHA256_C)
558 case MBEDTLS_MD_SHA224:
559 return( mbedtls_sha256_update_ret( ctx->md_ctx, input, ilen ) );
560 case MBEDTLS_MD_SHA256:
561 return( mbedtls_sha256_update_ret( ctx->md_ctx, input, ilen ) );
562#endif
563#if defined(MBEDTLS_SHA512_C)
564#if !defined(MBEDTLS_SHA512_NO_SHA384)
565 case MBEDTLS_MD_SHA384:
566 return( mbedtls_sha512_update_ret( ctx->md_ctx, input, ilen ) );
567#endif
568 case MBEDTLS_MD_SHA512:
569 return( mbedtls_sha512_update_ret( ctx->md_ctx, input, ilen ) );
570#endif
571 default:
572 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
573 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200574}
575
576int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output )
577{
578 if( ctx == NULL || ctx->md_info == NULL )
579 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
580
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200581 switch( ctx->md_info->type )
582 {
583#if defined(MBEDTLS_MD2_C)
584 case MBEDTLS_MD_MD2:
585 return( mbedtls_md2_finish_ret( ctx->md_ctx, output ) );
586#endif
587#if defined(MBEDTLS_MD4_C)
588 case MBEDTLS_MD_MD4:
589 return( mbedtls_md4_finish_ret( ctx->md_ctx, output ) );
590#endif
591#if defined(MBEDTLS_MD5_C)
592 case MBEDTLS_MD_MD5:
593 return( mbedtls_md5_finish_ret( ctx->md_ctx, output ) );
594#endif
595#if defined(MBEDTLS_RIPEMD160_C)
596 case MBEDTLS_MD_RIPEMD160:
597 return( mbedtls_ripemd160_finish_ret( ctx->md_ctx, output ) );
598#endif
599#if defined(MBEDTLS_SHA1_C)
600 case MBEDTLS_MD_SHA1:
601 return( mbedtls_sha1_finish_ret( ctx->md_ctx, output ) );
602#endif
603#if defined(MBEDTLS_SHA256_C)
604 case MBEDTLS_MD_SHA224:
605 return( mbedtls_sha256_finish_ret( ctx->md_ctx, output ) );
606 case MBEDTLS_MD_SHA256:
607 return( mbedtls_sha256_finish_ret( ctx->md_ctx, output ) );
608#endif
609#if defined(MBEDTLS_SHA512_C)
610#if !defined(MBEDTLS_SHA512_NO_SHA384)
611 case MBEDTLS_MD_SHA384:
612 return( mbedtls_sha512_finish_ret( ctx->md_ctx, output ) );
613#endif
614 case MBEDTLS_MD_SHA512:
615 return( mbedtls_sha512_finish_ret( ctx->md_ctx, output ) );
616#endif
617 default:
618 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
619 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200620}
621
622int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
623 unsigned char *output )
624{
625 if( md_info == NULL )
626 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
627
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200628 switch( md_info->type )
629 {
630#if defined(MBEDTLS_MD2_C)
631 case MBEDTLS_MD_MD2:
632 return( mbedtls_md2_ret( input, ilen, output ) );
633#endif
634#if defined(MBEDTLS_MD4_C)
635 case MBEDTLS_MD_MD4:
636 return( mbedtls_md4_ret( input, ilen, output ) );
637#endif
638#if defined(MBEDTLS_MD5_C)
639 case MBEDTLS_MD_MD5:
640 return( mbedtls_md5_ret( input, ilen, output ) );
641#endif
642#if defined(MBEDTLS_RIPEMD160_C)
643 case MBEDTLS_MD_RIPEMD160:
644 return( mbedtls_ripemd160_ret( input, ilen, output ) );
645#endif
646#if defined(MBEDTLS_SHA1_C)
647 case MBEDTLS_MD_SHA1:
648 return( mbedtls_sha1_ret( input, ilen, output ) );
649#endif
650#if defined(MBEDTLS_SHA256_C)
651 case MBEDTLS_MD_SHA224:
652 return( mbedtls_sha256_ret( input, ilen, output, 1 ) );
653 case MBEDTLS_MD_SHA256:
654 return( mbedtls_sha256_ret( input, ilen, output, 0 ) );
655#endif
656#if defined(MBEDTLS_SHA512_C)
657#if !defined(MBEDTLS_SHA512_NO_SHA384)
658 case MBEDTLS_MD_SHA384:
659 return( mbedtls_sha512_ret( input, ilen, output, 1 ) );
660#endif
661 case MBEDTLS_MD_SHA512:
662 return( mbedtls_sha512_ret( input, ilen, output, 0 ) );
663#endif
664 default:
665 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
666 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200667}
668
669#if defined(MBEDTLS_FS_IO)
670int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigned char *output )
671{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200672 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200673 FILE *f;
674 size_t n;
675 mbedtls_md_context_t ctx;
676 unsigned char buf[1024];
677
678 if( md_info == NULL )
679 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
680
681 if( ( f = fopen( path, "rb" ) ) == NULL )
682 return( MBEDTLS_ERR_MD_FILE_IO_ERROR );
683
684 mbedtls_md_init( &ctx );
685
686 if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 )
687 goto cleanup;
688
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200689 if( ( ret = mbedtls_md_starts( &ctx ) ) != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100690 goto cleanup;
Jens Wiklander817466c2018-05-22 13:49:31 +0200691
692 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200693 if( ( ret = mbedtls_md_update( &ctx, buf, n ) ) != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100694 goto cleanup;
Jens Wiklander817466c2018-05-22 13:49:31 +0200695
696 if( ferror( f ) != 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200697 ret = MBEDTLS_ERR_MD_FILE_IO_ERROR;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100698 else
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200699 ret = mbedtls_md_finish( &ctx, output );
Jens Wiklander817466c2018-05-22 13:49:31 +0200700
701cleanup:
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100702 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Jens Wiklander817466c2018-05-22 13:49:31 +0200703 fclose( f );
704 mbedtls_md_free( &ctx );
705
706 return( ret );
707}
708#endif /* MBEDTLS_FS_IO */
709
710int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen )
711{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200712 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200713 unsigned char sum[MBEDTLS_MD_MAX_SIZE];
714 unsigned char *ipad, *opad;
715 size_t i;
716
717 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
718 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
719
720 if( keylen > (size_t) ctx->md_info->block_size )
721 {
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200722 if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100723 goto cleanup;
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200724 if( ( ret = mbedtls_md_update( ctx, key, keylen ) ) != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100725 goto cleanup;
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200726 if( ( ret = mbedtls_md_finish( ctx, sum ) ) != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100727 goto cleanup;
Jens Wiklander817466c2018-05-22 13:49:31 +0200728
729 keylen = ctx->md_info->size;
730 key = sum;
731 }
732
733 ipad = (unsigned char *) ctx->hmac_ctx;
734 opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
735
736 memset( ipad, 0x36, ctx->md_info->block_size );
737 memset( opad, 0x5C, ctx->md_info->block_size );
738
739 for( i = 0; i < keylen; i++ )
740 {
741 ipad[i] = (unsigned char)( ipad[i] ^ key[i] );
742 opad[i] = (unsigned char)( opad[i] ^ key[i] );
743 }
744
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200745 if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100746 goto cleanup;
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200747 if( ( ret = mbedtls_md_update( ctx, ipad,
748 ctx->md_info->block_size ) ) != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100749 goto cleanup;
Jens Wiklander817466c2018-05-22 13:49:31 +0200750
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100751cleanup:
752 mbedtls_platform_zeroize( sum, sizeof( sum ) );
Jens Wiklander817466c2018-05-22 13:49:31 +0200753
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100754 return( ret );
Jens Wiklander817466c2018-05-22 13:49:31 +0200755}
756
757int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
758{
759 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
760 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
761
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200762 return( mbedtls_md_update( ctx, input, ilen ) );
Jens Wiklander817466c2018-05-22 13:49:31 +0200763}
764
765int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output )
766{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200767 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200768 unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
769 unsigned char *opad;
770
771 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
772 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
773
774 opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
775
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200776 if( ( ret = mbedtls_md_finish( ctx, tmp ) ) != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100777 return( ret );
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200778 if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100779 return( ret );
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200780 if( ( ret = mbedtls_md_update( ctx, opad,
781 ctx->md_info->block_size ) ) != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100782 return( ret );
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200783 if( ( ret = mbedtls_md_update( ctx, tmp,
784 ctx->md_info->size ) ) != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100785 return( ret );
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200786 return( mbedtls_md_finish( ctx, output ) );
Jens Wiklander817466c2018-05-22 13:49:31 +0200787}
788
789int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx )
790{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200791 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200792 unsigned char *ipad;
793
794 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
795 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
796
797 ipad = (unsigned char *) ctx->hmac_ctx;
798
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200799 if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100800 return( ret );
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200801 return( mbedtls_md_update( ctx, ipad, ctx->md_info->block_size ) );
Jens Wiklander817466c2018-05-22 13:49:31 +0200802}
803
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100804int mbedtls_md_hmac( const mbedtls_md_info_t *md_info,
805 const unsigned char *key, size_t keylen,
806 const unsigned char *input, size_t ilen,
807 unsigned char *output )
Jens Wiklander817466c2018-05-22 13:49:31 +0200808{
809 mbedtls_md_context_t ctx;
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200810 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200811
812 if( md_info == NULL )
813 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
814
815 mbedtls_md_init( &ctx );
816
817 if( ( ret = mbedtls_md_setup( &ctx, md_info, 1 ) ) != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100818 goto cleanup;
Jens Wiklander817466c2018-05-22 13:49:31 +0200819
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100820 if( ( ret = mbedtls_md_hmac_starts( &ctx, key, keylen ) ) != 0 )
821 goto cleanup;
822 if( ( ret = mbedtls_md_hmac_update( &ctx, input, ilen ) ) != 0 )
823 goto cleanup;
824 if( ( ret = mbedtls_md_hmac_finish( &ctx, output ) ) != 0 )
825 goto cleanup;
Jens Wiklander817466c2018-05-22 13:49:31 +0200826
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100827cleanup:
Jens Wiklander817466c2018-05-22 13:49:31 +0200828 mbedtls_md_free( &ctx );
829
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100830 return( ret );
Jens Wiklander817466c2018-05-22 13:49:31 +0200831}
832
833int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data )
834{
835 if( ctx == NULL || ctx->md_info == NULL )
836 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
837
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200838 switch( ctx->md_info->type )
839 {
840#if defined(MBEDTLS_MD2_C)
841 case MBEDTLS_MD_MD2:
842 return( mbedtls_internal_md2_process( ctx->md_ctx ) );
843#endif
844#if defined(MBEDTLS_MD4_C)
845 case MBEDTLS_MD_MD4:
846 return( mbedtls_internal_md4_process( ctx->md_ctx, data ) );
847#endif
848#if defined(MBEDTLS_MD5_C)
849 case MBEDTLS_MD_MD5:
850 return( mbedtls_internal_md5_process( ctx->md_ctx, data ) );
851#endif
852#if defined(MBEDTLS_RIPEMD160_C)
853 case MBEDTLS_MD_RIPEMD160:
854 return( mbedtls_internal_ripemd160_process( ctx->md_ctx, data ) );
855#endif
856#if defined(MBEDTLS_SHA1_C)
857 case MBEDTLS_MD_SHA1:
858 return( mbedtls_internal_sha1_process( ctx->md_ctx, data ) );
859#endif
860#if defined(MBEDTLS_SHA256_C)
861 case MBEDTLS_MD_SHA224:
862 return( mbedtls_internal_sha256_process( ctx->md_ctx, data ) );
863 case MBEDTLS_MD_SHA256:
864 return( mbedtls_internal_sha256_process( ctx->md_ctx, data ) );
865#endif
866#if defined(MBEDTLS_SHA512_C)
867#if !defined(MBEDTLS_SHA512_NO_SHA384)
868 case MBEDTLS_MD_SHA384:
869 return( mbedtls_internal_sha512_process( ctx->md_ctx, data ) );
870#endif
871 case MBEDTLS_MD_SHA512:
872 return( mbedtls_internal_sha512_process( ctx->md_ctx, data ) );
873#endif
874 default:
875 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
876 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200877}
878
879unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info )
880{
881 if( md_info == NULL )
882 return( 0 );
883
884 return md_info->size;
885}
886
887mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info )
888{
889 if( md_info == NULL )
890 return( MBEDTLS_MD_NONE );
891
892 return md_info->type;
893}
894
895const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info )
896{
897 if( md_info == NULL )
898 return( NULL );
899
900 return md_info->name;
901}
902
903#endif /* MBEDTLS_MD_C */