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 The Mbed TLS Contributors 9 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 10 * 11 * This file is provided under the Apache License 2.0, or the 12 * GNU General Public License v2.0 or later. 13 * 14 * ********** 15 * Apache License 2.0: 16 * 17 * Licensed under the Apache License, Version 2.0 (the "License"); you may 18 * not use this file except in compliance with the License. 19 * You may obtain a copy of the License at 20 * 21 * http://www.apache.org/licenses/LICENSE-2.0 22 * 23 * Unless required by applicable law or agreed to in writing, software 24 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 25 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 26 * See the License for the specific language governing permissions and 27 * limitations under the License. 28 * 29 * ********** 30 * 31 * ********** 32 * GNU General Public License v2.0 or later: 33 * 34 * This program is free software; you can redistribute it and/or modify 35 * it under the terms of the GNU General Public License as published by 36 * the Free Software Foundation; either version 2 of the License, or 37 * (at your option) any later version. 38 * 39 * This program is distributed in the hope that it will be useful, 40 * but WITHOUT ANY WARRANTY; without even the implied warranty of 41 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 42 * GNU General Public License for more details. 43 * 44 * You should have received a copy of the GNU General Public License along 45 * with this program; if not, write to the Free Software Foundation, Inc., 46 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 47 * 48 * ********** 49 */ 50 51 #if !defined(MBEDTLS_CONFIG_FILE) 52 #include "mbedtls/config.h" 53 #else 54 #include MBEDTLS_CONFIG_FILE 55 #endif 56 57 #if defined(MBEDTLS_MD_C) 58 59 #include "mbedtls/md.h" 60 #include "mbedtls/md_internal.h" 61 #include "mbedtls/platform_util.h" 62 63 #if defined(MBEDTLS_PLATFORM_C) 64 #include "mbedtls/platform.h" 65 #else 66 #include <stdlib.h> 67 #define mbedtls_calloc calloc 68 #define mbedtls_free free 69 #endif 70 71 #include <string.h> 72 73 #if defined(MBEDTLS_FS_IO) 74 #include <stdio.h> 75 #endif 76 77 /* 78 * Reminder: update profiles in x509_crt.c when adding a new hash! 79 */ 80 static const int supported_digests[] = { 81 82 #if defined(MBEDTLS_SHA512_C) 83 MBEDTLS_MD_SHA512, 84 MBEDTLS_MD_SHA384, 85 #endif 86 87 #if defined(MBEDTLS_SHA256_C) 88 MBEDTLS_MD_SHA256, 89 MBEDTLS_MD_SHA224, 90 #endif 91 92 #if defined(MBEDTLS_SHA1_C) 93 MBEDTLS_MD_SHA1, 94 #endif 95 96 #if defined(MBEDTLS_RIPEMD160_C) 97 MBEDTLS_MD_RIPEMD160, 98 #endif 99 100 #if defined(MBEDTLS_MD5_C) 101 MBEDTLS_MD_MD5, 102 #endif 103 104 #if defined(MBEDTLS_MD4_C) 105 MBEDTLS_MD_MD4, 106 #endif 107 108 #if defined(MBEDTLS_MD2_C) 109 MBEDTLS_MD_MD2, 110 #endif 111 112 MBEDTLS_MD_NONE 113 }; 114 115 const int *mbedtls_md_list( void ) 116 { 117 return( supported_digests ); 118 } 119 120 const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name ) 121 { 122 if( NULL == md_name ) 123 return( NULL ); 124 125 /* Get the appropriate digest information */ 126 #if defined(MBEDTLS_MD2_C) 127 if( !strcmp( "MD2", md_name ) ) 128 return mbedtls_md_info_from_type( MBEDTLS_MD_MD2 ); 129 #endif 130 #if defined(MBEDTLS_MD4_C) 131 if( !strcmp( "MD4", md_name ) ) 132 return mbedtls_md_info_from_type( MBEDTLS_MD_MD4 ); 133 #endif 134 #if defined(MBEDTLS_MD5_C) 135 if( !strcmp( "MD5", md_name ) ) 136 return mbedtls_md_info_from_type( MBEDTLS_MD_MD5 ); 137 #endif 138 #if defined(MBEDTLS_RIPEMD160_C) 139 if( !strcmp( "RIPEMD160", md_name ) ) 140 return mbedtls_md_info_from_type( MBEDTLS_MD_RIPEMD160 ); 141 #endif 142 #if defined(MBEDTLS_SHA1_C) 143 if( !strcmp( "SHA1", md_name ) || !strcmp( "SHA", md_name ) ) 144 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ); 145 #endif 146 #if defined(MBEDTLS_SHA256_C) 147 if( !strcmp( "SHA224", md_name ) ) 148 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA224 ); 149 if( !strcmp( "SHA256", md_name ) ) 150 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ); 151 #endif 152 #if defined(MBEDTLS_SHA512_C) 153 if( !strcmp( "SHA384", md_name ) ) 154 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA384 ); 155 if( !strcmp( "SHA512", md_name ) ) 156 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA512 ); 157 #endif 158 return( NULL ); 159 } 160 161 const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type ) 162 { 163 switch( md_type ) 164 { 165 #if defined(MBEDTLS_MD2_C) 166 case MBEDTLS_MD_MD2: 167 return( &mbedtls_md2_info ); 168 #endif 169 #if defined(MBEDTLS_MD4_C) 170 case MBEDTLS_MD_MD4: 171 return( &mbedtls_md4_info ); 172 #endif 173 #if defined(MBEDTLS_MD5_C) 174 case MBEDTLS_MD_MD5: 175 return( &mbedtls_md5_info ); 176 #endif 177 #if defined(MBEDTLS_RIPEMD160_C) 178 case MBEDTLS_MD_RIPEMD160: 179 return( &mbedtls_ripemd160_info ); 180 #endif 181 #if defined(MBEDTLS_SHA1_C) 182 case MBEDTLS_MD_SHA1: 183 return( &mbedtls_sha1_info ); 184 #endif 185 #if defined(MBEDTLS_SHA256_C) 186 case MBEDTLS_MD_SHA224: 187 return( &mbedtls_sha224_info ); 188 case MBEDTLS_MD_SHA256: 189 return( &mbedtls_sha256_info ); 190 #endif 191 #if defined(MBEDTLS_SHA512_C) 192 case MBEDTLS_MD_SHA384: 193 return( &mbedtls_sha384_info ); 194 case MBEDTLS_MD_SHA512: 195 return( &mbedtls_sha512_info ); 196 #endif 197 default: 198 return( NULL ); 199 } 200 } 201 202 void mbedtls_md_init( mbedtls_md_context_t *ctx ) 203 { 204 memset( ctx, 0, sizeof( mbedtls_md_context_t ) ); 205 } 206 207 void mbedtls_md_free( mbedtls_md_context_t *ctx ) 208 { 209 if( ctx == NULL || ctx->md_info == NULL ) 210 return; 211 212 if( ctx->md_ctx != NULL ) 213 ctx->md_info->ctx_free_func( ctx->md_ctx ); 214 215 if( ctx->hmac_ctx != NULL ) 216 { 217 mbedtls_platform_zeroize( ctx->hmac_ctx, 218 2 * ctx->md_info->block_size ); 219 mbedtls_free( ctx->hmac_ctx ); 220 } 221 222 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md_context_t ) ); 223 } 224 225 int mbedtls_md_clone( mbedtls_md_context_t *dst, 226 const mbedtls_md_context_t *src ) 227 { 228 if( dst == NULL || dst->md_info == NULL || 229 src == NULL || src->md_info == NULL || 230 dst->md_info != src->md_info ) 231 { 232 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 233 } 234 235 dst->md_info->clone_func( dst->md_ctx, src->md_ctx ); 236 237 return( 0 ); 238 } 239 240 #if ! defined(MBEDTLS_DEPRECATED_REMOVED) 241 int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info ) 242 { 243 return mbedtls_md_setup( ctx, md_info, 1 ); 244 } 245 #endif 246 247 int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac ) 248 { 249 if( md_info == NULL || ctx == NULL ) 250 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 251 252 if( ( ctx->md_ctx = md_info->ctx_alloc_func() ) == NULL ) 253 return( MBEDTLS_ERR_MD_ALLOC_FAILED ); 254 255 if( hmac != 0 ) 256 { 257 ctx->hmac_ctx = mbedtls_calloc( 2, md_info->block_size ); 258 if( ctx->hmac_ctx == NULL ) 259 { 260 md_info->ctx_free_func( ctx->md_ctx ); 261 return( MBEDTLS_ERR_MD_ALLOC_FAILED ); 262 } 263 } 264 265 ctx->md_info = md_info; 266 267 return( 0 ); 268 } 269 270 int mbedtls_md_starts( mbedtls_md_context_t *ctx ) 271 { 272 if( ctx == NULL || ctx->md_info == NULL ) 273 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 274 275 return( ctx->md_info->starts_func( ctx->md_ctx ) ); 276 } 277 278 int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen ) 279 { 280 if( ctx == NULL || ctx->md_info == NULL ) 281 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 282 283 return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) ); 284 } 285 286 int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output ) 287 { 288 if( ctx == NULL || ctx->md_info == NULL ) 289 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 290 291 return( ctx->md_info->finish_func( ctx->md_ctx, output ) ); 292 } 293 294 int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen, 295 unsigned char *output ) 296 { 297 if( md_info == NULL ) 298 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 299 300 return( md_info->digest_func( input, ilen, output ) ); 301 } 302 303 #if defined(MBEDTLS_FS_IO) 304 int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigned char *output ) 305 { 306 int ret; 307 FILE *f; 308 size_t n; 309 mbedtls_md_context_t ctx; 310 unsigned char buf[1024]; 311 312 if( md_info == NULL ) 313 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 314 315 if( ( f = fopen( path, "rb" ) ) == NULL ) 316 return( MBEDTLS_ERR_MD_FILE_IO_ERROR ); 317 318 mbedtls_md_init( &ctx ); 319 320 if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 ) 321 goto cleanup; 322 323 if( ( ret = md_info->starts_func( ctx.md_ctx ) ) != 0 ) 324 goto cleanup; 325 326 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) 327 if( ( ret = md_info->update_func( ctx.md_ctx, buf, n ) ) != 0 ) 328 goto cleanup; 329 330 if( ferror( f ) != 0 ) 331 ret = MBEDTLS_ERR_MD_FILE_IO_ERROR; 332 else 333 ret = md_info->finish_func( ctx.md_ctx, output ); 334 335 cleanup: 336 mbedtls_platform_zeroize( buf, sizeof( buf ) ); 337 fclose( f ); 338 mbedtls_md_free( &ctx ); 339 340 return( ret ); 341 } 342 #endif /* MBEDTLS_FS_IO */ 343 344 int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen ) 345 { 346 int ret; 347 unsigned char sum[MBEDTLS_MD_MAX_SIZE]; 348 unsigned char *ipad, *opad; 349 size_t i; 350 351 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) 352 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 353 354 if( keylen > (size_t) ctx->md_info->block_size ) 355 { 356 if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) 357 goto cleanup; 358 if( ( ret = ctx->md_info->update_func( ctx->md_ctx, key, keylen ) ) != 0 ) 359 goto cleanup; 360 if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, sum ) ) != 0 ) 361 goto cleanup; 362 363 keylen = ctx->md_info->size; 364 key = sum; 365 } 366 367 ipad = (unsigned char *) ctx->hmac_ctx; 368 opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size; 369 370 memset( ipad, 0x36, ctx->md_info->block_size ); 371 memset( opad, 0x5C, ctx->md_info->block_size ); 372 373 for( i = 0; i < keylen; i++ ) 374 { 375 ipad[i] = (unsigned char)( ipad[i] ^ key[i] ); 376 opad[i] = (unsigned char)( opad[i] ^ key[i] ); 377 } 378 379 if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) 380 goto cleanup; 381 if( ( ret = ctx->md_info->update_func( ctx->md_ctx, ipad, 382 ctx->md_info->block_size ) ) != 0 ) 383 goto cleanup; 384 385 cleanup: 386 mbedtls_platform_zeroize( sum, sizeof( sum ) ); 387 388 return( ret ); 389 } 390 391 int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen ) 392 { 393 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) 394 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 395 396 return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) ); 397 } 398 399 int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output ) 400 { 401 int ret; 402 unsigned char tmp[MBEDTLS_MD_MAX_SIZE]; 403 unsigned char *opad; 404 405 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) 406 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 407 408 opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size; 409 410 if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, tmp ) ) != 0 ) 411 return( ret ); 412 if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) 413 return( ret ); 414 if( ( ret = ctx->md_info->update_func( ctx->md_ctx, opad, 415 ctx->md_info->block_size ) ) != 0 ) 416 return( ret ); 417 if( ( ret = ctx->md_info->update_func( ctx->md_ctx, tmp, 418 ctx->md_info->size ) ) != 0 ) 419 return( ret ); 420 return( ctx->md_info->finish_func( ctx->md_ctx, output ) ); 421 } 422 423 int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx ) 424 { 425 int ret; 426 unsigned char *ipad; 427 428 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) 429 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 430 431 ipad = (unsigned char *) ctx->hmac_ctx; 432 433 if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) 434 return( ret ); 435 return( ctx->md_info->update_func( ctx->md_ctx, ipad, 436 ctx->md_info->block_size ) ); 437 } 438 439 int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, 440 const unsigned char *key, size_t keylen, 441 const unsigned char *input, size_t ilen, 442 unsigned char *output ) 443 { 444 mbedtls_md_context_t ctx; 445 int ret; 446 447 if( md_info == NULL ) 448 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 449 450 mbedtls_md_init( &ctx ); 451 452 if( ( ret = mbedtls_md_setup( &ctx, md_info, 1 ) ) != 0 ) 453 goto cleanup; 454 455 if( ( ret = mbedtls_md_hmac_starts( &ctx, key, keylen ) ) != 0 ) 456 goto cleanup; 457 if( ( ret = mbedtls_md_hmac_update( &ctx, input, ilen ) ) != 0 ) 458 goto cleanup; 459 if( ( ret = mbedtls_md_hmac_finish( &ctx, output ) ) != 0 ) 460 goto cleanup; 461 462 cleanup: 463 mbedtls_md_free( &ctx ); 464 465 return( ret ); 466 } 467 468 int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data ) 469 { 470 if( ctx == NULL || ctx->md_info == NULL ) 471 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 472 473 return( ctx->md_info->process_func( ctx->md_ctx, data ) ); 474 } 475 476 unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info ) 477 { 478 if( md_info == NULL ) 479 return( 0 ); 480 481 return md_info->size; 482 } 483 484 mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info ) 485 { 486 if( md_info == NULL ) 487 return( MBEDTLS_MD_NONE ); 488 489 return md_info->type; 490 } 491 492 const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info ) 493 { 494 if( md_info == NULL ) 495 return( NULL ); 496 497 return md_info->name; 498 } 499 500 #endif /* MBEDTLS_MD_C */ 501