Fix missing bound check
diff --git a/ChangeLog b/ChangeLog
index 7bb1727..7845080 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -18,6 +18,8 @@
Bugfix
* Fix potential undefined behaviour in Camellia.
* Fix memory leaks in PKCS#5 and PKCS#12.
+ * Stack buffer overflow if ctr_drbg_update() is called with too large
+ add_len (found by Jean-Philippe Aumasson) (not triggerable remotely).
Changes
* Blind RSA private operations even when POLARSSL_RSA_NO_CRT is defined.
diff --git a/include/polarssl/ctr_drbg.h b/include/polarssl/ctr_drbg.h
index d5459d9..a2f1a61 100644
--- a/include/polarssl/ctr_drbg.h
+++ b/include/polarssl/ctr_drbg.h
@@ -154,6 +154,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 1b46f45..980d954 100644
--- a/library/ctr_drbg.c
+++ b/library/ctr_drbg.c
@@ -118,6 +118,9 @@
int i, j, 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 );
/*
@@ -233,6 +236,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 );
}