-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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: FIPS 140-3 modes reject ECDSA w/ curve P-521/SHA-512 in TLS #71757
Comments
Looks like prior to 1.24, when the defaults were not broken out, the algorithm was present: 0b57881 |
cc @golang/security |
Ah, I see this was done on purpose: d363534. Will try to dig up the rationale, but this is a breaking change for our HC Vault clustering code. |
@FiloSottile @rolandshoemaker I'm confused by this. I don't see how BoringSSL rev 20220613 / cert 4735 (used per Dockerfile) forbids P-521/SHA-512 since ECDSA FIPS 186-4 with P-521 is permitted under A2811 (page 8 & 9) unless the specific hash combination wasn't tested or it wasn't validated by the lab for TLS use? Perhaps it has to do with Page 18/19's ECDSA Signing Key bits field? The BoringSSL ACVP wrapper code at the FIPS tag seem to test it: https://github.com/google/boringssl/blob/fips-20220613/util/fipstools/acvp/modulewrapper/modulewrapper.cc#L448-L513. Likewise the Related, but why is HKDF not present/certified? I see nothing in that module's policy allowing the use of TLSv1.3; only 1.2 and earlier KDFs. It is likewise missing from the ACVP. Documents like OpenSSL Foundation's certification, BouncyCastle's v2.1.0 certificate, and Red Hat's OpenSSL certificate all clearly permit TLSv1.3 and have certified HKDF for use. The BoringSSL code at the Honestly, it seems like this patch is reversed. We should disable TLSv1.3 and enable P-521? It seems like the discussion linked here and in #62372 (comment) are referring to a different version of the SP than what was certified by NIST...? |
Re-edited the issue title, as this is not a boringcrypto specific problem, the code that restricts the TLS signature modes is not specific to any particular FIPS 140-3 mode of Go 1.24. |
The Go+BoringCrypto choices are based on BoringSSL's As for the Go FIPS 140-3 mode, NIST SP 800-52r2 Sections 3.2, 3.4.2.2, and 4.4.2.2 give a SHOULD for P-256 / P-384 on certificates (and a SHALL support P-256 / P-384 for key exchange with the option of using others). SP 800-52 is a more restrictive profile that applies to certain federal entities, so there is a valid argument for relaxing it. |
@FiloSottile Thanks!
As far as I can tell, this policy was added after certification and is not present on the Has the suggestion to use this mode (and its compliance with the actual certificate) been given elsewhere? As far as I can tell based on the initial comment here, that was the only other mention of this policy. AFAICT as an outsider, it looks like future work for a new certification. Since Go is also not using the BoringSSL TLS stack but instead reusing Go's native TLS stack from certified primitives, I think relaxing 800-52r2 compliance would be at this project's discretion. As noted in #62372 though, at the time of SP800-52r2's publication, P-521 was a NIST-approved curve, though I will admit it is curious it wasn't called out in 3.4.2.2 Supported Groups. Sadly I can't seem to load any of the draft comments, even from the Wayback archive. But I agree with your interpretation here:
So P-521 should be allowed within that scope, even if not the highest priority item; nothing in Sp800-52r2 precludes the use of other NIST/FIPS approved curves. That is, more concretely, I suppose the answer is it is hard to write a general policy that describes what approved modules actually certify versus what is theoretically approved. I'd probably suggest a FIPS profile selector which allows everything theoretically allowed versus strict internal compliance... and then allow the underlying module to expose certified primitives and compute the actual policies. My 2c. |
Change https://go.dev/cl/650576 mentions this issue: |
Go+BoringCrypto has always been an unsupported mode primarily tracking the internal requirements of Google. We are not going to diverge from BoringSSL's choices there. However, the point of doing our own native validation is being able to make reasoned choices for Go, and I agree we can relax the policy when using our module. We can even include Ed25519 and the ML-KEM hybrid! I mailed CL 650576. Kind of on the fence on whether we should backport it. @rolandshoemaker and @cpu?
Another upside of having our own tightly coupled module is that we don't need to do complex computations between crypto/tls and the module: we know what module we ship and what it certifies, so we can just make that the FIPS 140-3 mode policy. |
@FiloSottile Ah, I think what needs to happen is we need to update from 20220613 / cert#4735 to 20230428 / cert#4953. Google has gotten a new certificate which certifies HKDF. Then you're still in compliance with a newly certified module and can now use TLSv1.3 in an approved mode of operation. |
It's a pretty large change, not sure it's really worth it unless there is significant user demand for P521 (which given metrics I've seen seems very low). |
The problem we're running into is our FIPS offering hard codes P-521 variously, which worked on the FIPS 140-2 version of BoringCrypto but doesn't now. That includes the third party ecosystem plugins that use mTLS to talk to Vault. This essentially blocks our upgrade path to 1.24, including Fed customers who have been awaiting the certificate policy additions (thanks @rolandshoemaker ) |
Also, as @cipherboy notes, that restriction applies to BoringSSL HEAD, not 20220613, so the Go restriction is more restrictive than the policy in place at the time the module was submitted. The security policy associated with the CMVP cert explicitly calls out P-521 as approved, at the end of page 8 of the policy. |
I understand the reason to try to align with BoringSSL, and that boringcrypto is unsupported, but our ask is at least to have a workaround, possibly an experiment or env var that restores the status quo for those of us who are using boring, as we're stuck with no FIPS with a validated module story at all until the standard lib receives its cert. |
Again, Go+BoringCrypto is unsupported, and always has been. Updating the module and discussing its compliance strategy are not something we will be investing further resources in. If we are to consider a backport to mitigate the impact of the Go 1.24 changes on your workload (as a courtesy exception, despite the lack of backwards compatibility promises for unsupported experiments), can you clarify
Even if we provide an exceptional backport this time, it's imperative you make plans to migrate to the supported native Go Cryptographic Module, ideally as soon as it is In Process, which should happen soon and apply to Go 1.24, because this is unlikely to ever happen again. It would also be useful if you could confirm whether CL 650576 will work for you. Also, please test tip and the Release Candidates. This would have been easier if it had been raised back when this change was made. |
Understood, and we were aware of this, but didn't anticipate reduction in the available modes the module provided, especially on the stronger end. SHA-1 we expected.
And I believe the FIPS curve preferences list, though the latter doesn't appear to be necessary to prevent rejection of a TLS connection, but I worry about effects we haven't seen.
In our case, HashiCorp Vault uses P-521 for node to node communication, for our consensus algorithm (Raft), and all external plugins to the product. Basically nothing but unmodified single node Vault works now. We looked at whether we could downgrade to P-384, but there are significant migration concerns and it would require all customers to essentially rebuild their clusters, inducing downtime. These customers include large US federal ones, financial institutions, etc. I expect there are other orgs out there using FIPS and P-521 but I can't speak for them. Re native go module, we're pretty excited about it and fully intend to move to it once it's certified. Thanks, Scott. |
CL 650576 looks good to me. We'll explicitly test it tomorrow. |
If you only need P-521 ECDSA certificates but are ok with P-384 ECDH key exchange, it depends on the TLS version: TLS 1.3 will only look at the supported signature algorithms and only needs ECDSAWithP521AndSHA512; TLS 1.2 regrettably considers ECDSAWithP521AndSHA512 more like ECDSAWithSHA512 and then looks at the overloaded supported curves list. Do you need TLS 1.2 to work with FIPS and P-521 certificates? I'm asking because the smallest change the better, especially in a minor release backport. For example reintroducing P-521 ECDH key exchange can cause handshake performance to tank if it gets selected over P-256 or even P-384. |
Understood. Let me look further into it, but since curve is negotiated in
key exchange, we probably don't need P-521 there. It's the certificates we
generate at P-521 without being able to configure that today so you're
probably right. Will verify.
…On Tue, Feb 25, 2025 at 5:07 AM Filippo Valsorda ***@***.***> wrote:
And I believe the FIPS curve preferences list, though the latter doesn't
appear to be necessary to prevent rejection of a TLS connection, but I
worry about effects we haven't seen.
If you only need P-521 ECDSA certificates but are ok with P-384 ECDH key
exchange, it depends on the TLS version: TLS 1.3 will only look at the
supported signature algorithms and only needs ECDSAWithP521AndSHA512; TLS
1.2 regrettably considers ECDSAWithP521AndSHA512 more like ECDSAWithSHA512
and then looks at the overloaded supported curves list. Do you need TLS 1.2
to work with FIPS and P-521 certificates?
I'm asking because the smallest change the better, especially in a minor
release backport. For example reintroducing P-521 ECDH key exchange can
cause handshake performance to tank if it gets selected over P-256 or even
P-384.
—
Reply to this email directly, view it on GitHub
<#71757 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAJNHLT3T2YJQEETO35J5ND2RRFIVAVCNFSM6AAAAABXFQ3TBKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDMOBRGU4TKNRUGU>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
[image: FiloSottile]*FiloSottile* left a comment (golang/go#71757)
<#71757 (comment)>
And I believe the FIPS curve preferences list, though the latter doesn't
appear to be necessary to prevent rejection of a TLS connection, but I
worry about effects we haven't seen.
If you only need P-521 ECDSA certificates but are ok with P-384 ECDH key
exchange, it depends on the TLS version: TLS 1.3 will only look at the
supported signature algorithms and only needs ECDSAWithP521AndSHA512; TLS
1.2 regrettably considers ECDSAWithP521AndSHA512 more like ECDSAWithSHA512
and then looks at the overloaded supported curves list. Do you need TLS 1.2
to work with FIPS and P-521 certificates?
I'm asking because the smallest change the better, especially in a minor
release backport. For example reintroducing P-521 ECDH key exchange can
cause handshake performance to tank if it gets selected over P-256 or even
P-384.
—
Reply to this email directly, view it on GitHub
<#71757 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAJNHLT3T2YJQEETO35J5ND2RRFIVAVCNFSM6AAAAABXFQ3TBKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDMOBRGU4TKNRUGU>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
It depends on whether you need TLS 1.2 or not. TLS 1.2 reuses the curves list for both key exchange and certificate support, while TLS 1.3 thankfully cleaned that up. Ideally, you could confirm you can use TLS 1.3 for those workloads, minimizing the backport to be considered. FWIW, Fed workload are supposed to require TLS 1.3 since 2024. |
With the FIPS 140-3 cert we *could* have used TLS 1.3, but as I understand
from the rest of the discussion above, HKDF isn't approved in the
BoringCrypto cert used, so 1.3 is out for compliant workloads. And I'm
sure we wouldn't entertain updating the module.
…On Tue, Feb 25, 2025 at 9:39 AM Filippo Valsorda ***@***.***> wrote:
It depends on whether you need TLS 1.2 or not. TLS 1.2 reuses the curves
list for both key exchange and certificate support, while TLS 1.3
thankfully cleaned that up. Ideally, you could confirm you can use TLS 1.3
for those workloads, minimizing the backport to be considered. FWIW, Fed
workload are supposed to require TLS 1.3 since 2024.
—
Reply to this email directly, view it on GitHub
<#71757 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAJNHLWOBJG7UXQIMS6ZPFT2RSFCRAVCNFSM6AAAAABXFQ3TBKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDMOBSGM3DKNRTHA>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
[image: FiloSottile]*FiloSottile* left a comment (golang/go#71757)
<#71757 (comment)>
It depends on whether you need TLS 1.2 or not. TLS 1.2 reuses the curves
list for both key exchange and certificate support, while TLS 1.3
thankfully cleaned that up. Ideally, you could confirm you can use TLS 1.3
for those workloads, minimizing the backport to be considered. FWIW, Fed
workload are supposed to require TLS 1.3 since 2024.
—
Reply to this email directly, view it on GitHub
<#71757 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAJNHLWOBJG7UXQIMS6ZPFT2RSFCRAVCNFSM6AAAAABXFQ3TBKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDMOBSGM3DKNRTHA>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
Go version
go version go1.24.0 linux/amd64
Output of
go env
in your module/workspace:What did you do?
In updating our software to 1.24, using FIPS mode (in our case BoringCrypto in order to be against a CMVP validated module), TLS broke in our cluster communication. We generate ECDSA P-521 keys for our certificates, which according to our read of Implementation Guidance for FIPS 140-3 and the Cryptographic Module Validation Program, and SP 800-186 is an allowed curve when paired with SHA-512 (ECDSAWithP521AndSHA512). These are rejected by Go 1.24, due to this list of allowed ciphers in
crypto/tls/defaults.go
:This list over prunes defaultSupportedSignatureAlgorithms, losing the last non-SHA-1 line, or possibly P-521 wasn't allowed in FIPS 140-2 but is in -3. In addition, Ed25519 should probably also be supported in FIPS 140-3 (not -2 of course).
What did you see happen?
"error handshaking cluster connection: error="tls: peer doesn't support any of the certificate's signature algorithms"
What did you expect to see?
A successfully negotiated TLS connection.
The text was updated successfully, but these errors were encountered: