Open FiloSottile opened 4 days ago
Related Issues and Documentation
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)
This proposal has been added to the active column of the proposals project and will now be reviewed at the weekly proposal review meetings.
NIST SP 800-38D and in particular FIPS 140-3 IG C.H essentially require that AES-GCM nonces be either generated according to an industry protocol (TLS, SSH) or internally at random by the cryptographic module.
This makes somewhat sense, because AES-GCM nonce reuse is catastrophic and common enough. It makes somewhat less sense because AES-GCM nonces are 96 bits, making the birthday bound of messages that can be encrypted with random nonces with low enough (2⁻³²) chance of collisions a mere 2³² (~4.3 billions).
Anyway, we should offer applications a way to comply with the requirement, and wire it up to the appropriate #69536 API.
The simplest proposal I can think of is to copy NewGCM, folding the NonceSize into the Overhead, like #54364.
Do we want to take the opportunity to make the API return a concrete type? #54364 doesn't and to me it feels like it's not worth breaking the pattern yet (or having it not sort next to the other NewGCMs).
This will have the same implementation challenge described in https://github.com/golang/go/issues/54364#issuecomment-1725379404: since plaintext and ciphertext don't overlap perfectly when the buffer is reused, Seal will need to avoid stepping over itself.
I regret we are growing a bit of a zoo of AEADs with different properties, but I can't see a way around it (and it's in good part due to the fact that we have only had a bunch of imperfect options for decades, each sub-optimal in different ways): we'll have NewGCMSIV, NewGCMWithRandomNonce, and maybe XAES and XChaCha20Poly1305 with automatic nonces, of which NewGCMWithRandomNonce and NewGCMSIV have a low birthday bound, but NewGCMSIV is collision resistant (as in, it degrades to safe deterministic encryption); and then NewGCM (and the WithNonceSize and WithTagSize variants), NewGCMSIVWithNonce, chacha20poly1305.New, and chacha20poly1305.NewX with manual nonces, of which only NewGCMSIVWithNonce is nonce-misuse resistance. We should eventually clean this all up with a v2 API that only provides the safe ones with automatic nonces, probably with a different interface, but not in Go 1.24.