Fix missing bound check
diff --git a/ChangeLog b/ChangeLog
index 89c87e0..8370738 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -9,6 +9,10 @@
* Add support for Extended Master Secret (draft-ietf-tls-session-hash)
* Add support for Encrypt-then-MAC (RFC 7366)
+Bugfix
+ * Stack buffer overflow if ctr_drbg_update() is called with too large
+ add_len (found by Jean-Philippe Aumasson) (not triggerable remotely).
+
= PolarSSL 1.3.9 released 2014-10-20
Security
* Lowest common hash was selected from signature_algorithms extension in
diff --git a/include/polarssl/ctr_drbg.h b/include/polarssl/ctr_drbg.h
index bebbfe9..de696dc 100644
--- a/include/polarssl/ctr_drbg.h
+++ b/include/polarssl/ctr_drbg.h
@@ -188,6 +188,10 @@
* \param ctx CTR_DRBG context
* \param additional Additional data to update state with
* \param add_len Length of additional data
+ *
+ * \note If add_len is greater than CTR_DRBG_MAX_SEED_INPUT,
+ * only the first CTR_DRBG_MAX_SEED_INPUT bytes are used,
+ * the remaining ones are silently discarded.
*/
void ctr_drbg_update( ctr_drbg_context *ctx,
const unsigned char *additional, size_t add_len );
diff --git a/library/ctr_drbg.c b/library/ctr_drbg.c
index 96ee4f1..91e0615 100644
--- a/library/ctr_drbg.c
+++ b/library/ctr_drbg.c
@@ -137,6 +137,9 @@
int i, j;
size_t buf_len, use_len;
+ if( data_len > CTR_DRBG_MAX_SEED_INPUT )
+ return( POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG );
+
memset( buf, 0, CTR_DRBG_MAX_SEED_INPUT + CTR_DRBG_BLOCKSIZE + 16 );
aes_init( &aes_ctx );
@@ -256,6 +259,11 @@
if( add_len > 0 )
{
+ /* MAX_INPUT would be more logical here, but we have to match
+ * block_cipher_df()'s limits since we can't propagate errors */
+ if( add_len > CTR_DRBG_MAX_SEED_INPUT )
+ add_len = CTR_DRBG_MAX_SEED_INPUT;
+
block_cipher_df( add_input, additional, add_len );
ctr_drbg_update_internal( ctx, add_input );
}