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

crypto/tls: TLS 1.3 unable to disable non-NIST approved ChaCha20 Cipher Suite #54072

upsampled opened this issue Jul 26, 2022 · 7 comments
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.


Copy link

upsampled commented Jul 26, 2022

What version of Go are you using (go version)?

go version go1.18.4 linux/amd64

Does this issue reproduce with the latest release?


What operating system and processor architecture are you using (go env)?

go env Output
golang:1.18:4 docker image

What did you do?

Attempted to disable the ChaCha20 TLS 1.3 suite as it is not approved by NIST yet by removing it from cipher list:

package main

import (

func main() {
	server := http.Server{
		Addr: "localhost:2443",
		TLSConfig: &tls.Config{
			CipherSuites: []uint16{tls.TLS_AES_256_GCM_SHA384,tls.TLS_AES_128_GCM_SHA256},
			MinVersion:   tls.VersionTLS13,
	log.Fatal(server.ListenAndServeTLS("localhost.pem", "localhost-key.pem"))

I then tried to force a client to choose the ChaCha20 suite:

openssl s_client -connect localhost:2443 -ciphersuites TLS_CHACHA20_POLY1305_SHA256

What did you expect to see?

To error when a client tries to force the ChaCha20 cipher suite to be used

What did you see instead?

New, TLSv1.3, Cipher is TLS_CHACHA20_POLY1305_SHA256
Server public key is 4096 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 18 (self signed certificate)


FIPS 140-3 seems to be approving all the components of TLS 1.3 except the ChaCha20 suite. This has ruffled many feather as this Public Response on the NIST website points out:

Limiting the label to only NIST approved cryptography seems overly restrictive. For example,
software may include support for TLS 1.3, which can include ChaCha20/Poly1305 and neither of
those are NIST approved as of today.

The response doesn't point out that there is a CAVP for TLS 1.3 Key Derivation Function so that looks like it is going to be accepted/tolerated, but there seems to be active silence regarding ChaCha20. There is seemingly no way currently to get it approved.

Regarding issue ##29349, it basically left off with:

what would work here would be to open a new one about a use case (not about a specific solution) with supporting information to show what the requirements are like and how common they are

So that is what I am trying to do. NIST can very well change its mind and approve ChaCha20, but it right now there is no real indicator that they will and many indicators that TLS 1.3 will be approved in FIPS environments without it.

Copy link

seankhliao commented Jul 26, 2022

cc @golang/security

@seankhliao seankhliao added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Jul 26, 2022
Copy link

FiloSottile commented Jul 26, 2022

Disabling ChaCha20Poly1305 is a solution, not a use case. The implicit use case seems to be FIPS 140-3 compliance, but just disabling a couple cipher suites does not get you within any compliance framework that I'm aware of. Can you tell us more about what requirements you are trying to comply with?

@mvdan mvdan added the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label Jul 27, 2022
Copy link

upsampled commented Jul 27, 2022

Without getting into the specifics, I am aiming at the very least for the non-official designation of "FIPS 140-3 compliant" (IE: A threat scanner would show the same ciphers being used as a valid FIPS 140-3 module) with the idea that there is still a valid path to lower class, Hardware/Hybrid module validation using only Go code (boring's ARM support is not clear for FIP 140-2 and I don't expect that to change with 140-3).

Copy link

upsampled commented Aug 2, 2022

I have tracked down a more explicit 'snub' of ChaCha20 from NIST.

Per the latest NIST Guidance on TLS, NIST 800-52r2 Appendix B.2 "Interpreting Cipher Suites Names in TLS 1.3":

As shown in Section 3.3.1, these cipher suites have the following form:
AEAD indicates the AEAD algorithm that is used for confidentiality, integrity, and message authentication. The NIST-approved TLS 1.3 AEAD algorithms comprise a NIST-recommended block cipher and NIST-recommended AEAD mode.
HASH indicates the hashing algorithm that is used with the HKDF during key derivation.
The following examples illustrate how to interpret TLS 1.3 cipher suite names:

TLS_AES_256_GCM_SHA384: Messages are encrypted and authenticated with AES256 in GCM mode, and SHA-384 is used with the HKDF.
• TLS_AES_128_CCM_SHA256: Messages are encrypted and authenticated with AES128 in CCM mode, and SHA-256 is used with the HKDF.

The negotiation of the key exchange method is handled elsewhere in the TLS handshake.

The ChaCha20 Suite is the only TLS 1.3 suite omitted from this section and there is no mention of it in the entire document.

Copy link

upsampled commented Aug 4, 2022

@FiloSottile, FIPS aside, I believe that "we only allow explicitly NIST approved ciphers or functions within our security boundary" is a valid use case.

Right now there is no evidence that ChaCha20 is NIST approved so it seems reasonable to just allow it to be disabled.

I also understand that there may be some other tweaks in order to satisfy this use case such as potentially also disabling 'x25519'; however, I will need to look at that more and in another ticket.

Copy link

FiloSottile commented Aug 4, 2022

ChaCha20Poly1305 is not part of any NIST framework, that's for sure.

However, "the non-official designation of FIPS 140-3 compliant" is, as far as I can tell, a made up target. crypto/tls is built to minimize complexity and configuration options, and to do that we need to minimize the targets we support. FIPS 140 is a popular one, so although it isn't officially supported, you can look into the BoringCrypto branch or Red Hat's solutions to find a way to satisfy that compliance requirement.

Part of the goal of the BoringCrypto branch is to bottle up the compliance-driven requirements so they don't affect other users. Satisfying a request like "I want some of the configurability to meet some sort of FIPS-like target but without the other negative side-effects" would require leaking the side-effect (like extra complexity due to configurability) into the code that everyone unconstrained by compliance uses.

I suggest you look into the existing FIPS compliance options. This is not official advice, but it sounds like simply building the BoringCrypto experiment would make your threat scanners happy.

Copy link

upsampled commented Aug 4, 2022

"we only allow explicitly NIST approved ciphers or functions within our security boundary" is a valid, non-made up target. Guides for satisfyingly this target are pretty easy to find; here is the one for OpenShift .

As for the general compliance vs complexity argument. TLSConfig has non-uniform behavior when setting the ciphers for TLS12 vs TLS13. I would argue that most users would expect the TLSConfig to actual configure the cipher suite as directed and not just ignore it silently. Keeping the behavior the same between TLS12 and TLS13 would make usage less complex.

As for the boring branch being the defacto compliance branch. last i experimented with it, it was not suited for ARM targets, (huge performance hit and arch macros prevented the FIPS parts to compile) .

Finally the CHACHA20 suite is not mandatory even by the RFC specification (it gets a SHOULD not a MUST):

A TLS-compliant application MUST implement the TLS_AES_128_GCM_SHA256
[GCM] cipher suite and SHOULD implement the TLS_AES_256_GCM_SHA384
[GCM] and TLS_CHACHA20_POLY1305_SHA256 [RFC8439] cipher suites (see
Appendix B.4).

@seankhliao seankhliao removed the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label Aug 20, 2022
@seankhliao seankhliao added this to the Unplanned milestone Aug 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
None yet

No branches or pull requests

4 participants