mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-12-24 17:25:39 +00:00
3252c4d913
When MBEDTLS_MD_SINGLE_HASH is set, both the underlying digest context and the HMAC data are embedded into the mbedtls_md_context; otherwise, they're dynamically allocated and referenced from mbedtls_md_context. When the HMAC data is embedded in mbedtls_md_context, it's unnecessary to check whether mbedtls_md_context::hmac_ctx is NULL, because that's never the case in defined behaviour, but the check has kept for uniformity so far. However, contrary to the expectation that compilers would silently remove this check as always false, ARMC6 complains about it, breaking some tests in all.sh. This commit fixes this by guarding checks for mbedtls_md_context::hmac_ctx == NULL by !MBEDTLS_MD_SINGLE_HASH.
751 lines
19 KiB
C
751 lines
19 KiB
C
/**
|
|
* \file mbedtls_md.c
|
|
*
|
|
* \brief Generic message digest wrapper for mbed TLS
|
|
*
|
|
* \author Adriaan de Jong <dejong@fox-it.com>
|
|
*
|
|
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
* not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*
|
|
* This file is part of mbed TLS (https://tls.mbed.org)
|
|
*/
|
|
|
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
|
#include "mbedtls/config.h"
|
|
#else
|
|
#include MBEDTLS_CONFIG_FILE
|
|
#endif
|
|
|
|
#if defined(MBEDTLS_MD_C)
|
|
|
|
#include "mbedtls/md.h"
|
|
#include "mbedtls/platform_util.h"
|
|
|
|
#if defined(MBEDTLS_PLATFORM_C)
|
|
#include "mbedtls/platform.h"
|
|
#else
|
|
#include <stdlib.h>
|
|
#define mbedtls_calloc calloc
|
|
#define mbedtls_free free
|
|
#endif
|
|
|
|
#include <string.h>
|
|
|
|
#if defined(MBEDTLS_FS_IO)
|
|
#include <stdio.h>
|
|
#endif
|
|
|
|
#if !defined(MBEDTLS_MD_SINGLE_HASH)
|
|
/*
|
|
*
|
|
* Definitions of MD information structures for various digests.
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* MD-2
|
|
*/
|
|
#if defined(MBEDTLS_MD2_C)
|
|
static const mbedtls_md_info_t mbedtls_md2_info = {
|
|
MBEDTLS_MD_MD2,
|
|
"MD2",
|
|
16,
|
|
16,
|
|
mbedtls_md2_starts_wrap,
|
|
mbedtls_md2_update_wrap,
|
|
mbedtls_md2_finish_wrap,
|
|
mbedtls_md2_ret,
|
|
mbedtls_md2_ctx_alloc,
|
|
mbedtls_md2_ctx_free,
|
|
mbedtls_md2_clone_wrap,
|
|
mbedtls_md2_process_wrap,
|
|
};
|
|
#endif /* MBEDTLS_MD2_C */
|
|
|
|
/*
|
|
* MD-4
|
|
*/
|
|
|
|
#if defined(MBEDTLS_MD4_C)
|
|
static const mbedtls_md_info_t mbedtls_md4_info = {
|
|
MBEDTLS_MD_MD4,
|
|
"MD4",
|
|
16,
|
|
64,
|
|
mbedtls_md4_starts_wrap,
|
|
mbedtls_md4_update_wrap,
|
|
mbedtls_md4_finish_wrap,
|
|
mbedtls_md4_ret,
|
|
mbedtls_md4_ctx_alloc,
|
|
mbedtls_md4_ctx_free,
|
|
mbedtls_md4_clone_wrap,
|
|
mbedtls_md4_process_wrap,
|
|
};
|
|
#endif /* MBEDTLS_MD4_C */
|
|
|
|
/*
|
|
* MD-5
|
|
*/
|
|
|
|
#if defined(MBEDTLS_MD5_C)
|
|
static const mbedtls_md_info_t mbedtls_md5_info = {
|
|
MBEDTLS_MD_MD5,
|
|
"MD5",
|
|
16,
|
|
64,
|
|
mbedtls_md5_starts_wrap,
|
|
mbedtls_md5_update_wrap,
|
|
mbedtls_md5_finish_wrap,
|
|
mbedtls_md5_ret,
|
|
mbedtls_md5_ctx_alloc,
|
|
mbedtls_md5_ctx_free,
|
|
mbedtls_md5_clone_wrap,
|
|
mbedtls_md5_process_wrap,
|
|
};
|
|
#endif /* MBEDTLS_MD5_C */
|
|
|
|
/*
|
|
* RIPEMD-160
|
|
*/
|
|
|
|
#if defined(MBEDTLS_RIPEMD160_C)
|
|
static const mbedtls_md_info_t mbedtls_ripemd160_info = {
|
|
MBEDTLS_MD_RIPEMD160,
|
|
"RIPEMD160",
|
|
20,
|
|
64,
|
|
mbedtls_ripemd160_starts_wrap,
|
|
mbedtls_ripemd160_update_wrap,
|
|
mbedtls_ripemd160_finish_wrap,
|
|
mbedtls_ripemd160_ret,
|
|
mbedtls_ripemd160_ctx_alloc,
|
|
mbedtls_ripemd160_ctx_free,
|
|
mbedtls_ripemd160_clone_wrap,
|
|
mbedtls_ripemd160_process_wrap,
|
|
};
|
|
#endif /* MBEDTLS_RIPEMD160_C */
|
|
|
|
/*
|
|
* SHA-1
|
|
*/
|
|
|
|
#if defined(MBEDTLS_SHA1_C)
|
|
static const mbedtls_md_info_t mbedtls_sha1_info = {
|
|
MBEDTLS_MD_SHA1,
|
|
"SHA1",
|
|
20,
|
|
64,
|
|
mbedtls_sha1_starts_wrap,
|
|
mbedtls_sha1_update_wrap,
|
|
mbedtls_sha1_finish_wrap,
|
|
mbedtls_sha1_ret,
|
|
mbedtls_sha1_ctx_alloc,
|
|
mbedtls_sha1_ctx_free,
|
|
mbedtls_sha1_clone_wrap,
|
|
mbedtls_sha1_process_wrap,
|
|
};
|
|
#endif /* MBEDTLS_SHA1_C */
|
|
|
|
/*
|
|
* SHA-224 and SHA-256
|
|
*/
|
|
|
|
#if defined(MBEDTLS_SHA256_C)
|
|
#if !defined(MBEDTLS_SHA256_NO_SHA224)
|
|
static const mbedtls_md_info_t mbedtls_sha224_info = {
|
|
MBEDTLS_MD_SHA224,
|
|
"SHA224",
|
|
28,
|
|
64,
|
|
mbedtls_sha224_starts_wrap,
|
|
mbedtls_sha224_update_wrap,
|
|
mbedtls_sha224_finish_wrap,
|
|
mbedtls_sha224_wrap,
|
|
mbedtls_sha224_ctx_alloc,
|
|
mbedtls_sha224_ctx_free,
|
|
mbedtls_sha224_clone_wrap,
|
|
mbedtls_sha224_process_wrap,
|
|
};
|
|
#endif /* !MBEDTLS_SHA256_NO_SHA224 */
|
|
static const mbedtls_md_info_t mbedtls_sha256_info =
|
|
MBEDTLS_MD_INFO( MBEDTLS_MD_INFO_SHA256 );
|
|
#endif /* MBEDTLS_SHA256_C */
|
|
|
|
/*
|
|
* SHA-384 and SHA-512
|
|
*/
|
|
|
|
#if defined(MBEDTLS_SHA512_C)
|
|
static const mbedtls_md_info_t mbedtls_sha384_info = {
|
|
MBEDTLS_MD_SHA384,
|
|
"SHA384",
|
|
48,
|
|
128,
|
|
mbedtls_sha384_starts_wrap,
|
|
mbedtls_sha384_update_wrap,
|
|
mbedtls_sha384_finish_wrap,
|
|
mbedtls_sha384_wrap,
|
|
mbedtls_sha384_ctx_alloc,
|
|
mbedtls_sha384_ctx_free,
|
|
mbedtls_sha384_clone_wrap,
|
|
mbedtls_sha384_process_wrap,
|
|
};
|
|
static const mbedtls_md_info_t mbedtls_sha512_info = {
|
|
MBEDTLS_MD_SHA512,
|
|
"SHA512",
|
|
64,
|
|
128,
|
|
mbedtls_sha512_starts_wrap,
|
|
mbedtls_sha384_update_wrap,
|
|
mbedtls_sha384_finish_wrap,
|
|
mbedtls_sha512_wrap,
|
|
mbedtls_sha384_ctx_alloc,
|
|
mbedtls_sha384_ctx_free,
|
|
mbedtls_sha384_clone_wrap,
|
|
mbedtls_sha384_process_wrap,
|
|
};
|
|
#endif /* MBEDTLS_SHA512_C */
|
|
|
|
/*
|
|
* Reminder: update profiles in x509_crt.c when adding a new hash!
|
|
*/
|
|
static const int supported_digests[] = {
|
|
|
|
#if defined(MBEDTLS_SHA512_C)
|
|
MBEDTLS_MD_SHA512,
|
|
MBEDTLS_MD_SHA384,
|
|
#endif
|
|
|
|
#if defined(MBEDTLS_SHA256_C)
|
|
MBEDTLS_MD_SHA256,
|
|
#if !defined(MBEDTLS_SHA256_NO_SHA224)
|
|
MBEDTLS_MD_SHA224,
|
|
#endif
|
|
#endif /* MBEDTLS_SHA256_C */
|
|
|
|
#if defined(MBEDTLS_SHA1_C)
|
|
MBEDTLS_MD_SHA1,
|
|
#endif
|
|
|
|
#if defined(MBEDTLS_RIPEMD160_C)
|
|
MBEDTLS_MD_RIPEMD160,
|
|
#endif
|
|
|
|
#if defined(MBEDTLS_MD5_C)
|
|
MBEDTLS_MD_MD5,
|
|
#endif
|
|
|
|
#if defined(MBEDTLS_MD4_C)
|
|
MBEDTLS_MD_MD4,
|
|
#endif
|
|
|
|
#if defined(MBEDTLS_MD2_C)
|
|
MBEDTLS_MD_MD2,
|
|
#endif
|
|
|
|
MBEDTLS_MD_NONE
|
|
};
|
|
|
|
const int *mbedtls_md_list( void )
|
|
{
|
|
return( supported_digests );
|
|
}
|
|
|
|
mbedtls_md_handle_t mbedtls_md_info_from_string( const char *md_name )
|
|
{
|
|
if( NULL == md_name )
|
|
return( NULL );
|
|
|
|
/* Get the appropriate digest information */
|
|
#if defined(MBEDTLS_MD2_C)
|
|
if( !strcmp( "MD2", md_name ) )
|
|
return mbedtls_md_info_from_type( MBEDTLS_MD_MD2 );
|
|
#endif
|
|
#if defined(MBEDTLS_MD4_C)
|
|
if( !strcmp( "MD4", md_name ) )
|
|
return mbedtls_md_info_from_type( MBEDTLS_MD_MD4 );
|
|
#endif
|
|
#if defined(MBEDTLS_MD5_C)
|
|
if( !strcmp( "MD5", md_name ) )
|
|
return mbedtls_md_info_from_type( MBEDTLS_MD_MD5 );
|
|
#endif
|
|
#if defined(MBEDTLS_RIPEMD160_C)
|
|
if( !strcmp( "RIPEMD160", md_name ) )
|
|
return mbedtls_md_info_from_type( MBEDTLS_MD_RIPEMD160 );
|
|
#endif
|
|
#if defined(MBEDTLS_SHA1_C)
|
|
if( !strcmp( "SHA1", md_name ) || !strcmp( "SHA", md_name ) )
|
|
return mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
|
|
#endif
|
|
#if defined(MBEDTLS_SHA256_C)
|
|
#if !defined(MBEDTLS_SHA256_NO_SHA224)
|
|
if( !strcmp( "SHA224", md_name ) )
|
|
return mbedtls_md_info_from_type( MBEDTLS_MD_SHA224 );
|
|
#endif
|
|
if( !strcmp( "SHA256", md_name ) )
|
|
return mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 );
|
|
#endif /* MBEDTLS_SHA256_C */
|
|
#if defined(MBEDTLS_SHA512_C)
|
|
if( !strcmp( "SHA384", md_name ) )
|
|
return mbedtls_md_info_from_type( MBEDTLS_MD_SHA384 );
|
|
if( !strcmp( "SHA512", md_name ) )
|
|
return mbedtls_md_info_from_type( MBEDTLS_MD_SHA512 );
|
|
#endif
|
|
return( NULL );
|
|
}
|
|
|
|
mbedtls_md_handle_t mbedtls_md_info_from_type( mbedtls_md_type_t md_type )
|
|
{
|
|
switch( md_type )
|
|
{
|
|
#if defined(MBEDTLS_MD2_C)
|
|
case MBEDTLS_MD_MD2:
|
|
return( &mbedtls_md2_info );
|
|
#endif
|
|
#if defined(MBEDTLS_MD4_C)
|
|
case MBEDTLS_MD_MD4:
|
|
return( &mbedtls_md4_info );
|
|
#endif
|
|
#if defined(MBEDTLS_MD5_C)
|
|
case MBEDTLS_MD_MD5:
|
|
return( &mbedtls_md5_info );
|
|
#endif
|
|
#if defined(MBEDTLS_RIPEMD160_C)
|
|
case MBEDTLS_MD_RIPEMD160:
|
|
return( &mbedtls_ripemd160_info );
|
|
#endif
|
|
#if defined(MBEDTLS_SHA1_C)
|
|
case MBEDTLS_MD_SHA1:
|
|
return( &mbedtls_sha1_info );
|
|
#endif
|
|
#if defined(MBEDTLS_SHA256_C)
|
|
#if !defined(MBEDTLS_SHA256_NO_SHA224)
|
|
case MBEDTLS_MD_SHA224:
|
|
return( &mbedtls_sha224_info );
|
|
#endif
|
|
case MBEDTLS_MD_SHA256:
|
|
return( &mbedtls_sha256_info );
|
|
#endif /* MBEDTLS_SHA256_C */
|
|
#if defined(MBEDTLS_SHA512_C)
|
|
case MBEDTLS_MD_SHA384:
|
|
return( &mbedtls_sha384_info );
|
|
case MBEDTLS_MD_SHA512:
|
|
return( &mbedtls_sha512_info );
|
|
#endif
|
|
default:
|
|
return( NULL );
|
|
}
|
|
}
|
|
|
|
#else /* MBEDTLS_MD_SINGLE_HASH */
|
|
|
|
const int *mbedtls_md_list( void )
|
|
{
|
|
static int single_hash[2] =
|
|
{ MBEDTLS_MD_INFO_TYPE( MBEDTLS_MD_SINGLE_HASH ),
|
|
MBEDTLS_MD_INVALID_HANDLE };
|
|
|
|
return( single_hash );
|
|
}
|
|
|
|
mbedtls_md_handle_t mbedtls_md_info_from_string( const char *md_name )
|
|
{
|
|
static const char * const hash_name =
|
|
MBEDTLS_MD_INFO_NAME( MBEDTLS_MD_SINGLE_HASH );
|
|
|
|
if( md_name != NULL && strcmp( hash_name, md_name ) == 0 )
|
|
return( MBEDTLS_MD_UNIQUE_VALID_HANDLE );
|
|
|
|
return( MBEDTLS_MD_INVALID_HANDLE );
|
|
}
|
|
|
|
mbedtls_md_handle_t mbedtls_md_info_from_type( mbedtls_md_type_t md_type )
|
|
{
|
|
static const mbedtls_md_type_t hash_type =
|
|
MBEDTLS_MD_INFO_TYPE( MBEDTLS_MD_SINGLE_HASH );
|
|
|
|
if( hash_type == md_type )
|
|
return( MBEDTLS_MD_UNIQUE_VALID_HANDLE );
|
|
|
|
return( MBEDTLS_MD_INVALID_HANDLE );
|
|
}
|
|
|
|
#endif /* MBEDTLS_MD_SINGLE_HASH */
|
|
|
|
void mbedtls_md_init( mbedtls_md_context_t *ctx )
|
|
{
|
|
memset( ctx, 0, sizeof( mbedtls_md_context_t ) );
|
|
|
|
#if defined(MBEDTLS_MD_SINGLE_HASH)
|
|
mbedtls_md_info_init( mbedtls_md_get_handle( ctx ),
|
|
ctx->md_ctx );
|
|
#endif
|
|
}
|
|
|
|
void mbedtls_md_free( mbedtls_md_context_t *ctx )
|
|
{
|
|
if( ctx == NULL || mbedtls_md_get_handle( ctx ) == MBEDTLS_MD_INVALID_HANDLE )
|
|
return;
|
|
|
|
#if !defined(MBEDTLS_MD_SINGLE_HASH)
|
|
if( ctx->md_ctx != NULL )
|
|
{
|
|
mbedtls_md_info_ctx_free( mbedtls_md_get_handle( ctx ), ctx->md_ctx );
|
|
}
|
|
|
|
if( ctx->hmac_ctx != NULL )
|
|
{
|
|
mbedtls_platform_zeroize( ctx->hmac_ctx,
|
|
2 * mbedtls_md_info_block_size( mbedtls_md_get_handle( ctx ) ) );
|
|
mbedtls_free( ctx->hmac_ctx );
|
|
}
|
|
#endif /* MBEDTLS_MD_SINGLE_HASH */
|
|
|
|
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md_context_t ) );
|
|
}
|
|
|
|
int mbedtls_md_clone( mbedtls_md_context_t *dst,
|
|
const mbedtls_md_context_t *src )
|
|
{
|
|
if( dst == NULL || mbedtls_md_get_handle( dst ) == MBEDTLS_MD_INVALID_HANDLE ||
|
|
src == NULL || mbedtls_md_get_handle( src ) == MBEDTLS_MD_INVALID_HANDLE ||
|
|
mbedtls_md_get_handle( dst ) != mbedtls_md_get_handle( src ) )
|
|
{
|
|
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
|
|
}
|
|
|
|
mbedtls_md_info_clone( mbedtls_md_get_handle( dst ),
|
|
dst->md_ctx, src->md_ctx );
|
|
return( 0 );
|
|
}
|
|
|
|
#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
|
|
int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, mbedtls_md_handle_t md_info )
|
|
{
|
|
return mbedtls_md_setup( ctx, md_info, 1 );
|
|
}
|
|
#endif
|
|
|
|
#if !defined(MBEDTLS_MD_SINGLE_HASH)
|
|
int mbedtls_md_setup( mbedtls_md_context_t *ctx, mbedtls_md_handle_t md_info, int hmac )
|
|
{
|
|
return( mbedtls_md_setup_internal( ctx, md_info, hmac ) );
|
|
}
|
|
|
|
int mbedtls_md_starts( mbedtls_md_context_t *ctx )
|
|
{
|
|
return( mbedtls_md_starts_internal( ctx ) );
|
|
}
|
|
|
|
int mbedtls_md_update( mbedtls_md_context_t *ctx,
|
|
const unsigned char *input,
|
|
size_t ilen )
|
|
{
|
|
return( mbedtls_md_update_internal( ctx, input, ilen ) );
|
|
}
|
|
|
|
int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output )
|
|
{
|
|
return( mbedtls_md_finish_internal( ctx, output ) );
|
|
}
|
|
|
|
int mbedtls_md( mbedtls_md_handle_t md_info, const unsigned char *input, size_t ilen,
|
|
unsigned char *output )
|
|
{
|
|
return( mbedtls_md_internal( md_info, input, ilen, output ) );
|
|
}
|
|
#endif /* !MBEDTLS_MD_SINGLE_HASH */
|
|
|
|
#if defined(MBEDTLS_FS_IO)
|
|
int mbedtls_md_file( mbedtls_md_handle_t md_info, const char *path, unsigned char *output )
|
|
{
|
|
int ret;
|
|
FILE *f;
|
|
size_t n;
|
|
mbedtls_md_context_t ctx;
|
|
unsigned char buf[1024];
|
|
|
|
if( md_info == MBEDTLS_MD_INVALID_HANDLE )
|
|
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
|
|
|
|
if( ( f = fopen( path, "rb" ) ) == NULL )
|
|
return( MBEDTLS_ERR_MD_FILE_IO_ERROR );
|
|
|
|
mbedtls_md_init( &ctx );
|
|
|
|
if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 )
|
|
goto cleanup;
|
|
|
|
ret = mbedtls_md_info_starts( md_info, ctx.md_ctx );
|
|
if( ret != 0 )
|
|
goto cleanup;
|
|
|
|
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
|
|
{
|
|
ret = mbedtls_md_info_update( md_info, ctx.md_ctx,
|
|
buf, n );
|
|
if( ret != 0 )
|
|
goto cleanup;
|
|
}
|
|
|
|
if( ferror( f ) != 0 )
|
|
{
|
|
ret = MBEDTLS_ERR_MD_FILE_IO_ERROR;
|
|
}
|
|
else
|
|
{
|
|
ret = mbedtls_md_info_finish( md_info, ctx.md_ctx,
|
|
output );
|
|
}
|
|
|
|
cleanup:
|
|
mbedtls_platform_zeroize( buf, sizeof( buf ) );
|
|
fclose( f );
|
|
mbedtls_md_free( &ctx );
|
|
|
|
return( ret );
|
|
}
|
|
#endif /* MBEDTLS_FS_IO */
|
|
|
|
int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen )
|
|
{
|
|
int ret;
|
|
unsigned char sum[MBEDTLS_MD_MAX_SIZE];
|
|
unsigned char *ipad, *opad;
|
|
size_t i;
|
|
|
|
mbedtls_md_handle_t md_info;
|
|
|
|
if( ctx == NULL )
|
|
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
|
|
|
|
#if !defined(MBEDTLS_MD_SINGLE_HASH)
|
|
if( ctx->hmac_ctx == NULL )
|
|
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
|
|
#endif /* !MBEDTLS_MD_SINGLE_HASH */
|
|
|
|
md_info = mbedtls_md_get_handle( ctx );
|
|
if( md_info == MBEDTLS_MD_INVALID_HANDLE )
|
|
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
|
|
|
|
if( keylen > (size_t) mbedtls_md_info_block_size( md_info ) )
|
|
{
|
|
if( ( ret = mbedtls_md_info_starts( md_info, ctx->md_ctx ) ) != 0 )
|
|
goto cleanup;
|
|
|
|
if( ( ret = mbedtls_md_info_update( md_info, ctx->md_ctx,
|
|
key, keylen ) ) != 0 )
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
if( ( ret = mbedtls_md_info_finish( md_info, ctx->md_ctx, sum ) ) != 0 )
|
|
goto cleanup;
|
|
|
|
keylen = mbedtls_md_info_size( md_info );
|
|
key = sum;
|
|
}
|
|
|
|
ipad = (unsigned char *) ctx->hmac_ctx;
|
|
opad = (unsigned char *) ctx->hmac_ctx +
|
|
mbedtls_md_info_block_size( md_info );
|
|
|
|
memset( ipad, 0x36, mbedtls_md_info_block_size( md_info ) );
|
|
memset( opad, 0x5C, mbedtls_md_info_block_size( md_info ) );
|
|
|
|
for( i = 0; i < keylen; i++ )
|
|
{
|
|
ipad[i] = (unsigned char)( ipad[i] ^ key[i] );
|
|
opad[i] = (unsigned char)( opad[i] ^ key[i] );
|
|
}
|
|
|
|
if( ( ret = mbedtls_md_info_starts( md_info, ctx->md_ctx ) ) != 0 )
|
|
goto cleanup;
|
|
|
|
if( ( ret = mbedtls_md_info_update( md_info, ctx->md_ctx, ipad,
|
|
mbedtls_md_info_block_size( md_info ) ) ) != 0 )
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
cleanup:
|
|
mbedtls_platform_zeroize( sum, sizeof( sum ) );
|
|
|
|
return( ret );
|
|
}
|
|
|
|
int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx,
|
|
const unsigned char *input, size_t ilen )
|
|
{
|
|
mbedtls_md_handle_t md_info;
|
|
|
|
if( ctx == NULL )
|
|
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
|
|
|
|
#if !defined(MBEDTLS_MD_SINGLE_HASH)
|
|
if( ctx->hmac_ctx == NULL )
|
|
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
|
|
#endif /* !MBEDTLS_MD_SINGLE_HASH */
|
|
|
|
md_info = mbedtls_md_get_handle( ctx );
|
|
if( md_info == MBEDTLS_MD_INVALID_HANDLE )
|
|
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
|
|
|
|
return( mbedtls_md_info_update( md_info,
|
|
ctx->md_ctx, input,
|
|
ilen ) );
|
|
}
|
|
|
|
int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output )
|
|
{
|
|
int ret;
|
|
unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
|
|
unsigned char *opad;
|
|
|
|
mbedtls_md_handle_t md_info;
|
|
|
|
if( ctx == NULL )
|
|
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
|
|
|
|
#if !defined(MBEDTLS_MD_SINGLE_HASH)
|
|
if( ctx->hmac_ctx == NULL )
|
|
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
|
|
#endif /* !MBEDTLS_MD_SINGLE_HASH */
|
|
|
|
md_info = mbedtls_md_get_handle( ctx );
|
|
if( md_info == MBEDTLS_MD_INVALID_HANDLE )
|
|
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
|
|
|
|
opad = (unsigned char *) ctx->hmac_ctx +
|
|
mbedtls_md_info_block_size( md_info );
|
|
|
|
if( ( ret = mbedtls_md_info_finish( md_info, ctx->md_ctx, tmp ) ) != 0 )
|
|
return( ret );
|
|
|
|
if( ( ret = mbedtls_md_info_starts( md_info, ctx->md_ctx ) ) != 0 )
|
|
return( ret );
|
|
|
|
if( ( ret = mbedtls_md_info_update( md_info, ctx->md_ctx, opad,
|
|
mbedtls_md_info_block_size( md_info ) ) ) != 0 )
|
|
{
|
|
return( ret );
|
|
}
|
|
|
|
if( ( ret = mbedtls_md_info_update( md_info, ctx->md_ctx, tmp,
|
|
mbedtls_md_info_size( md_info ) ) ) != 0 )
|
|
{
|
|
return( ret );
|
|
}
|
|
|
|
if( ( ret = mbedtls_md_info_finish( md_info, ctx->md_ctx, output ) ) != 0 )
|
|
return( ret );
|
|
|
|
return( 0 );
|
|
}
|
|
|
|
int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx )
|
|
{
|
|
int ret;
|
|
unsigned char *ipad;
|
|
|
|
mbedtls_md_handle_t md_info;
|
|
|
|
if( ctx == NULL )
|
|
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
|
|
|
|
#if !defined(MBEDTLS_MD_SINGLE_HASH)
|
|
if( ctx->hmac_ctx == NULL )
|
|
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
|
|
#endif /* !MBEDTLS_MD_SINGLE_HASH */
|
|
|
|
md_info = mbedtls_md_get_handle( ctx );
|
|
if( md_info == MBEDTLS_MD_INVALID_HANDLE )
|
|
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
|
|
|
|
ipad = (unsigned char *) ctx->hmac_ctx;
|
|
|
|
ret = mbedtls_md_info_starts( md_info, ctx->md_ctx );
|
|
if( ret != 0 )
|
|
return( ret );
|
|
|
|
ret = mbedtls_md_info_update( md_info,
|
|
ctx->md_ctx, ipad,
|
|
mbedtls_md_info_block_size( md_info ) );
|
|
return( ret );
|
|
}
|
|
|
|
int mbedtls_md_hmac( mbedtls_md_handle_t md_info,
|
|
const unsigned char *key, size_t keylen,
|
|
const unsigned char *input, size_t ilen,
|
|
unsigned char *output )
|
|
{
|
|
mbedtls_md_context_t ctx;
|
|
int ret;
|
|
|
|
if( md_info == MBEDTLS_MD_INVALID_HANDLE )
|
|
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
|
|
|
|
mbedtls_md_init( &ctx );
|
|
|
|
if( ( ret = mbedtls_md_setup( &ctx, md_info, 1 ) ) != 0 )
|
|
goto cleanup;
|
|
|
|
if( ( ret = mbedtls_md_hmac_starts( &ctx, key, keylen ) ) != 0 )
|
|
goto cleanup;
|
|
if( ( ret = mbedtls_md_hmac_update( &ctx, input, ilen ) ) != 0 )
|
|
goto cleanup;
|
|
if( ( ret = mbedtls_md_hmac_finish( &ctx, output ) ) != 0 )
|
|
goto cleanup;
|
|
|
|
cleanup:
|
|
mbedtls_md_free( &ctx );
|
|
|
|
return( ret );
|
|
}
|
|
|
|
#if !defined(MBEDTLS_MD_SINGLE_HASH)
|
|
int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data )
|
|
{
|
|
return( mbedtls_md_process_internal( ctx, data ) );
|
|
}
|
|
#endif /* !MBEDTLS_MD_SINGLE_HASH */
|
|
|
|
unsigned char mbedtls_md_get_size( mbedtls_md_handle_t md_info )
|
|
{
|
|
if( md_info == MBEDTLS_MD_INVALID_HANDLE )
|
|
return( 0 );
|
|
|
|
return mbedtls_md_info_size( md_info );
|
|
}
|
|
|
|
mbedtls_md_type_t mbedtls_md_get_type( mbedtls_md_handle_t md_info )
|
|
{
|
|
if( md_info == MBEDTLS_MD_INVALID_HANDLE )
|
|
return( MBEDTLS_MD_NONE );
|
|
|
|
return mbedtls_md_info_type( md_info );
|
|
}
|
|
|
|
const char *mbedtls_md_get_name( mbedtls_md_handle_t md_info )
|
|
{
|
|
if( md_info == MBEDTLS_MD_INVALID_HANDLE )
|
|
return( NULL );
|
|
|
|
return mbedtls_md_info_name( md_info );
|
|
}
|
|
|
|
#endif /* MBEDTLS_MD_C */
|