1 /** 2 * \file mbedtls_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 (C) 2006-2015, ARM Limited, All Rights Reserved 9 * SPDX-License-Identifier: GPL-2.0 10 * 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. 15 * 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. 20 * 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. 24 * 25 * This file is part of mbed TLS (https://tls.mbed.org) 26 */ 27 28 #if !defined(MBEDTLS_CONFIG_FILE) 29 #include "mbedtls/config.h" 30 #else 31 #include MBEDTLS_CONFIG_FILE 32 #endif 33 34 #if defined(MBEDTLS_MD_C) 35 36 #include "mbedtls/md.h" 37 #include "mbedtls/md_internal.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 /* 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; 56 } 57 58 /* 59 * Reminder: update profiles in x509_crt.c when adding a new hash! 60 */ 61 static const int supported_digests[] = { 62 63 #if defined(MBEDTLS_SHA512_C) 64 MBEDTLS_MD_SHA512, 65 MBEDTLS_MD_SHA384, 66 #endif 67 68 #if defined(MBEDTLS_SHA256_C) 69 MBEDTLS_MD_SHA256, 70 MBEDTLS_MD_SHA224, 71 #endif 72 73 #if defined(MBEDTLS_SHA1_C) 74 MBEDTLS_MD_SHA1, 75 #endif 76 77 #if defined(MBEDTLS_RIPEMD160_C) 78 MBEDTLS_MD_RIPEMD160, 79 #endif 80 81 #if defined(MBEDTLS_MD5_C) 82 MBEDTLS_MD_MD5, 83 #endif 84 85 #if defined(MBEDTLS_MD4_C) 86 MBEDTLS_MD_MD4, 87 #endif 88 89 #if defined(MBEDTLS_MD2_C) 90 MBEDTLS_MD_MD2, 91 #endif 92 93 MBEDTLS_MD_NONE 94 }; 95 96 const int *mbedtls_md_list( void ) 97 { 98 return( supported_digests ); 99 } 100 101 const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name ) 102 { 103 if( NULL == md_name ) 104 return( NULL ); 105 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 ); 110 #endif 111 #if defined(MBEDTLS_MD4_C) 112 if( !strcmp( "MD4", md_name ) ) 113 return mbedtls_md_info_from_type( MBEDTLS_MD_MD4 ); 114 #endif 115 #if defined(MBEDTLS_MD5_C) 116 if( !strcmp( "MD5", md_name ) ) 117 return mbedtls_md_info_from_type( MBEDTLS_MD_MD5 ); 118 #endif 119 #if defined(MBEDTLS_RIPEMD160_C) 120 if( !strcmp( "RIPEMD160", md_name ) ) 121 return mbedtls_md_info_from_type( MBEDTLS_MD_RIPEMD160 ); 122 #endif 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 ); 126 #endif 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 ); 132 #endif 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 ); 138 #endif 139 return( NULL ); 140 } 141 142 const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type ) 143 { 144 switch( md_type ) 145 { 146 #if defined(MBEDTLS_MD2_C) 147 case MBEDTLS_MD_MD2: 148 return( &mbedtls_md2_info ); 149 #endif 150 #if defined(MBEDTLS_MD4_C) 151 case MBEDTLS_MD_MD4: 152 return( &mbedtls_md4_info ); 153 #endif 154 #if defined(MBEDTLS_MD5_C) 155 case MBEDTLS_MD_MD5: 156 return( &mbedtls_md5_info ); 157 #endif 158 #if defined(MBEDTLS_RIPEMD160_C) 159 case MBEDTLS_MD_RIPEMD160: 160 return( &mbedtls_ripemd160_info ); 161 #endif 162 #if defined(MBEDTLS_SHA1_C) 163 case MBEDTLS_MD_SHA1: 164 return( &mbedtls_sha1_info ); 165 #endif 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 ); 171 #endif 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 ); 177 #endif 178 default: 179 return( NULL ); 180 } 181 } 182 183 void mbedtls_md_init( mbedtls_md_context_t *ctx ) 184 { 185 memset( ctx, 0, sizeof( mbedtls_md_context_t ) ); 186 } 187 188 void mbedtls_md_free( mbedtls_md_context_t *ctx ) 189 { 190 if( ctx == NULL || ctx->md_info == NULL ) 191 return; 192 193 if( ctx->md_ctx != NULL ) 194 ctx->md_info->ctx_free_func( ctx->md_ctx ); 195 196 if( ctx->hmac_ctx != NULL ) 197 { 198 mbedtls_zeroize( ctx->hmac_ctx, 2 * ctx->md_info->block_size ); 199 mbedtls_free( ctx->hmac_ctx ); 200 } 201 202 mbedtls_zeroize( ctx, sizeof( mbedtls_md_context_t ) ); 203 } 204 205 int mbedtls_md_clone( mbedtls_md_context_t *dst, 206 const mbedtls_md_context_t *src ) 207 { 208 if( dst == NULL || dst->md_info == NULL || 209 src == NULL || src->md_info == NULL || 210 dst->md_info != src->md_info ) 211 { 212 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 213 } 214 215 dst->md_info->clone_func( dst->md_ctx, src->md_ctx ); 216 217 return( 0 ); 218 } 219 220 #if ! defined(MBEDTLS_DEPRECATED_REMOVED) 221 int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info ) 222 { 223 return mbedtls_md_setup( ctx, md_info, 1 ); 224 } 225 #endif 226 227 int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac ) 228 { 229 if( md_info == NULL || ctx == NULL ) 230 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 231 232 if( ( ctx->md_ctx = md_info->ctx_alloc_func() ) == NULL ) 233 return( MBEDTLS_ERR_MD_ALLOC_FAILED ); 234 235 if( hmac != 0 ) 236 { 237 ctx->hmac_ctx = mbedtls_calloc( 2, md_info->block_size ); 238 if( ctx->hmac_ctx == NULL ) 239 { 240 md_info->ctx_free_func( ctx->md_ctx ); 241 return( MBEDTLS_ERR_MD_ALLOC_FAILED ); 242 } 243 } 244 245 ctx->md_info = md_info; 246 247 return( 0 ); 248 } 249 250 int mbedtls_md_starts( mbedtls_md_context_t *ctx ) 251 { 252 if( ctx == NULL || ctx->md_info == NULL ) 253 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 254 255 return( ctx->md_info->starts_func( ctx->md_ctx ) ); 256 } 257 258 int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen ) 259 { 260 if( ctx == NULL || ctx->md_info == NULL ) 261 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 262 263 return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) ); 264 } 265 266 int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output ) 267 { 268 if( ctx == NULL || ctx->md_info == NULL ) 269 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 270 271 return( ctx->md_info->finish_func( ctx->md_ctx, output ) ); 272 } 273 274 int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen, 275 unsigned char *output ) 276 { 277 if( md_info == NULL ) 278 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 279 280 return( md_info->digest_func( input, ilen, output ) ); 281 } 282 283 #if defined(MBEDTLS_FS_IO) 284 int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigned char *output ) 285 { 286 int ret; 287 FILE *f; 288 size_t n; 289 mbedtls_md_context_t ctx; 290 unsigned char buf[1024]; 291 292 if( md_info == NULL ) 293 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 294 295 if( ( f = fopen( path, "rb" ) ) == NULL ) 296 return( MBEDTLS_ERR_MD_FILE_IO_ERROR ); 297 298 mbedtls_md_init( &ctx ); 299 300 if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 ) 301 goto cleanup; 302 303 if( ( ret = md_info->starts_func( ctx.md_ctx ) ) != 0 ) 304 goto cleanup; 305 306 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) 307 if( ( ret = md_info->update_func( ctx.md_ctx, buf, n ) ) != 0 ) 308 goto cleanup; 309 310 if( ferror( f ) != 0 ) 311 ret = MBEDTLS_ERR_MD_FILE_IO_ERROR; 312 else 313 ret = md_info->finish_func( ctx.md_ctx, output ); 314 315 cleanup: 316 mbedtls_zeroize( buf, sizeof( buf ) ); 317 fclose( f ); 318 mbedtls_md_free( &ctx ); 319 320 return( ret ); 321 } 322 #endif /* MBEDTLS_FS_IO */ 323 324 int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen ) 325 { 326 int ret; 327 unsigned char sum[MBEDTLS_MD_MAX_SIZE]; 328 unsigned char *ipad, *opad; 329 size_t i; 330 331 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) 332 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 333 334 if( keylen > (size_t) ctx->md_info->block_size ) 335 { 336 if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) 337 goto cleanup; 338 if( ( ret = ctx->md_info->update_func( ctx->md_ctx, key, keylen ) ) != 0 ) 339 goto cleanup; 340 if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, sum ) ) != 0 ) 341 goto cleanup; 342 343 keylen = ctx->md_info->size; 344 key = sum; 345 } 346 347 ipad = (unsigned char *) ctx->hmac_ctx; 348 opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size; 349 350 memset( ipad, 0x36, ctx->md_info->block_size ); 351 memset( opad, 0x5C, ctx->md_info->block_size ); 352 353 for( i = 0; i < keylen; i++ ) 354 { 355 ipad[i] = (unsigned char)( ipad[i] ^ key[i] ); 356 opad[i] = (unsigned char)( opad[i] ^ key[i] ); 357 } 358 359 if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) 360 goto cleanup; 361 if( ( ret = ctx->md_info->update_func( ctx->md_ctx, ipad, 362 ctx->md_info->block_size ) ) != 0 ) 363 goto cleanup; 364 365 cleanup: 366 mbedtls_zeroize( sum, sizeof( sum ) ); 367 368 return( ret ); 369 } 370 371 int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen ) 372 { 373 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) 374 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 375 376 return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) ); 377 } 378 379 int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output ) 380 { 381 int ret; 382 unsigned char tmp[MBEDTLS_MD_MAX_SIZE]; 383 unsigned char *opad; 384 385 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) 386 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 387 388 opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size; 389 390 if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, tmp ) ) != 0 ) 391 return( ret ); 392 if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) 393 return( ret ); 394 if( ( ret = ctx->md_info->update_func( ctx->md_ctx, opad, 395 ctx->md_info->block_size ) ) != 0 ) 396 return( ret ); 397 if( ( ret = ctx->md_info->update_func( ctx->md_ctx, tmp, 398 ctx->md_info->size ) ) != 0 ) 399 return( ret ); 400 return( ctx->md_info->finish_func( ctx->md_ctx, output ) ); 401 } 402 403 int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx ) 404 { 405 int ret; 406 unsigned char *ipad; 407 408 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) 409 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 410 411 ipad = (unsigned char *) ctx->hmac_ctx; 412 413 if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) 414 return( ret ); 415 return( ctx->md_info->update_func( ctx->md_ctx, ipad, 416 ctx->md_info->block_size ) ); 417 } 418 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 ) 423 { 424 mbedtls_md_context_t ctx; 425 int ret; 426 427 if( md_info == NULL ) 428 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 429 430 mbedtls_md_init( &ctx ); 431 432 if( ( ret = mbedtls_md_setup( &ctx, md_info, 1 ) ) != 0 ) 433 goto cleanup; 434 435 if( ( ret = mbedtls_md_hmac_starts( &ctx, key, keylen ) ) != 0 ) 436 goto cleanup; 437 if( ( ret = mbedtls_md_hmac_update( &ctx, input, ilen ) ) != 0 ) 438 goto cleanup; 439 if( ( ret = mbedtls_md_hmac_finish( &ctx, output ) ) != 0 ) 440 goto cleanup; 441 442 cleanup: 443 mbedtls_md_free( &ctx ); 444 445 return( ret ); 446 } 447 448 int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data ) 449 { 450 if( ctx == NULL || ctx->md_info == NULL ) 451 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 452 453 return( ctx->md_info->process_func( ctx->md_ctx, data ) ); 454 } 455 456 unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info ) 457 { 458 if( md_info == NULL ) 459 return( 0 ); 460 461 return md_info->size; 462 } 463 464 mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info ) 465 { 466 if( md_info == NULL ) 467 return( MBEDTLS_MD_NONE ); 468 469 return md_info->type; 470 } 471 472 const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info ) 473 { 474 if( md_info == NULL ) 475 return( NULL ); 476 477 return md_info->name; 478 } 479 480 #endif /* MBEDTLS_MD_C */ 481