Merge pull request #3553 from AndrzejKurek/crc-calculation-base
Validate AES keys after each use checking CRC
diff --git a/include/mbedtls/asn1.h b/include/mbedtls/asn1.h
index adab7a1..44cf94a 100644
--- a/include/mbedtls/asn1.h
+++ b/include/mbedtls/asn1.h
@@ -130,11 +130,11 @@
*/
#define MBEDTLS_OID_CMP(oid_str, oid_buf) \
( ( MBEDTLS_OID_SIZE(oid_str) != (oid_buf)->len ) || \
- mbedtls_platform_memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) != 0 )
+ mbedtls_platform_memequal( (oid_str), (oid_buf)->p, (oid_buf)->len) != 0 )
#define MBEDTLS_OID_CMP_RAW(oid_str, oid_buf, oid_buf_len) \
( ( MBEDTLS_OID_SIZE(oid_str) != (oid_buf_len) ) || \
- mbedtls_platform_memcmp( (oid_str), (oid_buf), (oid_buf_len) ) != 0 )
+ mbedtls_platform_memequal( (oid_str), (oid_buf), (oid_buf_len) ) != 0 )
#ifdef __cplusplus
extern "C" {
diff --git a/include/mbedtls/compat-1.3.h b/include/mbedtls/compat-1.3.h
index 6e0fb8d..bd6de87 100644
--- a/include/mbedtls/compat-1.3.h
+++ b/include/mbedtls/compat-1.3.h
@@ -2231,7 +2231,7 @@
#define rsa_rsassa_pss_verify_ext mbedtls_rsa_rsassa_pss_verify_ext
#define rsa_self_test mbedtls_rsa_self_test
#define rsa_set_padding mbedtls_rsa_set_padding
-#define safer_memcmp mbedtls_platform_memcmp
+#define safer_memcmp mbedtls_platform_memequal
#define set_alarm mbedtls_set_alarm
#define sha1 mbedtls_sha1
#define sha1_context mbedtls_sha1_context
diff --git a/include/mbedtls/hmac_drbg.h b/include/mbedtls/hmac_drbg.h
index eec05e4..19a7c44 100644
--- a/include/mbedtls/hmac_drbg.h
+++ b/include/mbedtls/hmac_drbg.h
@@ -77,6 +77,9 @@
#define MBEDTLS_HMAC_DRBG_PR_OFF 0x55555555 /**< No prediction resistance */
#define MBEDTLS_HMAC_DRBG_PR_ON 0x2AAAAAAA /**< Prediction resistance enabled */
+#define MBEDTLS_HMAC_DRBG_RESEED 0x78547854 /**< Default environment, reseeding enabled */
+#define MBEDTLS_HMAC_DRBG_NO_RESEED 0x07AB87F0 /**< Reseeding disabled, no f_entropy required */
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -91,7 +94,7 @@
mbedtls_md_context_t md_ctx; /*!< HMAC context (inc. K) */
unsigned char V[MBEDTLS_MD_MAX_SIZE]; /*!< V in the spec */
int reseed_counter; /*!< reseed counter */
-
+ int reseed_flag; /*!< disables reseeding if set to MBEDTLS_HMAC_DRBG_NO_RESEED */
/* Administrative state */
size_t entropy_len; /*!< entropy bytes grabbed on each (re)seed */
int prediction_resistance; /*!< enable prediction resistance (Automatic
@@ -221,6 +224,20 @@
int resistance );
/**
+ * \brief This function turns reseeding on or off.
+ * Default value is on.
+ *
+ * \note If set to MBEDTLS_HMAC_DRBG_NO_RESEED, this function
+ * disables reseeding, providing a no_reseed environment.
+ * f_entropy can then be null.
+ *
+ * \param ctx The HMAC_DRBG context.
+ * \param reseed_flag #MBEDTLS_HMAC_DRBG_NO_RESEED or #MBEDTLS_HMAC_DRBG_RESEED
+ */
+void mbedtls_hmac_drbg_set_reseeding( mbedtls_hmac_drbg_context *ctx,
+ int reseed_flag );
+
+/**
* \brief This function sets the amount of entropy grabbed on each
* seed or reseed.
*
@@ -228,9 +245,11 @@
*
* \param ctx The HMAC_DRBG context.
* \param len The amount of entropy to grab, in bytes.
+ *
+ * \return \c 0 if \p len is valid, MBEDTLS_HMAC_DRBG_MAX_INPUT otherwise.
*/
-void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx,
- size_t len );
+int mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx,
+ size_t len );
/**
* \brief Set the reseed interval.
diff --git a/include/mbedtls/platform_util.h b/include/mbedtls/platform_util.h
index 7d16074..c65c853 100644
--- a/include/mbedtls/platform_util.h
+++ b/include/mbedtls/platform_util.h
@@ -161,40 +161,43 @@
* \param buf Buffer to be zeroized
* \param len Length of the buffer in bytes
*
+ * \return The value of \p buf if the operation was successful.
+ * \return NULL if a potential FI attack was detected or input parameters
+ * are not valid.
*/
-void mbedtls_platform_zeroize( void *buf, size_t len );
+void *mbedtls_platform_zeroize( void *buf, size_t len );
/**
* \brief Secure memset
*
- * This is a constant-time version of memset(). If
- * MBEDTLS_ENTROPY_HARDWARE_ALT is defined, the buffer is
- * initialised with random data and the order is also
- * randomised using the hardware RNG in order to further harden
- * against side-channel attacks.
+ * This is a constant-time version of memset(). The buffer is
+ * initialised with random data and the order is also randomised
+ * using the RNG in order to further harden against side-channel
+ * attacks.
*
* \param ptr Buffer to be set.
* \param value Value to be used when setting the buffer.
* \param num The length of the buffer in bytes.
*
- * \return The value of \p ptr.
+ * \return The value of \p ptr if the operation was successful.
+ * \return NULL if a potential FI attack was detected.
*/
void *mbedtls_platform_memset( void *ptr, int value, size_t num );
/**
* \brief Secure memcpy
*
- * This is a constant-time version of memcpy(). If
- * MBEDTLS_ENTROPY_HARDWARE_ALT is defined, the buffer is
- * initialised with random data and the order is also
- * randomised using the hardware RNG in order to further harden
- * against side-channel attacks.
+ * This is a constant-time version of memcpy(). The buffer is
+ * initialised with random data and the order is also randomised
+ * using the RNG in order to further harden against side-channel
+ * attacks.
*
* \param dst Destination buffer where the data is being copied to.
* \param src Source buffer where the data is being copied from.
* \param num The length of the buffers in bytes.
*
* \return The value of \p dst.
+ * \return NULL if a potential FI attack was detected.
*/
void *mbedtls_platform_memcpy( void *dst, const void *src, size_t num );
@@ -215,12 +218,11 @@
int mbedtls_platform_memmove( void *dst, const void *src, size_t num );
/**
- * \brief Secure memcmp
+ * \brief Secure check if the buffers have the same data.
*
- * This is a constant-time version of memcmp(). If
- * MBEDTLS_ENTROPY_HARDWARE_ALT is defined, the order is also
- * randomised using the hardware RNG in order to further harden
- * against side-channel attacks.
+ * This is a constant-time version of memcmp(), but without checking
+ * if the bytes are greater or lower. The order is also randomised
+ * using the RNG in order to further harden against side-channel attacks.
*
* \param buf1 First buffer to compare.
* \param buf2 Second buffer to compare against.
@@ -229,16 +231,11 @@
* \return 0 if the buffers were equal or an unspecified non-zero value
* otherwise.
*/
-int mbedtls_platform_memcmp( const void *buf1, const void *buf2, size_t num );
+int mbedtls_platform_memequal( const void *buf1, const void *buf2, size_t num );
/**
* \brief RNG-function for getting a random 32-bit integer.
*
- *
- * \note Currently the function is dependent of hardware providing an
- * rng with MBEDTLS_ENTROPY_HARDWARE_ALT. By default, 0 is
- * returned.
- *
* \return The generated random number.
*/
uint32_t mbedtls_platform_random_uint32( void );
@@ -253,10 +250,6 @@
* cryptographically secure RNG, but provide an RNG for utility
* functions.
*
- * \note Currently the function is dependent of hardware providing an
- * rng with MBEDTLS_ENTROPY_HARDWARE_ALT. By default, 0 is
- * returned.
- *
* \note If the given range is [0, 0), 0 is returned.
*
* \param num Max-value for the generated random number, exclusive.
@@ -264,7 +257,7 @@
*
* \return The generated random number.
*/
-uint32_t mbedtls_platform_random_in_range( size_t num );
+uint32_t mbedtls_platform_random_in_range( uint32_t num );
/**
* \brief Random delay function.
@@ -275,8 +268,9 @@
* Duration of the delay is random as number of variable increments
* is randomized.
*
- * \note Currently the function is dependent of hardware providing an
- * rng with MBEDTLS_ENTROPY_HARDWARE_ALT.
+ * \note This function works only if the MBEDTLS_FI_COUNTERMEASURES flag
+ * is defined in the configuration. Otherwise, the function does
+ * nothing.
*/
void mbedtls_platform_random_delay( void );
diff --git a/library/asn1parse.c b/library/asn1parse.c
index 8cdc1f1..1563716 100644
--- a/library/asn1parse.c
+++ b/library/asn1parse.c
@@ -431,7 +431,7 @@
while( list != NULL )
{
if( list->oid.len == len &&
- mbedtls_platform_memcmp( list->oid.p, oid, len ) == 0 )
+ mbedtls_platform_memequal( list->oid.p, oid, len ) == 0 )
{
break;
}
diff --git a/library/asn1write.c b/library/asn1write.c
index e393ef8..fe10e21 100644
--- a/library/asn1write.c
+++ b/library/asn1write.c
@@ -348,7 +348,7 @@
while( list != NULL )
{
if( list->oid.len == len &&
- mbedtls_platform_memcmp( list->oid.p, oid, len ) == 0 )
+ mbedtls_platform_memequal( list->oid.p, oid, len ) == 0 )
{
break;
}
diff --git a/library/des.c b/library/des.c
index c920328..8f01ec1 100644
--- a/library/des.c
+++ b/library/des.c
@@ -417,7 +417,7 @@
int i;
for( i = 0; i < WEAK_KEY_COUNT; i++ )
- if( mbedtls_platform_memcmp( weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0 )
+ if( mbedtls_platform_memequal( weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0 )
return( 1 );
return( 0 );
diff --git a/library/ecdsa.c b/library/ecdsa.c
index 6cfaa08..a0b890d 100644
--- a/library/ecdsa.c
+++ b/library/ecdsa.c
@@ -482,6 +482,7 @@
mbedtls_hmac_drbg_context rng_ctx_blind;
mbedtls_hmac_drbg_init( &rng_ctx_blind );
+ mbedtls_hmac_drbg_set_reseeding( &rng_ctx_blind, MBEDTLS_HMAC_DRBG_NO_RESEED );
p_rng_blind_det = &rng_ctx_blind;
mbedtls_hmac_drbg_seed_buf( p_rng_blind_det, md_info,
@@ -509,6 +510,7 @@
* a valid ECDSA signature.
*/
p_rng_blind_det = p_rng;
+ mbedtls_hmac_drbg_set_reseeding( p_rng_blind_det, MBEDTLS_HMAC_DRBG_NO_RESEED );
#endif /* MBEDTLS_ECP_RESTARTABLE */
/*
diff --git a/library/entropy.c b/library/entropy.c
index 8db3d94..2b1e7ef 100644
--- a/library/entropy.c
+++ b/library/entropy.c
@@ -462,9 +462,10 @@
for( i = 0; i < ctx->source_count; i++ )
ctx->source[i].size = 0;
- mbedtls_platform_memcpy( output, buf, len );
-
- ret = 0;
+ if( output == mbedtls_platform_memcpy( output, buf, len ) )
+ {
+ ret = 0;
+ }
exit:
mbedtls_platform_zeroize( buf, sizeof( buf ) );
diff --git a/library/hmac_drbg.c b/library/hmac_drbg.c
index 58750c8..d8669c3 100644
--- a/library/hmac_drbg.c
+++ b/library/hmac_drbg.c
@@ -62,6 +62,8 @@
{
memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) );
+ ctx->prediction_resistance = MBEDTLS_HMAC_DRBG_PR_OFF;
+ ctx->reseed_flag = MBEDTLS_HMAC_DRBG_RESEED;
#if defined(MBEDTLS_THREADING_C)
mbedtls_mutex_init( &ctx->mutex );
#endif
@@ -210,7 +212,7 @@
size_t seedlen = 0;
size_t total_entropy_len;
int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
- volatile const unsigned char *additional_dup = additional;
+ const unsigned char * volatile additional_dup = additional;
volatile size_t len_dup = len;
int reseed_counter_backup = -1;
@@ -388,11 +390,24 @@
}
/*
+ * Set the reseeding flag
+ */
+void mbedtls_hmac_drbg_set_reseeding( mbedtls_hmac_drbg_context *ctx,
+ int reseed_flag )
+{
+ ctx->reseed_flag = reseed_flag;
+}
+
+/*
* Set entropy length grabbed for seeding
*/
-void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
+int mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
{
+ if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT )
+ return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
+
ctx->entropy_len = len;
+ return 0;
}
/*
@@ -417,7 +432,7 @@
mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
size_t md_len = mbedtls_md_get_size(
mbedtls_md_get_handle( &ctx->md_ctx ) );
- size_t left = out_len;
+ volatile size_t left = out_len;
unsigned char *out = output;
/* II. Check request length */
@@ -429,14 +444,20 @@
return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
/* 1. (aka VII and IX) Check reseed counter and PR */
- if( ctx->f_entropy != NULL && /* For no-reseeding instances */
+ if( ctx->reseed_flag != MBEDTLS_HMAC_DRBG_NO_RESEED &&
( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
ctx->reseed_counter > ctx->reseed_interval ) )
{
- if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
- return( ret );
-
- add_len = 0; /* VII.4 */
+ if( ctx->f_entropy == NULL )
+ {
+ return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
+ }
+ else
+ {
+ if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
+ return( ret );
+ add_len = 0; /* VII.4 */
+ }
}
/* 2. Use additional data if any */
diff --git a/library/oid.c b/library/oid.c
index 00a02c3..98235a1 100644
--- a/library/oid.c
+++ b/library/oid.c
@@ -75,7 +75,7 @@
if( p == NULL || oid == NULL ) return( NULL ); \
while( cur->asn1 != NULL ) { \
if( cur->asn1_len == oid->len && \
- mbedtls_platform_memcmp( cur->asn1, oid->p, oid->len ) == 0 ) { \
+ mbedtls_platform_memequal( cur->asn1, oid->p, oid->len ) == 0 ) { \
return( p ); \
} \
p++; \
diff --git a/library/pem.c b/library/pem.c
index 5e2fca9..41a4931 100644
--- a/library/pem.c
+++ b/library/pem.c
@@ -273,7 +273,7 @@
enc = 0;
- if( s2 - s1 >= 22 && mbedtls_platform_memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 )
+ if( s2 - s1 >= 22 && mbedtls_platform_memequal( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 )
{
#if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) && \
( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) )
@@ -286,7 +286,7 @@
#if defined(MBEDTLS_DES_C)
- if( s2 - s1 >= 23 && mbedtls_platform_memcmp( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) == 0 )
+ if( s2 - s1 >= 23 && mbedtls_platform_memequal( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) == 0 )
{
enc_alg = MBEDTLS_CIPHER_DES_EDE3_CBC;
@@ -296,7 +296,7 @@
s1 += 16;
}
- else if( s2 - s1 >= 18 && mbedtls_platform_memcmp( s1, "DEK-Info: DES-CBC,", 18 ) == 0 )
+ else if( s2 - s1 >= 18 && mbedtls_platform_memequal( s1, "DEK-Info: DES-CBC,", 18 ) == 0 )
{
enc_alg = MBEDTLS_CIPHER_DES_CBC;
@@ -309,15 +309,15 @@
#endif /* MBEDTLS_DES_C */
#if defined(MBEDTLS_AES_C)
- if( s2 - s1 >= 14 && mbedtls_platform_memcmp( s1, "DEK-Info: AES-", 14 ) == 0 )
+ if( s2 - s1 >= 14 && mbedtls_platform_memequal( s1, "DEK-Info: AES-", 14 ) == 0 )
{
if( s2 - s1 < 22 )
return( MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG );
- else if( mbedtls_platform_memcmp( s1, "DEK-Info: AES-128-CBC,", 22 ) == 0 )
+ else if( mbedtls_platform_memequal( s1, "DEK-Info: AES-128-CBC,", 22 ) == 0 )
enc_alg = MBEDTLS_CIPHER_AES_128_CBC;
- else if( mbedtls_platform_memcmp( s1, "DEK-Info: AES-192-CBC,", 22 ) == 0 )
+ else if( mbedtls_platform_memequal( s1, "DEK-Info: AES-192-CBC,", 22 ) == 0 )
enc_alg = MBEDTLS_CIPHER_AES_192_CBC;
- else if( mbedtls_platform_memcmp( s1, "DEK-Info: AES-256-CBC,", 22 ) == 0 )
+ else if( mbedtls_platform_memequal( s1, "DEK-Info: AES-256-CBC,", 22 ) == 0 )
enc_alg = MBEDTLS_CIPHER_AES_256_CBC;
else
return( MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG );
diff --git a/library/pk.c b/library/pk.c
index fea7576..4976f1f 100644
--- a/library/pk.c
+++ b/library/pk.c
@@ -556,7 +556,7 @@
const mbedtls_uecc_keypair *uecc_prv =
(const mbedtls_uecc_keypair *) prv;
- if( mbedtls_platform_memcmp( uecc_pub->public_key,
+ if( mbedtls_platform_memequal( uecc_pub->public_key,
uecc_prv->public_key,
2 * NUM_ECC_BYTES ) == 0 )
{
diff --git a/library/pkparse.c b/library/pkparse.c
index 411fbaa..83974f8 100644
--- a/library/pkparse.c
+++ b/library/pkparse.c
@@ -309,7 +309,7 @@
return( ret );
if( len != MBEDTLS_OID_SIZE( MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD ) ||
- mbedtls_platform_memcmp( p, MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD, len ) != 0 )
+ mbedtls_platform_memequal( p, MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD, len ) != 0 )
{
return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
}
@@ -561,9 +561,13 @@
if( buf[0] != 0x04 )
return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
- mbedtls_platform_memcpy( uecc_keypair->public_key, buf + 1, 2 * NUM_ECC_BYTES );
+ if( mbedtls_platform_memcpy( uecc_keypair->public_key, buf + 1, 2 * NUM_ECC_BYTES ) ==
+ uecc_keypair->public_key )
+ {
+ return( 0 );
+ }
- return( 0 );
+ return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
}
static int pk_get_ueccpubkey( unsigned char **p,
@@ -976,7 +980,11 @@
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
- mbedtls_platform_memcpy( keypair->private_key, p, len );
+ if( mbedtls_platform_memcpy( keypair->private_key, p, len ) !=
+ keypair->private_key )
+ {
+ return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+ }
p += len;
diff --git a/library/platform_util.c b/library/platform_util.c
index fc6eb5a..3b098d2 100644
--- a/library/platform_util.c
+++ b/library/platform_util.c
@@ -51,9 +51,20 @@
#include <stddef.h>
#include <string.h>
-/* Max number of loops for mbedtls_platform_random_delay */
+/* Max number of loops for mbedtls_platform_random_delay. */
#define MAX_RAND_DELAY 100
+/* Parameters for the linear congruential generator used as a non-cryptographic
+ * random number generator. The same parameters are used by e.g. ANSI C. */
+#define RAND_MULTIPLIER 1103515245
+#define RAND_INCREMENT 12345
+#define RAND_MODULUS 0x80000000
+
+/* The number of iterations after which the seed of the non-cryptographic
+ * random number generator will be changed. This is used only if the
+ * MBEDTLS_ENTROPY_HARDWARE_ALT option is enabled. */
+#define RAND_SEED_LIFE 10000
+
#if !defined(MBEDTLS_PLATFORM_ZEROIZE_ALT)
/*
* This implementation should never be optimized out by the compiler
@@ -84,67 +95,142 @@
void *mbedtls_platform_memset( void *, int, size_t );
static void * (* const volatile memset_func)( void *, int, size_t ) = mbedtls_platform_memset;
-void mbedtls_platform_zeroize( void *buf, size_t len )
+void *mbedtls_platform_zeroize( void *buf, size_t len )
{
- MBEDTLS_INTERNAL_VALIDATE( len == 0 || buf != NULL );
+ volatile size_t vlen = len;
- if( len > 0 )
- memset_func( buf, 0, len );
+ MBEDTLS_INTERNAL_VALIDATE_RET( ( len == 0 || buf != NULL ), NULL );
+
+ if( vlen > 0 )
+ {
+ return memset_func( buf, 0, vlen );
+ }
+ else
+ {
+ mbedtls_platform_random_delay();
+ if( vlen == 0 && vlen == len )
+ {
+ return buf;
+ }
+ }
+ return NULL;
}
#endif /* MBEDTLS_PLATFORM_ZEROIZE_ALT */
void *mbedtls_platform_memset( void *ptr, int value, size_t num )
{
- /* Randomize start offset. */
- size_t start_offset = (size_t) mbedtls_platform_random_in_range( num );
- /* Randomize data */
- uint32_t data = mbedtls_platform_random_in_range( 256 );
+ size_t i, start_offset;
+ volatile size_t flow_counter = 0;
+ volatile char *b = ptr;
+ char rnd_data;
- /* Perform a pair of memset operations from random locations with
- * random data */
- memset( (void *) ( (unsigned char *) ptr + start_offset ), data,
- ( num - start_offset ) );
- memset( (void *) ptr, data, start_offset );
+ start_offset = (size_t) mbedtls_platform_random_in_range( (uint32_t) num );
+ rnd_data = (char) mbedtls_platform_random_in_range( 256 );
- /* Perform the original memset */
- return( memset( ptr, value, num ) );
+ /* Perform a memset operations with random data and start from a random
+ * location */
+ for( i = start_offset; i < num; ++i )
+ {
+ b[i] = rnd_data;
+ flow_counter++;
+ }
+
+ /* Start from a random location with target data */
+ for( i = start_offset; i < num; ++i )
+ {
+ b[i] = value;
+ flow_counter++;
+ }
+
+ /* Second memset operation with random data */
+ for( i = 0; i < start_offset; ++i )
+ {
+ b[i] = rnd_data;
+ flow_counter++;
+ }
+
+ /* Finish memset operation with correct data */
+ for( i = 0; i < start_offset; ++i )
+ {
+ b[i] = value;
+ flow_counter++;
+ }
+
+ /* check the correct number of iterations */
+ if( flow_counter == 2 * num )
+ {
+ mbedtls_platform_random_delay();
+ if( flow_counter == 2 * num )
+ {
+ return ptr;
+ }
+ }
+ return NULL;
}
void *mbedtls_platform_memcpy( void *dst, const void *src, size_t num )
{
- /* Randomize start offset. */
- size_t start_offset = (size_t) mbedtls_platform_random_in_range( num );
- /* Randomize initial data to prevent leakage while copying */
- uint32_t data = mbedtls_platform_random_in_range( 256 );
+ size_t i;
+ volatile size_t flow_counter = 0;
- /* Use memset with random value at first to increase security - memset is
- not normally part of the memcpy function and here can be useed
- with regular, unsecured implementation */
- memset( (void *) dst, data, num );
- memcpy( (void *) ( (unsigned char *) dst + start_offset ),
- (void *) ( (unsigned char *) src + start_offset ),
- ( num - start_offset ) );
- return( memcpy( (void *) dst, (void *) src, start_offset ) );
+ if( num > 0 )
+ {
+ /* Randomize start offset. */
+ size_t start_offset = (size_t) mbedtls_platform_random_in_range( (uint32_t) num );
+ /* Randomize initial data to prevent leakage while copying */
+ uint32_t data = mbedtls_platform_random_in_range( 256 );
+
+ /* Use memset with random value at first to increase security - memset is
+ not normally part of the memcpy function and here can be useed
+ with regular, unsecured implementation */
+ memset( (void *) dst, data, num );
+
+ /* Make a copy starting from a random location. */
+ i = start_offset;
+ do
+ {
+ ( (char*) dst )[i] = ( (char*) src )[i];
+ flow_counter++;
+ }
+ while( ( i = ( i + 1 ) % num ) != start_offset );
+ }
+
+ /* check the correct number of iterations */
+ if( flow_counter == num )
+ {
+ mbedtls_platform_random_delay();
+ if( flow_counter == num )
+ {
+ return dst;
+ }
+ }
+ return NULL;
}
int mbedtls_platform_memmove( void *dst, const void *src, size_t num )
{
+ void *ret1 = NULL;
+ void *ret2 = NULL;
/* The buffers can have a common part, so we cannot do a copy from a random
* location. By using a temporary buffer we can do so, but the cost of it
* is using more memory and longer transfer time. */
void *tmp = mbedtls_calloc( 1, num );
if( tmp != NULL )
{
- mbedtls_platform_memcpy( tmp, src, num );
- mbedtls_platform_memcpy( dst, tmp, num );
+ ret1 = mbedtls_platform_memcpy( tmp, src, num );
+ ret2 = mbedtls_platform_memcpy( dst, tmp, num );
mbedtls_free( tmp );
- return 0;
+ if( ret1 == tmp && ret2 == dst )
+ {
+ return 0;
+ }
+ return MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
}
return MBEDTLS_ERR_PLATFORM_ALLOC_FAILED;
}
-int mbedtls_platform_memcmp( const void *buf1, const void *buf2, size_t num )
+int mbedtls_platform_memequal( const void *buf1, const void *buf2, size_t num )
{
volatile const unsigned char *A = (volatile const unsigned char *) buf1;
volatile const unsigned char *B = (volatile const unsigned char *) buf2;
@@ -152,7 +238,7 @@
/* Start from a random location and check the correct number of iterations */
size_t i, flow_counter = 0;
- size_t start_offset = (size_t) mbedtls_platform_random_in_range( num );
+ size_t start_offset = (size_t) mbedtls_platform_random_in_range( (uint32_t) num );
for( i = start_offset; i < num; i++ )
{
@@ -172,51 +258,80 @@
return( (int) diff | (int) ( flow_counter ^ num ) );
}
-uint32_t mbedtls_platform_random_uint32( )
+/* This function implements a non-cryptographic random number generator based
+ * on the linear congruential generator algorithm. Additionally, if the
+ * MBEDTLS_ENTROPY_HARDWARE_ALT flag is defined, the seed is set at the first
+ * call of this function with using a hardware random number generator and
+ * changed every RAND_SEED_LIFE number of iterations.
+ *
+ * The value of the returned number is in the range [0; 0xffff].
+ *
+ * Note: The range of values with a 16-bit precision is related to the modulo
+ * parameter of the generator and the fact that the function does not return the
+ * full value of the internal state of the generator.
+ */
+static uint32_t mbedtls_platform_random_uint16( void )
{
-#if !defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
- return 0;
-#else
- uint32_t result = 0;
- size_t olen = 0;
+ /* Set random_state - the first random value should not be zero. */
+ static uint32_t random_state = RAND_INCREMENT;
- mbedtls_hardware_poll( NULL, (unsigned char *) &result, sizeof( result ),
- &olen );
- return( result );
-#endif
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+
+ static uint32_t random_seed_life = 0;
+
+ if( 0 < random_seed_life )
+ {
+ --random_seed_life;
+ }
+ else
+ {
+ size_t olen = 0;
+ uint32_t hw_random;
+ mbedtls_hardware_poll( NULL,
+ (unsigned char *) &hw_random, sizeof( hw_random ),
+ &olen );
+ if( olen == sizeof( hw_random ) )
+ {
+ random_state ^= hw_random;
+ random_seed_life = RAND_SEED_LIFE;
+ }
+ }
+
+#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */
+
+ random_state = ( ( random_state * RAND_MULTIPLIER ) + RAND_INCREMENT ) % RAND_MODULUS;
+
+ /* Do not return the entire random_state to hide generator predictability for
+ * the next iteration */
+ return( ( random_state >> 15 ) & 0xffff );
}
-uint32_t mbedtls_platform_random_in_range( size_t num )
+uint32_t mbedtls_platform_random_uint32( void )
{
-#if !defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
- (void) num;
- return 0;
-#else
- uint32_t result = 0;
- size_t olen = 0;
+ return( ( mbedtls_platform_random_uint16() << 16 ) |
+ mbedtls_platform_random_uint16() );
+}
- mbedtls_hardware_poll( NULL, (unsigned char *) &result, sizeof( result ),
- &olen );
+uint32_t mbedtls_platform_random_in_range( uint32_t num )
+{
+ uint32_t result;
- if( num == 0 )
+ if( num <= 1 )
{
result = 0;
}
else
{
- result %= num;
+ result = mbedtls_platform_random_uint32() % num;
}
return( result );
-#endif
}
void mbedtls_platform_random_delay( void )
{
-#if !defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
- return;
-#else
- size_t rn_1, rn_2, rn_3;
+#if defined(MBEDTLS_FI_COUNTERMEASURES)
+ uint32_t rn_1, rn_2, rn_3;
volatile size_t i = 0;
uint8_t shift;
@@ -229,17 +344,17 @@
i++;
/* Dummy calculations to increase the time between iterations and
* make side channel attack more difficult by reducing predictability
- * of its behaviour */
- shift = rn_2 & 0x07;
+ * of its behaviour. */
+ shift = ( rn_2 & 0x07 ) + 1;
if ( i % 2 )
- rn_2 = (uint32_t)( rn_2 >> shift | rn_2 << ( 32 - shift ) );
+ rn_2 = ( rn_2 >> shift ) | ( rn_2 << ( 32 - shift ) );
else
- rn_3 = (uint32_t)( rn_3 << shift | rn_3 >> ( 32 - shift ) );
+ rn_3 = ( rn_3 << shift ) | ( rn_3 >> ( 32 - shift ) );
rn_2 ^= rn_3;
} while( i < rn_1 || rn_2 == 0 || rn_3 == 0 );
+#endif /* MBEDTLS_FI_COUNTERMEASURES */
return;
-#endif /* !MBEDTLS_ENTROPY_HARDWARE_ALT */
}
#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT)
diff --git a/library/rsa.c b/library/rsa.c
index 3f480a3..83a4f38 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -60,9 +60,9 @@
#include <stdlib.h>
#endif
-#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
-#else
+
+#if !defined(MBEDTLS_PLATFORM_C)
#include <stdio.h>
#define mbedtls_printf printf
#define mbedtls_calloc calloc
@@ -1974,8 +1974,11 @@
/* Are we signing raw data? */
if( md_alg == MBEDTLS_MD_NONE )
{
- mbedtls_platform_memcpy( p, hash, hashlen );
- return( 0 );
+ if( mbedtls_platform_memcpy( p, hash, hashlen ) == p )
+ {
+ return( 0 );
+ }
+ return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
}
/* Signing hashed data, add corresponding ASN.1 structure
@@ -2003,7 +2006,10 @@
*p++ = 0x00;
*p++ = MBEDTLS_ASN1_OCTET_STRING;
*p++ = (unsigned char) hashlen;
- mbedtls_platform_memcpy( p, hash, hashlen );
+ if( mbedtls_platform_memcpy( p, hash, hashlen ) != p )
+ {
+ return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+ }
p += hashlen;
/* Just a sanity-check, should be automatic
@@ -2029,7 +2035,7 @@
const unsigned char *hash,
unsigned char *sig )
{
- int ret;
+ int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
unsigned char *sig_try = NULL, *verif = NULL;
RSA_VALIDATE_RET( ctx != NULL );
@@ -2087,7 +2093,10 @@
goto cleanup;
}
- mbedtls_platform_memcpy( sig, sig_try, ctx->len );
+ if( mbedtls_platform_memcpy( sig, sig_try, ctx->len ) != sig )
+ {
+ ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
+ }
cleanup:
mbedtls_free( sig_try );
@@ -2275,7 +2284,7 @@
if ( ret != 0 )
goto exit;
- if( mbedtls_platform_memcmp( hash_start, result, hlen ) != 0 )
+ if( mbedtls_platform_memequal( hash_start, result, hlen ) != 0 )
{
ret = MBEDTLS_ERR_RSA_VERIFY_FAILED;
goto exit;
diff --git a/library/ssl_cache.c b/library/ssl_cache.c
index a4d8cd3..278a477 100644
--- a/library/ssl_cache.c
+++ b/library/ssl_cache.c
@@ -94,7 +94,7 @@
continue;
}
- if( mbedtls_platform_memcmp( session->id, entry->session.id,
+ if( mbedtls_platform_memequal( session->id, entry->session.id,
entry->session.id_len ) != 0 )
continue;
@@ -180,7 +180,7 @@
}
#endif
- if( mbedtls_platform_memcmp( session->id, cur->session.id, cur->session.id_len ) == 0 )
+ if( mbedtls_platform_memequal( session->id, cur->session.id, cur->session.id_len ) == 0 )
break; /* client reconnected, keep timestamp for session id */
#if defined(MBEDTLS_HAVE_TIME)
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 58cbd87..e2c24e2 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -1164,9 +1164,9 @@
/* Check verify-data in constant-time. The length OTOH is no secret */
if( len != 1 + ssl->verify_data_len * 2 ||
buf[0] != ssl->verify_data_len * 2 ||
- mbedtls_platform_memcmp( buf + 1,
+ mbedtls_platform_memequal( buf + 1,
ssl->own_verify_data, ssl->verify_data_len ) != 0 ||
- mbedtls_platform_memcmp( buf + 1 + ssl->verify_data_len,
+ mbedtls_platform_memequal( buf + 1 + ssl->verify_data_len,
ssl->peer_verify_data, ssl->verify_data_len ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) );
@@ -1495,7 +1495,7 @@
for( p = ssl->conf->alpn_list; *p != NULL; p++ )
{
if( name_len == strlen( *p ) &&
- mbedtls_platform_memcmp( buf + 3, *p, name_len ) == 0 )
+ mbedtls_platform_memequal( buf + 3, *p, name_len ) == 0 )
{
ssl->alpn_chosen = *p;
return( 0 );
@@ -1746,7 +1746,7 @@
mbedtls_platform_memcpy( ssl->handshake->randbytes + 32, buf + 2, 32 );
- if( mbedtls_platform_memcmp( ssl->handshake->randbytes + 32, buf + 2, 32 ) == 0 )
+ if( mbedtls_platform_memequal( ssl->handshake->randbytes + 32, buf + 2, 32 ) == 0 )
{
ssl->handshake->hello_random_set = MBEDTLS_SSL_FI_FLAG_SET;
}
@@ -1847,7 +1847,7 @@
mbedtls_ssl_session_get_ciphersuite( ssl->session_negotiate ) != i ||
mbedtls_ssl_session_get_compression( ssl->session_negotiate ) != comp ||
ssl->session_negotiate->id_len != n ||
- mbedtls_platform_memcmp( ssl->session_negotiate->id, buf + 35, n ) != 0 )
+ mbedtls_platform_memequal( ssl->session_negotiate->id, buf + 35, n ) != 0 )
{
ssl->handshake->resume = MBEDTLS_SSL_FI_FLAG_UNSET;
}
@@ -2876,7 +2876,7 @@
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
}
- if( mbedtls_platform_memcmp( p, ecdh_group, sizeof( ecdh_group ) ) != 0 )
+ if( mbedtls_platform_memequal( p, ecdh_group, sizeof( ecdh_group ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad server key exchange (unexpected header)" ) );
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
diff --git a/library/ssl_cookie.c b/library/ssl_cookie.c
index 5b590db..f2d3ede 100644
--- a/library/ssl_cookie.c
+++ b/library/ssl_cookie.c
@@ -229,7 +229,7 @@
if( ret != 0 )
return( ret );
- if( mbedtls_platform_memcmp( cookie + 4, ref_hmac, sizeof( ref_hmac ) ) != 0 )
+ if( mbedtls_platform_memequal( cookie + 4, ref_hmac, sizeof( ref_hmac ) ) != 0 )
return( -1 );
#if defined(MBEDTLS_HAVE_TIME)
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index abfef5d..ec0c21a 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -162,7 +162,7 @@
/* Check verify-data in constant-time. The length OTOH is no secret */
if( len != 1 + ssl->verify_data_len ||
buf[0] != ssl->verify_data_len ||
- mbedtls_platform_memcmp( buf + 1, ssl->peer_verify_data,
+ mbedtls_platform_memequal( buf + 1, ssl->peer_verify_data,
ssl->verify_data_len ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) );
@@ -711,7 +711,7 @@
cur_len = *theirs++;
if( cur_len == ours_len &&
- mbedtls_platform_memcmp( theirs, *ours, cur_len ) == 0 )
+ mbedtls_platform_memequal( theirs, *ours, cur_len ) == 0 )
{
ssl->alpn_chosen = *ours;
return( 0 );
@@ -1228,7 +1228,7 @@
ssl->handshake->hello_random_set = MBEDTLS_SSL_FI_FLAG_UNSET;
memset( ssl->handshake->randbytes, 0, 64 );
mbedtls_platform_memcpy( ssl->handshake->randbytes + 32 - chal_len, p, chal_len );
- if( mbedtls_platform_memcmp( ssl->handshake->randbytes + 32 - chal_len, p, chal_len ) == 0 )
+ if( mbedtls_platform_memequal( ssl->handshake->randbytes + 32 - chal_len, p, chal_len ) == 0 )
{
ssl->handshake->hello_random_set = MBEDTLS_SSL_FI_FLAG_SET;
}
@@ -1628,7 +1628,7 @@
* fragment_offset == 0 and fragment_length == length
*/
if( ssl->in_msg[6] != 0 || ssl->in_msg[7] != 0 || ssl->in_msg[8] != 0 ||
- mbedtls_platform_memcmp( ssl->in_msg + 1, ssl->in_msg + 9, 3 ) != 0 )
+ mbedtls_platform_memequal( ssl->in_msg + 1, ssl->in_msg + 9, 3 ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "ClientHello fragmentation not supported" ) );
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
@@ -1728,7 +1728,7 @@
MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, random bytes", buf + 2, 32 );
mbedtls_platform_memcpy( ssl->handshake->randbytes, buf + 2, 32 );
- if( mbedtls_platform_memcmp( ssl->handshake->randbytes, buf + 2, 32 ) == 0 )
+ if( mbedtls_platform_memequal( ssl->handshake->randbytes, buf + 2, 32 ) == 0 )
{
ssl->handshake->hello_random_set = MBEDTLS_SSL_FI_FLAG_SET;
}
@@ -2827,7 +2827,7 @@
p += 28;
ssl->handshake->hello_random_set = MBEDTLS_SSL_FI_FLAG_UNSET;
mbedtls_platform_memcpy( ssl->handshake->randbytes + 32, buf + 6, 32 );
- if( mbedtls_platform_memcmp( ssl->handshake->randbytes + 32, buf + 6, 32 ) == 0 )
+ if( mbedtls_platform_memequal( ssl->handshake->randbytes + 32, buf + 6, 32 ) == 0 )
{
ssl->handshake->hello_random_set = MBEDTLS_SSL_FI_FLAG_SET;
}
@@ -4119,7 +4119,7 @@
/* Identity is not a big secret since clients send it in the clear,
* but treat it carefully anyway, just in case */
if( n != ssl->conf->psk_identity_len ||
- mbedtls_platform_memcmp( ssl->conf->psk_identity, *p, n ) != 0 )
+ mbedtls_platform_memequal( ssl->conf->psk_identity, *p, n ) != 0 )
{
ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY;
}
diff --git a/library/ssl_ticket.c b/library/ssl_ticket.c
index 98147b7..96478f6 100644
--- a/library/ssl_ticket.c
+++ b/library/ssl_ticket.c
@@ -259,7 +259,7 @@
unsigned char i;
for( i = 0; i < sizeof( ctx->keys ) / sizeof( *ctx->keys ); i++ )
- if( mbedtls_platform_memcmp( name, ctx->keys[i].name, 4 ) == 0 )
+ if( mbedtls_platform_memequal( name, ctx->keys[i].name, 4 ) == 0 )
return( &ctx->keys[i] );
return( NULL );
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 1ee7af0..4ebfb5c 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -92,7 +92,11 @@
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
}
- mbedtls_platform_memcpy( ssl->handshake->ecdh_peerkey, *p + 2, 2 * NUM_ECC_BYTES );
+ if( mbedtls_platform_memcpy( ssl->handshake->ecdh_peerkey, *p + 2, 2 * NUM_ECC_BYTES ) !=
+ ssl->handshake->ecdh_peerkey )
+ {
+ return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+ }
*p += secp256r1_uncompressed_point_length;
return( 0 );
@@ -1886,9 +1890,13 @@
return( ret );
}
- mbedtls_platform_zeroize( handshake->premaster,
- sizeof(handshake->premaster) );
- return( 0 );
+ if( handshake->premaster == mbedtls_platform_zeroize(
+ handshake->premaster, sizeof(handshake->premaster) ) )
+ {
+ return( 0 );
+ }
+
+ return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
}
int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
@@ -2289,7 +2297,10 @@
if( end < p || (size_t)( end - p ) < psk_len )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- mbedtls_platform_memcpy( p, psk, psk_len );
+ if( mbedtls_platform_memcpy( p, psk, psk_len ) != p )
+ {
+ return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+ }
p += psk_len;
ssl->handshake->pmslen = p - ssl->handshake->premaster;
@@ -3164,7 +3175,7 @@
*
* Afterwards, we know that data + data_len is followed by at
* least maclen Bytes, which justifies the call to
- * mbedtls_platform_memcmp() below.
+ * mbedtls_platform_memequal() below.
*
* Further, we still know that data_len > minlen */
rec->data_len -= transform->maclen;
@@ -3186,8 +3197,8 @@
transform->maclen );
/* Compare expected MAC with MAC at the end of the record. */
- if( mbedtls_platform_memcmp( data + rec->data_len, mac_expect,
- transform->maclen ) != 0 )
+ if( mbedtls_platform_memequal( data + rec->data_len, mac_expect,
+ transform->maclen ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
return( MBEDTLS_ERR_SSL_INVALID_MAC );
@@ -3525,8 +3536,8 @@
MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", data + rec->data_len, transform->maclen );
#endif
- if( mbedtls_platform_memcmp( data + rec->data_len, mac_expect,
- transform->maclen ) != 0 )
+ if( mbedtls_platform_memequal( data + rec->data_len, mac_expect,
+ transform->maclen ) != 0 )
{
#if defined(MBEDTLS_SSL_DEBUG_ALL)
MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
@@ -4491,8 +4502,16 @@
/* Handshake hashes are computed without fragmentation,
* so set frag_offset = 0 and frag_len = hs_len for now */
- mbedtls_platform_memset( ssl->out_msg + 6, 0x00, 3 );
- mbedtls_platform_memcpy( ssl->out_msg + 9, ssl->out_msg + 1, 3 );
+ if( mbedtls_platform_memset( ssl->out_msg + 6, 0x00, 3 ) !=
+ ssl->out_msg + 6 )
+ {
+ return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+ }
+ if( mbedtls_platform_memcpy( ssl->out_msg + 9, ssl->out_msg + 1, 3 ) !=
+ ssl->out_msg + 9 )
+ {
+ return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+ }
}
#endif /* MBEDTLS_SSL_PROTO_DTLS */
@@ -4734,8 +4753,8 @@
static int ssl_hs_is_proper_fragment( mbedtls_ssl_context *ssl )
{
if( ssl->in_msglen < ssl->in_hslen ||
- mbedtls_platform_memcmp( ssl->in_msg + 6, "\0\0\0", 3 ) != 0 ||
- mbedtls_platform_memcmp( ssl->in_msg + 9, ssl->in_msg + 1, 3 ) != 0 )
+ mbedtls_platform_memequal( ssl->in_msg + 6, "\0\0\0", 3 ) != 0 ||
+ mbedtls_platform_memequal( ssl->in_msg + 9, ssl->in_msg + 1, 3 ) != 0 )
{
return( PROPER_HS_FRAGMENT );
}
@@ -6123,9 +6142,24 @@
/* Prepare final header: copy msg_type, length and message_seq,
* then add standardised fragment_offset and fragment_length */
- mbedtls_platform_memcpy( hs_buf->data, ssl->in_msg, 6 );
- mbedtls_platform_memset( hs_buf->data + 6, 0, 3 );
- mbedtls_platform_memcpy( hs_buf->data + 9, hs_buf->data + 1, 3 );
+ if( mbedtls_platform_memcpy( hs_buf->data, ssl->in_msg, 6 ) !=
+ hs_buf->data )
+ {
+ ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
+ goto exit;
+ }
+ if( mbedtls_platform_memset( hs_buf->data + 6, 0, 3 ) !=
+ hs_buf->data + 6 )
+ {
+ ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
+ goto exit;
+ }
+ if( mbedtls_platform_memcpy( hs_buf->data + 9, hs_buf->data + 1, 3 ) !=
+ hs_buf->data + 9 )
+ {
+ ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
+ goto exit;
+ }
hs_buf->is_valid = 1;
@@ -7070,7 +7104,7 @@
if( peer_crt->raw.len != crt_buf_len )
return( PEER_CRT_CHANGED );
- return( mbedtls_platform_memcmp( peer_crt->raw.p, crt_buf, crt_buf_len ) );
+ return( mbedtls_platform_memequal( peer_crt->raw.p, crt_buf, crt_buf_len ) );
}
#elif defined(MBEDTLS_SSL_RENEGOTIATION)
#define PEER_CRT_CHANGED 0x75555555
@@ -7102,7 +7136,7 @@
if( ret != 0 )
return( PEER_CRT_CHANGED );
- return( mbedtls_platform_memcmp( tmp_digest, peer_cert_digest, digest_len ) );
+ return( mbedtls_platform_memequal( tmp_digest, peer_cert_digest, digest_len ) );
}
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE && MBEDTLS_SSL_RENEGOTIATION */
#endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */
@@ -8350,8 +8384,8 @@
return( MBEDTLS_ERR_SSL_BAD_HS_FINISHED );
}
- if( mbedtls_platform_memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ),
- buf, hash_len ) != 0 )
+ if( mbedtls_platform_memequal( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ),
+ buf, hash_len ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
mbedtls_ssl_pend_fatal_alert( ssl,
@@ -11175,11 +11209,19 @@
n = ( len < ssl->in_msglen )
? len : ssl->in_msglen;
- mbedtls_platform_memcpy( buf, ssl->in_offt, n );
+ if( mbedtls_platform_memcpy( buf, ssl->in_offt, n ) !=
+ buf )
+ {
+ return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+ }
ssl->in_msglen -= n;
// clear incoming data after it's copied to buffer
- mbedtls_platform_memset(ssl->in_offt, 0, n);
+ if( mbedtls_platform_memset( ssl->in_offt, 0, n ) !=
+ ssl->in_offt )
+ {
+ return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+ }
if( ssl->in_msglen == 0 )
{
@@ -11269,7 +11311,10 @@
*/
ssl->out_msglen = len;
ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA;
- mbedtls_platform_memcpy( ssl->out_msg, buf, len );
+ if( mbedtls_platform_memcpy( ssl->out_msg, buf, len ) != ssl->out_msg )
+ {
+ return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+ }
#if defined(MBEDTLS_FI_COUNTERMEASURES) && !defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
/*
@@ -12125,7 +12170,7 @@
for( cur = ssl->conf->alpn_list; *cur != NULL; cur++ )
{
if( strlen( *cur ) == alpn_len &&
- mbedtls_platform_memcmp( p, cur, alpn_len ) == 0 )
+ mbedtls_platform_memequal( p, cur, alpn_len ) == 0 )
{
ssl->alpn_chosen = *cur;
break;
diff --git a/library/x509.c b/library/x509.c
index 65f2ec6..f86e9e3 100644
--- a/library/x509.c
+++ b/library/x509.c
@@ -516,7 +516,7 @@
{
if( a->tag == b->tag &&
a->len == b->len &&
- mbedtls_platform_memcmp( a->p, b->p, b->len ) == 0 )
+ mbedtls_platform_memequal( a->p, b->p, b->len ) == 0 )
{
return( 0 );
}
@@ -605,7 +605,7 @@
goto exit;
if( oid[0].len != oid[1].len ||
- mbedtls_platform_memcmp( oid[0].p, oid[1].p, oid[1].len ) != 0 )
+ mbedtls_platform_memequal( oid[0].p, oid[1].p, oid[1].len ) != 0 )
{
return( 1 );
}
diff --git a/library/x509_crl.c b/library/x509_crl.c
index d295229..8af5de8 100644
--- a/library/x509_crl.c
+++ b/library/x509_crl.c
@@ -511,10 +511,10 @@
}
if( crl->sig_oid.len != sig_oid2.len ||
- mbedtls_platform_memcmp( crl->sig_oid.p, sig_oid2.p, crl->sig_oid.len ) != 0 ||
+ mbedtls_platform_memequal( crl->sig_oid.p, sig_oid2.p, crl->sig_oid.len ) != 0 ||
sig_params1.len != sig_params2.len ||
( sig_params1.len != 0 &&
- mbedtls_platform_memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) )
+ mbedtls_platform_memequal( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) )
{
mbedtls_x509_crl_free( crl );
return( MBEDTLS_ERR_X509_SIG_MISMATCH );
diff --git a/library/x509_crt.c b/library/x509_crt.c
index 43bb977..3b75bb5 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -1322,7 +1322,7 @@
* signature field in the sequence tbsCertificate (Section 4.1.2.3).
*/
if( outer_sig_alg.len != inner_sig_alg_len ||
- mbedtls_platform_memcmp( outer_sig_alg.p, inner_sig_alg_start, inner_sig_alg_len ) != 0 )
+ mbedtls_platform_memequal( outer_sig_alg.p, inner_sig_alg_start, inner_sig_alg_len ) != 0 )
{
return( MBEDTLS_ERR_X509_SIG_MISMATCH );
}
@@ -2594,7 +2594,7 @@
return( 1 );
}
- if( data_len == cb_ctx->oid_len && mbedtls_platform_memcmp( data, cb_ctx->oid,
+ if( data_len == cb_ctx->oid_len && mbedtls_platform_memequal( data, cb_ctx->oid,
data_len ) == 0 )
{
return( 1 );
@@ -2652,7 +2652,7 @@
while( cur != NULL && cur->serial.len != 0 )
{
if( serial_len == cur->serial.len &&
- mbedtls_platform_memcmp( serial, cur->serial.p, serial_len ) == 0 )
+ mbedtls_platform_memequal( serial, cur->serial.p, serial_len ) == 0 )
{
if( mbedtls_x509_time_is_past( &cur->revocation_date ) )
return( 1 );
@@ -3191,7 +3191,7 @@
for( cur = trust_ca; cur != NULL; cur = cur->next )
{
if( crt->raw.len == cur->raw.len &&
- mbedtls_platform_memcmp( crt->raw.p, cur->raw.p, crt->raw.len ) == 0 )
+ mbedtls_platform_memequal( crt->raw.p, cur->raw.p, crt->raw.len ) == 0 )
{
return( 0 );
}
diff --git a/tests/suites/test_suite_hmac_drbg.function b/tests/suites/test_suite_hmac_drbg.function
index da280db..b812b70 100644
--- a/tests/suites/test_suite_hmac_drbg.function
+++ b/tests/suites/test_suite_hmac_drbg.function
@@ -94,12 +94,12 @@
TEST_ASSERT( entropy.len < last_len );
/* Finally, check setting entropy_len */
- mbedtls_hmac_drbg_set_entropy_len( &ctx, 42 );
+ TEST_ASSERT( mbedtls_hmac_drbg_set_entropy_len( &ctx, 42 ) == 0 );
last_len = entropy.len;
TEST_ASSERT( mbedtls_hmac_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
TEST_ASSERT( (int) last_len - entropy.len == 42 );
- mbedtls_hmac_drbg_set_entropy_len( &ctx, 13 );
+ TEST_ASSERT( mbedtls_hmac_drbg_set_entropy_len( &ctx, 13 ) == 0 );
last_len = entropy.len;
TEST_ASSERT( mbedtls_hmac_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
TEST_ASSERT( (int) last_len - entropy.len == 13 );
@@ -149,6 +149,7 @@
TEST_ASSERT( mbedtls_hmac_drbg_seed_buf( &ctx, md_info, buf, sizeof( buf ) ) == 0 );
/* Make sure it never tries to reseed (would segfault otherwise) */
+ mbedtls_hmac_drbg_set_reseeding( &ctx, MBEDTLS_HMAC_DRBG_NO_RESEED );
mbedtls_hmac_drbg_set_reseed_interval( &ctx, 3 );
mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
@@ -172,7 +173,7 @@
mbedtls_hmac_drbg_context ctx;
mbedtls_hmac_drbg_init( &ctx );
-
+ mbedtls_hmac_drbg_set_reseeding( &ctx, MBEDTLS_HMAC_DRBG_NO_RESEED );
p_entropy.p = entropy->x;
p_entropy.len = entropy->len;
@@ -219,6 +220,7 @@
mbedtls_hmac_drbg_context ctx;
mbedtls_hmac_drbg_init( &ctx );
+ mbedtls_hmac_drbg_set_reseeding( &ctx, MBEDTLS_HMAC_DRBG_NO_RESEED );
p_entropy.p = entropy->x;
p_entropy.len = entropy->len;
diff --git a/tinycrypt/ecc_dh.c b/tinycrypt/ecc_dh.c
index 5a7a9e5..6285cf3 100644
--- a/tinycrypt/ecc_dh.c
+++ b/tinycrypt/ecc_dh.c
@@ -81,7 +81,10 @@
/* This function is designed for test purposes-only (such as validating NIST
* test vectors) as it uses a provided value for d instead of generating
* it uniformly at random. */
- mbedtls_platform_memcpy (_private, d, NUM_ECC_BYTES);
+ if( mbedtls_platform_memcpy (_private, d, NUM_ECC_BYTES) != _private )
+ {
+ goto exit;
+ }
/* Computing public-key from private: */
ret = EccPoint_compute_public_key(_public, _private);
@@ -186,7 +189,9 @@
uECC_vli_nativeToBytes(secret, num_bytes, _public);
/* erasing temporary buffer used to store secret: */
- mbedtls_platform_zeroize(_private, sizeof(_private));
+ if (_private == mbedtls_platform_zeroize(_private, sizeof(_private))) {
+ return r;
+ }
- return r;
+ return UECC_FAULT_DETECTED;
}