1c6672fdcSEdison Ai // SPDX-License-Identifier: Apache-2.0 2817466cbSJens Wiklander /** 3817466cbSJens Wiklander * \file mbedtls_md.c 4817466cbSJens Wiklander * 5817466cbSJens Wiklander * \brief Generic message digest wrapper for mbed TLS 6817466cbSJens Wiklander * 7817466cbSJens Wiklander * \author Adriaan de Jong <dejong@fox-it.com> 8817466cbSJens Wiklander * 9817466cbSJens Wiklander * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 10817466cbSJens Wiklander * 11817466cbSJens Wiklander * Licensed under the Apache License, Version 2.0 (the "License"); you may 12817466cbSJens Wiklander * not use this file except in compliance with the License. 13817466cbSJens Wiklander * You may obtain a copy of the License at 14817466cbSJens Wiklander * 15817466cbSJens Wiklander * http://www.apache.org/licenses/LICENSE-2.0 16817466cbSJens Wiklander * 17817466cbSJens Wiklander * Unless required by applicable law or agreed to in writing, software 18817466cbSJens Wiklander * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 19817466cbSJens Wiklander * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20817466cbSJens Wiklander * See the License for the specific language governing permissions and 21817466cbSJens Wiklander * limitations under the License. 22817466cbSJens Wiklander * 23817466cbSJens Wiklander * This file is part of mbed TLS (https://tls.mbed.org) 24817466cbSJens Wiklander */ 25817466cbSJens Wiklander 26817466cbSJens Wiklander #if !defined(MBEDTLS_CONFIG_FILE) 27817466cbSJens Wiklander #include "mbedtls/config.h" 28817466cbSJens Wiklander #else 29817466cbSJens Wiklander #include MBEDTLS_CONFIG_FILE 30817466cbSJens Wiklander #endif 31817466cbSJens Wiklander 32817466cbSJens Wiklander #if defined(MBEDTLS_MD_C) 33817466cbSJens Wiklander 34817466cbSJens Wiklander #include "mbedtls/md.h" 35817466cbSJens Wiklander #include "mbedtls/md_internal.h" 363d3b0591SJens Wiklander #include "mbedtls/platform_util.h" 37817466cbSJens Wiklander 38817466cbSJens Wiklander #if defined(MBEDTLS_PLATFORM_C) 39817466cbSJens Wiklander #include "mbedtls/platform.h" 40817466cbSJens Wiklander #else 41817466cbSJens Wiklander #include <stdlib.h> 42817466cbSJens Wiklander #define mbedtls_calloc calloc 43817466cbSJens Wiklander #define mbedtls_free free 44817466cbSJens Wiklander #endif 45817466cbSJens Wiklander 46817466cbSJens Wiklander #include <string.h> 47817466cbSJens Wiklander 48817466cbSJens Wiklander #if defined(MBEDTLS_FS_IO) 49817466cbSJens Wiklander #include <stdio.h> 50817466cbSJens Wiklander #endif 51817466cbSJens Wiklander 52817466cbSJens Wiklander /* 53817466cbSJens Wiklander * Reminder: update profiles in x509_crt.c when adding a new hash! 54817466cbSJens Wiklander */ 55817466cbSJens Wiklander static const int supported_digests[] = { 56817466cbSJens Wiklander 57817466cbSJens Wiklander #if defined(MBEDTLS_SHA512_C) 58817466cbSJens Wiklander MBEDTLS_MD_SHA512, 59817466cbSJens Wiklander MBEDTLS_MD_SHA384, 60817466cbSJens Wiklander #endif 61817466cbSJens Wiklander 62817466cbSJens Wiklander #if defined(MBEDTLS_SHA256_C) 63817466cbSJens Wiklander MBEDTLS_MD_SHA256, 64817466cbSJens Wiklander MBEDTLS_MD_SHA224, 65817466cbSJens Wiklander #endif 66817466cbSJens Wiklander 67817466cbSJens Wiklander #if defined(MBEDTLS_SHA1_C) 68817466cbSJens Wiklander MBEDTLS_MD_SHA1, 69817466cbSJens Wiklander #endif 70817466cbSJens Wiklander 71817466cbSJens Wiklander #if defined(MBEDTLS_RIPEMD160_C) 72817466cbSJens Wiklander MBEDTLS_MD_RIPEMD160, 73817466cbSJens Wiklander #endif 74817466cbSJens Wiklander 75817466cbSJens Wiklander #if defined(MBEDTLS_MD5_C) 76817466cbSJens Wiklander MBEDTLS_MD_MD5, 77817466cbSJens Wiklander #endif 78817466cbSJens Wiklander 79817466cbSJens Wiklander #if defined(MBEDTLS_MD4_C) 80817466cbSJens Wiklander MBEDTLS_MD_MD4, 81817466cbSJens Wiklander #endif 82817466cbSJens Wiklander 83817466cbSJens Wiklander #if defined(MBEDTLS_MD2_C) 84817466cbSJens Wiklander MBEDTLS_MD_MD2, 85817466cbSJens Wiklander #endif 86817466cbSJens Wiklander 87817466cbSJens Wiklander MBEDTLS_MD_NONE 88817466cbSJens Wiklander }; 89817466cbSJens Wiklander 90817466cbSJens Wiklander const int *mbedtls_md_list( void ) 91817466cbSJens Wiklander { 92817466cbSJens Wiklander return( supported_digests ); 93817466cbSJens Wiklander } 94817466cbSJens Wiklander 95817466cbSJens Wiklander const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name ) 96817466cbSJens Wiklander { 97817466cbSJens Wiklander if( NULL == md_name ) 98817466cbSJens Wiklander return( NULL ); 99817466cbSJens Wiklander 100817466cbSJens Wiklander /* Get the appropriate digest information */ 101817466cbSJens Wiklander #if defined(MBEDTLS_MD2_C) 102817466cbSJens Wiklander if( !strcmp( "MD2", md_name ) ) 103817466cbSJens Wiklander return mbedtls_md_info_from_type( MBEDTLS_MD_MD2 ); 104817466cbSJens Wiklander #endif 105817466cbSJens Wiklander #if defined(MBEDTLS_MD4_C) 106817466cbSJens Wiklander if( !strcmp( "MD4", md_name ) ) 107817466cbSJens Wiklander return mbedtls_md_info_from_type( MBEDTLS_MD_MD4 ); 108817466cbSJens Wiklander #endif 109817466cbSJens Wiklander #if defined(MBEDTLS_MD5_C) 110817466cbSJens Wiklander if( !strcmp( "MD5", md_name ) ) 111817466cbSJens Wiklander return mbedtls_md_info_from_type( MBEDTLS_MD_MD5 ); 112817466cbSJens Wiklander #endif 113817466cbSJens Wiklander #if defined(MBEDTLS_RIPEMD160_C) 114817466cbSJens Wiklander if( !strcmp( "RIPEMD160", md_name ) ) 115817466cbSJens Wiklander return mbedtls_md_info_from_type( MBEDTLS_MD_RIPEMD160 ); 116817466cbSJens Wiklander #endif 117817466cbSJens Wiklander #if defined(MBEDTLS_SHA1_C) 118817466cbSJens Wiklander if( !strcmp( "SHA1", md_name ) || !strcmp( "SHA", md_name ) ) 119817466cbSJens Wiklander return mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ); 120817466cbSJens Wiklander #endif 121817466cbSJens Wiklander #if defined(MBEDTLS_SHA256_C) 122817466cbSJens Wiklander if( !strcmp( "SHA224", md_name ) ) 123817466cbSJens Wiklander return mbedtls_md_info_from_type( MBEDTLS_MD_SHA224 ); 124817466cbSJens Wiklander if( !strcmp( "SHA256", md_name ) ) 125817466cbSJens Wiklander return mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ); 126817466cbSJens Wiklander #endif 127817466cbSJens Wiklander #if defined(MBEDTLS_SHA512_C) 128817466cbSJens Wiklander if( !strcmp( "SHA384", md_name ) ) 129817466cbSJens Wiklander return mbedtls_md_info_from_type( MBEDTLS_MD_SHA384 ); 130817466cbSJens Wiklander if( !strcmp( "SHA512", md_name ) ) 131817466cbSJens Wiklander return mbedtls_md_info_from_type( MBEDTLS_MD_SHA512 ); 132817466cbSJens Wiklander #endif 133817466cbSJens Wiklander return( NULL ); 134817466cbSJens Wiklander } 135817466cbSJens Wiklander 136817466cbSJens Wiklander const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type ) 137817466cbSJens Wiklander { 138817466cbSJens Wiklander switch( md_type ) 139817466cbSJens Wiklander { 140817466cbSJens Wiklander #if defined(MBEDTLS_MD2_C) 141817466cbSJens Wiklander case MBEDTLS_MD_MD2: 142817466cbSJens Wiklander return( &mbedtls_md2_info ); 143817466cbSJens Wiklander #endif 144817466cbSJens Wiklander #if defined(MBEDTLS_MD4_C) 145817466cbSJens Wiklander case MBEDTLS_MD_MD4: 146817466cbSJens Wiklander return( &mbedtls_md4_info ); 147817466cbSJens Wiklander #endif 148817466cbSJens Wiklander #if defined(MBEDTLS_MD5_C) 149817466cbSJens Wiklander case MBEDTLS_MD_MD5: 150817466cbSJens Wiklander return( &mbedtls_md5_info ); 151817466cbSJens Wiklander #endif 152817466cbSJens Wiklander #if defined(MBEDTLS_RIPEMD160_C) 153817466cbSJens Wiklander case MBEDTLS_MD_RIPEMD160: 154817466cbSJens Wiklander return( &mbedtls_ripemd160_info ); 155817466cbSJens Wiklander #endif 156817466cbSJens Wiklander #if defined(MBEDTLS_SHA1_C) 157817466cbSJens Wiklander case MBEDTLS_MD_SHA1: 158817466cbSJens Wiklander return( &mbedtls_sha1_info ); 159817466cbSJens Wiklander #endif 160817466cbSJens Wiklander #if defined(MBEDTLS_SHA256_C) 161817466cbSJens Wiklander case MBEDTLS_MD_SHA224: 162817466cbSJens Wiklander return( &mbedtls_sha224_info ); 163817466cbSJens Wiklander case MBEDTLS_MD_SHA256: 164817466cbSJens Wiklander return( &mbedtls_sha256_info ); 165817466cbSJens Wiklander #endif 166817466cbSJens Wiklander #if defined(MBEDTLS_SHA512_C) 167817466cbSJens Wiklander case MBEDTLS_MD_SHA384: 168817466cbSJens Wiklander return( &mbedtls_sha384_info ); 169817466cbSJens Wiklander case MBEDTLS_MD_SHA512: 170817466cbSJens Wiklander return( &mbedtls_sha512_info ); 171817466cbSJens Wiklander #endif 172817466cbSJens Wiklander default: 173817466cbSJens Wiklander return( NULL ); 174817466cbSJens Wiklander } 175817466cbSJens Wiklander } 176817466cbSJens Wiklander 177817466cbSJens Wiklander void mbedtls_md_init( mbedtls_md_context_t *ctx ) 178817466cbSJens Wiklander { 179817466cbSJens Wiklander memset( ctx, 0, sizeof( mbedtls_md_context_t ) ); 180817466cbSJens Wiklander } 181817466cbSJens Wiklander 182817466cbSJens Wiklander void mbedtls_md_free( mbedtls_md_context_t *ctx ) 183817466cbSJens Wiklander { 184817466cbSJens Wiklander if( ctx == NULL || ctx->md_info == NULL ) 185817466cbSJens Wiklander return; 186817466cbSJens Wiklander 187817466cbSJens Wiklander if( ctx->md_ctx != NULL ) 188817466cbSJens Wiklander ctx->md_info->ctx_free_func( ctx->md_ctx ); 189817466cbSJens Wiklander 190817466cbSJens Wiklander if( ctx->hmac_ctx != NULL ) 191817466cbSJens Wiklander { 1923d3b0591SJens Wiklander mbedtls_platform_zeroize( ctx->hmac_ctx, 1933d3b0591SJens Wiklander 2 * ctx->md_info->block_size ); 194817466cbSJens Wiklander mbedtls_free( ctx->hmac_ctx ); 195817466cbSJens Wiklander } 196817466cbSJens Wiklander 1973d3b0591SJens Wiklander mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md_context_t ) ); 198817466cbSJens Wiklander } 199817466cbSJens Wiklander 200817466cbSJens Wiklander int mbedtls_md_clone( mbedtls_md_context_t *dst, 201817466cbSJens Wiklander const mbedtls_md_context_t *src ) 202817466cbSJens Wiklander { 203817466cbSJens Wiklander if( dst == NULL || dst->md_info == NULL || 204817466cbSJens Wiklander src == NULL || src->md_info == NULL || 205817466cbSJens Wiklander dst->md_info != src->md_info ) 206817466cbSJens Wiklander { 207817466cbSJens Wiklander return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 208817466cbSJens Wiklander } 209817466cbSJens Wiklander 210817466cbSJens Wiklander dst->md_info->clone_func( dst->md_ctx, src->md_ctx ); 211817466cbSJens Wiklander 212*12484fc7SEdison Ai if( dst->hmac_ctx != NULL && src->hmac_ctx != NULL ) 213*12484fc7SEdison Ai memcpy( dst->hmac_ctx, src->hmac_ctx, 2 * src->md_info->block_size ); 214*12484fc7SEdison Ai 215817466cbSJens Wiklander return( 0 ); 216817466cbSJens Wiklander } 217817466cbSJens Wiklander 218817466cbSJens Wiklander #if ! defined(MBEDTLS_DEPRECATED_REMOVED) 219817466cbSJens Wiklander int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info ) 220817466cbSJens Wiklander { 221817466cbSJens Wiklander return mbedtls_md_setup( ctx, md_info, 1 ); 222817466cbSJens Wiklander } 223817466cbSJens Wiklander #endif 224817466cbSJens Wiklander 225817466cbSJens Wiklander int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac ) 226817466cbSJens Wiklander { 227817466cbSJens Wiklander if( md_info == NULL || ctx == NULL ) 228817466cbSJens Wiklander return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 229817466cbSJens Wiklander 230817466cbSJens Wiklander if( ( ctx->md_ctx = md_info->ctx_alloc_func() ) == NULL ) 231817466cbSJens Wiklander return( MBEDTLS_ERR_MD_ALLOC_FAILED ); 232817466cbSJens Wiklander 233817466cbSJens Wiklander if( hmac != 0 ) 234817466cbSJens Wiklander { 235817466cbSJens Wiklander ctx->hmac_ctx = mbedtls_calloc( 2, md_info->block_size ); 236817466cbSJens Wiklander if( ctx->hmac_ctx == NULL ) 237817466cbSJens Wiklander { 238817466cbSJens Wiklander md_info->ctx_free_func( ctx->md_ctx ); 239817466cbSJens Wiklander return( MBEDTLS_ERR_MD_ALLOC_FAILED ); 240817466cbSJens Wiklander } 241817466cbSJens Wiklander } 242817466cbSJens Wiklander 243817466cbSJens Wiklander ctx->md_info = md_info; 244817466cbSJens Wiklander 245817466cbSJens Wiklander return( 0 ); 246817466cbSJens Wiklander } 247817466cbSJens Wiklander 248817466cbSJens Wiklander int mbedtls_md_starts( mbedtls_md_context_t *ctx ) 249817466cbSJens Wiklander { 250817466cbSJens Wiklander if( ctx == NULL || ctx->md_info == NULL ) 251817466cbSJens Wiklander return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 252817466cbSJens Wiklander 2533d3b0591SJens Wiklander return( ctx->md_info->starts_func( ctx->md_ctx ) ); 254817466cbSJens Wiklander } 255817466cbSJens Wiklander 256817466cbSJens Wiklander int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen ) 257817466cbSJens Wiklander { 258817466cbSJens Wiklander if( ctx == NULL || ctx->md_info == NULL ) 259817466cbSJens Wiklander return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 260817466cbSJens Wiklander 2613d3b0591SJens Wiklander return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) ); 262817466cbSJens Wiklander } 263817466cbSJens Wiklander 264817466cbSJens Wiklander int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output ) 265817466cbSJens Wiklander { 266817466cbSJens Wiklander if( ctx == NULL || ctx->md_info == NULL ) 267817466cbSJens Wiklander return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 268817466cbSJens Wiklander 2693d3b0591SJens Wiklander return( ctx->md_info->finish_func( ctx->md_ctx, output ) ); 270817466cbSJens Wiklander } 271817466cbSJens Wiklander 272817466cbSJens Wiklander int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen, 273817466cbSJens Wiklander unsigned char *output ) 274817466cbSJens Wiklander { 275817466cbSJens Wiklander if( md_info == NULL ) 276817466cbSJens Wiklander return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 277817466cbSJens Wiklander 2783d3b0591SJens Wiklander return( md_info->digest_func( input, ilen, output ) ); 279817466cbSJens Wiklander } 280817466cbSJens Wiklander 281817466cbSJens Wiklander #if defined(MBEDTLS_FS_IO) 282817466cbSJens Wiklander int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigned char *output ) 283817466cbSJens Wiklander { 284817466cbSJens Wiklander int ret; 285817466cbSJens Wiklander FILE *f; 286817466cbSJens Wiklander size_t n; 287817466cbSJens Wiklander mbedtls_md_context_t ctx; 288817466cbSJens Wiklander unsigned char buf[1024]; 289817466cbSJens Wiklander 290817466cbSJens Wiklander if( md_info == NULL ) 291817466cbSJens Wiklander return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 292817466cbSJens Wiklander 293817466cbSJens Wiklander if( ( f = fopen( path, "rb" ) ) == NULL ) 294817466cbSJens Wiklander return( MBEDTLS_ERR_MD_FILE_IO_ERROR ); 295817466cbSJens Wiklander 296817466cbSJens Wiklander mbedtls_md_init( &ctx ); 297817466cbSJens Wiklander 298817466cbSJens Wiklander if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 ) 299817466cbSJens Wiklander goto cleanup; 300817466cbSJens Wiklander 3013d3b0591SJens Wiklander if( ( ret = md_info->starts_func( ctx.md_ctx ) ) != 0 ) 3023d3b0591SJens Wiklander goto cleanup; 303817466cbSJens Wiklander 304817466cbSJens Wiklander while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) 3053d3b0591SJens Wiklander if( ( ret = md_info->update_func( ctx.md_ctx, buf, n ) ) != 0 ) 3063d3b0591SJens Wiklander goto cleanup; 307817466cbSJens Wiklander 308817466cbSJens Wiklander if( ferror( f ) != 0 ) 309817466cbSJens Wiklander ret = MBEDTLS_ERR_MD_FILE_IO_ERROR; 3103d3b0591SJens Wiklander else 3113d3b0591SJens Wiklander ret = md_info->finish_func( ctx.md_ctx, output ); 312817466cbSJens Wiklander 313817466cbSJens Wiklander cleanup: 3143d3b0591SJens Wiklander mbedtls_platform_zeroize( buf, sizeof( buf ) ); 315817466cbSJens Wiklander fclose( f ); 316817466cbSJens Wiklander mbedtls_md_free( &ctx ); 317817466cbSJens Wiklander 318817466cbSJens Wiklander return( ret ); 319817466cbSJens Wiklander } 320817466cbSJens Wiklander #endif /* MBEDTLS_FS_IO */ 321817466cbSJens Wiklander 322817466cbSJens Wiklander int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen ) 323817466cbSJens Wiklander { 3243d3b0591SJens Wiklander int ret; 325817466cbSJens Wiklander unsigned char sum[MBEDTLS_MD_MAX_SIZE]; 326817466cbSJens Wiklander unsigned char *ipad, *opad; 327817466cbSJens Wiklander size_t i; 328817466cbSJens Wiklander 329817466cbSJens Wiklander if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) 330817466cbSJens Wiklander return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 331817466cbSJens Wiklander 332817466cbSJens Wiklander if( keylen > (size_t) ctx->md_info->block_size ) 333817466cbSJens Wiklander { 3343d3b0591SJens Wiklander if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) 3353d3b0591SJens Wiklander goto cleanup; 3363d3b0591SJens Wiklander if( ( ret = ctx->md_info->update_func( ctx->md_ctx, key, keylen ) ) != 0 ) 3373d3b0591SJens Wiklander goto cleanup; 3383d3b0591SJens Wiklander if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, sum ) ) != 0 ) 3393d3b0591SJens Wiklander goto cleanup; 340817466cbSJens Wiklander 341817466cbSJens Wiklander keylen = ctx->md_info->size; 342817466cbSJens Wiklander key = sum; 343817466cbSJens Wiklander } 344817466cbSJens Wiklander 345817466cbSJens Wiklander ipad = (unsigned char *) ctx->hmac_ctx; 346817466cbSJens Wiklander opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size; 347817466cbSJens Wiklander 348817466cbSJens Wiklander memset( ipad, 0x36, ctx->md_info->block_size ); 349817466cbSJens Wiklander memset( opad, 0x5C, ctx->md_info->block_size ); 350817466cbSJens Wiklander 351817466cbSJens Wiklander for( i = 0; i < keylen; i++ ) 352817466cbSJens Wiklander { 353817466cbSJens Wiklander ipad[i] = (unsigned char)( ipad[i] ^ key[i] ); 354817466cbSJens Wiklander opad[i] = (unsigned char)( opad[i] ^ key[i] ); 355817466cbSJens Wiklander } 356817466cbSJens Wiklander 3573d3b0591SJens Wiklander if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) 3583d3b0591SJens Wiklander goto cleanup; 3593d3b0591SJens Wiklander if( ( ret = ctx->md_info->update_func( ctx->md_ctx, ipad, 3603d3b0591SJens Wiklander ctx->md_info->block_size ) ) != 0 ) 3613d3b0591SJens Wiklander goto cleanup; 362817466cbSJens Wiklander 3633d3b0591SJens Wiklander cleanup: 3643d3b0591SJens Wiklander mbedtls_platform_zeroize( sum, sizeof( sum ) ); 365817466cbSJens Wiklander 3663d3b0591SJens Wiklander return( ret ); 367817466cbSJens Wiklander } 368817466cbSJens Wiklander 369817466cbSJens Wiklander int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen ) 370817466cbSJens Wiklander { 371817466cbSJens Wiklander if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) 372817466cbSJens Wiklander return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 373817466cbSJens Wiklander 3743d3b0591SJens Wiklander return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) ); 375817466cbSJens Wiklander } 376817466cbSJens Wiklander 377817466cbSJens Wiklander int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output ) 378817466cbSJens Wiklander { 3793d3b0591SJens Wiklander int ret; 380817466cbSJens Wiklander unsigned char tmp[MBEDTLS_MD_MAX_SIZE]; 381817466cbSJens Wiklander unsigned char *opad; 382817466cbSJens Wiklander 383817466cbSJens Wiklander if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) 384817466cbSJens Wiklander return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 385817466cbSJens Wiklander 386817466cbSJens Wiklander opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size; 387817466cbSJens Wiklander 3883d3b0591SJens Wiklander if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, tmp ) ) != 0 ) 3893d3b0591SJens Wiklander return( ret ); 3903d3b0591SJens Wiklander if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) 3913d3b0591SJens Wiklander return( ret ); 3923d3b0591SJens Wiklander if( ( ret = ctx->md_info->update_func( ctx->md_ctx, opad, 3933d3b0591SJens Wiklander ctx->md_info->block_size ) ) != 0 ) 3943d3b0591SJens Wiklander return( ret ); 3953d3b0591SJens Wiklander if( ( ret = ctx->md_info->update_func( ctx->md_ctx, tmp, 3963d3b0591SJens Wiklander ctx->md_info->size ) ) != 0 ) 3973d3b0591SJens Wiklander return( ret ); 3983d3b0591SJens Wiklander return( ctx->md_info->finish_func( ctx->md_ctx, output ) ); 399817466cbSJens Wiklander } 400817466cbSJens Wiklander 401817466cbSJens Wiklander int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx ) 402817466cbSJens Wiklander { 4033d3b0591SJens Wiklander int ret; 404817466cbSJens Wiklander unsigned char *ipad; 405817466cbSJens Wiklander 406817466cbSJens Wiklander if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) 407817466cbSJens Wiklander return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 408817466cbSJens Wiklander 409817466cbSJens Wiklander ipad = (unsigned char *) ctx->hmac_ctx; 410817466cbSJens Wiklander 4113d3b0591SJens Wiklander if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 ) 4123d3b0591SJens Wiklander return( ret ); 4133d3b0591SJens Wiklander return( ctx->md_info->update_func( ctx->md_ctx, ipad, 4143d3b0591SJens Wiklander ctx->md_info->block_size ) ); 415817466cbSJens Wiklander } 416817466cbSJens Wiklander 4173d3b0591SJens Wiklander int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, 4183d3b0591SJens Wiklander const unsigned char *key, size_t keylen, 419817466cbSJens Wiklander const unsigned char *input, size_t ilen, 420817466cbSJens Wiklander unsigned char *output ) 421817466cbSJens Wiklander { 422817466cbSJens Wiklander mbedtls_md_context_t ctx; 423817466cbSJens Wiklander int ret; 424817466cbSJens Wiklander 425817466cbSJens Wiklander if( md_info == NULL ) 426817466cbSJens Wiklander return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 427817466cbSJens Wiklander 428817466cbSJens Wiklander mbedtls_md_init( &ctx ); 429817466cbSJens Wiklander 430817466cbSJens Wiklander if( ( ret = mbedtls_md_setup( &ctx, md_info, 1 ) ) != 0 ) 4313d3b0591SJens Wiklander goto cleanup; 432817466cbSJens Wiklander 4333d3b0591SJens Wiklander if( ( ret = mbedtls_md_hmac_starts( &ctx, key, keylen ) ) != 0 ) 4343d3b0591SJens Wiklander goto cleanup; 4353d3b0591SJens Wiklander if( ( ret = mbedtls_md_hmac_update( &ctx, input, ilen ) ) != 0 ) 4363d3b0591SJens Wiklander goto cleanup; 4373d3b0591SJens Wiklander if( ( ret = mbedtls_md_hmac_finish( &ctx, output ) ) != 0 ) 4383d3b0591SJens Wiklander goto cleanup; 439817466cbSJens Wiklander 4403d3b0591SJens Wiklander cleanup: 441817466cbSJens Wiklander mbedtls_md_free( &ctx ); 442817466cbSJens Wiklander 4433d3b0591SJens Wiklander return( ret ); 444817466cbSJens Wiklander } 445817466cbSJens Wiklander 446817466cbSJens Wiklander int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data ) 447817466cbSJens Wiklander { 448817466cbSJens Wiklander if( ctx == NULL || ctx->md_info == NULL ) 449817466cbSJens Wiklander return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 450817466cbSJens Wiklander 4513d3b0591SJens Wiklander return( ctx->md_info->process_func( ctx->md_ctx, data ) ); 452817466cbSJens Wiklander } 453817466cbSJens Wiklander 454817466cbSJens Wiklander unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info ) 455817466cbSJens Wiklander { 456817466cbSJens Wiklander if( md_info == NULL ) 457817466cbSJens Wiklander return( 0 ); 458817466cbSJens Wiklander 459817466cbSJens Wiklander return md_info->size; 460817466cbSJens Wiklander } 461817466cbSJens Wiklander 462817466cbSJens Wiklander mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info ) 463817466cbSJens Wiklander { 464817466cbSJens Wiklander if( md_info == NULL ) 465817466cbSJens Wiklander return( MBEDTLS_MD_NONE ); 466817466cbSJens Wiklander 467817466cbSJens Wiklander return md_info->type; 468817466cbSJens Wiklander } 469817466cbSJens Wiklander 470817466cbSJens Wiklander const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info ) 471817466cbSJens Wiklander { 472817466cbSJens Wiklander if( md_info == NULL ) 473817466cbSJens Wiklander return( NULL ); 474817466cbSJens Wiklander 475817466cbSJens Wiklander return md_info->name; 476817466cbSJens Wiklander } 477817466cbSJens Wiklander 478817466cbSJens Wiklander #endif /* MBEDTLS_MD_C */ 479