diff --git a/defaults_boring.go b/defaults_boring.go index bb0f71b..c953408 100644 --- a/defaults_boring.go +++ b/defaults_boring.go @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build boringcrypto + package reality import ( diff --git a/defaults_fips140.go b/defaults_fips140.go new file mode 100644 index 0000000..a0606b8 --- /dev/null +++ b/defaults_fips140.go @@ -0,0 +1,76 @@ +// Copyright 2025 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !boringcrypto + +package reality + +import ( + "crypto/ecdsa" + "crypto/ed25519" + "crypto/elliptic" + "crypto/rsa" + "crypto/x509" +) + +// These FIPS 140-3 policies allow anything approved by SP 800-140C +// and SP 800-140D, and tested as part of the Go Cryptographic Module. +// +// Notably, not SHA-1, 3DES, RC4, ChaCha20Poly1305, RSA PKCS #1 v1.5 key +// transport, or TLS 1.0—1.1 (because we don't test its KDF). +// +// These are not default lists, but filters to apply to the default or +// configured lists. Missing items are treated as if they were not implemented. +// +// They are applied when the fips140 GODEBUG is "on" or "only". + +var ( + allowedSupportedVersionsFIPS = []uint16{ + VersionTLS12, + VersionTLS13, + } + allowedCurvePreferencesFIPS = []CurveID{ + X25519MLKEM768, + CurveP256, + CurveP384, + CurveP521, + } + allowedSupportedSignatureAlgorithmsFIPS = []SignatureScheme{ + PSSWithSHA256, + ECDSAWithP256AndSHA256, + Ed25519, + PSSWithSHA384, + PSSWithSHA512, + PKCS1WithSHA256, + PKCS1WithSHA384, + PKCS1WithSHA512, + ECDSAWithP384AndSHA384, + ECDSAWithP521AndSHA512, + } + allowedCipherSuitesFIPS = []uint16{ + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + } + allowedCipherSuitesTLS13FIPS = []uint16{ + TLS_AES_128_GCM_SHA256, + TLS_AES_256_GCM_SHA384, + } +) + +func isCertificateAllowedFIPS(c *x509.Certificate) bool { + switch k := c.PublicKey.(type) { + case *rsa.PublicKey: + return k.N.BitLen() >= 2048 + case *ecdsa.PublicKey: + return k.Curve == elliptic.P256() || k.Curve == elliptic.P384() || k.Curve == elliptic.P521() + case ed25519.PublicKey: + return true + default: + return false + } +} \ No newline at end of file diff --git a/tls.go b/tls.go index c1e6ebd..2b47035 100644 --- a/tls.go +++ b/tls.go @@ -10,10 +10,13 @@ // // # FIPS 140-3 mode // -// When the program is in [FIPS 140-3 mode], this package behaves as if -// only protocol versions, cipher suites, signature algorithms, and -// key exchange algorithms approved by NIST SP 800-52r2 are implemented. -// Others are silently ignored and not negotiated. +// When the program is in [FIPS 140-3 mode], this package behaves as if only +// SP 800-140C and SP 800-140D approved protocol versions, cipher suites, +// signature algorithms, certificate public key types and sizes, and key +// exchange and derivation algorithms were implemented. Others are silently +// ignored and not negotiated, or rejected. This set may depend on the +// algorithms supported by the FIPS 140-3 Go Cryptographic Module selected with +// GOFIPS140, and may change across Go versions. // // [FIPS 140-3 mode]: https://go.dev/doc/security/fips140 package reality