Merge pull request #3448 from piotr-now/platform_util
Renamed mbedtls_platform_memcmp() to mbedtls_platform_memequal()
diff --git a/include/mbedtls/aes.h b/include/mbedtls/aes.h
index 6990be0..cb7d726 100644
--- a/include/mbedtls/aes.h
+++ b/include/mbedtls/aes.h
@@ -87,6 +87,9 @@
{
int nr; /*!< The number of rounds. */
uint32_t *rk; /*!< AES round keys. */
+#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES)
+ uint32_t frk[8]; /*!< Fake AES round keys. */
+#endif
#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) && !defined(MBEDTLS_PADLOCK_C)
uint32_t buf[44]; /*!< Unaligned data buffer */
#else /* MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
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/library/aes.c b/library/aes.c
index e9e7544..e7a888f 100644
--- a/library/aes.c
+++ b/library/aes.c
@@ -675,6 +675,18 @@
}
#endif /* MBEDTLS_CIPHER_MODE_XTS */
+#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES)
+static void mbedtls_generate_fake_key( unsigned int keybits, mbedtls_aes_context *ctx )
+{
+ unsigned int qword;
+
+ for( qword = keybits >> 5; qword > 0; qword-- )
+ {
+ ctx->frk[ qword - 1 ] = mbedtls_platform_random_uint32();
+ }
+}
+#endif /* MBEDTLS_AES_SCA_COUNTERMEASURES */
+
/*
* AES key schedule (encryption)
*/
@@ -719,6 +731,9 @@
else
#endif
ctx->rk = RK = ctx->buf;
+#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES)
+ mbedtls_generate_fake_key( keybits, ctx );
+#endif
#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
@@ -858,6 +873,9 @@
else
#endif
ctx->rk = RK = ctx->buf;
+#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES)
+ mbedtls_generate_fake_key( keybits, ctx );
+#endif
/* Also checks keybits */
if( ( ret = mbedtls_aes_setkey_enc( &cty, key, keybits ) ) != 0 )
@@ -1071,7 +1089,8 @@
uint8_t round_ctrl_table[( 14 + AES_SCA_CM_ROUNDS + 2 )];
aes_data_real.rk_ptr = ctx->rk;
- aes_data_fake.rk_ptr = ctx->rk;
+ aes_data_fake.rk_ptr = ctx->frk;
+
aes_data_table[0] = &aes_data_real;
aes_data_table[1] = &aes_data_fake;
@@ -1351,7 +1370,8 @@
uint8_t round_ctrl_table[( 14 + AES_SCA_CM_ROUNDS + 2 )];
aes_data_real.rk_ptr = ctx->rk;
- aes_data_fake.rk_ptr = ctx->rk;
+ aes_data_fake.rk_ptr = ctx->frk;
+
aes_data_table[0] = &aes_data_real;
aes_data_table[1] = &aes_data_fake;
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/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/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;