Fix out-of-bounds read in ctr_XOR
authorBenjamin Kaduk <bkaduk@akamai.com>
Wed, 19 Jul 2017 22:59:52 +0000 (17:59 -0500)
committerBenjamin Kaduk <kaduk@mit.edu>
Thu, 20 Jul 2017 17:12:36 +0000 (12:12 -0500)
Looking at
http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf
we see that in the CTR_DRBG_Update() algorithm (internal page number 51),
the provided input data is (after truncation to seedlen) xor-d with the
key and V vector (of length keylen and blocklen respectively).  The comment
in ctr_XOR notes that xor-ing with 0 is the identity function, so we can
just ignore the case when the provided input is shorter than seedlen.

The code in ctr_XOR() then proceeds to xor the key with the input, up
to the amount of input present, and computes the remaining input that
could be used to xor with the V vector, before accessing a full 16-byte
stretch of the input vector and ignoring the calculated length.  The correct
behavior is to respect the supplied input length and only xor the
indicated number of bytes.

Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/3971)

crypto/rand/drbg_rand.c

index 4ff347c7ea901faabb0e614090ef7c67744ee86e..77d59ec8136ddbf11612302ea5f96f5994b6f2e8 100644 (file)
@@ -77,7 +77,7 @@ static void ctr_XOR(DRBG_CTR_CTX *cctx, const unsigned char *in, size_t inlen)
         /* Should never happen */
         n = 16;
     }
-    for (i = 0; i < 16; i++)
+    for (i = 0; i < n; i++)
         cctx->V[i] ^= in[i + cctx->keylen];
 }