Merge branch 'mbedtls-2.16-restricted'

This commit is contained in:
Janos Follath 2020-08-26 14:16:04 +01:00
commit 36169d479f
19 changed files with 725 additions and 139 deletions

View file

@ -0,0 +1,11 @@
Security
* In (D)TLS record decryption, when using a CBC ciphersuites without the
Encrypt-then-Mac extension, use constant code flow memory access patterns
to extract and check the MAC. This is an improvement to the existing
countermeasure against Lucky 13 attacks. The previous countermeasure was
effective against network-based attackers, but less so against local
attackers. The new countermeasure defends against local attackers, even
if they have access to fine-grained measurements. In particular, this
fixes a local Lucky 13 cache attack found and reported by Tuba Yavuz,
Farhaan Fowze, Ken (Yihan) Bai, Grant Hernandez, and Kevin Butler
(University of Florida) and Dave Tian (Purdue University).

View file

@ -0,0 +1,6 @@
Security
* Fix side channel in RSA private key operations and static (finite-field)
Diffie-Hellman. An adversary with precise enough timing and memory access
information (typically an untrusted operating system attacking a secure
enclave) could bypass an existing counter-measure (base blinding) and
potentially fully recover the private key.

View file

@ -0,0 +1,4 @@
Security
* Fix a 1-byte buffer overread in mbedtls_x509_crl_parse_der().
Credit to OSS-Fuzz for detecting the problem and to Philippe Antoine
for pinpointing the problematic code.

View file

@ -0,0 +1,4 @@
Security
* Zeroising of plaintext buffers in mbedtls_ssl_read() to erase unused
application data from memory. Reported in #689 by
Johan Uppman Bruce of Sectra.

View file

@ -197,6 +197,16 @@
#error "MBEDTLS_ENTROPY_FORCE_SHA256 defined, but not all prerequisites" #error "MBEDTLS_ENTROPY_FORCE_SHA256 defined, but not all prerequisites"
#endif #endif
#if defined(__has_feature)
#if __has_feature(memory_sanitizer)
#define MBEDTLS_HAS_MEMSAN
#endif
#endif
#if defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN) && !defined(MBEDTLS_HAS_MEMSAN)
#error "MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN requires building with MemorySanitizer"
#endif
#undef MBEDTLS_HAS_MEMSAN
#if defined(MBEDTLS_TEST_NULL_ENTROPY) && \ #if defined(MBEDTLS_TEST_NULL_ENTROPY) && \
( !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) ) ( !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) )
#error "MBEDTLS_TEST_NULL_ENTROPY defined, but not all prerequisites" #error "MBEDTLS_TEST_NULL_ENTROPY defined, but not all prerequisites"

View file

