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

ChaCha20 Explicitly Set Counter #1010

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

btoms20
Copy link
Contributor

@btoms20 btoms20 commented Apr 10, 2023

Feature: Set Counter in ChaCha20 Cipher's Initializer

Checklist:

  • Correct file headers (see CONTRIBUTING.md).
  • Formatted with SwiftFormat.
  • Tests added.

Changes proposed in this pull request:
Are there any reasons, security or otherwise, that the leading 4 bytes in the ChaCha20 Cipher's counter param can't be explicitly set to something other than [0, 0, 0, 0]?

I'm trying to generate a QUIC header protection mask (as discussed in RFC 9001 - section 5.4.4) and it requires the 4 byte prefix in the counter to be explicitly set upon the cipher's initialization.

The change proposed in this PR is to add a counter param to the ChaCha20 initializer that defaults to the standard 4 zero bytes. The default value prevents breaking changes while keeping only a single initializer. I also wasn't sure what API would be preferable...

  1. Default counter param in the current initializer (this way the user knows for sure they're setting the counter).
public init(key: Array<UInt8>, counter: Array<UInt8> = [0, 0, 0, 0], iv nonce: Array<UInt8>) throws {
    precondition(counter.count == 4 && (nonce.count == 12 || nonce.count == 8))
    ...
}
  1. Allow for 16 byte Nonce / IV (perhaps more confusing).
public init(key: Array<UInt8>, iv nonce: Array<UInt8>) throws {
    precondition(nonce.count == 16 || nonce.count == 12 || nonce.count == 8)
    ...
}

Either method would allow for the following to be accomplished...
Example from RFC 9001 Appendix A.5 Quic v1

let hpKey = Array(hex: "0x25a282b9e82f06f21f488917a4fc8f1b73573685608597d0efcb076b0ab7a7a4")

///            |  Counter |           IV             |
/// Sample: 0x | 5e5cd55c | 41f69080575d7999c25a5bfb |
let counter = Array(hex: "0x5e5cd55c")
let iv = Array(hex: "0x41f69080575d7999c25a5bfb")

let mask = try CryptoSwift.ChaCha20(key: hpKey, counter: counter, iv: iv).encrypt(Array<UInt8>(repeating: 0, count: 5))

XCTAssertEqual(mask, "aefefe7d03")

Let me know what you think

Thanks

@krzyzanowskim
Copy link
Owner

it's been a while, I'm sorry. Do you mind resolve conflict here? I'm ok with the change

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants