mirror of
https://github.com/slackhq/nebula.git
synced 2026-10-07 02:27:55 +02:00
Support native Golang "fips140" mode (#1696)
Add support for the "fips140" mode of Go: - https://go.dev/doc/security/fips140 - https://csrc.nist.gov/projects/cryptographic-module-validation-program/certificate/5247 You can build with `make fips140`, see the README changes for more info. Some differences from the boringcrypto builds: - We switch to using `go:linkname crypto/tls.aeadAESGCMTLS13`, which gives us the fips implementation for both `boringcrypto` and `fips140` modes. This means we also no longer need `-checklinkname=0` - Go native `fips140` doesn't need CGO_ENABLED=1 - We decide if we should use the fips140 GCM at runtime, if `fips140.Enabled()` is true. If you use the `make release-fips140`, we build with build tag `fips140enforce` which ensures the binary is running with fips140 enabled and that only P256 / AES-GCM is being used. If you don't want this enforce mode, you can build without the build tag.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package nebula
|
||||
|
||||
import (
|
||||
"crypto/fips140"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
@@ -237,10 +238,17 @@ func (cs *CertState) getCertificate(v cert.Version) cert.Certificate {
|
||||
return nil
|
||||
}
|
||||
|
||||
func newCipherSuite(curve cert.Curve, pkcs11backed bool, cipher string) (noise.CipherSuite, error) {
|
||||
// newCipherSuite builds the noise.CipherSuite for the given curve and cipher.
|
||||
// When fips140Enforced is true (FIPS 140-only mode), non-approved algorithms
|
||||
// (Curve25519 and ChaChaPoly) are rejected with an error. Callers pass
|
||||
// fips140.Enforced() for fips140Enforced.
|
||||
func newCipherSuite(curve cert.Curve, pkcs11backed bool, cipher string, fips140Enforced bool) (noise.CipherSuite, error) {
|
||||
var dhFunc noise.DHFunc
|
||||
switch curve {
|
||||
case cert.Curve_CURVE25519:
|
||||
if fips140Enforced {
|
||||
return nil, errors.New("pki: use of Curve25519 is not allowed in FIPS 140-only mode")
|
||||
}
|
||||
dhFunc = noise.DH25519
|
||||
case cert.Curve_P256:
|
||||
if pkcs11backed {
|
||||
@@ -253,6 +261,9 @@ func newCipherSuite(curve cert.Curve, pkcs11backed bool, cipher string) (noise.C
|
||||
}
|
||||
|
||||
if cipher == "chachapoly" {
|
||||
if fips140Enforced {
|
||||
return nil, errors.New("pki: use of ChaChaPoly is not allowed in FIPS 140-only mode")
|
||||
}
|
||||
return noise.NewCipherSuite(dhFunc, noise.CipherChaChaPoly, noise.HashSHA256), nil
|
||||
}
|
||||
return noise.NewCipherSuite(dhFunc, noiseutil.CipherAESGCM, noise.HashSHA256), nil
|
||||
@@ -326,6 +337,10 @@ func newCertStateFromConfig(c *config.C, cipher string) (*CertState, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if fips140.Enforced() && crt.Curve() != cert.Curve_P256 {
|
||||
return nil, fmt.Errorf("pki: use of %s is not allowed in FIPS 140-only mode", crt.Curve())
|
||||
}
|
||||
|
||||
switch crt.Version() {
|
||||
case cert.Version1:
|
||||
if v1 != nil {
|
||||
@@ -405,7 +420,7 @@ func newCertState(dv cert.Version, v1, v2 cert.Certificate, pkcs11backed bool, p
|
||||
//NOTE: We do not currently have a method to verify a public private key pair when the private key is in an hsm
|
||||
} else {
|
||||
if err := v1.VerifyPrivateKey(privateKeyCurve, privateKey); err != nil {
|
||||
return nil, fmt.Errorf("private key is not a pair with public key in nebula cert")
|
||||
return nil, fmt.Errorf("private key is not a pair with public key in nebula cert: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -413,7 +428,7 @@ func newCertState(dv cert.Version, v1, v2 cert.Certificate, pkcs11backed bool, p
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error marshalling v1 certificate for handshake: %w", err)
|
||||
}
|
||||
ncs, err := newCipherSuite(v1.Curve(), pkcs11backed, cipher)
|
||||
ncs, err := newCipherSuite(v1.Curve(), pkcs11backed, cipher, fips140.Enforced())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -430,7 +445,7 @@ func newCertState(dv cert.Version, v1, v2 cert.Certificate, pkcs11backed bool, p
|
||||
//NOTE: We do not currently have a method to verify a public private key pair when the private key is in an hsm
|
||||
} else {
|
||||
if err := v2.VerifyPrivateKey(privateKeyCurve, privateKey); err != nil {
|
||||
return nil, fmt.Errorf("private key is not a pair with public key in nebula cert")
|
||||
return nil, fmt.Errorf("private key is not a pair with public key in nebula cert: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -438,7 +453,7 @@ func newCertState(dv cert.Version, v1, v2 cert.Certificate, pkcs11backed bool, p
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error marshalling v2 certificate for handshake: %w", err)
|
||||
}
|
||||
ncs, err := newCipherSuite(v2.Curve(), pkcs11backed, cipher)
|
||||
ncs, err := newCipherSuite(v2.Curve(), pkcs11backed, cipher, fips140.Enforced())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user