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 00037 #if defined(MBEDTLS_PLATFORM_C) 00038 #include "mbedtls/platform.h" 00039 #else 00040 #include <stdlib.h> 00041 #define mbedtls_calloc calloc 00042 #define mbedtls_free free 00043 #endif 00044 00045 #include <string.h> 00046 00047 #if defined(MBEDTLS_FS_IO) 00048 #include <stdio.h> 00049 #endif 00050 00051 /* Implementation that should never be optimized out by the compiler */ 00052 static void mbedtls_zeroize( void *v, size_t n ) { 00053 volatile unsigned char *p = v; while( n-- ) *p++ = 0; 00054 } 00055 00056 /* 00057 * Reminder: update profiles in x509_crt.c when adding a new hash! 00058 */ 00059 static const int supported_digests[] = { 00060 00061 #if defined(MBEDTLS_SHA512_C) 00062 MBEDTLS_MD_SHA512, 00063 MBEDTLS_MD_SHA384, 00064 #endif 00065 00066 #if defined(MBEDTLS_SHA256_C) 00067 MBEDTLS_MD_SHA256, 00068 MBEDTLS_MD_SHA224, 00069 #endif 00070 00071 #if defined(MBEDTLS_SHA1_C) 00072 MBEDTLS_MD_SHA1, 00073 #endif 00074 00075 #if defined(MBEDTLS_RIPEMD160_C) 00076 MBEDTLS_MD_RIPEMD160, 00077 #endif 00078 00079 #if defined(MBEDTLS_MD5_C) 00080 MBEDTLS_MD_MD5, 00081 #endif 00082 00083 #if defined(MBEDTLS_MD4_C) 00084 MBEDTLS_MD_MD4, 00085 #endif 00086 00087 #if defined(MBEDTLS_MD2_C) 00088 MBEDTLS_MD_MD2, 00089 #endif 00090 00091 MBEDTLS_MD_NONE 00092 }; 00093 00094 const int *mbedtls_md_list( void ) 00095 { 00096 return( supported_digests ); 00097 } 00098 00099 const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name ) 00100 { 00101 if( NULL == md_name ) 00102 return( NULL ); 00103 00104 /* Get the appropriate digest information */ 00105 #if defined(MBEDTLS_MD2_C) 00106 if( !strcmp( "MD2", md_name ) ) 00107 return mbedtls_md_info_from_type( MBEDTLS_MD_MD2 ); 00108 #endif 00109 #if defined(MBEDTLS_MD4_C) 00110 if( !strcmp( "MD4", md_name ) ) 00111 return mbedtls_md_info_from_type( MBEDTLS_MD_MD4 ); 00112 #endif 00113 #if defined(MBEDTLS_MD5_C) 00114 if( !strcmp( "MD5", md_name ) ) 00115 return mbedtls_md_info_from_type( MBEDTLS_MD_MD5 ); 00116 #endif 00117 #if defined(MBEDTLS_RIPEMD160_C) 00118 if( !strcmp( "RIPEMD160", md_name ) ) 00119 return mbedtls_md_info_from_type( MBEDTLS_MD_RIPEMD160 ); 00120 #endif 00121 #if defined(MBEDTLS_SHA1_C) 00122 if( !strcmp( "SHA1", md_name ) || !strcmp( "SHA", md_name ) ) 00123 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ); 00124 #endif 00125 #if defined(MBEDTLS_SHA256_C) 00126 if( !strcmp( "SHA224", md_name ) ) 00127 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA224 ); 00128 if( !strcmp( "SHA256", md_name ) ) 00129 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ); 00130 #endif 00131 #if defined(MBEDTLS_SHA512_C) 00132 if( !strcmp( "SHA384", md_name ) ) 00133 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA384 ); 00134 if( !strcmp( "SHA512", md_name ) ) 00135 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA512 ); 00136 #endif 00137 return( NULL ); 00138 } 00139 00140 const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type ) 00141 { 00142 switch( md_type ) 00143 { 00144 #if defined(MBEDTLS_MD2_C) 00145 case MBEDTLS_MD_MD2: 00146 return( &mbedtls_md2_info ); 00147 #endif 00148 #if defined(MBEDTLS_MD4_C) 00149 case MBEDTLS_MD_MD4: 00150 return( &mbedtls_md4_info ); 00151 #endif 00152 #if defined(MBEDTLS_MD5_C) 00153 case MBEDTLS_MD_MD5: 00154 return( &mbedtls_md5_info ); 00155 #endif 00156 #if defined(MBEDTLS_RIPEMD160_C) 00157 case MBEDTLS_MD_RIPEMD160: 00158 return( &mbedtls_ripemd160_info ); 00159 #endif 00160 #if defined(MBEDTLS_SHA1_C) 00161 case MBEDTLS_MD_SHA1: 00162 return( &mbedtls_sha1_info ); 00163 #endif 00164 #if defined(MBEDTLS_SHA256_C) 00165 case MBEDTLS_MD_SHA224: 00166 return( &mbedtls_sha224_info ); 00167 case MBEDTLS_MD_SHA256: 00168 return( &mbedtls_sha256_info ); 00169 #endif 00170 #if defined(MBEDTLS_SHA512_C) 00171 case MBEDTLS_MD_SHA384: 00172 return( &mbedtls_sha384_info ); 00173 case MBEDTLS_MD_SHA512: 00174 return( &mbedtls_sha512_info ); 00175 #endif 00176 default: 00177 return( NULL ); 00178 } 00179 } 00180 00181 void mbedtls_md_init( mbedtls_md_context_t *ctx ) 00182 { 00183 memset( ctx, 0, sizeof( mbedtls_md_context_t ) ); 00184 } 00185 00186 void mbedtls_md_free( mbedtls_md_context_t *ctx ) 00187 { 00188 if( ctx == NULL || ctx->md_info == NULL ) 00189 return; 00190 00191 if( ctx->md_ctx != NULL ) 00192 ctx->md_info->ctx_free_func( ctx->md_ctx ); 00193 00194 if( ctx->hmac_ctx != NULL ) 00195 { 00196 mbedtls_zeroize( ctx->hmac_ctx, 2 * ctx->md_info->block_size ); 00197 mbedtls_free( ctx->hmac_ctx ); 00198 } 00199 00200 mbedtls_zeroize( ctx, sizeof( mbedtls_md_context_t ) ); 00201 } 00202 00203 int mbedtls_md_clone( mbedtls_md_context_t *dst, 00204 const mbedtls_md_context_t *src ) 00205 { 00206 if( dst == NULL || dst->md_info == NULL || 00207 src == NULL || src->md_info == NULL || 00208 dst->md_info != src->md_info ) 00209 { 00210 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 00211 } 00212 00213 dst->md_info->clone_func( dst->md_ctx, src->md_ctx ); 00214 00215 return( 0 ); 00216 } 00217 00218 #if ! defined(MBEDTLS_DEPRECATED_REMOVED) 00219 int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info ) 00220 { 00221 return mbedtls_md_setup( ctx, md_info, 1 ); 00222 } 00223 #endif 00224 00225 int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac ) 00226 { 00227 if( md_info == NULL || ctx == NULL ) 00228 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 00229 00230 if( ( ctx->md_ctx = md_info->ctx_alloc_func() ) == NULL ) 00231 return( MBEDTLS_ERR_MD_ALLOC_FAILED ); 00232 00233 if( hmac != 0 ) 00234 { 00235 ctx->hmac_ctx = mbedtls_calloc( 2, md_info->block_size ); 00236 if( ctx->hmac_ctx == NULL ) 00237 { 00238 md_info->ctx_free_func( ctx->md_ctx ); 00239 return( MBEDTLS_ERR_MD_ALLOC_FAILED ); 00240 } 00241 } 00242 00243 ctx->md_info = md_info; 00244 00245 return( 0 ); 00246 } 00247 00248 int mbedtls_md_starts( mbedtls_md_context_t *ctx ) 00249 { 00250 if( ctx == NULL || ctx->md_info == NULL ) 00251 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 00252 00253 return( ctx->md_info->starts_func( ctx->md_ctx ) ); 00254 } 00255 00256 int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen ) 00257 { 00258 if( ctx == NULL || ctx->md_info == NULL ) 00259 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 00260 00261 return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) ); 00262 } 00263 00264 int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output ) 00265 { 00266 if( ctx == NULL || ctx->md_info == NULL ) 00267 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 00268 00269 return( ctx->md_info->finish_func( ctx->md_ctx, output ) ); 00270 } 00271 00272 int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen, 00273 unsigned char *output ) 00274 { 00275 if( md_info == NULL ) 00276 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 00277 00278 return( md_info->digest_func( input, ilen, output ) ); 00279 } 00280 00281 #if defined(MBEDTLS_FS_IO) 00282 int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigned char *output ) 00283 { 00284 int ret; 00285 FILE *f; 00286 size_t n; 00287 mbedtls_md_context_t ctx; 00288 unsigned char buf[1024]; 00289 00290 if( md_info == NULL ) 00291 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 00292 00293 if( ( f = fopen( path, "rb" ) ) == NULL ) 00294 return( MBEDTLS_ERR_MD_FILE_IO_ERROR ); 00295 00296 mbedtls_md_init( &ctx ); 00297 00298 if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 ) 00299 goto cleanup; 00300 00301 if( ( ret = md_info->starts_func( ctx.md_ctx ) ) != 0 ) 00302 goto cleanup; 00303 00304 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) 00305 if( ( ret = md_info->update_func( ctx.md_ctx, buf, n ) ) != 0 ) 00306 goto cleanup; 00307 00308 if( ferror( f ) != 0 ) 00309 ret = MBEDTLS_ERR_MD_FILE_IO_ERROR; 00310 else 00311 ret = md_info->finish_func( ctx.md_ctx, output ); 00312 00313 cleanup: 00314 mbedtls_zeroize( buf, sizeof( buf ) ); 00315 fclose( f ); 00316 mbedtls_md_free( &ctx ); 00317 00318 return( ret ); 00319 } 00320 #endif /* MBEDTLS_FS_IO */ 00321 00322 int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen ) 00323 { 00324 int ret; 00325 unsigned char sum[MBEDTLS_MD_MAX_SIZE]; 00326 unsigned char *ipad, *opad; 00327 size_t i; 00328 00329 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) 00330 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 00331 00332 if( keylen > (size_t) ctx->md_info->block_size ) 00333 { 00334 if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) 00335 goto cleanup; 00336 if( ( ret = ctx->md_info->update_func( ctx->md_ctx, key, keylen ) ) != 0 ) 00337 goto cleanup; 00338 if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, sum ) ) != 0 ) 00339 goto cleanup; 00340 00341 keylen = ctx->md_info->size; 00342 key = sum; 00343 } 00344 00345 ipad = (unsigned char *) ctx->hmac_ctx; 00346 opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size; 00347 00348 memset( ipad, 0x36, ctx->md_info->block_size ); 00349 memset( opad, 0x5C, ctx->md_info->block_size ); 00350 00351 for( i = 0; i < keylen; i++ ) 00352 { 00353 ipad[i] = (unsigned char)( ipad[i] ^ key[i] ); 00354 opad[i] = (unsigned char)( opad[i] ^ key[i] ); 00355 } 00356 00357 if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) 00358 goto cleanup; 00359 if( ( ret = ctx->md_info->update_func( ctx->md_ctx, ipad, 00360 ctx->md_info->block_size ) ) != 0 ) 00361 goto cleanup; 00362 00363 cleanup: 00364 mbedtls_zeroize( sum, sizeof( sum ) ); 00365 00366 return( ret ); 00367 } 00368 00369 int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen ) 00370 { 00371 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) 00372 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 00373 00374 return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) ); 00375 } 00376 00377 int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output ) 00378 { 00379 int ret; 00380 unsigned char tmp[MBEDTLS_MD_MAX_SIZE]; 00381 unsigned char *opad; 00382 00383 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) 00384 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 00385 00386 opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size; 00387 00388 if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, tmp ) ) != 0 ) 00389 return( ret ); 00390 if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) 00391 return( ret ); 00392 if( ( ret = ctx->md_info->update_func( ctx->md_ctx, opad, 00393 ctx->md_info->block_size ) ) != 0 ) 00394 return( ret ); 00395 if( ( ret = ctx->md_info->update_func( ctx->md_ctx, tmp, 00396 ctx->md_info->size ) ) != 0 ) 00397 return( ret ); 00398 return( ctx->md_info->finish_func( ctx->md_ctx, output ) ); 00399 } 00400 00401 int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx ) 00402 { 00403 int ret; 00404 unsigned char *ipad; 00405 00406 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) 00407 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 00408 00409 ipad = (unsigned char *) ctx->hmac_ctx; 00410 00411 if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) 00412 return( ret ); 00413 return( ctx->md_info->update_func( ctx->md_ctx, ipad, 00414 ctx->md_info->block_size ) ); 00415 } 00416 00417 int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, 00418 const unsigned char *key, size_t keylen, 00419 const unsigned char *input, size_t ilen, 00420 unsigned char *output ) 00421 { 00422 mbedtls_md_context_t ctx; 00423 int ret; 00424 00425 if( md_info == NULL ) 00426 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 00427 00428 mbedtls_md_init( &ctx ); 00429 00430 if( ( ret = mbedtls_md_setup( &ctx, md_info, 1 ) ) != 0 ) 00431 goto cleanup; 00432 00433 if( ( ret = mbedtls_md_hmac_starts( &ctx, key, keylen ) ) != 0 ) 00434 goto cleanup; 00435 if( ( ret = mbedtls_md_hmac_update( &ctx, input, ilen ) ) != 0 ) 00436 goto cleanup; 00437 if( ( ret = mbedtls_md_hmac_finish( &ctx, output ) ) != 0 ) 00438 goto cleanup; 00439 00440 cleanup: 00441 mbedtls_md_free( &ctx ); 00442 00443 return( ret ); 00444 } 00445 00446 int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data ) 00447 { 00448 if( ctx == NULL || ctx->md_info == NULL ) 00449 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 00450 00451 return( ctx->md_info->process_func( ctx->md_ctx, data ) ); 00452 } 00453 00454 unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info ) 00455 { 00456 if( md_info == NULL ) 00457 return( 0 ); 00458 00459 return md_info->size; 00460 } 00461 00462 mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info ) 00463 { 00464 if( md_info == NULL ) 00465 return( MBEDTLS_MD_NONE ); 00466 00467 return md_info->type; 00468 } 00469 00470 const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info ) 00471 { 00472 if( md_info == NULL ) 00473 return( NULL ); 00474 00475 return md_info->name; 00476 } 00477 00478 #endif /* MBEDTLS_MD_C */
Generated on Tue Jul 12 2022 18:18:43 by
