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