Fix a NULL dereference in chacha20_poly1305_init_key()
authorKazuki Yamaguchi <k@rhe.jp>
Tue, 10 May 2016 10:46:08 +0000 (19:46 +0900)
committerRichard Levitte <levitte@openssl.org>
Wed, 18 May 2016 09:08:55 +0000 (11:08 +0200)
chacha20_poly1305_init_key() dereferences NULL when called with inkey !=
NULL && iv == NULL. This function is called by EVP_EncryptInit_ex()
family, whose documentation allows setting key and iv in separate calls.

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
crypto/evp/e_chacha20_poly1305.c

index e3a0bef8c5896c7cadab4548d04c63fec1855148..26fefd9781b28cd01d09ed83a2deaae3ca853825 100644 (file)
@@ -164,7 +164,6 @@ static int chacha20_poly1305_init_key(EVP_CIPHER_CTX *ctx,
                                       const unsigned char *iv, int enc)
 {
     EVP_CHACHA_AEAD_CTX *actx = aead_data(ctx);
-    unsigned char temp[CHACHA_CTR_SIZE];
 
     if (!inkey && !iv)
         return 1;
@@ -175,16 +174,21 @@ static int chacha20_poly1305_init_key(EVP_CIPHER_CTX *ctx,
     actx->mac_inited = 0;
     actx->tls_payload_length = NO_TLS_PAYLOAD_LENGTH;
 
-    /* pad on the left */
-    memset(temp, 0, sizeof(temp));
-    if (actx->nonce_len <= CHACHA_CTR_SIZE)
-        memcpy(temp + CHACHA_CTR_SIZE - actx->nonce_len, iv, actx->nonce_len);
+    if (iv != NULL) {
+        unsigned char temp[CHACHA_CTR_SIZE] = { 0 };
 
-    chacha_init_key(ctx, inkey, temp, enc);
+        /* pad on the left */
+        if (actx->nonce_len <= CHACHA_CTR_SIZE)
+            memcpy(temp + CHACHA_CTR_SIZE - actx->nonce_len, iv, actx->nonce_len);
 
-    actx->nonce[0] = actx->key.counter[1];
-    actx->nonce[1] = actx->key.counter[2];
-    actx->nonce[2] = actx->key.counter[3];
+        chacha_init_key(ctx, inkey, temp, enc);
+
+        actx->nonce[0] = actx->key.counter[1];
+        actx->nonce[1] = actx->key.counter[2];
+        actx->nonce[2] = actx->key.counter[3];
+    } else {
+        chacha_init_key(ctx, inkey, NULL, enc);
+    }
 
     return 1;
 }