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.
Fork of mbedtls by
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 ctx->md_info->starts_func( ctx->md_ctx ); 00254 00255 return( 0 ); 00256 } 00257 00258 int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen ) 00259 { 00260 if( ctx == NULL || ctx->md_info == NULL ) 00261 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 00262 00263 ctx->md_info->update_func( ctx->md_ctx, input, ilen ); 00264 00265 return( 0 ); 00266 } 00267 00268 int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output ) 00269 { 00270 if( ctx == NULL || ctx->md_info == NULL ) 00271 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 00272 00273 ctx->md_info->finish_func( ctx->md_ctx, output ); 00274 00275 return( 0 ); 00276 } 00277 00278 int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen, 00279 unsigned char *output ) 00280 { 00281 if( md_info == NULL ) 00282 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 00283 00284 md_info->digest_func( input, ilen, output ); 00285 00286 return( 0 ); 00287 } 00288 00289 #if defined(MBEDTLS_FS_IO) 00290 int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigned char *output ) 00291 { 00292 int ret; 00293 FILE *f; 00294 size_t n; 00295 mbedtls_md_context_t ctx; 00296 unsigned char buf[1024]; 00297 00298 if( md_info == NULL ) 00299 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 00300 00301 if( ( f = fopen( path, "rb" ) ) == NULL ) 00302 return( MBEDTLS_ERR_MD_FILE_IO_ERROR ); 00303 00304 mbedtls_md_init( &ctx ); 00305 00306 if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 ) 00307 goto cleanup; 00308 00309 md_info->starts_func( ctx.md_ctx ); 00310 00311 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) 00312 md_info->update_func( ctx.md_ctx, buf, n ); 00313 00314 if( ferror( f ) != 0 ) 00315 { 00316 ret = MBEDTLS_ERR_MD_FILE_IO_ERROR; 00317 goto cleanup; 00318 } 00319 00320 md_info->finish_func( ctx.md_ctx, output ); 00321 00322 cleanup: 00323 fclose( f ); 00324 mbedtls_md_free( &ctx ); 00325 00326 return( ret ); 00327 } 00328 #endif /* MBEDTLS_FS_IO */ 00329 00330 int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen ) 00331 { 00332 unsigned char sum[MBEDTLS_MD_MAX_SIZE]; 00333 unsigned char *ipad, *opad; 00334 size_t i; 00335 00336 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) 00337 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 00338 00339 if( keylen > (size_t) ctx->md_info->block_size ) 00340 { 00341 ctx->md_info->starts_func( ctx->md_ctx ); 00342 ctx->md_info->update_func( ctx->md_ctx, key, keylen ); 00343 ctx->md_info->finish_func( ctx->md_ctx, sum ); 00344 00345 keylen = ctx->md_info->size; 00346 key = sum; 00347 } 00348 00349 ipad = (unsigned char *) ctx->hmac_ctx; 00350 opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size; 00351 00352 memset( ipad, 0x36, ctx->md_info->block_size ); 00353 memset( opad, 0x5C, ctx->md_info->block_size ); 00354 00355 for( i = 0; i < keylen; i++ ) 00356 { 00357 ipad[i] = (unsigned char)( ipad[i] ^ key[i] ); 00358 opad[i] = (unsigned char)( opad[i] ^ key[i] ); 00359 } 00360 00361 mbedtls_zeroize( sum, sizeof( sum ) ); 00362 00363 ctx->md_info->starts_func( ctx->md_ctx ); 00364 ctx->md_info->update_func( ctx->md_ctx, ipad, ctx->md_info->block_size ); 00365 00366 return( 0 ); 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 ctx->md_info->update_func( ctx->md_ctx, input, ilen ); 00375 00376 return( 0 ); 00377 } 00378 00379 int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output ) 00380 { 00381 unsigned char tmp[MBEDTLS_MD_MAX_SIZE]; 00382 unsigned char *opad; 00383 00384 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) 00385 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 00386 00387 opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size; 00388 00389 ctx->md_info->finish_func( ctx->md_ctx, tmp ); 00390 ctx->md_info->starts_func( ctx->md_ctx ); 00391 ctx->md_info->update_func( ctx->md_ctx, opad, ctx->md_info->block_size ); 00392 ctx->md_info->update_func( ctx->md_ctx, tmp, ctx->md_info->size ); 00393 ctx->md_info->finish_func( ctx->md_ctx, output ); 00394 00395 return( 0 ); 00396 } 00397 00398 int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx ) 00399 { 00400 unsigned char *ipad; 00401 00402 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) 00403 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 00404 00405 ipad = (unsigned char *) ctx->hmac_ctx; 00406 00407 ctx->md_info->starts_func( ctx->md_ctx ); 00408 ctx->md_info->update_func( ctx->md_ctx, ipad, ctx->md_info->block_size ); 00409 00410 return( 0 ); 00411 } 00412 00413 int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, const unsigned char *key, size_t keylen, 00414 const unsigned char *input, size_t ilen, 00415 unsigned char *output ) 00416 { 00417 mbedtls_md_context_t ctx; 00418 int ret; 00419 00420 if( md_info == NULL ) 00421 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 00422 00423 mbedtls_md_init( &ctx ); 00424 00425 if( ( ret = mbedtls_md_setup( &ctx, md_info, 1 ) ) != 0 ) 00426 return( ret ); 00427 00428 mbedtls_md_hmac_starts( &ctx, key, keylen ); 00429 mbedtls_md_hmac_update( &ctx, input, ilen ); 00430 mbedtls_md_hmac_finish( &ctx, output ); 00431 00432 mbedtls_md_free( &ctx ); 00433 00434 return( 0 ); 00435 } 00436 00437 int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data ) 00438 { 00439 if( ctx == NULL || ctx->md_info == NULL ) 00440 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 00441 00442 ctx->md_info->process_func( ctx->md_ctx, data ); 00443 00444 return( 0 ); 00445 } 00446 00447 unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info ) 00448 { 00449 if( md_info == NULL ) 00450 return( 0 ); 00451 00452 return md_info->size; 00453 } 00454 00455 mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info ) 00456 { 00457 if( md_info == NULL ) 00458 return( MBEDTLS_MD_NONE ); 00459 00460 return md_info->type; 00461 } 00462 00463 const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info ) 00464 { 00465 if( md_info == NULL ) 00466 return( NULL ); 00467 00468 return md_info->name; 00469 } 00470 00471 #endif /* MBEDTLS_MD_C */
Generated on Tue Jul 12 2022 17:25:42 by
