Add dummy constant-flow HMAC function with tests
The dummy implementation is not constant-flow at all for now, it's just here as a starting point and a support for developing the tests and putting the infrastructure in place. Depending on the implementation strategy, there might be various corner cases depending on where the lengths fall relative to block boundaries. So it seems safer to just test all possible lengths in a given range than to use only a few randomly-chosen values. Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
This commit is contained in:
parent
2df1f1f16f
commit
045f094c81
5 changed files with 216 additions and 0 deletions
78
library/ssl_invasive.h
Normal file
78
library/ssl_invasive.h
Normal file
|
@ -0,0 +1,78 @@
|
|||
/**
|
||||
* \file ssl_invasive.h
|
||||
*
|
||||
* \brief SSL module: interfaces for invasive testing only.
|
||||
*
|
||||
* The interfaces in this file are intended for testing purposes only.
|
||||
* They SHOULD NOT be made available in library integrations except when
|
||||
* building the library for testing.
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2020, 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)
|
||||
*/
|
||||
#ifndef MBEDTLS_SSL_INVASIVE_H
|
||||
#define MBEDTLS_SSL_INVASIVE_H
|
||||
|
||||
#include "common.h"
|
||||
#include "mbedtls/md.h"
|
||||
|
||||
#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) && \
|
||||
( defined(MBEDTLS_SSL_PROTO_TLS1) || \
|
||||
defined(MBEDTLS_SSL_PROTO_TLS1_1) | \
|
||||
defined(MBEDTLS_SSL_PROTO_TLS1_2) )
|
||||
/** \brief Compute the HMAC of variable-length data with constant flow.
|
||||
*
|
||||
* This function computes the HMAC of the concatenation of \p add_data and \p
|
||||
* data, and does with a code flow and memory access pattern that does not
|
||||
* depend on \p data_len_secret, but only on \p min_data_len and \p
|
||||
* max_data_len. In particular, this function always reads exactly \p
|
||||
* max_data_len bytes from \p data.
|
||||
*
|
||||
* \param ctx The HMAC context. It must have keys configured
|
||||
* with mbedtls_md_hmac_starts(). It is reset using
|
||||
* mbedtls_md_hmac_reset() after the computation is
|
||||
* complete to prepare for the next computation.
|
||||
* \param add_data The additional data prepended to \p data. This
|
||||
* must point to a readable buffer of \p add_data_len
|
||||
* bytes.
|
||||
* \param add_data_len The length of \p add_data in bytes.
|
||||
* \param data The data appended to \p add_data. This must point
|
||||
* to a readable buffer of \p max_data_len bytes.
|
||||
* \param data_len_secret The length of the data to process in \p data.
|
||||
* This must be no less than \p min_data_len and no
|
||||
* greated than \p max_data_len.
|
||||
* \param min_data_len The minimal length of \p data in bytes.
|
||||
* \param max_data_len The maximal length of \p data in bytes.
|
||||
* \param output The HMAC will be written here. This must point to
|
||||
* a writeable buffer of sufficient size to hold the
|
||||
* HMAC value.
|
||||
*
|
||||
* \retval 0
|
||||
* Success.
|
||||
* \retval MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED
|
||||
* The hardware accelerator failed.
|
||||
*/
|
||||
int mbedtls_ssl_cf_hmac(
|
||||
mbedtls_md_context_t *ctx,
|
||||
const unsigned char *add_data, size_t add_data_len,
|
||||
const unsigned char *data, size_t data_len_secret,
|
||||
size_t min_data_len, size_t max_data_len,
|
||||
unsigned char *output );
|
||||
#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC && TLS 1.0-1.2 */
|
||||
|
||||
#endif /* MBEDTLS_SSL_INVASIVE_H */
|
|
@ -47,6 +47,8 @@
|
|||
#include "mbedtls/platform_util.h"
|
||||
#include "mbedtls/version.h"
|
||||
|
||||
#include "ssl_invasive.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
|
@ -1064,6 +1066,32 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl,
|
|||
return( 0 );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) && \
|
||||
( defined(MBEDTLS_SSL_PROTO_TLS1) || \
|
||||
defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
|
||||
defined(MBEDTLS_SSL_PROTO_TLS1_2) )
|
||||
/*
|
||||
* Compute HMAC of variable-length data with constant flow.
|
||||
*/
|
||||
int mbedtls_ssl_cf_hmac(
|
||||
mbedtls_md_context_t *ctx,
|
||||
const unsigned char *add_data, size_t add_data_len,
|
||||
const unsigned char *data, size_t data_len_secret,
|
||||
size_t min_data_len, size_t max_data_len,
|
||||
unsigned char *output )
|
||||
{
|
||||
/* WORK IN PROGRESS - THIS IS NOT CONSTANT FLOW AT ALL */
|
||||
(void) min_data_len;
|
||||
(void) max_data_len;
|
||||
mbedtls_md_hmac_update( ctx, add_data, add_data_len );
|
||||
mbedtls_md_hmac_update( ctx, data, data_len_secret );
|
||||
mbedtls_md_hmac_finish( ctx, output );
|
||||
mbedtls_md_hmac_reset( ctx );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC && TLS 1.0-1.2 */
|
||||
|
||||
int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
|
||||
mbedtls_ssl_transform *transform,
|
||||
mbedtls_record *rec )
|
||||
|
|
|
@ -9504,3 +9504,19 @@ ssl_serialize_session_load_buf_size:42:"data_files/server5.crt"
|
|||
Session serialization, load buffer size: large ticket, cert
|
||||
depends_on:MBEDTLS_SSL_SESSION_TICKETS:MBEDTLS_SSL_CLI_C:MBEDTLS_X509_USE_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_FS_IO
|
||||
ssl_serialize_session_load_buf_size:1023:"data_files/server5.crt"
|
||||
|
||||
Constant-flow HMAC: MD5
|
||||
depends_on:MBEDTLS_MD5_C
|
||||
ssl_cf_hmac:MBEDTLS_MD_MD5
|
||||
|
||||
Constant-flow HMAC: SHA1
|
||||
depends_on:MBEDTLS_SHA1_C
|
||||
ssl_cf_hmac:MBEDTLS_MD_SHA1
|
||||
|
||||
Constant-flow HMAC: SHA256
|
||||
depends_on:MBEDTLS_SHA256_C
|
||||
ssl_cf_hmac:MBEDTLS_MD_SHA256
|
||||
|
||||
Constant-flow HMAC: SHA384
|
||||
depends_on:MBEDTLS_SHA512_C:!MBEDTLS_SHA512_NO_SHA384
|
||||
ssl_cf_hmac:MBEDTLS_MD_SHA384
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include <mbedtls/timing.h>
|
||||
#include <mbedtls/debug.h>
|
||||
|
||||
#include <ssl_invasive.h>
|
||||
|
||||
typedef struct log_pattern
|
||||
{
|
||||
const char *pattern;
|
||||
|
@ -4050,3 +4052,94 @@ void resize_buffers_renegotiate_mfl( int mfl, int legacy_renegotiation,
|
|||
goto exit;
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE depends_on:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_AES_C:MBEDTLS_SSL_PROTO_TLS1_2 */
|
||||
void ssl_cf_hmac( int hash )
|
||||
{
|
||||
/*
|
||||
* Test the function mbedtls_ssl_cf_hmac() against a reference
|
||||
* implementation.
|
||||
*
|
||||
* Note: the dependency is actually on TLS 1.0-1.2 and (AES or ARIA or
|
||||
* Camellia or DES), but since the test framework doesn't support
|
||||
* alternation in dependencies, just depend on the most common.
|
||||
*/
|
||||
mbedtls_md_context_t ctx, ref_ctx;
|
||||
const mbedtls_md_info_t *md_info;
|
||||
size_t out_len, block_size;
|
||||
size_t min_in_len, in_len, max_in_len, i;
|
||||
/* TLS additional data is 13 bytes (hence the "lucky 13" name) */
|
||||
unsigned char add_data[13];
|
||||
unsigned char ref_out[MBEDTLS_MD_MAX_SIZE];
|
||||
unsigned char *data = NULL;
|
||||
unsigned char *out = NULL;
|
||||
unsigned char rec_num = 0;
|
||||
|
||||
mbedtls_md_init( &ctx );
|
||||
mbedtls_md_init( &ref_ctx );
|
||||
|
||||
md_info = mbedtls_md_info_from_type( hash );
|
||||
TEST_ASSERT( md_info != NULL );
|
||||
out_len = mbedtls_md_get_size( md_info );
|
||||
TEST_ASSERT( out_len != 0 );
|
||||
block_size = hash == MBEDTLS_MD_SHA384 ? 128 : 64;
|
||||
|
||||
/* Use allocated out buffer to catch overwrites */
|
||||
ASSERT_ALLOC( out, out_len );
|
||||
|
||||
/* Set up contexts with the given hash and a dummy key */
|
||||
TEST_EQUAL( 0, mbedtls_md_setup( &ctx, md_info, 1 ) );
|
||||
TEST_EQUAL( 0, mbedtls_md_setup( &ref_ctx, md_info, 1 ) );
|
||||
memset( ref_out, 42, sizeof( ref_out ) );
|
||||
TEST_EQUAL( 0, mbedtls_md_hmac_starts( &ctx, ref_out, out_len ) );
|
||||
TEST_EQUAL( 0, mbedtls_md_hmac_starts( &ref_ctx, ref_out, out_len ) );
|
||||
memset( ref_out, 0, sizeof( ref_out ) );
|
||||
|
||||
/*
|
||||
* Test all possible lengths up to a point. The difference between
|
||||
* max_in_len and min_in_len is at most 255, and make sure they both vary
|
||||
* by at least one block size.
|
||||
*/
|
||||
for( max_in_len = 0; max_in_len <= 255 + block_size; max_in_len++ )
|
||||
{
|
||||
/* Use allocated in buffer to catch overreads */
|
||||
ASSERT_ALLOC( data, max_in_len != 0 ? max_in_len : 1 );
|
||||
|
||||
min_in_len = max_in_len > 255 ? max_in_len - 255 : 0;
|
||||
for( in_len = min_in_len; in_len <= max_in_len; in_len++ )
|
||||
{
|
||||
/* Set up dummy data and add_data */
|
||||
rec_num++;
|
||||
memset( add_data, rec_num, sizeof( add_data ) );
|
||||
for( i = 0; i < in_len; i++ )
|
||||
data[i] = ( i & 0xff ) ^ rec_num;
|
||||
|
||||
/* Get the function's result */
|
||||
TEST_EQUAL( 0, mbedtls_ssl_cf_hmac( &ctx, add_data, sizeof( add_data ),
|
||||
data, in_len,
|
||||
min_in_len, max_in_len,
|
||||
out ) );
|
||||
|
||||
/* Compute the reference result */
|
||||
TEST_EQUAL( 0, mbedtls_md_hmac_update( &ref_ctx, add_data,
|
||||
sizeof( add_data ) ) );
|
||||
TEST_EQUAL( 0, mbedtls_md_hmac_update( &ref_ctx, data, in_len ) );
|
||||
TEST_EQUAL( 0, mbedtls_md_hmac_finish( &ref_ctx, ref_out ) );
|
||||
TEST_EQUAL( 0, mbedtls_md_hmac_reset( &ref_ctx ) );
|
||||
|
||||
/* Compare */
|
||||
ASSERT_COMPARE( out, out_len, ref_out, out_len );
|
||||
}
|
||||
|
||||
mbedtls_free( data );
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
exit:
|
||||
mbedtls_md_free( &ref_ctx );
|
||||
mbedtls_md_free( &ctx );
|
||||
|
||||
mbedtls_free( data );
|
||||
mbedtls_free( out );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
|
|
@ -245,6 +245,7 @@
|
|||
<ClInclude Include="..\..\library\psa_crypto_service_integration.h" />
|
||||
<ClInclude Include="..\..\library\psa_crypto_slot_management.h" />
|
||||
<ClInclude Include="..\..\library\psa_crypto_storage.h" />
|
||||
<ClInclude Include="..\..\library\ssl_invasive.h" />
|
||||
<ClInclude Include="..\..\3rdparty\everest\include\everest\everest.h" />
|
||||
<ClInclude Include="..\..\3rdparty\everest\include\everest\Hacl_Curve25519.h" />
|
||||
<ClInclude Include="..\..\3rdparty\everest\include\everest\kremlib.h" />
|
||||
|
|
Loading…
Reference in a new issue