Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
md.c
00001 /** 00002 * \file mbedtls_md.c 00003 * 00004 * \brief Generic message digest wrapper for mbed TLS 00005 * 00006 * \author Adriaan de Jong <dejong@fox-it.com> 00007 * 00008 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 00009 * SPDX-License-Identifier: Apache-2.0 00010 * 00011 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00012 * not use this file except in compliance with the License. 00013 * You may obtain a copy of the License at 00014 * 00015 * http://www.apache.org/licenses/LICENSE-2.0 00016 * 00017 * Unless required by applicable law or agreed to in writing, software 00018 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00019 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00020 * See the License for the specific language governing permissions and 00021 * limitations under the License. 00022 * 00023 * This file is part of mbed TLS (https://tls.mbed.org) 00024 */ 00025 00026 #if !defined(MBEDTLS_CONFIG_FILE) 00027 #include "mbedtls/config.h" 00028 #else 00029 #include MBEDTLS_CONFIG_FILE 00030 #endif 00031 00032 #if defined(MBEDTLS_MD_C) 00033 00034 #include "mbedtls/md.h" 00035 #include "mbedtls/md_internal.h" 00036 #include "mbedtls/platform_util.h" 00037 00038 #if defined(MBEDTLS_PLATFORM_C) 00039 #include "mbedtls/platform.h" 00040 #else 00041 #include <stdlib.h> 00042 #define mbedtls_calloc calloc 00043 #define mbedtls_free free 00044 #endif 00045 00046 #include <string.h> 00047 00048 #if defined(MBEDTLS_FS_IO) 00049 #include <stdio.h> 00050 #endif 00051 00052 /* 00053 * Reminder: update profiles in x509_crt.c when adding a new hash! 00054 */ 00055 static const int supported_digests[] = { 00056 00057 #if defined(MBEDTLS_SHA512_C) 00058 MBEDTLS_MD_SHA512, 00059 MBEDTLS_MD_SHA384, 00060 #endif 00061 00062 #if defined(MBEDTLS_SHA256_C) 00063 MBEDTLS_MD_SHA256, 00064 MBEDTLS_MD_SHA224, 00065 #endif 00066 00067 #if defined(MBEDTLS_SHA1_C) 00068 MBEDTLS_MD_SHA1, 00069 #endif 00070 00071 #if defined(MBEDTLS_RIPEMD160_C) 00072 MBEDTLS_MD_RIPEMD160, 00073 #endif 00074 00075 #if defined(MBEDTLS_MD5_C) 00076 MBEDTLS_MD_MD5, 00077 #endif 00078 00079 #if defined(MBEDTLS_MD4_C) 00080 MBEDTLS_MD_MD4, 00081 #endif 00082 00083 #if defined(MBEDTLS_MD2_C) 00084 MBEDTLS_MD_MD2, 00085 #endif 00086 00087 MBEDTLS_MD_NONE 00088 }; 00089 00090 const int *mbedtls_md_list( void ) 00091 { 00092 return( supported_digests ); 00093 } 00094 00095 const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name ) 00096 { 00097 if( NULL == md_name ) 00098 return( NULL ); 00099 00100 /* Get the appropriate digest information */ 00101 #if defined(MBEDTLS_MD2_C) 00102 if( !strcmp( "MD2", md_name ) ) 00103 return mbedtls_md_info_from_type( MBEDTLS_MD_MD2 ); 00104 #endif 00105 #if defined(MBEDTLS_MD4_C) 00106 if( !strcmp( "MD4", md_name ) ) 00107 return mbedtls_md_info_from_type( MBEDTLS_MD_MD4 ); 00108 #endif 00109 #if defined(MBEDTLS_MD5_C) 00110 if( !strcmp( "MD5", md_name ) ) 00111 return mbedtls_md_info_from_type( MBEDTLS_MD_MD5 ); 00112 #endif 00113 #if defined(MBEDTLS_RIPEMD160_C) 00114 if( !strcmp( "RIPEMD160", md_name ) ) 00115 return mbedtls_md_info_from_type( MBEDTLS_MD_RIPEMD160 ); 00116 #endif 00117 #if defined(MBEDTLS_SHA1_C) 00118 if( !strcmp( "SHA1", md_name ) || !strcmp( "SHA", md_name ) ) 00119 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ); 00120 #endif 00121 #if defined(MBEDTLS_SHA256_C) 00122 if( !strcmp( "SHA224", md_name ) ) 00123 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA224 ); 00124 if( !strcmp( "SHA256", md_name ) ) 00125 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ); 00126 #endif 00127 #if defined(MBEDTLS_SHA512_C) 00128 if( !strcmp( "SHA384", md_name ) ) 00129 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA384 ); 00130 if( !strcmp( "SHA512", md_name ) ) 00131 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA512 ); 00132 #endif 00133 return( NULL ); 00134 } 00135 00136 const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type ) 00137 { 00138 switch( md_type ) 00139 { 00140 #if defined(MBEDTLS_MD2_C) 00141 case MBEDTLS_MD_MD2: 00142 return( &mbedtls_md2_info ); 00143 #endif 00144 #if defined(MBEDTLS_MD4_C) 00145 case MBEDTLS_MD_MD4: 00146 return( &mbedtls_md4_info ); 00147 #endif 00148 #if defined(MBEDTLS_MD5_C) 00149 case MBEDTLS_MD_MD5: 00150 return( &mbedtls_md5_info ); 00151 #endif 00152 #if defined(MBEDTLS_RIPEMD160_C) 00153 case MBEDTLS_MD_RIPEMD160: 00154 return( &mbedtls_ripemd160_info ); 00155 #endif 00156 #if defined(MBEDTLS_SHA1_C) 00157 case MBEDTLS_MD_SHA1: 00158 return( &mbedtls_sha1_info ); 00159 #endif 00160 #if defined(MBEDTLS_SHA256_C) 00161 case MBEDTLS_MD_SHA224: 00162 return( &mbedtls_sha224_info ); 00163 case MBEDTLS_MD_SHA256: 00164 return( &mbedtls_sha256_info ); 00165 #endif 00166 #if defined(MBEDTLS_SHA512_C) 00167 case MBEDTLS_MD_SHA384: 00168 return( &mbedtls_sha384_info ); 00169 case MBEDTLS_MD_SHA512: 00170 return( &mbedtls_sha512_info ); 00171 #endif 00172 default: 00173 return( NULL ); 00174 } 00175 } 00176 00177 void mbedtls_md_init( mbedtls_md_context_t *ctx ) 00178 { 00179 memset( ctx, 0, sizeof( mbedtls_md_context_t ) ); 00180 } 00181 00182 void mbedtls_md_free( mbedtls_md_context_t *ctx ) 00183 { 00184 if( ctx == NULL || ctx->md_info == NULL ) 00185 return; 00186 00187 if( ctx->md_ctx != NULL ) 00188 ctx->md_info->ctx_free_func( ctx->md_ctx ); 00189 00190 if( ctx->hmac_ctx != NULL ) 00191 { 00192 mbedtls_platform_zeroize( ctx->hmac_ctx, 00193 2 * ctx->md_info->block_size ); 00194 mbedtls_free( ctx->hmac_ctx ); 00195 } 00196 00197 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md_context_t ) ); 00198 } 00199 00200 int mbedtls_md_clone( mbedtls_md_context_t *dst, 00201 const mbedtls_md_context_t *src ) 00202 { 00203 if( dst == NULL || dst->md_info == NULL || 00204 src == NULL || src->md_info == NULL || 00205 dst->md_info != src->md_info ) 00206 { 00207 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 00208 } 00209 00210 dst->md_info->clone_func( dst->md_ctx, src->md_ctx ); 00211 00212 return( 0 ); 00213 } 00214 00215 #if ! defined(MBEDTLS_DEPRECATED_REMOVED) 00216 int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info ) 00217 { 00218 return mbedtls_md_setup( ctx, md_info, 1 ); 00219 } 00220 #endif 00221 00222 int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac ) 00223 { 00224 if( md_info == NULL || ctx == NULL ) 00225 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 00226 00227 if( ( ctx->md_ctx = md_info->ctx_alloc_func() ) == NULL ) 00228 return( MBEDTLS_ERR_MD_ALLOC_FAILED ); 00229 00230 if( hmac != 0 ) 00231 { 00232 ctx->hmac_ctx = mbedtls_calloc( 2, md_info->block_size ); 00233 if( ctx->hmac_ctx == NULL ) 00234 { 00235 md_info->ctx_free_func( ctx->md_ctx ); 00236 return( MBEDTLS_ERR_MD_ALLOC_FAILED ); 00237 } 00238 } 00239 00240 ctx->md_info = md_info; 00241 00242 return( 0 ); 00243 } 00244 00245 int mbedtls_md_starts( mbedtls_md_context_t *ctx ) 00246 { 00247 if( ctx == NULL || ctx->md_info == NULL ) 00248 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 00249 00250 return( ctx->md_info->starts_func( ctx->md_ctx ) ); 00251 } 00252 00253 int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen ) 00254 { 00255 if( ctx == NULL || ctx->md_info == NULL ) 00256 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 00257 00258 return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) ); 00259 } 00260 00261 int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output ) 00262 { 00263 if( ctx == NULL || ctx->md_info == NULL ) 00264 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 00265 00266 return( ctx->md_info->finish_func( ctx->md_ctx, output ) ); 00267 } 00268 00269 int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen, 00270 unsigned char *output ) 00271 { 00272 if( md_info == NULL ) 00273 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 00274 00275 return( md_info->digest_func( input, ilen, output ) ); 00276 } 00277 00278 #if defined(MBEDTLS_FS_IO) 00279 int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigned char *output ) 00280 { 00281 int ret; 00282 FILE *f; 00283 size_t n; 00284 mbedtls_md_context_t ctx; 00285 unsigned char buf[1024]; 00286 00287 if( md_info == NULL ) 00288 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 00289 00290 if( ( f = fopen( path, "rb" ) ) == NULL ) 00291 return( MBEDTLS_ERR_MD_FILE_IO_ERROR ); 00292 00293 mbedtls_md_init( &ctx ); 00294 00295 if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 ) 00296 goto cleanup; 00297 00298 if( ( ret = md_info->starts_func( ctx.md_ctx ) ) != 0 ) 00299 goto cleanup; 00300 00301 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) 00302 if( ( ret = md_info->update_func( ctx.md_ctx, buf, n ) ) != 0 ) 00303 goto cleanup; 00304 00305 if( ferror( f ) != 0 ) 00306 ret = MBEDTLS_ERR_MD_FILE_IO_ERROR; 00307 else 00308 ret = md_info->finish_func( ctx.md_ctx, output ); 00309 00310 cleanup: 00311 mbedtls_platform_zeroize( buf, sizeof( buf ) ); 00312 fclose( f ); 00313 mbedtls_md_free( &ctx ); 00314 00315 return( ret ); 00316 } 00317 #endif /* MBEDTLS_FS_IO */ 00318 00319 int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen ) 00320 { 00321 int ret; 00322 unsigned char sum[MBEDTLS_MD_MAX_SIZE]; 00323 unsigned char *ipad, *opad; 00324 size_t i; 00325 00326 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) 00327 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 00328 00329 if( keylen > (size_t) ctx->md_info->block_size ) 00330 { 00331 if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) 00332 goto cleanup; 00333 if( ( ret = ctx->md_info->update_func( ctx->md_ctx, key, keylen ) ) != 0 ) 00334 goto cleanup; 00335 if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, sum ) ) != 0 ) 00336 goto cleanup; 00337 00338 keylen = ctx->md_info->size; 00339 key = sum; 00340 } 00341 00342 ipad = (unsigned char *) ctx->hmac_ctx; 00343 opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size; 00344 00345 memset( ipad, 0x36, ctx->md_info->block_size ); 00346 memset( opad, 0x5C, ctx->md_info->block_size ); 00347 00348 for( i = 0; i < keylen; i++ ) 00349 { 00350 ipad[i] = (unsigned char)( ipad[i] ^ key[i] ); 00351 opad[i] = (unsigned char)( opad[i] ^ key[i] ); 00352 } 00353 00354 if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) 00355 goto cleanup; 00356 if( ( ret = ctx->md_info->update_func( ctx->md_ctx, ipad, 00357 ctx->md_info->block_size ) ) != 0 ) 00358 goto cleanup; 00359 00360 cleanup: 00361 mbedtls_platform_zeroize( sum, sizeof( sum ) ); 00362 00363 return( ret ); 00364 } 00365 00366 int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen ) 00367 { 00368 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) 00369 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 00370 00371 return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) ); 00372 } 00373 00374 int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output ) 00375 { 00376 int ret; 00377 unsigned char tmp[MBEDTLS_MD_MAX_SIZE]; 00378 unsigned char *opad; 00379 00380 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) 00381 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 00382 00383 opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size; 00384 00385 if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, tmp ) ) != 0 ) 00386 return( ret ); 00387 if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) 00388 return( ret ); 00389 if( ( ret = ctx->md_info->update_func( ctx->md_ctx, opad, 00390 ctx->md_info->block_size ) ) != 0 ) 00391 return( ret ); 00392 if( ( ret = ctx->md_info->update_func( ctx->md_ctx, tmp, 00393 ctx->md_info->size ) ) != 0 ) 00394 return( ret ); 00395 return( ctx->md_info->finish_func( ctx->md_ctx, output ) ); 00396 } 00397 00398 int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx ) 00399 { 00400 int ret; 00401 unsigned char *ipad; 00402 00403 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) 00404 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 00405 00406 ipad = (unsigned char *) ctx->hmac_ctx; 00407 00408 if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) 00409 return( ret ); 00410 return( ctx->md_info->update_func( ctx->md_ctx, ipad, 00411 ctx->md_info->block_size ) ); 00412 } 00413 00414 int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, 00415 const unsigned char *key, size_t keylen, 00416 const unsigned char *input, size_t ilen, 00417 unsigned char *output ) 00418 { 00419 mbedtls_md_context_t ctx; 00420 int ret; 00421 00422 if( md_info == NULL ) 00423 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 00424 00425 mbedtls_md_init( &ctx ); 00426 00427 if( ( ret = mbedtls_md_setup( &ctx, md_info, 1 ) ) != 0 ) 00428 goto cleanup; 00429 00430 if( ( ret = mbedtls_md_hmac_starts( &ctx, key, keylen ) ) != 0 ) 00431 goto cleanup; 00432 if( ( ret = mbedtls_md_hmac_update( &ctx, input, ilen ) ) != 0 ) 00433 goto cleanup; 00434 if( ( ret = mbedtls_md_hmac_finish( &ctx, output ) ) != 0 ) 00435 goto cleanup; 00436 00437 cleanup: 00438 mbedtls_md_free( &ctx ); 00439 00440 return( ret ); 00441 } 00442 00443 int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data ) 00444 { 00445 if( ctx == NULL || ctx->md_info == NULL ) 00446 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 00447 00448 return( ctx->md_info->process_func( ctx->md_ctx, data ) ); 00449 } 00450 00451 unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info ) 00452 { 00453 if( md_info == NULL ) 00454 return( 0 ); 00455 00456 return md_info->size; 00457 } 00458 00459 mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info ) 00460 { 00461 if( md_info == NULL ) 00462 return( MBEDTLS_MD_NONE ); 00463 00464 return md_info->type; 00465 } 00466 00467 const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info ) 00468 { 00469 if( md_info == NULL ) 00470 return( NULL ); 00471 00472 return md_info->name; 00473 } 00474 00475 #endif /* MBEDTLS_MD_C */
Generated on Tue Jul 12 2022 13:53:25 by
