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"
39 #if defined(MBEDTLS_PLATFORM_C)
40 #include "mbedtls/platform.h"
43 #define mbedtls_calloc calloc
44 #define mbedtls_free free
49 #if defined(MBEDTLS_FS_IO)
53 /* Implementation that should never be optimized out by the compiler */
54 static void mbedtls_zeroize( void *v
, size_t n
) {
55 volatile unsigned char *p
= v
; while( n
-- ) *p
++ = 0;
59 * Reminder: update profiles in x509_crt.c when adding a new hash!
61 static const int supported_digests
[] = {
63 #if defined(MBEDTLS_SHA512_C)
68 #if defined(MBEDTLS_SHA256_C)
73 #if defined(MBEDTLS_SHA1_C)
77 #if defined(MBEDTLS_RIPEMD160_C)
81 #if defined(MBEDTLS_MD5_C)
85 #if defined(MBEDTLS_MD4_C)
89 #if defined(MBEDTLS_MD2_C)
96 const int *mbedtls_md_list( void )
98 return( supported_digests
);
101 const mbedtls_md_info_t
*mbedtls_md_info_from_string( const char *md_name
)
103 if( NULL
== md_name
)
106 /* Get the appropriate digest information */
107 #if defined(MBEDTLS_MD2_C)
108 if( !strcmp( "MD2", md_name
) )
109 return mbedtls_md_info_from_type( MBEDTLS_MD_MD2
);
111 #if defined(MBEDTLS_MD4_C)
112 if( !strcmp( "MD4", md_name
) )
113 return mbedtls_md_info_from_type( MBEDTLS_MD_MD4
);
115 #if defined(MBEDTLS_MD5_C)
116 if( !strcmp( "MD5", md_name
) )
117 return mbedtls_md_info_from_type( MBEDTLS_MD_MD5
);
119 #if defined(MBEDTLS_RIPEMD160_C)
120 if( !strcmp( "RIPEMD160", md_name
) )
121 return mbedtls_md_info_from_type( MBEDTLS_MD_RIPEMD160
);
123 #if defined(MBEDTLS_SHA1_C)
124 if( !strcmp( "SHA1", md_name
) || !strcmp( "SHA", md_name
) )
125 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA1
);
127 #if defined(MBEDTLS_SHA256_C)
128 if( !strcmp( "SHA224", md_name
) )
129 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA224
);
130 if( !strcmp( "SHA256", md_name
) )
131 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA256
);
133 #if defined(MBEDTLS_SHA512_C)
134 if( !strcmp( "SHA384", md_name
) )
135 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA384
);
136 if( !strcmp( "SHA512", md_name
) )
137 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA512
);
142 const mbedtls_md_info_t
*mbedtls_md_info_from_type( mbedtls_md_type_t md_type
)
146 #if defined(MBEDTLS_MD2_C)
148 return( &mbedtls_md2_info
);
150 #if defined(MBEDTLS_MD4_C)
152 return( &mbedtls_md4_info
);
154 #if defined(MBEDTLS_MD5_C)
156 return( &mbedtls_md5_info
);
158 #if defined(MBEDTLS_RIPEMD160_C)
159 case MBEDTLS_MD_RIPEMD160
:
160 return( &mbedtls_ripemd160_info
);
162 #if defined(MBEDTLS_SHA1_C)
163 case MBEDTLS_MD_SHA1
:
164 return( &mbedtls_sha1_info
);
166 #if defined(MBEDTLS_SHA256_C)
167 case MBEDTLS_MD_SHA224
:
168 return( &mbedtls_sha224_info
);
169 case MBEDTLS_MD_SHA256
:
170 return( &mbedtls_sha256_info
);
172 #if defined(MBEDTLS_SHA512_C)
173 case MBEDTLS_MD_SHA384
:
174 return( &mbedtls_sha384_info
);
175 case MBEDTLS_MD_SHA512
:
176 return( &mbedtls_sha512_info
);
183 void mbedtls_md_init( mbedtls_md_context_t
*ctx
)
185 memset( ctx
, 0, sizeof( mbedtls_md_context_t
) );
188 void mbedtls_md_free( mbedtls_md_context_t
*ctx
)
190 if( ctx
== NULL
|| ctx
->md_info
== NULL
)
193 if( ctx
->md_ctx
!= NULL
)
194 ctx
->md_info
->ctx_free_func( ctx
->md_ctx
);
196 if( ctx
->hmac_ctx
!= NULL
)
198 mbedtls_zeroize( ctx
->hmac_ctx
, 2 * ctx
->md_info
->block_size
);
199 mbedtls_free( ctx
->hmac_ctx
);
202 mbedtls_zeroize( ctx
, sizeof( mbedtls_md_context_t
) );
205 int mbedtls_md_clone( mbedtls_md_context_t
*dst
,
206 const mbedtls_md_context_t
*src
)
208 if( dst
== NULL
|| dst
->md_info
== NULL
||
209 src
== NULL
|| src
->md_info
== NULL
||
210 dst
->md_info
!= src
->md_info
)
212 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA
);
215 dst
->md_info
->clone_func( dst
->md_ctx
, src
->md_ctx
);
220 #if ! defined(MBEDTLS_DEPRECATED_REMOVED)
221 int mbedtls_md_init_ctx( mbedtls_md_context_t
*ctx
, const mbedtls_md_info_t
*md_info
)
223 return mbedtls_md_setup( ctx
, md_info
, 1 );
227 int mbedtls_md_setup( mbedtls_md_context_t
*ctx
, const mbedtls_md_info_t
*md_info
, int hmac
)
229 if( md_info
== NULL
|| ctx
== NULL
)
230 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA
);
232 if( ( ctx
->md_ctx
= md_info
->ctx_alloc_func() ) == NULL
)
233 return( MBEDTLS_ERR_MD_ALLOC_FAILED
);
237 ctx
->hmac_ctx
= mbedtls_calloc( 2, md_info
->block_size
);
238 if( ctx
->hmac_ctx
== NULL
)
240 md_info
->ctx_free_func( ctx
->md_ctx
);
241 return( MBEDTLS_ERR_MD_ALLOC_FAILED
);
245 ctx
->md_info
= md_info
;
250 int mbedtls_md_starts( mbedtls_md_context_t
*ctx
)
252 if( ctx
== NULL
|| ctx
->md_info
== NULL
)
253 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA
);
255 return( ctx
->md_info
->starts_func( ctx
->md_ctx
) );
258 int mbedtls_md_update( mbedtls_md_context_t
*ctx
, const unsigned char *input
, size_t ilen
)
260 if( ctx
== NULL
|| ctx
->md_info
== NULL
)
261 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA
);
263 return( ctx
->md_info
->update_func( ctx
->md_ctx
, input
, ilen
) );
266 int mbedtls_md_finish( mbedtls_md_context_t
*ctx
, unsigned char *output
)
268 if( ctx
== NULL
|| ctx
->md_info
== NULL
)
269 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA
);
271 return( ctx
->md_info
->finish_func( ctx
->md_ctx
, output
) );
274 int mbedtls_md( const mbedtls_md_info_t
*md_info
, const unsigned char *input
, size_t ilen
,
275 unsigned char *output
)
277 if( md_info
== NULL
)
278 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA
);
280 return( md_info
->digest_func( input
, ilen
, output
) );
283 #if defined(MBEDTLS_FS_IO)
284 int mbedtls_md_file( const mbedtls_md_info_t
*md_info
, const char *path
, unsigned char *output
)
289 mbedtls_md_context_t ctx
;
290 unsigned char buf
[1024];
292 if( md_info
== NULL
)
293 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA
);
295 if( ( f
= fopen( path
, "rb" ) ) == NULL
)
296 return( MBEDTLS_ERR_MD_FILE_IO_ERROR
);
298 mbedtls_md_init( &ctx
);
300 if( ( ret
= mbedtls_md_setup( &ctx
, md_info
, 0 ) ) != 0 )
303 if( ( ret
= md_info
->starts_func( ctx
.md_ctx
) ) != 0 )
306 while( ( n
= fread( buf
, 1, sizeof( buf
), f
) ) > 0 )
307 if( ( ret
= md_info
->update_func( ctx
.md_ctx
, buf
, n
) ) != 0 )
310 if( ferror( f
) != 0 )
311 ret
= MBEDTLS_ERR_MD_FILE_IO_ERROR
;
313 ret
= md_info
->finish_func( ctx
.md_ctx
, output
);
316 mbedtls_zeroize( buf
, sizeof( buf
) );
318 mbedtls_md_free( &ctx
);
322 #endif /* MBEDTLS_FS_IO */
324 int mbedtls_md_hmac_starts( mbedtls_md_context_t
*ctx
, const unsigned char *key
, size_t keylen
)
327 unsigned char sum
[MBEDTLS_MD_MAX_SIZE
];
328 unsigned char *ipad
, *opad
;
331 if( ctx
== NULL
|| ctx
->md_info
== NULL
|| ctx
->hmac_ctx
== NULL
)
332 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA
);
334 if( keylen
> (size_t) ctx
->md_info
->block_size
)
336 if( ( ret
= ctx
->md_info
->starts_func( ctx
->md_ctx
) ) != 0 )
338 if( ( ret
= ctx
->md_info
->update_func( ctx
->md_ctx
, key
, keylen
) ) != 0 )
340 if( ( ret
= ctx
->md_info
->finish_func( ctx
->md_ctx
, sum
) ) != 0 )
343 keylen
= ctx
->md_info
->size
;
347 ipad
= (unsigned char *) ctx
->hmac_ctx
;
348 opad
= (unsigned char *) ctx
->hmac_ctx
+ ctx
->md_info
->block_size
;
350 memset( ipad
, 0x36, ctx
->md_info
->block_size
);
351 memset( opad
, 0x5C, ctx
->md_info
->block_size
);
353 for( i
= 0; i
< keylen
; i
++ )
355 ipad
[i
] = (unsigned char)( ipad
[i
] ^ key
[i
] );
356 opad
[i
] = (unsigned char)( opad
[i
] ^ key
[i
] );
359 if( ( ret
= ctx
->md_info
->starts_func( ctx
->md_ctx
) ) != 0 )
361 if( ( ret
= ctx
->md_info
->update_func( ctx
->md_ctx
, ipad
,
362 ctx
->md_info
->block_size
) ) != 0 )
366 mbedtls_zeroize( sum
, sizeof( sum
) );
371 int mbedtls_md_hmac_update( mbedtls_md_context_t
*ctx
, const unsigned char *input
, size_t ilen
)
373 if( ctx
== NULL
|| ctx
->md_info
== NULL
|| ctx
->hmac_ctx
== NULL
)
374 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA
);
376 return( ctx
->md_info
->update_func( ctx
->md_ctx
, input
, ilen
) );
379 int mbedtls_md_hmac_finish( mbedtls_md_context_t
*ctx
, unsigned char *output
)
382 unsigned char tmp
[MBEDTLS_MD_MAX_SIZE
];
385 if( ctx
== NULL
|| ctx
->md_info
== NULL
|| ctx
->hmac_ctx
== NULL
)
386 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA
);
388 opad
= (unsigned char *) ctx
->hmac_ctx
+ ctx
->md_info
->block_size
;
390 if( ( ret
= ctx
->md_info
->finish_func( ctx
->md_ctx
, tmp
) ) != 0 )
392 if( ( ret
= ctx
->md_info
->starts_func( ctx
->md_ctx
) ) != 0 )
394 if( ( ret
= ctx
->md_info
->update_func( ctx
->md_ctx
, opad
,
395 ctx
->md_info
->block_size
) ) != 0 )
397 if( ( ret
= ctx
->md_info
->update_func( ctx
->md_ctx
, tmp
,
398 ctx
->md_info
->size
) ) != 0 )
400 return( ctx
->md_info
->finish_func( ctx
->md_ctx
, output
) );
403 int mbedtls_md_hmac_reset( mbedtls_md_context_t
*ctx
)
408 if( ctx
== NULL
|| ctx
->md_info
== NULL
|| ctx
->hmac_ctx
== NULL
)
409 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA
);
411 ipad
= (unsigned char *) ctx
->hmac_ctx
;
413 if( ( ret
= ctx
->md_info
->starts_func( ctx
->md_ctx
) ) != 0 )
415 return( ctx
->md_info
->update_func( ctx
->md_ctx
, ipad
,
416 ctx
->md_info
->block_size
) );
419 int mbedtls_md_hmac( const mbedtls_md_info_t
*md_info
,
420 const unsigned char *key
, size_t keylen
,
421 const unsigned char *input
, size_t ilen
,
422 unsigned char *output
)
424 mbedtls_md_context_t ctx
;
427 if( md_info
== NULL
)
428 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA
);
430 mbedtls_md_init( &ctx
);
432 if( ( ret
= mbedtls_md_setup( &ctx
, md_info
, 1 ) ) != 0 )
435 if( ( ret
= mbedtls_md_hmac_starts( &ctx
, key
, keylen
) ) != 0 )
437 if( ( ret
= mbedtls_md_hmac_update( &ctx
, input
, ilen
) ) != 0 )
439 if( ( ret
= mbedtls_md_hmac_finish( &ctx
, output
) ) != 0 )
443 mbedtls_md_free( &ctx
);
448 int mbedtls_md_process( mbedtls_md_context_t
*ctx
, const unsigned char *data
)
450 if( ctx
== NULL
|| ctx
->md_info
== NULL
)
451 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA
);
453 return( ctx
->md_info
->process_func( ctx
->md_ctx
, data
) );
456 unsigned char mbedtls_md_get_size( const mbedtls_md_info_t
*md_info
)
458 if( md_info
== NULL
)
461 return md_info
->size
;
464 mbedtls_md_type_t
mbedtls_md_get_type( const mbedtls_md_info_t
*md_info
)
466 if( md_info
== NULL
)
467 return( MBEDTLS_MD_NONE
);
469 return md_info
->type
;
472 const char *mbedtls_md_get_name( const mbedtls_md_info_t
*md_info
)
474 if( md_info
== NULL
)
477 return md_info
->name
;
480 #endif /* MBEDTLS_MD_C */