diff --git a/src/cmd/go/testdata/script/gopath_std_vendor.txt b/src/cmd/go/testdata/script/gopath_std_vendor.txt index a0a41a5..208aa70 100644 --- a/src/cmd/go/testdata/script/gopath_std_vendor.txt +++ b/src/cmd/go/testdata/script/gopath_std_vendor.txt @@ -21,11 +21,11 @@ go build . go list -deps -f '{{.ImportPath}} {{.Dir}}' . stdout $GOPATH[/\\]src[/\\]vendor[/\\]golang.org[/\\]x[/\\]net[/\\]http2[/\\]hpack -! stdout $GOROOT[/\\]src[/\\]vendor +! stdout $GOROOT[/\\]src[/\\]vendor[/\\]golang.org[/\\]x[/\\]net[/\\]http2[/\\]hpack go list -test -deps -f '{{.ImportPath}} {{.Dir}}' . stdout $GOPATH[/\\]src[/\\]vendor[/\\]golang.org[/\\]x[/\\]net[/\\]http2[/\\]hpack -! stdout $GOROOT[/\\]src[/\\]vendor +! stdout $GOROOT[/\\]src[/\\]vendor[/\\]golang.org[/\\]x[/\\]net[/\\]http2[/\\]hpack -- issue16333/issue16333.go -- package vendoring17 diff --git a/src/crypto/ed25519/ed25519_test.go b/src/crypto/ed25519/ed25519_test.go index 7c51817..102c4e5 100644 --- a/src/crypto/ed25519/ed25519_test.go +++ b/src/crypto/ed25519/ed25519_test.go @@ -187,6 +187,7 @@ func TestMalleability(t *testing.T) { } func TestAllocations(t *testing.T) { + t.Skip("Allocations test broken with openssl linkage") if boring.Enabled { t.Skip("skipping allocations test with BoringCrypto") } diff --git a/src/crypto/ed25519/ed25519vectors_test.go b/src/crypto/ed25519/ed25519vectors_test.go index f933f28..223ce04 100644 --- a/src/crypto/ed25519/ed25519vectors_test.go +++ b/src/crypto/ed25519/ed25519vectors_test.go @@ -72,6 +72,7 @@ func TestEd25519Vectors(t *testing.T) { } func downloadEd25519Vectors(t *testing.T) []byte { + t.Skip("skipping test that downloads external data") testenv.MustHaveExternalNetwork(t) // Create a temp dir and modcache subdir. diff --git a/src/crypto/internal/backend/bbig/big.go b/src/crypto/internal/backend/bbig/big.go new file mode 100644 index 0000000..c0800df --- /dev/null +++ b/src/crypto/internal/backend/bbig/big.go @@ -0,0 +1,38 @@ +// Copyright 2022 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. + +// This is a mirror of crypto/internal/boring/bbig/big.go. + +package bbig + +import ( + "math/big" + "unsafe" + + "github.com/golang-fips/openssl-fips/openssl" +) + +func Enc(b *big.Int) openssl.BigInt { + if b == nil { + return nil + } + x := b.Bits() + if len(x) == 0 { + return openssl.BigInt{} + } + // TODO: Use unsafe.Slice((*uint)(&x[0]), len(x)) once go1.16 is no longer supported. + return (*(*[]uint)(unsafe.Pointer(&x)))[:len(x)] +} + +func Dec(b openssl.BigInt) *big.Int { + if b == nil { + return nil + } + if len(b) == 0 { + return new(big.Int) + } + // TODO: Use unsafe.Slice((*uint)(&b[0]), len(b)) once go1.16 is no longer supported. + x := (*(*[]big.Word)(unsafe.Pointer(&b)))[:len(b)] + return new(big.Int).SetBits(x) +} diff --git a/src/crypto/internal/backend/dummy.s b/src/crypto/internal/backend/dummy.s new file mode 100644 index 0000000..e69de29 diff --git a/src/crypto/internal/backend/nobackend.go b/src/crypto/internal/backend/nobackend.go new file mode 100644 index 0000000..1d75287 --- /dev/null +++ b/src/crypto/internal/backend/nobackend.go @@ -0,0 +1,140 @@ +// Copyright 2017 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 !linux || !cgo || android || cmd_go_bootstrap || msan || no_openssl +// +build !linux !cgo android cmd_go_bootstrap msan no_openssl + +package backend + +import ( + "crypto" + "crypto/cipher" + "crypto/internal/boring/sig" + "github.com/golang-fips/openssl-fips/openssl" + "hash" +) + +var enabled = false + +// Unreachable marks code that should be unreachable +// when BoringCrypto is in use. It is a no-op without BoringCrypto. +func Unreachable() { + // Code that's unreachable when using BoringCrypto + // is exactly the code we want to detect for reporting + // standard Go crypto. + sig.StandardCrypto() +} + +// UnreachableExceptTests marks code that should be unreachable +// when BoringCrypto is in use. It is a no-op without BoringCrypto. +func UnreachableExceptTests() {} + +func ExecutingTest() bool { return false } + +// This is a noop withotu BoringCrytpo. +func PanicIfStrictFIPS(v interface{}) {} + +type randReader int + +func (randReader) Read(b []byte) (int, error) { panic("boringcrypto: not available") } + +const RandReader = randReader(0) + +func Enabled() bool { return false } +func NewSHA1() hash.Hash { panic("boringcrypto: not available") } +func NewSHA224() hash.Hash { panic("boringcrypto: not available") } +func NewSHA256() hash.Hash { panic("boringcrypto: not available") } +func NewSHA384() hash.Hash { panic("boringcrypto: not available") } +func NewSHA512() hash.Hash { panic("boringcrypto: not available") } +func SHA1(_ []byte) [20]byte { panic("boringcrypto: not available") } +func SHA224(_ []byte) [28]byte { panic("boringcrypto: not available") } +func SHA256(_ []byte) [32]byte { panic("boringcrypto: not available") } +func SHA384(_ []byte) [48]byte { panic("boringcrypto: not available") } +func SHA512(_ []byte) [64]byte { panic("boringcrypto: not available") } + +func NewHMAC(h func() hash.Hash, key []byte) hash.Hash { panic("boringcrypto: not available") } + +func NewAESCipher(key []byte) (cipher.Block, error) { panic("boringcrypto: not available") } + +type PublicKeyECDSA struct{ _ int } +type PrivateKeyECDSA struct{ _ int } + +func NewGCMTLS(c cipher.Block) (cipher.AEAD, error) { + panic("boringcrypto: not available") +} +func GenerateKeyECDSA(curve string) (X, Y, D openssl.BigInt, err error) { + panic("boringcrypto: not available") +} +func NewPrivateKeyECDSA(curve string, X, Y, D openssl.BigInt) (*PrivateKeyECDSA, error) { + panic("boringcrypto: not available") +} +func NewPublicKeyECDSA(curve string, X, Y openssl.BigInt) (*PublicKeyECDSA, error) { + panic("boringcrypto: not available") +} +func SignECDSA(priv *PrivateKeyECDSA, hash []byte, h crypto.Hash) (r, s openssl.BigInt, err error) { + panic("boringcrypto: not available") +} +func SignMarshalECDSA(priv *PrivateKeyECDSA, hash []byte) ([]byte, error) { + panic("boringcrypto: not available") +} +func VerifyECDSA(pub *PublicKeyECDSA, hash, sig []byte) bool { + panic("boringcrypto: not available") +} + +type PublicKeyECDH struct{ _ int } +type PrivateKeyECDH struct{ _ int } + +func GenerateKeyECDH(curve string) (X, Y, D openssl.BigInt, err error) { + panic("boringcrypto: not available") +} +func NewPrivateKeyECDH(curve string, X, Y, D openssl.BigInt) (*PrivateKeyECDH, error) { + panic("boringcrypto: not available") +} +func NewPublicKeyECDH(curve string, X, Y openssl.BigInt) (*PublicKeyECDH, error) { + panic("boringcrypto: not available") +} +func SharedKeyECDH(priv *PrivateKeyECDH, peerPublicKey []byte) ([]byte, error) { + panic("boringcrypto: not available") +} + +type PublicKeyRSA struct{ _ int } +type PrivateKeyRSA struct{ _ int } + +func DecryptRSAOAEP(h hash.Hash, priv *PrivateKeyRSA, ciphertext, label []byte) ([]byte, error) { + panic("boringcrypto: not available") +} +func DecryptRSAPKCS1(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) { + panic("boringcrypto: not available") +} +func DecryptRSANoPadding(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) { + panic("boringcrypto: not available") +} +func EncryptRSAOAEP(h hash.Hash, pub *PublicKeyRSA, msg, label []byte) ([]byte, error) { + panic("boringcrypto: not available") +} +func EncryptRSAPKCS1(pub *PublicKeyRSA, msg []byte) ([]byte, error) { + panic("boringcrypto: not available") +} +func EncryptRSANoPadding(pub *PublicKeyRSA, msg []byte) ([]byte, error) { + panic("boringcrypto: not available") +} +func GenerateKeyRSA(bits int) (N, E, D, P, Q, Dp, Dq, Qinv openssl.BigInt, err error) { + panic("boringcrypto: not available") +} +func NewPrivateKeyRSA(N, E, D, P, Q, Dp, Dq, Qinv openssl.BigInt) (*PrivateKeyRSA, error) { + panic("boringcrypto: not available") +} +func NewPublicKeyRSA(N, E openssl.BigInt) (*PublicKeyRSA, error) { panic("boringcrypto: not available") } +func SignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte, msgHashed bool) ([]byte, error) { + panic("boringcrypto: not available") +} +func SignRSAPSS(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte, saltLen int) ([]byte, error) { + panic("boringcrypto: not available") +} +func VerifyRSAPKCS1v15(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte, msgHashed bool) error { + panic("boringcrypto: not available") +} +func VerifyRSAPSS(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte, saltLen int) error { + panic("boringcrypto: not available") +} diff --git a/src/crypto/internal/backend/openssl.go b/src/crypto/internal/backend/openssl.go new file mode 100644 index 0000000..4c327e0 --- /dev/null +++ b/src/crypto/internal/backend/openssl.go @@ -0,0 +1,92 @@ +// Copyright 2017 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 linux && !android && !gocrypt && !cmd_go_bootstrap && !msan && !no_openssl +// +build linux,!android,!gocrypt,!cmd_go_bootstrap,!msan,!no_openssl + +// Package openssl provides access to OpenSSLCrypto implementation functions. +// Check the variable Enabled to find out whether OpenSSLCrypto is available. +// If OpenSSLCrypto is not available, the functions in this package all panic. +package backend + +import ( + "github.com/golang-fips/openssl-fips/openssl" +) + +// Enabled controls whether FIPS crypto is enabled. +var Enabled = openssl.Enabled + +// Unreachable marks code that should be unreachable +// when OpenSSLCrypto is in use. It panics only when +// the system is in FIPS mode. +func Unreachable() { + if Enabled() { + panic("opensslcrypto: invalid code execution") + } +} + +// Provided by runtime.crypto_backend_runtime_arg0 to avoid os import. +func runtime_arg0() string + +func hasSuffix(s, t string) bool { + return len(s) > len(t) && s[len(s)-len(t):] == t +} + +// UnreachableExceptTests marks code that should be unreachable +// when OpenSSLCrypto is in use. It panics. +func UnreachableExceptTests() { + name := runtime_arg0() + // If OpenSSLCrypto ran on Windows we'd need to allow _test.exe and .test.exe as well. + if Enabled() && !hasSuffix(name, "_test") && !hasSuffix(name, ".test") { + println("opensslcrypto: unexpected code execution in", name) + panic("opensslcrypto: invalid code execution") + } +} + +var ExecutingTest = openssl.ExecutingTest + +const RandReader = openssl.RandReader + +var NewGCMTLS = openssl.NewGCMTLS +var NewSHA1 = openssl.NewSHA1 +var NewSHA224 = openssl.NewSHA224 +var NewSHA256 = openssl.NewSHA256 +var NewSHA384 = openssl.NewSHA384 +var NewSHA512 = openssl.NewSHA512 + +var SHA1 = openssl.SHA1 +var SHA224 = openssl.SHA224 +var SHA256 = openssl.SHA256 +var SHA384 = openssl.SHA384 +var SHA512 = openssl.SHA512 + +var NewHMAC = openssl.NewHMAC + +var NewAESCipher = openssl.NewAESCipher + +type PublicKeyECDSA = openssl.PublicKeyECDSA +type PrivateKeyECDSA = openssl.PrivateKeyECDSA + +var GenerateKeyECDSA = openssl.GenerateKeyECDSA +var NewPrivateKeyECDSA = openssl.NewPrivateKeyECDSA +var NewPublicKeyECDSA = openssl.NewPublicKeyECDSA +var SignMarshalECDSA = openssl.SignMarshalECDSA +var VerifyECDSA = openssl.VerifyECDSA + +type PublicKeyRSA = openssl.PublicKeyRSA +type PrivateKeyRSA = openssl.PrivateKeyRSA + +var DecryptRSAOAEP = openssl.DecryptRSAOAEP +var DecryptRSAPKCS1 = openssl.DecryptRSAPKCS1 +var DecryptRSANoPadding = openssl.DecryptRSANoPadding +var EncryptRSAOAEP = openssl.EncryptRSAOAEP +var EncryptRSAPKCS1 = openssl.EncryptRSAPKCS1 +var EncryptRSANoPadding = openssl.EncryptRSANoPadding +var GenerateKeyRSA = openssl.GenerateKeyRSA +var NewPrivateKeyRSA = openssl.NewPrivateKeyRSA +var NewPublicKeyRSA = openssl.NewPublicKeyRSA +var SignRSAPKCS1v15 = openssl.SignRSAPKCS1v15 +var SignRSAPSS = openssl.SignRSAPSS +var VerifyRSAPKCS1v15 = openssl.VerifyRSAPKCS1v15 +var VerifyRSAPSS = openssl.VerifyRSAPSS diff --git a/src/crypto/tls/boring.go b/src/crypto/tls/boring.go index 1827f76..239e6a2 100644 --- a/src/crypto/tls/boring.go +++ b/src/crypto/tls/boring.go @@ -8,8 +8,15 @@ package tls import ( "crypto/internal/boring/fipstls" + boring "crypto/internal/backend" ) +func init() { + if boring.Enabled && !boring.ExecutingTest() { + fipstls.Force() + } +} + // needFIPS returns fipstls.Required(); it avoids a new import in common.go. func needFIPS() bool { return fipstls.Required() diff --git a/src/crypto/tls/handshake_client_test.go b/src/crypto/tls/handshake_client_test.go index 380de9f..02b4ac8 100644 --- a/src/crypto/tls/handshake_client_test.go +++ b/src/crypto/tls/handshake_client_test.go @@ -2135,6 +2135,7 @@ func testBuffering(t *testing.T, version uint16) { } func TestAlertFlushing(t *testing.T) { + t.Skip("unsupported in FIPS mode, different error returned") c, s := localPipe(t) done := make(chan bool) diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go index 141fdb9..71434f2 100644 --- a/src/go/build/deps_test.go +++ b/src/go/build/deps_test.go @@ -414,19 +414,23 @@ var depsRules = ` < crypto/internal/edwards25519 < crypto/cipher; - crypto/cipher, + fmt, crypto/cipher, crypto/internal/boring/bcache < crypto/internal/boring + < github.com/golang-fips/openssl-fips/openssl + < crypto/internal/backend < crypto/boring < crypto/aes, crypto/des, crypto/hmac, crypto/md5, crypto/rc4, crypto/sha1, crypto/sha256, crypto/sha512 < CRYPTO; - CGO, fmt, net !< CRYPTO; + CGO, net !< CRYPTO; # CRYPTO-MATH is core bignum-based crypto - no cgo, net; fmt now ok. CRYPTO, FMT, math/big, embed + < github.com/golang-fips/openssl-fips/openssl/bbig < crypto/internal/boring/bbig + < crypto/internal/backend/bbig < crypto/internal/randutil < crypto/rand < crypto/ed25519 @@ -644,7 +648,7 @@ var buildIgnore = []byte("\n//go:build ignore") func findImports(pkg string) ([]string, error) { vpkg := pkg - if strings.HasPrefix(pkg, "golang.org") { + if strings.HasPrefix(pkg, "golang.org") || strings.HasPrefix(pkg, "github.com") { vpkg = "vendor/" + pkg } dir := filepath.Join(Default.GOROOT, "src", vpkg) @@ -654,7 +658,7 @@ func findImports(pkg string) ([]string, error) { } var imports []string var haveImport = map[string]bool{} - if pkg == "crypto/internal/boring" { + if pkg == "crypto/internal/boring" || pkg == "github.com/golang-fips/openssl-fips/openssl" { haveImport["C"] = true // kludge: prevent C from appearing in crypto/internal/boring imports } fset := token.NewFileSet() diff --git a/src/runtime/runtime_boring.go b/src/runtime/runtime_boring.go index 5a98b20..dc25cdc 100644 --- a/src/runtime/runtime_boring.go +++ b/src/runtime/runtime_boring.go @@ -17,3 +17,8 @@ func boring_runtime_arg0() string { //go:linkname fipstls_runtime_arg0 crypto/internal/boring/fipstls.runtime_arg0 func fipstls_runtime_arg0() string { return boring_runtime_arg0() } + +//go:linkname crypto_backend_runtime_arg0 crypto/internal/backend.runtime_arg0 +func crypto_backend_runtime_arg0() string { + return boring_runtime_arg0() +} \ No newline at end of file