@ -549,6 +549,42 @@
//#define MBEDTLS_ECP_RANDOMIZE_MXZ_ALT //#define MBEDTLS_ECP_RANDOMIZE_MXZ_ALT
//#define MBEDTLS_ECP_NORMALIZE_MXZ_ALT //#define MBEDTLS_ECP_NORMALIZE_MXZ_ALT
/**
* \def MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN
*
* Enable testing of the constant-flow nature of some sensitive functions with
* clang's MemorySanitizer. This causes some existing tests to also test
* this non-functional property of the code under test.
*
* This setting requires compiling with clang -fsanitize=memory. The test
* suites can then be run normally.
*
* \warning This macro is only used for extended testing; it is not considered
* part of the library's API, so it may change or disappear at any time.
*
* Uncomment to enable testing of the constant-flow nature of selected code.
*/
//#define MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN
/**
* \def MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND
*
* Enable testing of the constant-flow nature of some sensitive functions with
* valgrind's memcheck tool. This causes some existing tests to also test
* this non-functional property of the code under test.
*
* This setting requires valgrind headers for building, and is only useful for
* testing if the tests suites are run with valgrind's memcheck. This can be
* done for an individual test suite with 'valgrind ./test_suite_xxx', or when
* using CMake, this can be done for all test suites with 'make memcheck'.
*
* \warning This macro is only used for extended testing; it is not considered
* part of the library's API, so it may change or disappear at any time.
*
* Uncomment to enable testing of the constant-flow nature of selected code.
*/
//#define MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND
/** /**
* \def MBEDTLS_TEST_NULL_ENTROPY * \def MBEDTLS_TEST_NULL_ENTROPY
* *

View file

@ -150,6 +150,24 @@
#define MBEDTLS_SSL_RETRANS_WAITING 2 #define MBEDTLS_SSL_RETRANS_WAITING 2
#define MBEDTLS_SSL_RETRANS_FINISHED 3 #define MBEDTLS_SSL_RETRANS_FINISHED 3
/* This macro determines whether CBC is supported. */
#if defined(MBEDTLS_CIPHER_MODE_CBC) && \
( defined(MBEDTLS_AES_C) || \
defined(MBEDTLS_CAMELLIA_C) || \
defined(MBEDTLS_ARIA_C) || \
defined(MBEDTLS_DES_C) )
#define MBEDTLS_SSL_SOME_SUITES_USE_CBC
#endif
/* This macro determines whether the CBC construct used in TLS 1.0-1.2 (as
* opposed to the very different CBC construct used in SSLv3) is supported. */
#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) )
#define MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC
#endif
/* /*
* Allow extra bytes for record, authentication and encryption overhead: * Allow extra bytes for record, authentication and encryption overhead:
* counter (8) + header (5) + IV(16) + MAC (16-48) + padding (0-256) * counter (8) + header (5) + IV(16) + MAC (16-48) + padding (0-256)
@ -841,6 +859,73 @@ int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
MBEDTLS_SSL_PROTO_TLS1_2 */ MBEDTLS_SSL_PROTO_TLS1_2 */
#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
/** \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() and use one of the
* following hashes: SHA-384, SHA-256, SHA-1 or MD-5.
* 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
* greater 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 writable 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 );
/** \brief Copy data from a secret position with constant flow.
*
* This function copies \p len bytes from \p src_base + \p offset_secret to \p
* dst, with a code flow and memory access pattern that does not depend on \p
* offset_secret, but only on \p offset_min, \p offset_max and \p len.
*
* \param dst The destination buffer. This must point to a writable
* buffer of at least \p len bytes.
* \param src_base The base of the source buffer. This must point to a
* readable buffer of at least \p offset_max + \p len
* bytes.
* \param offset_secret The offset in the source buffer from which to copy.
* This must be no less than \p offset_min and no greater
* than \p offset_max.
* \param offset_min The minimal value of \p offset_secret.
* \param offset_max The maximal value of \p offset_secret.
* \param len The number of bytes to copy.
*/
void mbedtls_ssl_cf_memcpy_offset( unsigned char *dst,
const unsigned char *src_base,
size_t offset_secret,
size_t offset_min, size_t offset_max,
size_t len );
#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -348,6 +348,32 @@ cleanup:
return( 0 ); return( 0 );
} }
/*
* Pick a random R in the range [2, M) for blinding purposes
*/
static int dhm_random_below( mbedtls_mpi *R, const mbedtls_mpi *M,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
int ret, count;
count = 0;
do
{
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( R, mbedtls_mpi_size( M ), f_rng, p_rng ) );
while( mbedtls_mpi_cmp_mpi( R, M ) >= 0 )
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( R, 1 ) );
if( count++ > 10 )
return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
}
while( mbedtls_mpi_cmp_int( R, 1 ) <= 0 );
cleanup:
return( ret );
}
/* /*
* Use the blinding method and optimisation suggested in section 10 of: * Use the blinding method and optimisation suggested in section 10 of:
* KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA, * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
@ -357,7 +383,10 @@ cleanup:
static int dhm_update_blinding( mbedtls_dhm_context *ctx, static int dhm_update_blinding( mbedtls_dhm_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{ {
int ret, count; int ret;
mbedtls_mpi R;
mbedtls_mpi_init( &R );
/* /*
* Don't use any blinding the first time a particular X is used, * Don't use any blinding the first time a particular X is used,
@ -392,24 +421,23 @@ static int dhm_update_blinding( mbedtls_dhm_context *ctx,
*/ */
/* Vi = random( 2, P-1 ) */ /* Vi = random( 2, P-1 ) */
count = 0; MBEDTLS_MPI_CHK( dhm_random_below( &ctx->Vi, &ctx->P, f_rng, p_rng ) );
do
{
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vi, mbedtls_mpi_size( &ctx->P ), f_rng, p_rng ) );
while( mbedtls_mpi_cmp_mpi( &ctx->Vi, &ctx->P ) >= 0 ) /* Vf = Vi^-X mod P
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->Vi, 1 ) ); * First compute Vi^-1 = R * (R Vi)^-1, (avoiding leaks from inv_mod),
* then elevate to the Xth power. */
MBEDTLS_MPI_CHK( dhm_random_below( &R, &ctx->P, f_rng, p_rng ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vi, &R ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vf, &ctx->Vf, &ctx->P ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &R ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
if( count++ > 10 )
return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
}
while( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) <= 0 );
/* Vf = Vi^-X mod P */
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vf, &ctx->Vi, &ctx->P ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Vf, &ctx->Vf, &ctx->X, &ctx->P, &ctx->RP ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Vf, &ctx->Vf, &ctx->X, &ctx->P, &ctx->RP ) );
cleanup: cleanup:
mbedtls_mpi_free( &R );
return( ret ); return( ret );
} }

View file

