Skip to content

Conversation

theStack
Copy link
Contributor

The current interface description of ChaCha20::SetKey suggests that literally any key-length is supported (comment set key with flexible keylength; 256bit recommended), while passing in a key with a length less than 16 bytes would lead to a buffer overread:

input[4] = ReadLE32(k + 0);
input[5] = ReadLE32(k + 4);
input[6] = ReadLE32(k + 8);
input[7] = ReadLE32(k + 12);

This PR adds an assert to only allowing sizes of 16 or 32 bytes (i.e. 128 and 256 bits, respectively) which seem what was intended originally, looking at the following piece of code:

if (keylen == 32) { /* recommended */
k += 16;
constants = sigma;
} else { /* keylen == 16 */
constants = tau;
}

The fuzz tests are adopted accordingly to pick either 16 or 32 rather than a length in the range of 16 to 32. An alternative would be to just assert for the minimum size of 16 (and a maximum size of 32), if for some reason supporting keys with a length between 17 and 31 bytes is important; I guess it isn't though, it would also be confusing as the extra bytes wouldn't be used.

Copy link
Member

@maflcko maflcko left a comment

Choose a reason for hiding this comment

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

lgtm

The current interface description of `ChaCha20::SetKey` suggests that
literally any key-length is supported, while passing in a key with a
length less than 16 bytes would lead to a buffer overread. Only allowing
sizes of 16 or 32 bytes (i.e. 128 and 256 bits, respectively) seem to be
what was intended originally, so assert to that and adapt the fuzz that
accordingly to pick either 16 or 32 rather than a length in the range of
16 to 32.
@theStack theStack force-pushed the 202207-crypto-avoid_potential_buffer_overread_in_chacha20_setkey branch from e941e92 to 132034d Compare July 25, 2022 15:14
@maflcko
Copy link
Member

maflcko commented Jul 25, 2022

ref: #21781

@DrahtBot
Copy link
Contributor

DrahtBot commented Jul 25, 2022

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #26153 (Reduce wasted pseudorandom bytes in ChaCha20 + various improvements by sipa)
  • #25903 (Use static member functions from class instead of instances by aureleoules)
  • #25712 (crypto: drop 16 byte key support for ChaCha20 by theStack)
  • #25361 (BIP324: Cipher suite by dhruv)
  • #25172 (refactor: use std:: prefix for std lib funcs by fanquake)
  • #23561 (BIP324: Handshake prerequisites by dhruv)
  • #23233 (BIP324: Add encrypted p2p transport {de}serializer by dhruv)
  • #16545 (refactor: Implement missing error checking for ArgsManager flags by ryanofsky)

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

@sipa
Copy link
Member

sipa commented Jul 26, 2022

To simplify things, I think we could also just drop support for 16-byte keys and only permit 32-byte ones.

@theStack
Copy link
Contributor Author

To simplify things, I think we could also just drop support for 16-byte keys and only permit 32-byte ones.

Good idea, opened another pull for that: #25712
I'm still keeping this PR open right now, for the unlikely case that we would still need to support 16-byte keys for some reason.

@theStack
Copy link
Contributor Author

theStack commented Oct 2, 2022

Closed in favour or #26153 (includes removing 16-byte key support).

@theStack theStack closed this Oct 2, 2022
@bitcoin bitcoin locked and limited conversation to collaborators Oct 2, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants