1*c6672fdcSEdison 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" 36817466cbSJens Wiklander 37817466cbSJens Wiklander #if defined(MBEDTLS_PLATFORM_C) 38817466cbSJens Wiklander #include "mbedtls/platform.h" 39817466cbSJens Wiklander #else 40817466cbSJens Wiklander #include <stdlib.h> 41817466cbSJens Wiklander #define mbedtls_calloc calloc 42817466cbSJens Wiklander #define mbedtls_free free 43817466cbSJens Wiklander #endif 44817466cbSJens Wiklander 45817466cbSJens Wiklander #include <string.h> 46817466cbSJens Wiklander 47817466cbSJens Wiklander #if defined(MBEDTLS_FS_IO) 48817466cbSJens Wiklander #include <stdio.h> 49817466cbSJens Wiklander #endif 50817466cbSJens Wiklander 51817466cbSJens Wiklander /* Implementation that should never be optimized out by the compiler */ 52817466cbSJens Wiklander static void mbedtls_zeroize( void *v, size_t n ) { 53817466cbSJens Wiklander volatile unsigned char *p = v; while( n-- ) *p++ = 0; 54817466cbSJens Wiklander } 55817466cbSJens Wiklander 56817466cbSJens Wiklander /* 57817466cbSJens Wiklander * Reminder: update profiles in x509_crt.c when adding a new hash! 58817466cbSJens Wiklander */ 59817466cbSJens Wiklander static const int supported_digests[] = { 60817466cbSJens Wiklander 61817466cbSJens Wiklander #if defined(MBEDTLS_SHA512_C) 62817466cbSJens Wiklander MBEDTLS_MD_SHA512, 63817466cbSJens Wiklander MBEDTLS_MD_SHA384, 64817466cbSJens Wiklander #endif 65817466cbSJens Wiklander 66817466cbSJens Wiklander #if defined(MBEDTLS_SHA256_C) 67817466cbSJens Wiklander MBEDTLS_MD_SHA256, 68817466cbSJens Wiklander MBEDTLS_MD_SHA224, 69817466cbSJens Wiklander #endif 70817466cbSJens Wiklander 71817466cbSJens Wiklander #if defined(MBEDTLS_SHA1_C) 72817466cbSJens Wiklander MBEDTLS_MD_SHA1, 73817466cbSJens Wiklander #endif 74817466cbSJens Wiklander 75817466cbSJens Wiklander #if defined(MBEDTLS_RIPEMD160_C) 76817466cbSJens Wiklander MBEDTLS_MD_RIPEMD160, 77817466cbSJens Wiklander #endif 78817466cbSJens Wiklander 79817466cbSJens Wiklander #if defined(MBEDTLS_MD5_C) 80817466cbSJens Wiklander MBEDTLS_MD_MD5, 81817466cbSJens Wiklander #endif 82817466cbSJens Wiklander 83817466cbSJens Wiklander #if defined(MBEDTLS_MD4_C) 84817466cbSJens Wiklander MBEDTLS_MD_MD4, 85817466cbSJens Wiklander #endif 86817466cbSJens Wiklander 87817466cbSJens Wiklander #if defined(MBEDTLS_MD2_C) 88817466cbSJens Wiklander MBEDTLS_MD_MD2, 89817466cbSJens Wiklander #endif 90817466cbSJens Wiklander 91817466cbSJens Wiklander MBEDTLS_MD_NONE 92817466cbSJens Wiklander }; 93817466cbSJens Wiklander 94817466cbSJens Wiklander const int *mbedtls_md_list( void ) 95817466cbSJens Wiklander { 96817466cbSJens Wiklander return( supported_digests ); 97817466cbSJens Wiklander } 98817466cbSJens Wiklander 99817466cbSJens Wiklander const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name ) 100817466cbSJens Wiklander { 101817466cbSJens Wiklander if( NULL == md_name ) 102817466cbSJens Wiklander return( NULL ); 103817466cbSJens Wiklander 104817466cbSJens Wiklander /* Get the appropriate digest information */ 105817466cbSJens Wiklander #if defined(MBEDTLS_MD2_C) 106817466cbSJens Wiklander if( !strcmp( "MD2", md_name ) ) 107817466cbSJens Wiklander return mbedtls_md_info_from_type( MBEDTLS_MD_MD2 ); 108817466cbSJens Wiklander #endif 109817466cbSJens Wiklander #if defined(MBEDTLS_MD4_C) 110817466cbSJens Wiklander if( !strcmp( "MD4", md_name ) ) 111817466cbSJens Wiklander return mbedtls_md_info_from_type( MBEDTLS_MD_MD4 ); 112817466cbSJens Wiklander #endif 113817466cbSJens Wiklander #if defined(MBEDTLS_MD5_C) 114817466cbSJens Wiklander if( !strcmp( "MD5", md_name ) ) 115817466cbSJens Wiklander return mbedtls_md_info_from_type( MBEDTLS_MD_MD5 ); 116817466cbSJens Wiklander #endif 117817466cbSJens Wiklander #if defined(MBEDTLS_RIPEMD160_C) 118817466cbSJens Wiklander if( !strcmp( "RIPEMD160", md_name ) ) 119817466cbSJens Wiklander return mbedtls_md_info_from_type( MBEDTLS_MD_RIPEMD160 ); 120817466cbSJens Wiklander #endif 121817466cbSJens Wiklander #if defined(MBEDTLS_SHA1_C) 122817466cbSJens Wiklander if( !strcmp( "SHA1", md_name ) || !strcmp( "SHA", md_name ) ) 123817466cbSJens Wiklander return mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ); 124817466cbSJens Wiklander #endif 125817466cbSJens Wiklander #if defined(MBEDTLS_SHA256_C) 126817466cbSJens Wiklander if( !strcmp( "SHA224", md_name ) ) 127817466cbSJens Wiklander return mbedtls_md_info_from_type( MBEDTLS_MD_SHA224 ); 128817466cbSJens Wiklander if( !strcmp( "SHA256", md_name ) ) 129817466cbSJens Wiklander return mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ); 130817466cbSJens Wiklander #endif 131817466cbSJens Wiklander #if defined(MBEDTLS_SHA512_C) 132817466cbSJens Wiklander if( !strcmp( "SHA384", md_name ) ) 133817466cbSJens Wiklander return mbedtls_md_info_from_type( MBEDTLS_MD_SHA384 ); 134817466cbSJens Wiklander if( !strcmp( "SHA512", md_name ) ) 135817466cbSJens Wiklander return mbedtls_md_info_from_type( MBEDTLS_MD_SHA512 ); 136817466cbSJens Wiklander #endif 137817466cbSJens Wiklander return( NULL ); 138817466cbSJens Wiklander } 139817466cbSJens Wiklander 140817466cbSJens Wiklander const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type ) 141817466cbSJens Wiklander { 142817466cbSJens Wiklander switch( md_type ) 143817466cbSJens Wiklander { 144817466cbSJens Wiklander #if defined(MBEDTLS_MD2_C) 145817466cbSJens Wiklander case MBEDTLS_MD_MD2: 146817466cbSJens Wiklander return( &mbedtls_md2_info ); 147817466cbSJens Wiklander #endif 148817466cbSJens Wiklander #if defined(MBEDTLS_MD4_C) 149817466cbSJens Wiklander case MBEDTLS_MD_MD4: 150817466cbSJens Wiklander return( &mbedtls_md4_info ); 151817466cbSJens Wiklander #endif 152817466cbSJens Wiklander #if defined(MBEDTLS_MD5_C) 153817466cbSJens Wiklander case MBEDTLS_MD_MD5: 154817466cbSJens Wiklander return( &mbedtls_md5_info ); 155817466cbSJens Wiklander #endif 156817466cbSJens Wiklander #if defined(MBEDTLS_RIPEMD160_C) 157817466cbSJens Wiklander case MBEDTLS_MD_RIPEMD160: 158817466cbSJens Wiklander return( &mbedtls_ripemd160_info ); 159817466cbSJens Wiklander #endif 160817466cbSJens Wiklander #if defined(MBEDTLS_SHA1_C) 161817466cbSJens Wiklander case MBEDTLS_MD_SHA1: 162817466cbSJens Wiklander return( &mbedtls_sha1_info ); 163817466cbSJens Wiklander #endif 164817466cbSJens Wiklander #if defined(MBEDTLS_SHA256_C) 165817466cbSJens Wiklander case MBEDTLS_MD_SHA224: 166817466cbSJens Wiklander return( &mbedtls_sha224_info ); 167817466cbSJens Wiklander case MBEDTLS_MD_SHA256: 168817466cbSJens Wiklander return( &mbedtls_sha256_info ); 169817466cbSJens Wiklander #endif 170817466cbSJens Wiklander #if defined(MBEDTLS_SHA512_C) 171817466cbSJens Wiklander case MBEDTLS_MD_SHA384: 172817466cbSJens Wiklander return( &mbedtls_sha384_info ); 173817466cbSJens Wiklander case MBEDTLS_MD_SHA512: 174817466cbSJens Wiklander return( &mbedtls_sha512_info ); 175817466cbSJens Wiklander #endif 176817466cbSJens Wiklander default: 177817466cbSJens Wiklander return( NULL ); 178817466cbSJens Wiklander } 179817466cbSJens Wiklander } 180817466cbSJens Wiklander 181817466cbSJens Wiklander void mbedtls_md_init( mbedtls_md_context_t *ctx ) 182817466cbSJens Wiklander { 183817466cbSJens Wiklander memset( ctx, 0, sizeof( mbedtls_md_context_t ) ); 184817466cbSJens Wiklander } 185817466cbSJens Wiklander 186817466cbSJens Wiklander void mbedtls_md_free( mbedtls_md_context_t *ctx ) 187817466cbSJens Wiklander { 188817466cbSJens Wiklander if( ctx == NULL || ctx->md_info == NULL ) 189817466cbSJens Wiklander return; 190817466cbSJens Wiklander 191817466cbSJens Wiklander if( ctx->md_ctx != NULL ) 192817466cbSJens Wiklander ctx->md_info->ctx_free_func( ctx->md_ctx ); 193817466cbSJens Wiklander 194817466cbSJens Wiklander if( ctx->hmac_ctx != NULL ) 195817466cbSJens Wiklander { 196817466cbSJens Wiklander mbedtls_zeroize( ctx->hmac_ctx, 2 * ctx->md_info->block_size ); 197817466cbSJens Wiklander mbedtls_free( ctx->hmac_ctx ); 198817466cbSJens Wiklander } 199817466cbSJens Wiklander 200817466cbSJens Wiklander mbedtls_zeroize( ctx, sizeof( mbedtls_md_context_t ) ); 201817466cbSJens Wiklander } 202817466cbSJens Wiklander 203817466cbSJens Wiklander int mbedtls_md_clone( mbedtls_md_context_t *dst, 204817466cbSJens Wiklander const mbedtls_md_context_t *src ) 205817466cbSJens Wiklander { 206817466cbSJens Wiklander if( dst == NULL || dst->md_info == NULL || 207817466cbSJens Wiklander src == NULL || src->md_info == NULL || 208817466cbSJens Wiklander dst->md_info != src->md_info ) 209817466cbSJens Wiklander { 210817466cbSJens Wiklander return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 211817466cbSJens Wiklander } 212817466cbSJens Wiklander 213817466cbSJens Wiklander dst->md_info->clone_func( dst->md_ctx, src->md_ctx ); 214817466cbSJens Wiklander 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 253817466cbSJens Wiklander ctx->md_info->starts_func( ctx->md_ctx ); 254817466cbSJens Wiklander 255817466cbSJens Wiklander return( 0 ); 256817466cbSJens Wiklander } 257817466cbSJens Wiklander 258817466cbSJens Wiklander int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen ) 259817466cbSJens Wiklander { 260817466cbSJens Wiklander if( ctx == NULL || ctx->md_info == NULL ) 261817466cbSJens Wiklander return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 262817466cbSJens Wiklander 263817466cbSJens Wiklander ctx->md_info->update_func( ctx->md_ctx, input, ilen ); 264817466cbSJens Wiklander 265817466cbSJens Wiklander return( 0 ); 266817466cbSJens Wiklander } 267817466cbSJens Wiklander 268817466cbSJens Wiklander int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output ) 269817466cbSJens Wiklander { 270817466cbSJens Wiklander if( ctx == NULL || ctx->md_info == NULL ) 271817466cbSJens Wiklander return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 272817466cbSJens Wiklander 273817466cbSJens Wiklander ctx->md_info->finish_func( ctx->md_ctx, output ); 274817466cbSJens Wiklander 275817466cbSJens Wiklander return( 0 ); 276817466cbSJens Wiklander } 277817466cbSJens Wiklander 278817466cbSJens Wiklander int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen, 279817466cbSJens Wiklander unsigned char *output ) 280817466cbSJens Wiklander { 281817466cbSJens Wiklander if( md_info == NULL ) 282817466cbSJens Wiklander return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 283817466cbSJens Wiklander 284817466cbSJens Wiklander md_info->digest_func( input, ilen, output ); 285817466cbSJens Wiklander 286817466cbSJens Wiklander return( 0 ); 287817466cbSJens Wiklander } 288817466cbSJens Wiklander 289817466cbSJens Wiklander #if defined(MBEDTLS_FS_IO) 290817466cbSJens Wiklander int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigned char *output ) 291817466cbSJens Wiklander { 292817466cbSJens Wiklander int ret; 293817466cbSJens Wiklander FILE *f; 294817466cbSJens Wiklander size_t n; 295817466cbSJens Wiklander mbedtls_md_context_t ctx; 296817466cbSJens Wiklander unsigned char buf[1024]; 297817466cbSJens Wiklander 298817466cbSJens Wiklander if( md_info == NULL ) 299817466cbSJens Wiklander return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 300817466cbSJens Wiklander 301817466cbSJens Wiklander if( ( f = fopen( path, "rb" ) ) == NULL ) 302817466cbSJens Wiklander return( MBEDTLS_ERR_MD_FILE_IO_ERROR ); 303817466cbSJens Wiklander 304817466cbSJens Wiklander mbedtls_md_init( &ctx ); 305817466cbSJens Wiklander 306817466cbSJens Wiklander if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 ) 307817466cbSJens Wiklander goto cleanup; 308817466cbSJens Wiklander 309817466cbSJens Wiklander md_info->starts_func( ctx.md_ctx ); 310817466cbSJens Wiklander 311817466cbSJens Wiklander while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) 312817466cbSJens Wiklander md_info->update_func( ctx.md_ctx, buf, n ); 313817466cbSJens Wiklander 314817466cbSJens Wiklander if( ferror( f ) != 0 ) 315817466cbSJens Wiklander { 316817466cbSJens Wiklander ret = MBEDTLS_ERR_MD_FILE_IO_ERROR; 317817466cbSJens Wiklander goto cleanup; 318817466cbSJens Wiklander } 319817466cbSJens Wiklander 320817466cbSJens Wiklander md_info->finish_func( ctx.md_ctx, output ); 321817466cbSJens Wiklander 322817466cbSJens Wiklander cleanup: 323817466cbSJens Wiklander fclose( f ); 324817466cbSJens Wiklander mbedtls_md_free( &ctx ); 325817466cbSJens Wiklander 326817466cbSJens Wiklander return( ret ); 327817466cbSJens Wiklander } 328817466cbSJens Wiklander #endif /* MBEDTLS_FS_IO */ 329817466cbSJens Wiklander 330817466cbSJens Wiklander int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen ) 331817466cbSJens Wiklander { 332817466cbSJens Wiklander unsigned char sum[MBEDTLS_MD_MAX_SIZE]; 333817466cbSJens Wiklander unsigned char *ipad, *opad; 334817466cbSJens Wiklander size_t i; 335817466cbSJens Wiklander 336817466cbSJens Wiklander if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) 337817466cbSJens Wiklander return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 338817466cbSJens Wiklander 339817466cbSJens Wiklander if( keylen > (size_t) ctx->md_info->block_size ) 340817466cbSJens Wiklander { 341817466cbSJens Wiklander ctx->md_info->starts_func( ctx->md_ctx ); 342817466cbSJens Wiklander ctx->md_info->update_func( ctx->md_ctx, key, keylen ); 343817466cbSJens Wiklander ctx->md_info->finish_func( ctx->md_ctx, sum ); 344817466cbSJens Wiklander 345817466cbSJens Wiklander keylen = ctx->md_info->size; 346817466cbSJens Wiklander key = sum; 347817466cbSJens Wiklander } 348817466cbSJens Wiklander 349817466cbSJens Wiklander ipad = (unsigned char *) ctx->hmac_ctx; 350817466cbSJens Wiklander opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size; 351817466cbSJens Wiklander 352817466cbSJens Wiklander memset( ipad, 0x36, ctx->md_info->block_size ); 353817466cbSJens Wiklander memset( opad, 0x5C, ctx->md_info->block_size ); 354817466cbSJens Wiklander 355817466cbSJens Wiklander for( i = 0; i < keylen; i++ ) 356817466cbSJens Wiklander { 357817466cbSJens Wiklander ipad[i] = (unsigned char)( ipad[i] ^ key[i] ); 358817466cbSJens Wiklander opad[i] = (unsigned char)( opad[i] ^ key[i] ); 359817466cbSJens Wiklander } 360817466cbSJens Wiklander 361817466cbSJens Wiklander mbedtls_zeroize( sum, sizeof( sum ) ); 362817466cbSJens Wiklander 363817466cbSJens Wiklander ctx->md_info->starts_func( ctx->md_ctx ); 364817466cbSJens Wiklander ctx->md_info->update_func( ctx->md_ctx, ipad, ctx->md_info->block_size ); 365817466cbSJens Wiklander 366817466cbSJens Wiklander return( 0 ); 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 374817466cbSJens Wiklander ctx->md_info->update_func( ctx->md_ctx, input, ilen ); 375817466cbSJens Wiklander 376817466cbSJens Wiklander return( 0 ); 377817466cbSJens Wiklander } 378817466cbSJens Wiklander 379817466cbSJens Wiklander int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output ) 380817466cbSJens Wiklander { 381817466cbSJens Wiklander unsigned char tmp[MBEDTLS_MD_MAX_SIZE]; 382817466cbSJens Wiklander unsigned char *opad; 383817466cbSJens Wiklander 384817466cbSJens Wiklander if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) 385817466cbSJens Wiklander return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 386817466cbSJens Wiklander 387817466cbSJens Wiklander opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size; 388817466cbSJens Wiklander 389817466cbSJens Wiklander ctx->md_info->finish_func( ctx->md_ctx, tmp ); 390817466cbSJens Wiklander ctx->md_info->starts_func( ctx->md_ctx ); 391817466cbSJens Wiklander ctx->md_info->update_func( ctx->md_ctx, opad, ctx->md_info->block_size ); 392817466cbSJens Wiklander ctx->md_info->update_func( ctx->md_ctx, tmp, ctx->md_info->size ); 393817466cbSJens Wiklander ctx->md_info->finish_func( ctx->md_ctx, output ); 394817466cbSJens Wiklander 395817466cbSJens Wiklander return( 0 ); 396817466cbSJens Wiklander } 397817466cbSJens Wiklander 398817466cbSJens Wiklander int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx ) 399817466cbSJens Wiklander { 400817466cbSJens Wiklander unsigned char *ipad; 401817466cbSJens Wiklander 402817466cbSJens Wiklander if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) 403817466cbSJens Wiklander return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 404817466cbSJens Wiklander 405817466cbSJens Wiklander ipad = (unsigned char *) ctx->hmac_ctx; 406817466cbSJens Wiklander 407817466cbSJens Wiklander ctx->md_info->starts_func( ctx->md_ctx ); 408817466cbSJens Wiklander ctx->md_info->update_func( ctx->md_ctx, ipad, ctx->md_info->block_size ); 409817466cbSJens Wiklander 410817466cbSJens Wiklander return( 0 ); 411817466cbSJens Wiklander } 412817466cbSJens Wiklander 413817466cbSJens Wiklander int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, const unsigned char *key, size_t keylen, 414817466cbSJens Wiklander const unsigned char *input, size_t ilen, 415817466cbSJens Wiklander unsigned char *output ) 416817466cbSJens Wiklander { 417817466cbSJens Wiklander mbedtls_md_context_t ctx; 418817466cbSJens Wiklander int ret; 419817466cbSJens Wiklander 420817466cbSJens Wiklander if( md_info == NULL ) 421817466cbSJens Wiklander return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 422817466cbSJens Wiklander 423817466cbSJens Wiklander mbedtls_md_init( &ctx ); 424817466cbSJens Wiklander 425817466cbSJens Wiklander if( ( ret = mbedtls_md_setup( &ctx, md_info, 1 ) ) != 0 ) 426817466cbSJens Wiklander return( ret ); 427817466cbSJens Wiklander 428817466cbSJens Wiklander mbedtls_md_hmac_starts( &ctx, key, keylen ); 429817466cbSJens Wiklander mbedtls_md_hmac_update( &ctx, input, ilen ); 430817466cbSJens Wiklander mbedtls_md_hmac_finish( &ctx, output ); 431817466cbSJens Wiklander 432817466cbSJens Wiklander mbedtls_md_free( &ctx ); 433817466cbSJens Wiklander 434817466cbSJens Wiklander return( 0 ); 435817466cbSJens Wiklander } 436817466cbSJens Wiklander 437817466cbSJens Wiklander int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data ) 438817466cbSJens Wiklander { 439817466cbSJens Wiklander if( ctx == NULL || ctx->md_info == NULL ) 440817466cbSJens Wiklander return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); 441817466cbSJens Wiklander 442817466cbSJens Wiklander ctx->md_info->process_func( ctx->md_ctx, data ); 443817466cbSJens Wiklander 444817466cbSJens Wiklander return( 0 ); 445817466cbSJens Wiklander } 446817466cbSJens Wiklander 447817466cbSJens Wiklander unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info ) 448817466cbSJens Wiklander { 449817466cbSJens Wiklander if( md_info == NULL ) 450817466cbSJens Wiklander return( 0 ); 451817466cbSJens Wiklander 452817466cbSJens Wiklander return md_info->size; 453817466cbSJens Wiklander } 454817466cbSJens Wiklander 455817466cbSJens Wiklander mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info ) 456817466cbSJens Wiklander { 457817466cbSJens Wiklander if( md_info == NULL ) 458817466cbSJens Wiklander return( MBEDTLS_MD_NONE ); 459817466cbSJens Wiklander 460817466cbSJens Wiklander return md_info->type; 461817466cbSJens Wiklander } 462817466cbSJens Wiklander 463817466cbSJens Wiklander const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info ) 464817466cbSJens Wiklander { 465817466cbSJens Wiklander if( md_info == NULL ) 466817466cbSJens Wiklander return( NULL ); 467817466cbSJens Wiklander 468817466cbSJens Wiklander return md_info->name; 469817466cbSJens Wiklander } 470817466cbSJens Wiklander 471817466cbSJens Wiklander #endif /* MBEDTLS_MD_C */ 472