@ -806,6 +806,9 @@ static int rsa_prepare_blinding( mbedtls_rsa_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{ {
int ret, count = 0; int ret, count = 0;
mbedtls_mpi R;
mbedtls_mpi_init( &R );
if( ctx->Vf.p != NULL ) if( ctx->Vf.p != NULL )
{ {
@ -821,18 +824,41 @@ static int rsa_prepare_blinding( mbedtls_rsa_context *ctx,
/* Unblinding value: Vf = random number, invertible mod N */ /* Unblinding value: Vf = random number, invertible mod N */
do { do {
if( count++ > 10 ) if( count++ > 10 )
return( MBEDTLS_ERR_RSA_RNG_FAILED ); {
ret = MBEDTLS_ERR_RSA_RNG_FAILED;
goto cleanup;
}
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vf, ctx->len - 1, f_rng, p_rng ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vf, ctx->len - 1, f_rng, p_rng ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &ctx->Vi, &ctx->Vf, &ctx->N ) );
} while( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 );
/* Blinding value: Vi = Vf^(-e) mod N */ /* Compute Vf^-1 as R * (R Vf)^-1 to avoid leaks from inv_mod. */
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vi, &ctx->Vf, &ctx->N ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, ctx->len - 1, f_rng, p_rng ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vf, &R ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
/* At this point, Vi is invertible mod N if and only if both Vf and R
* are invertible mod N. If one of them isn't, we don't need to know
* which one, we just loop and choose new values for both of them.
* (Each iteration succeeds with overwhelming probability.) */
ret = mbedtls_mpi_inv_mod( &ctx->Vi, &ctx->Vi, &ctx->N );
if( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
continue;
if( ret != 0 )
goto cleanup;
/* Finish the computation of Vf^-1 = R * (R Vf)^-1 */
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &R ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
} while( 0 );
/* Blinding value: Vi = Vf^(-e) mod N
* (Vi already contains Vf^-1 at this point) */
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Vi, &ctx->Vi, &ctx->E, &ctx->N, &ctx->RN ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Vi, &ctx->Vi, &ctx->E, &ctx->N, &ctx->RN ) );
cleanup: cleanup:
mbedtls_mpi_free( &R );
return( ret ); return( ret );
} }

View file

@ -1431,32 +1431,10 @@ static void ssl_mac( mbedtls_md_context_t *md_ctx,
#endif /* MBEDTLS_SSL_PROTO_SSL3 */ #endif /* MBEDTLS_SSL_PROTO_SSL3 */
#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) || \ #if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) || \
( defined(MBEDTLS_CIPHER_MODE_CBC) && \ defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC)
( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) || defined(MBEDTLS_ARIA_C)) )
#define SSL_SOME_MODES_USE_MAC #define SSL_SOME_MODES_USE_MAC
#endif #endif
/* The function below is only used in the Lucky 13 counter-measure in
* ssl_decrypt_buf(). These are the defines that guard the call site. */
#if defined(SSL_SOME_MODES_USE_MAC) && \
( defined(MBEDTLS_SSL_PROTO_TLS1) || \
defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
defined(MBEDTLS_SSL_PROTO_TLS1_2) )
/* This function makes sure every byte in the memory region is accessed
* (in ascending addresses order) */
static void ssl_read_memory( unsigned char *p, size_t len )
{
unsigned char acc = 0;
volatile unsigned char force;
for( ; len != 0; p++, len-- )
acc ^= *p;
force = acc;
(void) force;
}
#endif /* SSL_SOME_MODES_USE_MAC && ( TLS1 || TLS1_1 || TLS1_2 ) */
/* /*
* Encryption/decryption functions * Encryption/decryption functions
*/ */
@ -1667,8 +1645,7 @@ static int ssl_encrypt_buf( mbedtls_ssl_context *ssl )
} }
else else
#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */ #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */
#if defined(MBEDTLS_CIPHER_MODE_CBC) && \ #if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC)
( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) || defined(MBEDTLS_ARIA_C) )
if( mode == MBEDTLS_MODE_CBC ) if( mode == MBEDTLS_MODE_CBC )
{ {
int ret; int ret;
@ -1787,8 +1764,7 @@ static int ssl_encrypt_buf( mbedtls_ssl_context *ssl )
#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
} }
else else
#endif /* MBEDTLS_CIPHER_MODE_CBC && #endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC */
( MBEDTLS_AES_C || MBEDTLS_CAMELLIA_C || MBEDTLS_ARIA_C ) */
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
@ -1806,6 +1782,156 @@ static int ssl_encrypt_buf( mbedtls_ssl_context *ssl )
return( 0 ); return( 0 );
} }
#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
/*
* Constant-flow conditional memcpy:
* - if c1 == c2, equivalent to memcpy(dst, src, len),
* - otherwise, a no-op,
* but with execution flow independent of the values of c1 and c2.
*
* Use only bit operations to avoid branches that could be used by some
* compilers on some platforms to translate comparison operators.
*/
static void mbedtls_ssl_cf_memcpy_if_eq( unsigned char *dst,
const unsigned char *src,
size_t len,
size_t c1, size_t c2 )
{
/* diff = 0 if c1 == c2, non-zero otherwise */
const size_t diff = c1 ^ c2;
/* MSVC has a warning about unary minus on unsigned integer types,
* but this is well-defined and precisely what we want to do here. */
#if defined(_MSC_VER)
#pragma warning( push )
#pragma warning( disable : 4146 )
#endif
/* diff_msb's most significant bit is equal to c1 != c2 */
const size_t diff_msb = ( diff | -diff );
/* diff1 = c1 != c2 */
const size_t diff1 = diff_msb >> ( sizeof( diff_msb ) * 8 - 1 );
/* mask = c1 != c2 ? 0xff : 0x00 */
const unsigned char mask = (unsigned char) -diff1;
#if defined(_MSC_VER)
#pragma warning( pop )
#endif
/* dst[i] = c1 != c2 ? dst[i] : src[i] */
size_t i;
for( i = 0; i < len; i++ )
dst[i] = ( dst[i] & mask ) | ( src[i] & ~mask );
}
/*
* Compute HMAC of variable-length data with constant flow.
*
* Only works with MD-5, SHA-1, SHA-256 and SHA-384.
* (Otherwise, computation of block_size needs to be adapted.)
*/
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 )
{
/*
* This function breaks the HMAC abstraction and uses the md_clone()
* extension to the MD API in order to get constant-flow behaviour.
*
* HMAC(msg) is defined as HASH(okey + HASH(ikey + msg)) where + means
* concatenation, and okey/ikey are the XOR of the key with some fixed bit
* patterns (see RFC 2104, sec. 2), which are stored in ctx->hmac_ctx.
*
* We'll first compute inner_hash = HASH(ikey + msg) by hashing up to
* minlen, then cloning the context, and for each byte up to maxlen
* finishing up the hash computation, keeping only the correct result.
*
* Then we only need to compute HASH(okey + inner_hash) and we're done.
*/
const mbedtls_md_type_t md_alg = mbedtls_md_get_type( ctx->md_info );
/* TLS 1.0-1.2 only support SHA-384, SHA-256, SHA-1, MD-5,
* all of which have the same block size except SHA-384. */
const size_t block_size = md_alg == MBEDTLS_MD_SHA384 ? 128 : 64;
const unsigned char * const ikey = ctx->hmac_ctx;
const unsigned char * const okey = ikey + block_size;
const size_t hash_size = mbedtls_md_get_size( ctx->md_info );
unsigned char aux_out[MBEDTLS_MD_MAX_SIZE];
mbedtls_md_context_t aux;
size_t offset;
int ret;
mbedtls_md_init( &aux );
#define MD_CHK( func_call ) \
do { \
ret = (func_call); \
if( ret != 0 ) \
goto cleanup; \
} while( 0 )
MD_CHK( mbedtls_md_setup( &aux, ctx->md_info, 0 ) );
/* After hmac_start() of hmac_reset(), ikey has already been hashed,
* so we can start directly with the message */
MD_CHK( mbedtls_md_update( ctx, add_data, add_data_len ) );
MD_CHK( mbedtls_md_update( ctx, data, min_data_len ) );
/* For each possible length, compute the hash up to that point */
for( offset = min_data_len; offset <= max_data_len; offset++ )
{
MD_CHK( mbedtls_md_clone( &aux, ctx ) );
MD_CHK( mbedtls_md_finish( &aux, aux_out ) );
/* Keep only the correct inner_hash in the output buffer */
mbedtls_ssl_cf_memcpy_if_eq( output, aux_out, hash_size,
offset, data_len_secret );
if( offset < max_data_len )
MD_CHK( mbedtls_md_update( ctx, data + offset, 1 ) );
}
/* Now compute HASH(okey + inner_hash) */
MD_CHK( mbedtls_md_starts( ctx ) );
MD_CHK( mbedtls_md_update( ctx, okey, block_size ) );
MD_CHK( mbedtls_md_update( ctx, output, hash_size ) );
MD_CHK( mbedtls_md_finish( ctx, output ) );
/* Done, get ready for next time */
MD_CHK( mbedtls_md_hmac_reset( ctx ) );
#undef MD_CHK
cleanup:
mbedtls_md_free( &aux );
return( ret );
}
/*
* Constant-flow memcpy from variable position in buffer.
* - functionally equivalent to memcpy(dst, src + offset_secret, len)
* - but with execution flow independent from the value of offset_secret.
*/
void mbedtls_ssl_cf_memcpy_offset( unsigned char *dst,
const unsigned char *src_base,
size_t offset_secret,
size_t offset_min, size_t offset_max,
size_t len )
{
size_t offset;
for( offset = offset_min; offset <= offset_max; offset++ )
{
mbedtls_ssl_cf_memcpy_if_eq( dst, src_base + offset, len,
offset, offset_secret );
}
}
#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
static int ssl_decrypt_buf( mbedtls_ssl_context *ssl ) static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
{ {
mbedtls_cipher_mode_t mode; mbedtls_cipher_mode_t mode;
@ -1960,8 +2086,7 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
} }
else else
#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */ #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */
#if defined(MBEDTLS_CIPHER_MODE_CBC) && \ #if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC)
( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) || defined(MBEDTLS_ARIA_C) )
if( mode == MBEDTLS_MODE_CBC ) if( mode == MBEDTLS_MODE_CBC )
{ {
/* /*
@ -2174,8 +2299,7 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
ssl->in_msglen -= padlen; ssl->in_msglen -= padlen;
} }
else else
#endif /* MBEDTLS_CIPHER_MODE_CBC && #endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC) */
( MBEDTLS_AES_C || MBEDTLS_CAMELLIA_C || MBEDTLS_ARIA_C ) */
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
@ -2194,6 +2318,7 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
if( auth_done == 0 ) if( auth_done == 0 )
{ {
unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD]; unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD];
unsigned char mac_peer[MBEDTLS_SSL_MAC_ADD];
ssl->in_msglen -= ssl->transform_in->maclen; ssl->in_msglen -= ssl->transform_in->maclen;
@ -2208,6 +2333,8 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
ssl->in_msg, ssl->in_msglen, ssl->in_msg, ssl->in_msglen,
ssl->in_ctr, ssl->in_msgtype, ssl->in_ctr, ssl->in_msgtype,
mac_expect ); mac_expect );
memcpy( mac_peer, ssl->in_msg + ssl->in_msglen,
ssl->transform_in->maclen );
} }
else else
#endif /* MBEDTLS_SSL_PROTO_SSL3 */ #endif /* MBEDTLS_SSL_PROTO_SSL3 */
@ -2215,34 +2342,8 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
defined(MBEDTLS_SSL_PROTO_TLS1_2) defined(MBEDTLS_SSL_PROTO_TLS1_2)
if( ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 ) if( ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 )
{ {
/* int ret;
* Process MAC and always update for padlen afterwards to make unsigned char add_data[13];
* total time independent of padlen.
*
* Known timing attacks:
* - Lucky Thirteen (http://www.isg.rhul.ac.uk/tls/TLStiming.pdf)
*
* To compensate for different timings for the MAC calculation
* depending on how much padding was removed (which is determined
* by padlen), process extra_run more blocks through the hash
* function.
*
* The formula in the paper is
* extra_run = ceil( (L1-55) / 64 ) - ceil( (L2-55) / 64 )
* where L1 is the size of the header plus the decrypted message
* plus CBC padding and L2 is the size of the header plus the
* decrypted message. This is for an underlying hash function
* with 64-byte blocks.
* We use ( (Lx+8) / 64 ) to handle 'negative Lx' values
* correctly. We round down instead of up, so -56 is the correct
* value for our calculations instead of -55.
*
* Repeat the formula rather than defining a block_size variable.
* This avoids requiring division by a variable at runtime
* (which would be marginally less efficient and would require
* linking an extra division function in some builds).
*/
size_t j, extra_run = 0;
/* /*
* The next two sizes are the minimum and maximum values of * The next two sizes are the minimum and maximum values of
@ -2257,66 +2358,25 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
const size_t max_len = ssl->in_msglen + padlen; const size_t max_len = ssl->in_msglen + padlen;
const size_t min_len = ( max_len > 256 ) ? max_len - 256 : 0; const size_t min_len = ( max_len > 256 ) ? max_len - 256 : 0;
switch( ssl->transform_in->ciphersuite_info->mac ) memcpy( add_data + 0, ssl->in_ctr, 8 );
memcpy( add_data + 8, ssl->in_hdr, 3 );
memcpy( add_data + 11, ssl->in_len, 2 );
ret = mbedtls_ssl_cf_hmac( &ssl->transform_in->md_ctx_dec,
add_data, sizeof( add_data ),
ssl->in_msg, ssl->in_msglen,
min_len, max_len,
mac_expect );
if( ret != 0 )
{ {
#if defined(MBEDTLS_MD5_C) || defined(MBEDTLS_SHA1_C) || \ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_cf_hmac", ret );
defined(MBEDTLS_SHA256_C) return( ret );
case MBEDTLS_MD_MD5:
case MBEDTLS_MD_SHA1:
case MBEDTLS_MD_SHA256:
/* 8 bytes of message size, 64-byte compression blocks */
extra_run = ( 13 + ssl->in_msglen + padlen + 8 ) / 64 -
( 13 + ssl->in_msglen + 8 ) / 64;
break;
#endif
#if defined(MBEDTLS_SHA512_C)
case MBEDTLS_MD_SHA384:
/* 16 bytes of message size, 128-byte compression blocks */
extra_run = ( 13 + ssl->in_msglen + padlen + 16 ) / 128 -
( 13 + ssl->in_msglen + 16 ) / 128;
break;
#endif
default:
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
} }
extra_run &= correct * 0xFF; mbedtls_ssl_cf_memcpy_offset( mac_peer, ssl->in_msg,
ssl->in_msglen,
mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_ctr, 8 ); min_len, max_len,
mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_hdr, 3 ); ssl->transform_in->maclen );
mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_len, 2 );
mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_msg,
ssl->in_msglen );
/* Make sure we access everything even when padlen > 0. This
* makes the synchronisation requirements for just-in-time
* Prime+Probe attacks much tighter and hopefully impractical. */
ssl_read_memory( ssl->in_msg + ssl->in_msglen, padlen );
mbedtls_md_hmac_finish( &ssl->transform_in->md_ctx_dec, mac_expect );
/* Dummy calls to compression function.
* Call mbedtls_md_process at least once due to cache attacks
* that observe whether md_process() was called of not.
* Respect the usual start-(process|update)-finish sequence for
* the sake of hardware accelerators that might require it. */
mbedtls_md_starts( &ssl->transform_in->md_ctx_dec );
for( j = 0; j < extra_run + 1; j++ )
mbedtls_md_process( &ssl->transform_in->md_ctx_dec, ssl->in_msg );
{
/* The switch statement above already checks that we're using
* one of MD-5, SHA-1, SHA-256 or SHA-384. */
unsigned char tmp[384 / 8];
mbedtls_md_finish( &ssl->transform_in->md_ctx_dec, tmp );
}
mbedtls_md_hmac_reset( &ssl->transform_in->md_ctx_dec );
/* Make sure we access all the memory that could contain the MAC,
* before we check it in the next code block. This makes the
* synchronisation requirements for just-in-time Prime+Probe
* attacks much tighter and hopefully impractical. */
ssl_read_memory( ssl->in_msg + min_len,
max_len - min_len + ssl->transform_in->maclen );
} }
else else
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
@ -2328,11 +2388,10 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_SSL_DEBUG_ALL) #if defined(MBEDTLS_SSL_DEBUG_ALL)
MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect, ssl->transform_in->maclen ); MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect, ssl->transform_in->maclen );
MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", ssl->in_msg + ssl->in_msglen, MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", mac_peer, ssl->transform_in->maclen );
ssl->transform_in->maclen );
#endif #endif
if( mbedtls_ssl_safer_memcmp( ssl->in_msg + ssl->in_msglen, mac_expect, if( mbedtls_ssl_safer_memcmp( mac_peer, mac_expect,
ssl->transform_in->maclen ) != 0 ) ssl->transform_in->maclen ) != 0 )
{ {
#if defined(MBEDTLS_SSL_DEBUG_ALL) #if defined(MBEDTLS_SSL_DEBUG_ALL)
@ -8594,6 +8653,10 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len )
memcpy( buf, ssl->in_offt, n ); memcpy( buf, ssl->in_offt, n );
ssl->in_msglen -= n; ssl->in_msglen -= n;
/* Zeroising the plaintext buffer to erase unused application data
from the memory. */
mbedtls_platform_zeroize( ssl->in_offt, n );
if( ssl->in_msglen == 0 ) if( ssl->in_msglen == 0 )
{ {
/* all bytes consumed */ /* all bytes consumed */

View file

@ -277,6 +277,12 @@ static const char *features[] = {
#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) #if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT)
"MBEDTLS_ECP_NORMALIZE_MXZ_ALT", "MBEDTLS_ECP_NORMALIZE_MXZ_ALT",
#endif /* MBEDTLS_ECP_NORMALIZE_MXZ_ALT */ #endif /* MBEDTLS_ECP_NORMALIZE_MXZ_ALT */
#if defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN)
"MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN",
#endif /* MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN */
#if defined(MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND)
"MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND",
#endif /* MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND */
#if defined(MBEDTLS_TEST_NULL_ENTROPY) #if defined(MBEDTLS_TEST_NULL_ENTROPY)
"MBEDTLS_TEST_NULL_ENTROPY", "MBEDTLS_TEST_NULL_ENTROPY",
#endif /* MBEDTLS_TEST_NULL_ENTROPY */ #endif /* MBEDTLS_TEST_NULL_ENTROPY */

View file

@ -283,13 +283,13 @@ static int x509_get_entries( unsigned char **p,
size_t len2; size_t len2;
const unsigned char *end2; const unsigned char *end2;
cur_entry->raw.tag = **p;
if( ( ret = mbedtls_asn1_get_tag( p, end, &len2, if( ( ret = mbedtls_asn1_get_tag( p, end, &len2,
MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED ) ) != 0 ) MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED ) ) != 0 )
{ {
return( ret ); return( ret );
} }
cur_entry->raw.tag = **p;
cur_entry->raw.p = *p; cur_entry->raw.p = *p;
cur_entry->raw.len = len2; cur_entry->raw.len = len2;
end2 = *p + len2; end2 = *p + len2;

View file

@ -739,6 +739,22 @@ int query_config( const char *config )
} }
#endif /* MBEDTLS_ECP_NORMALIZE_MXZ_ALT */ #endif /* MBEDTLS_ECP_NORMALIZE_MXZ_ALT */
#if defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN)
if( strcmp( "MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN", config ) == 0 )
{
MACRO_EXPANSION_TO_STR( MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN );
return( 0 );
}
#endif /* MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN */
#if defined(MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND)
if( strcmp( "MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND", config ) == 0 )
{
MACRO_EXPANSION_TO_STR( MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND );
return( 0 );
}
#endif /* MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND */
#if defined(MBEDTLS_TEST_NULL_ENTROPY) #if defined(MBEDTLS_TEST_NULL_ENTROPY)
if( strcmp( "MBEDTLS_TEST_NULL_ENTROPY", config ) == 0 ) if( strcmp( "MBEDTLS_TEST_NULL_ENTROPY", config ) == 0 )
{ {

View file

@ -126,6 +126,8 @@ MBEDTLS_REMOVE_3DES_CIPHERSUITES
MBEDTLS_REMOVE_ARC4_CIPHERSUITES MBEDTLS_REMOVE_ARC4_CIPHERSUITES
MBEDTLS_RSA_NO_CRT MBEDTLS_RSA_NO_CRT
MBEDTLS_SSL_HW_RECORD_ACCEL MBEDTLS_SSL_HW_RECORD_ACCEL
MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN
MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND
MBEDTLS_TEST_NULL_ENTROPY MBEDTLS_TEST_NULL_ENTROPY
MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
MBEDTLS_ZLIB_SUPPORT MBEDTLS_ZLIB_SUPPORT

View file

@ -1029,6 +1029,46 @@ component_test_full_cmake_clang () {
if_build_succeeded env OPENSSL_CMD="$OPENSSL_NEXT" tests/compat.sh -e '^$' -f 'ARIA\|CHACHA' if_build_succeeded env OPENSSL_CMD="$OPENSSL_NEXT" tests/compat.sh -e '^$' -f 'ARIA\|CHACHA'
} }
component_test_memsan_constant_flow () {
# This tests both (1) accesses to undefined memory, and (2) branches or
# memory access depending on secret values. To distinguish between those:
# - unset MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN - does the failure persist?
# - or alternatively, change the build type to MemSanDbg, which enables
# origin tracking and nicer stack traces (which are useful for debugging
# anyway), and check if the origin was TEST_CF_SECRET() or something else.
msg "build: cmake MSan (clang), full config with constant flow testing"
scripts/config.pl full
scripts/config.pl set MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN
scripts/config.pl unset MBEDTLS_AESNI_C # memsan doesn't grok asm
CC=clang cmake -D CMAKE_BUILD_TYPE:String=MemSan .
make
msg "test: main suites (Msan + constant flow)"
make test
}
component_test_valgrind_constant_flow () {
# This tests both (1) everything that valgrind's memcheck usually checks
# (heap buffer overflows, use of uninitialized memory, use-after-free,
# etc.) and (2) branches or memory access depending on secret values,
# which will be reported as uninitialized memory. To distinguish between
# secret and actually uninitialized:
# - unset MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND - does the failure persist?
# - or alternatively, build with debug info and manually run the offending
# test suite with valgrind --track-origins=yes, then check if the origin
# was TEST_CF_SECRET() or something else.
msg "build: cmake release GCC, full config with constant flow testing"
scripts/config.pl full
scripts/config.pl set MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND
cmake -D CMAKE_BUILD_TYPE:String=Release .
make
# this only shows a summary of the results (how many of each type)
# details are left in Testing/<date>/DynamicAnalysis.xml
msg "test: main suites (valgrind + constant flow)"
make memcheck
}
component_test_default_no_deprecated () { component_test_default_no_deprecated () {
# Test that removing the deprecated features from the default # Test that removing the deprecated features from the default
# configuration leaves something consistent. # configuration leaves something consistent.

View file

@ -46,6 +46,52 @@ typedef UINT32 uint32_t;
#include <strings.h> #include <strings.h>
#endif #endif
/*
* Define the two macros
*
* #define TEST_CF_SECRET(ptr, size)
* #define TEST_CF_PUBLIC(ptr, size)
*
* that can be used in tests to mark a memory area as secret (no branch or
* memory access should depend on it) or public (default, only needs to be
* marked explicitly when it was derived from secret data).
*
* Arguments:
* - ptr: a pointer to the memory area to be marked
* - size: the size in bytes of the memory area
*
* Implementation:
* The basic idea is that of ctgrind <https://github.com/agl/ctgrind>: we can
* re-use tools that were designed for checking use of uninitialized memory.
* This file contains two implementations: one based on MemorySanitizer, the
* other on valgrind's memcheck. If none of them is enabled, dummy macros that
* do nothing are defined for convenience.
*/
#if defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN)
#include <sanitizer/msan_interface.h>
/* Use macros to avoid messing up with origin tracking */
#define TEST_CF_SECRET __msan_allocated_memory
// void __msan_allocated_memory(const volatile void* data, size_t size);
#define TEST_CF_PUBLIC __msan_unpoison
// void __msan_unpoison(const volatile void *a, size_t size);
#elif defined(MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND)
#include <valgrind/memcheck.h>
#define TEST_CF_SECRET VALGRIND_MAKE_MEM_UNDEFINED
// VALGRIND_MAKE_MEM_UNDEFINED(_qzz_addr, _qzz_len)
#define TEST_CF_PUBLIC VALGRIND_MAKE_MEM_DEFINED
// VALGRIND_MAKE_MEM_DEFINED(_qzz_addr, _qzz_len)
#else /* MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN ||
MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND */
#define TEST_CF_SECRET(ptr, size)
#define TEST_CF_PUBLIC(ptr, size)
#endif /* MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN */
/* Type for Hex parameters */ /* Type for Hex parameters */
typedef struct data_tag typedef struct data_tag
{ {

View file

@ -57,3 +57,31 @@ ssl_dtls_replay:"abcd12340000abcd12340100":"abcd123400ff":0
SSL SET_HOSTNAME memory leak: call ssl_set_hostname twice SSL SET_HOSTNAME memory leak: call ssl_set_hostname twice
ssl_set_hostname_twice:"server0":"server1" ssl_set_hostname_twice:"server0":"server1"
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
# these are the numbers we'd get with an empty plaintext and truncated HMAC
Constant-flow memcpy from offset: small
ssl_cf_memcpy_offset:0:5:10
# we could get this with 255-bytes plaintext and untruncated SHA-256
Constant-flow memcpy from offset: medium
ssl_cf_memcpy_offset:0:255:32
# we could get this with 355-bytes plaintext and untruncated SHA-384
Constant-flow memcpy from offset: large
ssl_cf_memcpy_offset:100:339:48

View file

@ -52,3 +52,128 @@ void ssl_set_hostname_twice( char *hostname0, char *hostname1 )
mbedtls_ssl_free( &ssl ); mbedtls_ssl_free( &ssl );
} }
/* END_CASE */ /* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
void ssl_cf_hmac( int hash )
{
/*
* Test the function mbedtls_ssl_cf_hmac() against a reference
* implementation.
*/
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 */
out = mbedtls_calloc( 1, out_len );
TEST_ASSERT( out != NULL );
/* Set up contexts with the given hash and a dummy key */
TEST_ASSERT( 0 == mbedtls_md_setup( &ctx, md_info, 1 ) );
TEST_ASSERT( 0 == mbedtls_md_setup( &ref_ctx, md_info, 1 ) );
memset( ref_out, 42, sizeof( ref_out ) );
TEST_ASSERT( 0 == mbedtls_md_hmac_starts( &ctx, ref_out, out_len ) );
TEST_ASSERT( 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 */
data = mbedtls_calloc( 1, max_in_len );
TEST_ASSERT( data != NULL || max_in_len == 0 );
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_CF_SECRET( &in_len, sizeof( in_len ) );
TEST_ASSERT( 0 == mbedtls_ssl_cf_hmac( &ctx, add_data, sizeof( add_data ),
data, in_len,
min_in_len, max_in_len,
out ) );
TEST_CF_PUBLIC( &in_len, sizeof( in_len ) );
TEST_CF_PUBLIC( out, out_len );
/* Compute the reference result */
TEST_ASSERT( 0 == mbedtls_md_hmac_update( &ref_ctx, add_data,
sizeof( add_data ) ) );
TEST_ASSERT( 0 == mbedtls_md_hmac_update( &ref_ctx, data, in_len ) );
TEST_ASSERT( 0 == mbedtls_md_hmac_finish( &ref_ctx, ref_out ) );
TEST_ASSERT( 0 == mbedtls_md_hmac_reset( &ref_ctx ) );
/* Compare */
TEST_ASSERT( 0 == memcmp( out, 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 */
/* BEGIN_CASE depends_on:MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
void ssl_cf_memcpy_offset( int offset_min, int offset_max, int len )
{
unsigned char *dst = NULL;
unsigned char *src = NULL;
size_t src_len = offset_max + len;
size_t secret;
dst = mbedtls_calloc( 1, len );
TEST_ASSERT( dst != NULL );
src = mbedtls_calloc( 1, src_len );
TEST_ASSERT( src != NULL );
/* Fill src in a way that we can detect if we copied the right bytes */
rnd_std_rand( NULL, src, src_len );
for( secret = offset_min; secret <= (size_t) offset_max; secret++ )
{
TEST_CF_SECRET( &secret, sizeof( secret ) );
mbedtls_ssl_cf_memcpy_offset( dst, src, secret,
offset_min, offset_max, len );
TEST_CF_PUBLIC( &secret, sizeof( secret ) );
TEST_CF_PUBLIC( dst, len );
TEST_ASSERT( memcmp( dst, src + secret, len ) == 0 );
}
exit:
mbedtls_free( dst );
mbedtls_free( src );
}
/* END_CASE */

View file

@ -1352,10 +1352,60 @@ X509 CRL ASN1 (TBSCertList, sig present, len mismatch)
depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA256_C depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA256_C
x509parse_crl:"305d3047020100300d06092a864886f70d01010e0500300f310d300b0603550403130441424344170c303930313031303030303030301430128202abcd170c303831323331323335393539300d06092a864886f70d01010e05000302000100":"":MBEDTLS_ERR_X509_INVALID_FORMAT + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH x509parse_crl:"305d3047020100300d06092a864886f70d01010e0500300f310d300b0603550403130441424344170c303930313031303030303030301430128202abcd170c303831323331323335393539300d06092a864886f70d01010e05000302000100":"":MBEDTLS_ERR_X509_INVALID_FORMAT + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
# 305c
# 3047 tbsCertList TBSCertList
# 020100 version INTEGER OPTIONAL
# 300d signatureAlgorithm AlgorithmIdentifi
# 06092a864886f70d01010e
# 0500
# 300f issuer Name
# 310d300b0603550403130441424344
# 170c303930313031303030303030 thisUpdate Time
# 3014 revokedCertificates
# 3012 entry 1
# 8202abcd userCertificate CertificateSerialNum
# 170c303831323331323335393539 revocationDate Time
# 300d signatureAlgorithm AlgorithmIdentifi
# 06092a864886f70d01010e
# 0500
# 03020001 signatureValue BIT STRING
# The subsequent TBSCertList negative tests remove or modify some elements.
X509 CRL ASN1 (TBSCertList, sig present) X509 CRL ASN1 (TBSCertList, sig present)
depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA256_C depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA256_C
x509parse_crl:"305c3047020100300d06092a864886f70d01010e0500300f310d300b0603550403130441424344170c303930313031303030303030301430128202abcd170c303831323331323335393539300d06092a864886f70d01010e050003020001":"CRL version \: 1\nissuer name \: CN=ABCD\nthis update \: 2009-01-01 00\:00\:00\nnext update \: 0000-00-00 00\:00\:00\nRevoked certificates\:\nserial number\: AB\:CD revocation date\: 2008-12-31 23\:59\:59\nsigned using \: RSA with SHA-224\n":0 x509parse_crl:"305c3047020100300d06092a864886f70d01010e0500300f310d300b0603550403130441424344170c303930313031303030303030301430128202abcd170c303831323331323335393539300d06092a864886f70d01010e050003020001":"CRL version \: 1\nissuer name \: CN=ABCD\nthis update \: 2009-01-01 00\:00\:00\nnext update \: 0000-00-00 00\:00\:00\nRevoked certificates\:\nserial number\: AB\:CD revocation date\: 2008-12-31 23\:59\:59\nsigned using \: RSA with SHA-224\n":0
X509 CRL ASN1 (TBSCertList, signatureValue missing)
depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA256_C
x509parse_crl:"30583047020100300d06092a864886f70d01010e0500300f310d300b0603550403130441424344170c303930313031303030303030301430128202abcd170c303831323331323335393539300d06092a864886f70d01010e0500":"":MBEDTLS_ERR_X509_INVALID_SIGNATURE + MBEDTLS_ERR_ASN1_OUT_OF_DATA
X509 CRL ASN1 (TBSCertList, signatureAlgorithm missing)
depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA256_C
x509parse_crl:"30493047020100300d06092a864886f70d01010e0500300f310d300b0603550403130441424344170c303930313031303030303030301430128202abcd170c303831323331323335393539":"":MBEDTLS_ERR_X509_INVALID_ALG + MBEDTLS_ERR_ASN1_OUT_OF_DATA
X509 CRL ASN1 (TBSCertList, single empty entry at end)
depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA256_C
x509parse_crl:"30373035020100300d06092a864886f70d01010e0500300f310d300b0603550403130441424344170c30393031303130303030303030023000":"":MBEDTLS_ERR_X509_INVALID_SERIAL + MBEDTLS_ERR_ASN1_OUT_OF_DATA
X509 CRL ASN1 (TBSCertList, good entry then empty entry at end)
depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA256_C
x509parse_crl:"304b3049020100300d06092a864886f70d01010e0500300f310d300b0603550403130441424344170c303930313031303030303030301630128202abcd170c3038313233313233353935393000":"":MBEDTLS_ERR_X509_INVALID_SERIAL + MBEDTLS_ERR_ASN1_OUT_OF_DATA
X509 CRL ASN1 (TBSCertList, missing time in entry)
depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA256_C
x509parse_crl:"304e3039020100300d06092a864886f70d01010e0500300f310d300b0603550403130441424344170c303930313031303030303030300630048202abcd300d06092a864886f70d01010e050003020001":"":MBEDTLS_ERR_X509_INVALID_DATE + MBEDTLS_ERR_ASN1_OUT_OF_DATA
X509 CRL ASN1 (TBSCertList, missing time in entry at end)
depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA256_C
x509parse_crl:"303b3039020100300d06092a864886f70d01010e0500300f310d300b0603550403130441424344170c303930313031303030303030300630048202abcd":"":MBEDTLS_ERR_X509_INVALID_DATE + MBEDTLS_ERR_ASN1_OUT_OF_DATA
X509 CRL ASN1 (TBSCertList, invalid tag for time in entry)
depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA256_C
x509parse_crl:"305c3047020100300d06092a864886f70d01010e0500300f310d300b0603550403130441424344170c303930313031303030303030301430128202abcd190c303831323331323335393539300d06092a864886f70d01010e050003020001":"":MBEDTLS_ERR_X509_INVALID_DATE + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
X509 CRL ASN1 (TBSCertList, invalid tag for serial)
depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA256_C
x509parse_crl:"305c3047020100300d06092a864886f70d01010e0500300f310d300b0603550403130441424344170c303930313031303030303030301430128402abcd170c303831323331323335393539300d06092a864886f70d01010e050003020001":"":MBEDTLS_ERR_X509_INVALID_SERIAL + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
X509 CRL ASN1 (TBSCertList, no entries) X509 CRL ASN1 (TBSCertList, no entries)
depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA256_C depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA256_C
x509parse_crl:"30463031020100300d06092a864886f70d01010e0500300f310d300b0603550403130441424344170c303930313031303030303030300d06092a864886f70d01010e050003020001":"CRL version \: 1\nissuer name \: CN=ABCD\nthis update \: 2009-01-01 00\:00\:00\nnext update \: 0000-00-00 00\:00\:00\nRevoked certificates\:\nsigned using \: RSA with SHA-224\n":0 x509parse_crl:"30463031020100300d06092a864886f70d01010e0500300f310d300b0603550403130441424344170c303930313031303030303030300d06092a864886f70d01010e050003020001":"CRL version \: 1\nissuer name \: CN=ABCD\nthis update \: 2009-01-01 00\:00\:00\nnext update \: 0000-00-00 00\:00\:00\nRevoked certificates\:\nsigned using \: RSA with SHA-224\n":0