Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent over long nonces in ChaCha20-Poly1305 #8406

Closed

Conversation

mattcaswell
Copy link
Member

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
ignored.

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
affected.

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

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
ignored.

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
affected.

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 openssl#8345
@mattcaswell mattcaswell added branch: master Merge to master branch 1.1.0 branch: 1.1.1 Merge to OpenSSL_1_1_1-stable branch labels Mar 5, 2019
@mattcaswell
Copy link
Member Author

Note: CVE number will be added to commit message before commit.

@jorangreef
Copy link

Should the docs also be updated by this commit?

https://www.openssl.org/docs/man1.1.1/man3/EVP_CipherInit.html

ChaCha20-Poly1305
The following ctrls are supported for the ChaCha20-Poly1305 AEAD algorithm.

EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, ivlen, NULL)
Sets the nonce length. This call can only be made before specifying the nonce.
If not called a default nonce length of 12 (i.e. 96 bits) is used.
The maximum nonce length is 16 (CHACHA_CTR_SIZE, i.e. 128-bits).

The last line should change?

The maximum nonce length is 12 (CHACHA20_POLY1305_MAX_IVLEN, i.e. 96-bits).

@mattcaswell
Copy link
Member Author

The last line should change?

Ah! Yes. Thanks - good point. Will fix.

Correctly describe the maximum IV length.
@mattcaswell
Copy link
Member Author

New commit added fixing the documentation. That commit will not be back-ported to 1.1.0 since the offending sentence does not appear in the documentation in that version.

@paulidale paulidale added the approval: done This pull request has the required number of approvals label Mar 5, 2019
Copy link
Contributor

@paulidale paulidale left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still looks good.

Copy link
Member

@levitte levitte left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy now

levitte pushed a commit that referenced this pull request Mar 6, 2019
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
ignored.

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
affected.

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.

CVE-2019-1543

Fixes #8345

Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from #8406)

(cherry picked from commit 2a3d0ee)
levitte pushed a commit that referenced this pull request Mar 6, 2019
Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from #8406)

(cherry picked from commit a4f0b50)
levitte pushed a commit that referenced this pull request Mar 6, 2019
Correctly describe the maximum IV length.

Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from #8406)

(cherry picked from commit 27d5631)
levitte pushed a commit that referenced this pull request Mar 6, 2019
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
ignored.

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
affected.

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.

CVE-2019-1543

Fixes #8345

Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from #8406)

(cherry picked from commit 2a3d0ee)
levitte pushed a commit that referenced this pull request Mar 6, 2019
Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from #8406)

(cherry picked from commit a4f0b50)
@mattcaswell
Copy link
Member Author

Pushed. Thanks.

@mattcaswell mattcaswell closed this Mar 6, 2019
levitte pushed a commit that referenced this pull request Mar 6, 2019
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
ignored.

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
affected.

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.

CVE-2019-1543

Fixes #8345

Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from #8406)
levitte pushed a commit that referenced this pull request Mar 6, 2019
Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from #8406)
levitte pushed a commit that referenced this pull request Mar 6, 2019
Correctly describe the maximum IV length.

Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from #8406)
@davidben
Copy link
Contributor

davidben commented Mar 6, 2019

Variable-length ChaCha20-Poly1305 nonces appear to be a non-standard OpenSSL extension. They aren't covered by the security considerations in RFC 7539. What exactly are this extension's security properties? I don't see this documented anywhere.

CVE-2019-1543 suggests OpenSSL intended to promise that passing two different nonce values, assuming they were accepted, would not break the cipher. What exactly are the conditions? Right now single-byte and 12-byte nonces of all zeros still collide. Is that an OpenSSL bug, or is this considered misuse of the OpenSSL extension? [Edit: Previously this paragraph collided a 12-byte nonce with the empty string, but I see the empty string is rejected. The same problem occurs with other length mismatches, however.]

(I would suggest not adding such extensions. If the specification says the AEAD takes 12-byte nonces, only take 12-byte nonces. Were the primitive designed to take variable-length nonces, it would have encoded the length of the nonce somewhere.)

@mattcaswell
Copy link
Member Author

The documentation in this PR is supposed to make it clear what happens if an IV with less the 12 bytes is provided, i.e. it is front padded with 0 bytes to make it as 12 byte nonce, e.g. a single byte of value "1" is exactly identical to 11 bytes of 0s followed by "1".

@davidben
Copy link
Contributor

davidben commented Mar 7, 2019

Right, that tells you the implementation, but not the caller's obligations. One could have documented 16-byte nonces as valid but truncated, but that wouldn't exactly fit the usual rules for an AEAD (nonces that differ only in the final byte are okay), so there is a clearly an implicit security criteria here.

I would recommend doing both of the following:

  • Explicitly document that the caller must not mix multiple nonce lengths for a given key. This non-standard extension is only safe assuming all nonces have the same length.
  • Deprecate this non-standard extension and document that callers should only use the standard 12-byte nonce length.

themiron pushed a commit to RMerl/asuswrt-merlin.ng that referenced this pull request Apr 9, 2019
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
ignored.

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
affected.

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.

CVE-2019-1543

Fixes #8345

Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from openssl/openssl#8406)

(cherry picked from commit 2a3d0ee9d59156c48973592331404471aca886d6)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approval: done This pull request has the required number of approvals branch: master Merge to master branch branch: 1.1.1 Merge to OpenSSL_1_1_1-stable branch
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants