4 * \brief Generic message digest wrapper for mbed TLS
6 * \author Adriaan de Jong <dejong@fox-it.com>
8 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
9 * SPDX-License-Identifier: GPL-2.0
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 * This file is part of mbed TLS (https://tls.mbed.org)
28 #if !defined(MBEDTLS_CONFIG_FILE)
29 #include "mbedtls/config.h"
31 #include MBEDTLS_CONFIG_FILE
34 #if defined(MBEDTLS_MD_C)
36 #include "mbedtls/md.h"
37 #include "mbedtls/md_internal.h"
38 #include "mbedtls/platform_util.h"
40 #if defined(MBEDTLS_PLATFORM_C)
41 #include "mbedtls/platform.h"
44 #define mbedtls_calloc calloc
45 #define mbedtls_free free
50 #if defined(MBEDTLS_FS_IO)
55 * Reminder: update profiles in x509_crt.c when adding a new hash!
57 static const int supported_digests
[] = {
59 #if defined(MBEDTLS_SHA512_C)
64 #if defined(MBEDTLS_SHA256_C)
69 #if defined(MBEDTLS_SHA1_C)
73 #if defined(MBEDTLS_RIPEMD160_C)
77 #if defined(MBEDTLS_MD5_C)
81 #if defined(MBEDTLS_MD4_C)
85 #if defined(MBEDTLS_MD2_C)
92 const int *mbedtls_md_list( void )
94 return( supported_digests
);
97 const mbedtls_md_info_t
*mbedtls_md_info_from_string( const char *md_name
)
102 /* Get the appropriate digest information */
103 #if defined(MBEDTLS_MD2_C)
104 if( !strcmp( "MD2", md_name
) )
105 return mbedtls_md_info_from_type( MBEDTLS_MD_MD2
);
107 #if defined(MBEDTLS_MD4_C)
108 if( !strcmp( "MD4", md_name
) )
109 return mbedtls_md_info_from_type( MBEDTLS_MD_MD4
);
111 #if defined(MBEDTLS_MD5_C)
112 if( !strcmp( "MD5", md_name
) )
113 return mbedtls_md_info_from_type( MBEDTLS_MD_MD5
);
115 #if defined(MBEDTLS_RIPEMD160_C)
116 if( !strcmp( "RIPEMD160", md_name
) )
117 return mbedtls_md_info_from_type( MBEDTLS_MD_RIPEMD160
);
119 #if defined(MBEDTLS_SHA1_C)
120 if( !strcmp( "SHA1", md_name
) || !strcmp( "SHA", md_name
) )
121 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA1
);
123 #if defined(MBEDTLS_SHA256_C)
124 if( !strcmp( "SHA224", md_name
) )
125 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA224
);
126 if( !strcmp( "SHA256", md_name
) )
127 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA256
);
129 #if defined(MBEDTLS_SHA512_C)
130 if( !strcmp( "SHA384", md_name
) )
131 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA384
);
132 if( !strcmp( "SHA512", md_name
) )
133 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA512
);
138 const mbedtls_md_info_t
*mbedtls_md_info_from_type( mbedtls_md_type_t md_type
)
142 #if defined(MBEDTLS_MD2_C)
144 return( &mbedtls_md2_info
);
146 #if defined(MBEDTLS_MD4_C)
148 return( &mbedtls_md4_info
);
150 #if defined(MBEDTLS_MD5_C)
152 return( &mbedtls_md5_info
);
154 #if defined(MBEDTLS_RIPEMD160_C)
155 case MBEDTLS_MD_RIPEMD160
:
156 return( &mbedtls_ripemd160_info
);
158 #if defined(MBEDTLS_SHA1_C)
159 case MBEDTLS_MD_SHA1
:
160 return( &mbedtls_sha1_info
);
162 #if defined(MBEDTLS_SHA256_C)
163 case MBEDTLS_MD_SHA224
:
164 return( &mbedtls_sha224_info
);
165 case MBEDTLS_MD_SHA256
:
166 return( &mbedtls_sha256_info
);
168 #if defined(MBEDTLS_SHA512_C)
169 case MBEDTLS_MD_SHA384
:
170 return( &mbedtls_sha384_info
);
171 case MBEDTLS_MD_SHA512
:
172 return( &mbedtls_sha512_info
);
179 void mbedtls_md_init( mbedtls_md_context_t
*ctx
)
181 memset( ctx
, 0, sizeof( mbedtls_md_context_t
) );
184 void mbedtls_md_free( mbedtls_md_context_t
*ctx
)
186 if( ctx
== NULL
|| ctx
->md_info
== NULL
)
189 if( ctx
->md_ctx
!= NULL
)
190 ctx
->md_info
->ctx_free_func( ctx
->md_ctx
);
192 if( ctx
->hmac_ctx
!= NULL
)
194 mbedtls_platform_zeroize( ctx
->hmac_ctx
,
195 2 * ctx
->md_info
->block_size
);
196 mbedtls_free( ctx
->hmac_ctx
);
199 mbedtls_platform_zeroize( ctx
, sizeof( mbedtls_md_context_t
) );
202 int mbedtls_md_clone( mbedtls_md_context_t
*dst
,
203 const mbedtls_md_context_t
*src
)
205 if( dst
== NULL
|| dst
->md_info
== NULL
||
206 src
== NULL
|| src
->md_info
== NULL
||
207 dst
->md_info
!= src
->md_info
)
209 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA
);
212 dst
->md_info
->clone_func( dst
->md_ctx
, src
->md_ctx
);
217 #if ! defined(MBEDTLS_DEPRECATED_REMOVED)
218 int mbedtls_md_init_ctx( mbedtls_md_context_t
*ctx
, const mbedtls_md_info_t
*md_info
)
220 return mbedtls_md_setup( ctx
, md_info
, 1 );
224 int mbedtls_md_setup( mbedtls_md_context_t
*ctx
, const mbedtls_md_info_t
*md_info
, int hmac
)
226 if( md_info
== NULL
|| ctx
== NULL
)
227 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA
);
229 if( ( ctx
->md_ctx
= md_info
->ctx_alloc_func() ) == NULL
)
230 return( MBEDTLS_ERR_MD_ALLOC_FAILED
);
234 ctx
->hmac_ctx
= mbedtls_calloc( 2, md_info
->block_size
);
235 if( ctx
->hmac_ctx
== NULL
)
237 md_info
->ctx_free_func( ctx
->md_ctx
);
238 return( MBEDTLS_ERR_MD_ALLOC_FAILED
);
242 ctx
->md_info
= md_info
;
247 int mbedtls_md_starts( mbedtls_md_context_t
*ctx
)
249 if( ctx
== NULL
|| ctx
->md_info
== NULL
)
250 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA
);
252 return( ctx
->md_info
->starts_func( ctx
->md_ctx
) );
255 int mbedtls_md_update( mbedtls_md_context_t
*ctx
, const unsigned char *input
, size_t ilen
)
257 if( ctx
== NULL
|| ctx
->md_info
== NULL
)
258 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA
);
260 return( ctx
->md_info
->update_func( ctx
->md_ctx
, input
, ilen
) );
263 int mbedtls_md_finish( mbedtls_md_context_t
*ctx
, unsigned char *output
)
265 if( ctx
== NULL
|| ctx
->md_info
== NULL
)
266 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA
);
268 return( ctx
->md_info
->finish_func( ctx
->md_ctx
, output
) );
271 int mbedtls_md( const mbedtls_md_info_t
*md_info
, const unsigned char *input
, size_t ilen
,
272 unsigned char *output
)
274 if( md_info
== NULL
)
275 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA
);
277 return( md_info
->digest_func( input
, ilen
, output
) );
280 #if defined(MBEDTLS_FS_IO)
281 int mbedtls_md_file( const mbedtls_md_info_t
*md_info
, const char *path
, unsigned char *output
)
286 mbedtls_md_context_t ctx
;
287 unsigned char buf
[1024];
289 if( md_info
== NULL
)
290 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA
);
292 if( ( f
= fopen( path
, "rb" ) ) == NULL
)
293 return( MBEDTLS_ERR_MD_FILE_IO_ERROR
);
295 mbedtls_md_init( &ctx
);
297 if( ( ret
= mbedtls_md_setup( &ctx
, md_info
, 0 ) ) != 0 )
300 if( ( ret
= md_info
->starts_func( ctx
.md_ctx
) ) != 0 )
303 while( ( n
= fread( buf
, 1, sizeof( buf
), f
) ) > 0 )
304 if( ( ret
= md_info
->update_func( ctx
.md_ctx
, buf
, n
) ) != 0 )
307 if( ferror( f
) != 0 )
308 ret
= MBEDTLS_ERR_MD_FILE_IO_ERROR
;
310 ret
= md_info
->finish_func( ctx
.md_ctx
, output
);
313 mbedtls_platform_zeroize( buf
, sizeof( buf
) );
315 mbedtls_md_free( &ctx
);
319 #endif /* MBEDTLS_FS_IO */
321 int mbedtls_md_hmac_starts( mbedtls_md_context_t
*ctx
, const unsigned char *key
, size_t keylen
)
324 unsigned char sum
[MBEDTLS_MD_MAX_SIZE
];
325 unsigned char *ipad
, *opad
;
328 if( ctx
== NULL
|| ctx
->md_info
== NULL
|| ctx
->hmac_ctx
== NULL
)
329 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA
);
331 if( keylen
> (size_t) ctx
->md_info
->block_size
)
333 if( ( ret
= ctx
->md_info
->starts_func( ctx
->md_ctx
) ) != 0 )
335 if( ( ret
= ctx
->md_info
->update_func( ctx
->md_ctx
, key
, keylen
) ) != 0 )
337 if( ( ret
= ctx
->md_info
->finish_func( ctx
->md_ctx
, sum
) ) != 0 )
340 keylen
= ctx
->md_info
->size
;
344 ipad
= (unsigned char *) ctx
->hmac_ctx
;
345 opad
= (unsigned char *) ctx
->hmac_ctx
+ ctx
->md_info
->block_size
;
347 memset( ipad
, 0x36, ctx
->md_info
->block_size
);
348 memset( opad
, 0x5C, ctx
->md_info
->block_size
);
350 for( i
= 0; i
< keylen
; i
++ )
352 ipad
[i
] = (unsigned char)( ipad
[i
] ^ key
[i
] );
353 opad
[i
] = (unsigned char)( opad
[i
] ^ key
[i
] );
356 if( ( ret
= ctx
->md_info
->starts_func( ctx
->md_ctx
) ) != 0 )
358 if( ( ret
= ctx
->md_info
->update_func( ctx
->md_ctx
, ipad
,
359 ctx
->md_info
->block_size
) ) != 0 )
363 mbedtls_platform_zeroize( sum
, sizeof( sum
) );
368 int mbedtls_md_hmac_update( mbedtls_md_context_t
*ctx
, const unsigned char *input
, size_t ilen
)
370 if( ctx
== NULL
|| ctx
->md_info
== NULL
|| ctx
->hmac_ctx
== NULL
)
371 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA
);
373 return( ctx
->md_info
->update_func( ctx
->md_ctx
, input
, ilen
) );
376 int mbedtls_md_hmac_finish( mbedtls_md_context_t
*ctx
, unsigned char *output
)
379 unsigned char tmp
[MBEDTLS_MD_MAX_SIZE
];
382 if( ctx
== NULL
|| ctx
->md_info
== NULL
|| ctx
->hmac_ctx
== NULL
)
383 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA
);
385 opad
= (unsigned char *) ctx
->hmac_ctx
+ ctx
->md_info
->block_size
;
387 if( ( ret
= ctx
->md_info
->finish_func( ctx
->md_ctx
, tmp
) ) != 0 )
389 if( ( ret
= ctx
->md_info
->starts_func( ctx
->md_ctx
) ) != 0 )
391 if( ( ret
= ctx
->md_info
->update_func( ctx
->md_ctx
, opad
,
392 ctx
->md_info
->block_size
) ) != 0 )
394 if( ( ret
= ctx
->md_info
->update_func( ctx
->md_ctx
, tmp
,
395 ctx
->md_info
->size
) ) != 0 )
397 return( ctx
->md_info
->finish_func( ctx
->md_ctx
, output
) );
400 int mbedtls_md_hmac_reset( mbedtls_md_context_t
*ctx
)
405 if( ctx
== NULL
|| ctx
->md_info
== NULL
|| ctx
->hmac_ctx
== NULL
)
406 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA
);
408 ipad
= (unsigned char *) ctx
->hmac_ctx
;
410 if( ( ret
= ctx
->md_info
->starts_func( ctx
->md_ctx
) ) != 0 )
412 return( ctx
->md_info
->update_func( ctx
->md_ctx
, ipad
,
413 ctx
->md_info
->block_size
) );
416 int mbedtls_md_hmac( const mbedtls_md_info_t
*md_info
,
417 const unsigned char *key
, size_t keylen
,
418 const unsigned char *input
, size_t ilen
,
419 unsigned char *output
)
421 mbedtls_md_context_t ctx
;
424 if( md_info
== NULL
)
425 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA
);
427 mbedtls_md_init( &ctx
);
429 if( ( ret
= mbedtls_md_setup( &ctx
, md_info
, 1 ) ) != 0 )
432 if( ( ret
= mbedtls_md_hmac_starts( &ctx
, key
, keylen
) ) != 0 )
434 if( ( ret
= mbedtls_md_hmac_update( &ctx
, input
, ilen
) ) != 0 )
436 if( ( ret
= mbedtls_md_hmac_finish( &ctx
, output
) ) != 0 )
440 mbedtls_md_free( &ctx
);
445 int mbedtls_md_process( mbedtls_md_context_t
*ctx
, const unsigned char *data
)
447 if( ctx
== NULL
|| ctx
->md_info
== NULL
)
448 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA
);
450 return( ctx
->md_info
->process_func( ctx
->md_ctx
, data
) );
453 unsigned char mbedtls_md_get_size( const mbedtls_md_info_t
*md_info
)
455 if( md_info
== NULL
)
458 return md_info
->size
;
461 mbedtls_md_type_t
mbedtls_md_get_type( const mbedtls_md_info_t
*md_info
)
463 if( md_info
== NULL
)
464 return( MBEDTLS_MD_NONE
);
466 return md_info
->type
;
469 const char *mbedtls_md_get_name( const mbedtls_md_info_t
*md_info
)
471 if( md_info
== NULL
)
474 return md_info
->name
;
477 #endif /* MBEDTLS_MD_C */