Skip to content


Prevent over long nonces in ChaCha20-Poly1305
Browse files Browse the repository at this point in the history
ChaCha20-Poly1305 is an AEAD cipher, and requires a unique nonce input for
every encryption operation. RFC 7539 specifies that the nonce value (IV)
should be 96 bits (12 bytes). OpenSSL allows a variable nonce length and
front pads the nonce with 0 bytes if it is less than 12 bytes. However it
also incorrectly allows a nonce to be set of up to 16 bytes. In this case
only the last 12 bytes are significant and any additional leading bytes are

It is a requirement of using this cipher that nonce values are unique.
Messages encrypted using a reused nonce value are susceptible to serious
confidentiality and integrity attacks. If an application changes the
default nonce length to be longer than 12 bytes and then makes a change to
the leading bytes of the nonce expecting the new value to be a new unique
nonce then such an application could inadvertently encrypt messages with a
reused nonce.

Additionally the ignored bytes in a long nonce are not covered by the
integrity guarantee of this cipher. Any application that relies on the
integrity of these ignored leading bytes of a long nonce may be further

Any OpenSSL internal use of this cipher, including in SSL/TLS, is safe
because no such use sets such a long nonce value. However user
applications that use this cipher directly and set a non-default nonce
length to be longer than 12 bytes may be vulnerable.


Fixes #8345

Reviewed-by: Paul Dale <>
Reviewed-by: Richard Levitte <>
(Merged from #8406)

(cherry picked from commit 2a3d0ee)
  • Loading branch information
mattcaswell committed Mar 6, 2019
1 parent c62896c commit ee22257
Showing 1 changed file with 3 additions and 1 deletion.
4 changes: 3 additions & 1 deletion crypto/evp/e_chacha20_poly1305.c
Expand Up @@ -30,6 +30,8 @@ typedef struct {

#define data(ctx) ((EVP_CHACHA_KEY *)(ctx)->cipher_data)

#define CHACHA20_POLY1305_MAX_IVLEN 12

static int chacha_init_key(EVP_CIPHER_CTX *ctx,
const unsigned char user_key[CHACHA_KEY_SIZE],
const unsigned char iv[CHACHA_CTR_SIZE], int enc)
Expand Down Expand Up @@ -357,7 +359,7 @@ static int chacha20_poly1305_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
return 1;

if (arg <= 0 || arg > CHACHA_CTR_SIZE)
if (arg <= 0 || arg > CHACHA20_POLY1305_MAX_IVLEN)
return 0;
actx->nonce_len = arg;
return 1;
Expand Down

0 comments on commit ee22257

Please sign in to comment.