diff --git a/config/versions.json b/config/versions.json index 2958403087..3966f89268 100644 --- a/config/versions.json +++ b/config/versions.json @@ -1,5 +1,5 @@ { "github.com/golang-fips/go": "main", - "github.com/golang-fips/openssl": "7544e9a0711b109a2c114b021d079263a3d683a1", + "github.com/golang-fips/openssl": "41b6eb24da2819f9ebf7818b82a0da94dc3ae309", "github.com/golang/go": "go1.21.2" -} +} \ No newline at end of file diff --git a/patches/001-initial-openssl-for-fips.patch b/patches/001-initial-openssl-for-fips.patch index 1c2c4b97c2..2fb9f52c23 100644 --- a/patches/001-initial-openssl-for-fips.patch +++ b/patches/001-initial-openssl-for-fips.patch @@ -3725,24 +3725,24 @@ index 0c2cbf3182..e01c24292e 100644 } else { testCurve = elliptic.P384() diff --git a/src/go.mod b/src/go.mod -index 25829e17f2..c6a0d5eb02 100644 +index 25829e17f2..21cbbd3616 100644 --- a/src/go.mod +++ b/src/go.mod @@ -3,6 +3,7 @@ module std go 1.21 require ( -+ github.com/golang-fips/openssl/v2 v2.0.0-rc.2.0.20230825145541-7544e9a0711b ++ github.com/golang-fips/openssl/v2 v2.0.0-rc.3.0.20231108174110-41b6eb24da28 golang.org/x/crypto v0.11.1-0.20230711161743-2e82bdd1719d golang.org/x/net v0.12.1-0.20230712162946-57553cbff163 ) diff --git a/src/go.sum b/src/go.sum -index e474b8be31..0c87e9b273 100644 +index e474b8be31..09a44760af 100644 --- a/src/go.sum +++ b/src/go.sum @@ -1,3 +1,5 @@ -+github.com/golang-fips/openssl/v2 v2.0.0-rc.2.0.20230825145541-7544e9a0711b h1:tMz1iZ8n4ppQW9SOPzA1/7TcI5sixnWGSOra+R1qiic= -+github.com/golang-fips/openssl/v2 v2.0.0-rc.2.0.20230825145541-7544e9a0711b/go.mod h1:7tuBqX2Zov8Yq5mJ2yzlKhpnxOnWyEzi38AzeWRuQdg= ++github.com/golang-fips/openssl/v2 v2.0.0-rc.3.0.20231108174110-41b6eb24da28 h1:tFlW5hU9m5kkVIShxa1FFNLe9gwoygZFHw/d/60VE7s= ++github.com/golang-fips/openssl/v2 v2.0.0-rc.3.0.20231108174110-41b6eb24da28/go.mod h1:7tuBqX2Zov8Yq5mJ2yzlKhpnxOnWyEzi38AzeWRuQdg= golang.org/x/crypto v0.11.1-0.20230711161743-2e82bdd1719d h1:LiA25/KWKuXfIq5pMIBq1s5hz3HQxhJJSu/SUGlD+SM= golang.org/x/crypto v0.11.1-0.20230711161743-2e82bdd1719d/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/net v0.12.1-0.20230712162946-57553cbff163 h1:1EDKNuaCsog7zGLEml1qRuO4gt23jORUQX2f0IKZ860= @@ -3790,10 +3790,10 @@ index 0000000000..97e8515401 \ No newline at end of file diff --git a/src/vendor/github.com/golang-fips/openssl/v2/README.md b/src/vendor/github.com/golang-fips/openssl/v2/README.md new file mode 100644 -index 0000000000..e12474e6b5 +index 0000000000..ba6289ecff --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/README.md -@@ -0,0 +1,62 @@ +@@ -0,0 +1,66 @@ +# Go OpenSSL bindings for FIPS compliance + +[![Go Reference](https://pkg.go.dev/badge/github.com/golang-fips/openssl.svg)](https://pkg.go.dev/github.com/golang-fips/openssl) @@ -3856,12 +3856,172 @@ index 0000000000..e12474e6b5 +- All crypto stubs are a mirror of Google's [dev.boringcrypto branch](https://github.com/golang/go/tree/dev.boringcrypto) and the release branch ports of that branch. +- The mapping between BoringSSL and OpenSSL APIs is taken from the former [Red Hat Go fork](https://pagure.io/go). +- The portable OpenSSL implementation is ported from Microsoft's [.NET runtime](https://github.com/dotnet/runtime) cryptography module. ++ ++## Code of Conduct ++ ++This project adopts the Go code of conduct: https://go.dev/conduct. diff --git a/src/vendor/github.com/golang-fips/openssl/v2/aes.go b/src/vendor/github.com/golang-fips/openssl/v2/aes.go new file mode 100644 -index 0000000000..a7c3aea683 +index 0000000000..1fc11f00cd --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/aes.go -@@ -0,0 +1,552 @@ +@@ -0,0 +1,90 @@ ++//go:build !cmd_go_bootstrap ++ ++package openssl ++ ++// #include "goopenssl.h" ++import "C" ++import ( ++ "crypto/cipher" ++ "errors" ++) ++ ++type extraModes interface { ++ // Copied out of crypto/aes/modes.go. ++ NewCBCEncrypter(iv []byte) cipher.BlockMode ++ NewCBCDecrypter(iv []byte) cipher.BlockMode ++ NewCTR(iv []byte) cipher.Stream ++ NewGCM(nonceSize, tagSize int) (cipher.AEAD, error) ++ ++ // Invented for BoringCrypto. ++ NewGCMTLS() (cipher.AEAD, error) ++} ++ ++var _ extraModes = (*aesCipher)(nil) ++ ++func NewAESCipher(key []byte) (cipher.Block, error) { ++ var kind cipherKind ++ switch len(key) * 8 { ++ case 128: ++ kind = cipherAES128 ++ case 192: ++ kind = cipherAES192 ++ case 256: ++ kind = cipherAES256 ++ default: ++ return nil, errors.New("crypto/aes: invalid key size") ++ } ++ c, err := newEVPCipher(key, kind) ++ if err != nil { ++ return nil, err ++ } ++ return &aesCipher{c}, nil ++} ++ ++// NewGCMTLS returns a GCM cipher specific to TLS ++// and should not be used for non-TLS purposes. ++func NewGCMTLS(c cipher.Block) (cipher.AEAD, error) { ++ return c.(*aesCipher).NewGCMTLS() ++} ++ ++type aesCipher struct { ++ *evpCipher ++} ++ ++func (c *aesCipher) BlockSize() int { ++ return c.blockSize ++} ++ ++func (c *aesCipher) Encrypt(dst, src []byte) { ++ if err := c.encrypt(dst, src); err != nil { ++ // crypto/aes expects that the panic message starts with "crypto/aes: ". ++ panic("crypto/aes: " + err.Error()) ++ } ++} ++ ++func (c *aesCipher) Decrypt(dst, src []byte) { ++ if err := c.decrypt(dst, src); err != nil { ++ // crypto/aes expects that the panic message starts with "crypto/aes: ". ++ panic("crypto/aes: " + err.Error()) ++ } ++} ++ ++func (c *aesCipher) NewCBCEncrypter(iv []byte) cipher.BlockMode { ++ return c.newCBC(iv, cipherOpEncrypt) ++} ++ ++func (c *aesCipher) NewCBCDecrypter(iv []byte) cipher.BlockMode { ++ return c.newCBC(iv, cipherOpDecrypt) ++} ++ ++func (c *aesCipher) NewCTR(iv []byte) cipher.Stream { ++ return c.newCTR(iv) ++} ++ ++func (c *aesCipher) NewGCM(nonceSize, tagSize int) (cipher.AEAD, error) { ++ return c.newGCMChecked(nonceSize, tagSize) ++} ++ ++func (c *aesCipher) NewGCMTLS() (cipher.AEAD, error) { ++ return c.newGCM(true) ++} +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/bbig/big.go b/src/vendor/github.com/golang-fips/openssl/v2/bbig/big.go +new file mode 100644 +index 0000000000..a81cbdbef9 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/bbig/big.go +@@ -0,0 +1,37 @@ ++// 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 ++// https://github.com/golang/go/blob/36b87f273cc43e21685179dc1664ebb5493d26ae/src/crypto/internal/boring/bbig/big.go. ++ ++package bbig ++ ++import ( ++ "math/big" ++ "unsafe" ++ ++ "github.com/golang-fips/openssl/v2" ++) ++ ++func Enc(b *big.Int) openssl.BigInt { ++ if b == nil { ++ return nil ++ } ++ x := b.Bits() ++ if len(x) == 0 { ++ return openssl.BigInt{} ++ } ++ return unsafe.Slice((*uint)(&x[0]), len(x)) ++} ++ ++func Dec(b openssl.BigInt) *big.Int { ++ if b == nil { ++ return nil ++ } ++ if len(b) == 0 { ++ return new(big.Int) ++ } ++ x := unsafe.Slice((*big.Word)(&b[0]), len(b)) ++ return new(big.Int).SetBits(x) ++} +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/big.go b/src/vendor/github.com/golang-fips/openssl/v2/big.go +new file mode 100644 +index 0000000000..6461f241f8 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/big.go +@@ -0,0 +1,11 @@ ++package openssl ++ ++// This file does not have build constraints to ++// facilitate using BigInt in Go crypto. ++// Go crypto references BigInt unconditionally, ++// even if it is not finally used. ++ ++// A BigInt is the raw words from a BigInt. ++// This definition allows us to avoid importing math/big. ++// Conversion between BigInt and *big.Int is in openssl/bbig. ++type BigInt []uint +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/cipher.go b/src/vendor/github.com/golang-fips/openssl/v2/cipher.go +new file mode 100644 +index 0000000000..b56de6a74e +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/cipher.go +@@ -0,0 +1,534 @@ +//go:build !cmd_go_bootstrap + +package openssl @@ -3881,26 +4041,66 @@ index 0000000000..a7c3aea683 +type cipherKind int8 + +const ( -+ cipherAES128_ECB cipherKind = iota -+ cipherAES192_ECB -+ cipherAES256_ECB -+ cipherAES128_CBC -+ cipherAES192_CBC -+ cipherAES256_CBC -+ cipherAES128_CTR -+ cipherAES192_CTR -+ cipherAES256_CTR -+ cipherAES128_GCM -+ cipherAES192_GCM -+ cipherAES256_GCM ++ cipherAES128 cipherKind = iota ++ cipherAES192 ++ cipherAES256 ++ cipherDES ++ cipherDES3 ++ cipherRC4 ++) ++ ++func (c cipherKind) String() string { ++ switch c { ++ case cipherAES128: ++ return "AES-128" ++ case cipherAES192: ++ return "AES-192" ++ case cipherAES256: ++ return "AES-256" ++ case cipherDES: ++ return "DES" ++ case cipherDES3: ++ return "DES3" ++ case cipherRC4: ++ return "RC4" ++ default: ++ panic("unknown cipher kind: " + strconv.Itoa(int(c))) ++ } ++} ++ ++type cipherMode int8 ++ ++const ( ++ cipherModeNone cipherMode = -1 ++ cipherModeECB cipherMode = iota ++ cipherModeCBC ++ cipherModeCTR ++ cipherModeGCM ++) ++ ++// cipherOp is the allowed operations for a cipher, ++// as documented in [EVP_CipherInit_ex]. ++// ++// [EVP_CipherInit_ex]: https://www.openssl.org/docs/man3.0/man3/EVP_CipherInit_ex.html ++type cipherOp int8 ++ ++const ( ++ cipherOpNone cipherOp = -1 // leaves the value of the previous call, if any. ++ cipherOpDecrypt cipherOp = 0 ++ cipherOpEncrypt cipherOp = 1 +) + +// cacheCipher is a cache of cipherKind to GO_EVP_CIPHER_PTR. +var cacheCipher sync.Map + -+// newCipher returns a cipher object for the given k. -+func newCipher(k cipherKind) (cipher C.GO_EVP_CIPHER_PTR) { -+ if v, ok := cacheCipher.Load(k); ok { ++type cacheCipherKey struct { ++ kind cipherKind ++ mode cipherMode ++} ++ ++// loadCipher returns a cipher object for the given k. ++func loadCipher(k cipherKind, mode cipherMode) (cipher C.GO_EVP_CIPHER_PTR) { ++ if v, ok := cacheCipher.Load(cacheCipherKey{k, mode}); ok { + return v.(C.GO_EVP_CIPHER_PTR) + } + defer func() { @@ -3911,86 +4111,83 @@ index 0000000000..a7c3aea683 + // to fetch it on every call. Better to just fetch it once here. + cipher = C.go_openssl_EVP_CIPHER_fetch(nil, C.go_openssl_EVP_CIPHER_get0_name(cipher), nil) + } -+ cacheCipher.Store(k, cipher) ++ cacheCipher.Store(cacheCipherKey{k, mode}, cipher) + }() + switch k { -+ case cipherAES128_CBC: -+ cipher = C.go_openssl_EVP_aes_128_cbc() -+ case cipherAES192_CBC: -+ cipher = C.go_openssl_EVP_aes_192_cbc() -+ case cipherAES256_CBC: -+ cipher = C.go_openssl_EVP_aes_256_cbc() -+ case cipherAES128_ECB: -+ cipher = C.go_openssl_EVP_aes_128_ecb() -+ case cipherAES192_ECB: -+ cipher = C.go_openssl_EVP_aes_192_ecb() -+ case cipherAES256_ECB: -+ cipher = C.go_openssl_EVP_aes_256_ecb() -+ case cipherAES128_CTR: -+ cipher = C.go_openssl_EVP_aes_128_ctr() -+ case cipherAES192_CTR: -+ cipher = C.go_openssl_EVP_aes_192_ctr() -+ case cipherAES256_CTR: -+ cipher = C.go_openssl_EVP_aes_256_ctr() -+ case cipherAES128_GCM: -+ cipher = C.go_openssl_EVP_aes_128_gcm() -+ case cipherAES192_GCM: -+ cipher = C.go_openssl_EVP_aes_192_gcm() -+ case cipherAES256_GCM: -+ cipher = C.go_openssl_EVP_aes_256_gcm() ++ case cipherAES128: ++ switch mode { ++ case cipherModeECB: ++ cipher = C.go_openssl_EVP_aes_128_ecb() ++ case cipherModeCBC: ++ cipher = C.go_openssl_EVP_aes_128_cbc() ++ case cipherModeCTR: ++ cipher = C.go_openssl_EVP_aes_128_ctr() ++ case cipherModeGCM: ++ cipher = C.go_openssl_EVP_aes_128_gcm() ++ } ++ case cipherAES192: ++ switch mode { ++ case cipherModeECB: ++ cipher = C.go_openssl_EVP_aes_192_ecb() ++ case cipherModeCBC: ++ cipher = C.go_openssl_EVP_aes_192_cbc() ++ case cipherModeCTR: ++ cipher = C.go_openssl_EVP_aes_192_ctr() ++ case cipherModeGCM: ++ cipher = C.go_openssl_EVP_aes_192_gcm() ++ } ++ case cipherAES256: ++ switch mode { ++ case cipherModeECB: ++ cipher = C.go_openssl_EVP_aes_256_ecb() ++ case cipherModeCBC: ++ cipher = C.go_openssl_EVP_aes_256_cbc() ++ case cipherModeCTR: ++ cipher = C.go_openssl_EVP_aes_256_ctr() ++ case cipherModeGCM: ++ cipher = C.go_openssl_EVP_aes_256_gcm() ++ } ++ case cipherDES: ++ switch mode { ++ case cipherModeECB: ++ cipher = C.go_openssl_EVP_des_ecb() ++ case cipherModeCBC: ++ cipher = C.go_openssl_EVP_des_cbc() ++ } ++ case cipherDES3: ++ switch mode { ++ case cipherModeECB: ++ cipher = C.go_openssl_EVP_des_ede3_ecb() ++ case cipherModeCBC: ++ cipher = C.go_openssl_EVP_des_ede3_cbc() ++ } ++ case cipherRC4: ++ cipher = C.go_openssl_EVP_rc4() + } + return cipher +} + -+type aesKeySizeError int -+ -+func (k aesKeySizeError) Error() string { -+ return "crypto/aes: invalid key size " + strconv.Itoa(int(k)) -+} -+ -+const aesBlockSize = 16 -+ -+type aesCipher struct { -+ key []byte -+ enc_ctx C.GO_EVP_CIPHER_CTX_PTR -+ dec_ctx C.GO_EVP_CIPHER_CTX_PTR -+ kind cipherKind -+} -+ -+type extraModes interface { -+ // Copied out of crypto/aes/modes.go. -+ NewCBCEncrypter(iv []byte) cipher.BlockMode -+ NewCBCDecrypter(iv []byte) cipher.BlockMode -+ NewCTR(iv []byte) cipher.Stream -+ NewGCM(nonceSize, tagSize int) (cipher.AEAD, error) -+ -+ // Invented for BoringCrypto. -+ NewGCMTLS() (cipher.AEAD, error) ++type evpCipher struct { ++ key []byte ++ enc_ctx C.GO_EVP_CIPHER_CTX_PTR ++ dec_ctx C.GO_EVP_CIPHER_CTX_PTR ++ kind cipherKind ++ blockSize int +} + -+var _ extraModes = (*aesCipher)(nil) -+ -+func NewAESCipher(key []byte) (cipher.Block, error) { -+ c := &aesCipher{key: make([]byte, len(key))} -+ copy(c.key, key) -+ -+ switch len(c.key) * 8 { -+ case 128: -+ c.kind = cipherAES128_ECB -+ case 192: -+ c.kind = cipherAES192_ECB -+ case 256: -+ c.kind = cipherAES256_ECB -+ default: -+ return nil, errors.New("crypto/cipher: Invalid key size") ++func newEVPCipher(key []byte, kind cipherKind) (*evpCipher, error) { ++ cipher := loadCipher(kind, cipherModeECB) ++ if cipher == nil { ++ return nil, errors.New("crypto/cipher: unsupported cipher: " + kind.String()) + } -+ -+ runtime.SetFinalizer(c, (*aesCipher).finalize) -+ ++ c := &evpCipher{key: make([]byte, len(key)), kind: kind} ++ copy(c.key, key) ++ c.blockSize = int(C.go_openssl_EVP_CIPHER_get_block_size(cipher)) ++ runtime.SetFinalizer(c, (*evpCipher).finalize) + return c, nil +} + -+func (c *aesCipher) finalize() { ++func (c *evpCipher) finalize() { + if c.enc_ctx != nil { + C.go_openssl_EVP_CIPHER_CTX_free(c.enc_ctx) + } @@ -3999,72 +4196,77 @@ index 0000000000..a7c3aea683 + } +} + -+func (c *aesCipher) BlockSize() int { return aesBlockSize } -+ -+func (c *aesCipher) Encrypt(dst, src []byte) { -+ if len(src) < aesBlockSize { -+ panic("crypto/aes: input not full block") ++func (c *evpCipher) encrypt(dst, src []byte) error { ++ if len(src) < c.blockSize { ++ return errors.New("input not full block") + } -+ if len(dst) < aesBlockSize { -+ panic("crypto/aes: output not full block") ++ if len(dst) < c.blockSize { ++ return errors.New("output not full block") + } + // Only check for overlap between the parts of src and dst that will actually be used. + // This matches Go standard library behavior. -+ if inexactOverlap(dst[:aesBlockSize], src[:aesBlockSize]) { -+ panic("crypto/cipher: invalid buffer overlap") ++ if inexactOverlap(dst[:c.blockSize], src[:c.blockSize]) { ++ return errors.New("invalid buffer overlap") + } + if c.enc_ctx == nil { + var err error -+ c.enc_ctx, err = newCipherCtx(c.kind, C.GO_AES_ENCRYPT, c.key, nil) ++ c.enc_ctx, err = newCipherCtx(c.kind, cipherModeECB, cipherOpEncrypt, c.key, nil) + if err != nil { -+ panic(err) ++ return err + } + } + -+ if C.go_openssl_EVP_EncryptUpdate_wrapper(c.enc_ctx, base(dst), base(src), aesBlockSize) != 1 { -+ panic("crypto/cipher: EncryptUpdate failed") ++ if C.go_openssl_EVP_EncryptUpdate_wrapper(c.enc_ctx, base(dst), base(src), C.int(c.blockSize)) != 1 { ++ return errors.New("EncryptUpdate failed") + } + runtime.KeepAlive(c) ++ return nil +} + -+func (c *aesCipher) Decrypt(dst, src []byte) { -+ if len(src) < aesBlockSize { -+ panic("crypto/aes: input not full block") ++func (c *evpCipher) decrypt(dst, src []byte) error { ++ if len(src) < c.blockSize { ++ return errors.New("input not full block") + } -+ if len(dst) < aesBlockSize { -+ panic("crypto/aes: output not full block") ++ if len(dst) < c.blockSize { ++ return errors.New("output not full block") + } + // Only check for overlap between the parts of src and dst that will actually be used. + // This matches Go standard library behavior. -+ if inexactOverlap(dst[:aesBlockSize], src[:aesBlockSize]) { -+ panic("crypto/cipher: invalid buffer overlap") ++ if inexactOverlap(dst[:c.blockSize], src[:c.blockSize]) { ++ return errors.New("invalid buffer overlap") + } + if c.dec_ctx == nil { + var err error -+ c.dec_ctx, err = newCipherCtx(c.kind, C.GO_AES_DECRYPT, c.key, nil) ++ c.dec_ctx, err = newCipherCtx(c.kind, cipherModeECB, cipherOpDecrypt, c.key, nil) + if err != nil { -+ panic(err) ++ return err + } + if C.go_openssl_EVP_CIPHER_CTX_set_padding(c.dec_ctx, 0) != 1 { -+ panic("crypto/cipher: could not disable cipher padding") ++ return errors.New("could not disable cipher padding") + } + } + -+ C.go_openssl_EVP_DecryptUpdate_wrapper(c.dec_ctx, base(dst), base(src), aesBlockSize) ++ C.go_openssl_EVP_DecryptUpdate_wrapper(c.dec_ctx, base(dst), base(src), C.int(c.blockSize)) + runtime.KeepAlive(c) ++ return nil +} + -+type aesCBC struct { -+ ctx C.GO_EVP_CIPHER_CTX_PTR ++type cipherCBC struct { ++ ctx C.GO_EVP_CIPHER_CTX_PTR ++ blockSize int ++} ++ ++func (c *cipherCBC) finalize() { ++ C.go_openssl_EVP_CIPHER_CTX_free(c.ctx) +} + -+func (x *aesCBC) BlockSize() int { return aesBlockSize } ++func (x *cipherCBC) BlockSize() int { return x.blockSize } + -+func (x *aesCBC) CryptBlocks(dst, src []byte) { ++func (x *cipherCBC) CryptBlocks(dst, src []byte) { + if inexactOverlap(dst, src) { + panic("crypto/cipher: invalid buffer overlap") + } -+ if len(src)%aesBlockSize != 0 { ++ if len(src)%x.blockSize != 0 { + panic("crypto/cipher: input not full blocks") + } + if len(dst) < len(src) { @@ -4078,81 +4280,33 @@ index 0000000000..a7c3aea683 + } +} + -+func (x *aesCBC) SetIV(iv []byte) { -+ if len(iv) != aesBlockSize { ++func (x *cipherCBC) SetIV(iv []byte) { ++ if len(iv) != x.blockSize { + panic("cipher: incorrect length IV") + } -+ if C.go_openssl_EVP_CipherInit_ex(x.ctx, nil, nil, nil, base(iv), -1) != 1 { ++ if C.go_openssl_EVP_CipherInit_ex(x.ctx, nil, nil, nil, base(iv), C.int(cipherOpNone)) != 1 { + panic("cipher: unable to initialize EVP cipher ctx") + } +} + -+func (c *aesCipher) NewCBCEncrypter(iv []byte) cipher.BlockMode { -+ x := new(aesCBC) -+ -+ var cipher cipherKind -+ switch len(c.key) * 8 { -+ case 128: -+ cipher = cipherAES128_CBC -+ case 192: -+ cipher = cipherAES192_CBC -+ case 256: -+ cipher = cipherAES256_CBC -+ default: -+ panic("openssl: unsupported key length") -+ } -+ var err error -+ x.ctx, err = newCipherCtx(cipher, C.GO_AES_ENCRYPT, c.key, iv) -+ if err != nil { -+ panic(err) -+ } -+ -+ runtime.SetFinalizer(x, (*aesCBC).finalize) -+ -+ if C.go_openssl_EVP_CIPHER_CTX_set_padding(x.ctx, 0) != 1 { -+ panic("cipher: unable to set padding") -+ } -+ return x -+} -+ -+func (c *aesCBC) finalize() { -+ C.go_openssl_EVP_CIPHER_CTX_free(c.ctx) -+} -+ -+func (c *aesCipher) NewCBCDecrypter(iv []byte) cipher.BlockMode { -+ x := new(aesCBC) -+ -+ var cipher cipherKind -+ switch len(c.key) * 8 { -+ case 128: -+ cipher = cipherAES128_CBC -+ case 192: -+ cipher = cipherAES192_CBC -+ case 256: -+ cipher = cipherAES256_CBC -+ default: -+ panic("openssl: unsupported key length") -+ } -+ -+ var err error -+ x.ctx, err = newCipherCtx(cipher, C.GO_AES_DECRYPT, c.key, iv) ++func (c *evpCipher) newCBC(iv []byte, op cipherOp) cipher.BlockMode { ++ ctx, err := newCipherCtx(c.kind, cipherModeCBC, op, c.key, iv) + if err != nil { + panic(err) + } -+ -+ runtime.SetFinalizer(x, (*aesCBC).finalize) -+ ++ x := &cipherCBC{ctx: ctx, blockSize: c.blockSize} ++ runtime.SetFinalizer(x, (*cipherCBC).finalize) + if C.go_openssl_EVP_CIPHER_CTX_set_padding(x.ctx, 0) != 1 { + panic("cipher: unable to set padding") + } + return x +} + -+type aesCTR struct { ++type cipherCTR struct { + ctx C.GO_EVP_CIPHER_CTX_PTR +} + -+func (x *aesCTR) XORKeyStream(dst, src []byte) { ++func (x *cipherCTR) XORKeyStream(dst, src []byte) { + if inexactOverlap(dst, src) { + panic("crypto/cipher: invalid buffer overlap") + } @@ -4168,39 +4322,25 @@ index 0000000000..a7c3aea683 + runtime.KeepAlive(x) +} + -+func (c *aesCipher) NewCTR(iv []byte) cipher.Stream { -+ x := new(aesCTR) -+ -+ var cipher cipherKind -+ switch len(c.key) * 8 { -+ case 128: -+ cipher = cipherAES128_CTR -+ case 192: -+ cipher = cipherAES192_CTR -+ case 256: -+ cipher = cipherAES256_CTR -+ default: -+ panic("openssl: unsupported key length") -+ } -+ var err error -+ x.ctx, err = newCipherCtx(cipher, C.GO_AES_ENCRYPT, c.key, iv) ++func (c *evpCipher) newCTR(iv []byte) cipher.Stream { ++ ctx, err := newCipherCtx(c.kind, cipherModeCTR, cipherOpEncrypt, c.key, iv) + if err != nil { + panic(err) + } -+ -+ runtime.SetFinalizer(x, (*aesCTR).finalize) -+ ++ x := &cipherCTR{ctx: ctx} ++ runtime.SetFinalizer(x, (*cipherCTR).finalize) + return x +} + -+func (c *aesCTR) finalize() { ++func (c *cipherCTR) finalize() { + C.go_openssl_EVP_CIPHER_CTX_free(c.ctx) +} + -+type aesGCM struct { ++type cipherGCM struct { + ctx C.GO_EVP_CIPHER_CTX_PTR + tls bool + minNextNonce uint64 ++ blockSize int +} + +const ( @@ -4210,19 +4350,25 @@ index 0000000000..a7c3aea683 + gcmTlsFixedNonceSize = 4 +) + -+type aesNonceSizeError int ++type noGCM struct { ++ *evpCipher ++} + -+func (n aesNonceSizeError) Error() string { -+ return "crypto/aes: invalid GCM nonce size " + strconv.Itoa(int(n)) ++func (g *noGCM) BlockSize() int { ++ return g.blockSize +} + -+type noGCM struct { -+ cipher.Block ++func (g *noGCM) Encrypt(dst, src []byte) { ++ g.encrypt(dst, src) +} + -+func (c *aesCipher) NewGCM(nonceSize, tagSize int) (cipher.AEAD, error) { ++func (g *noGCM) Decrypt(dst, src []byte) { ++ g.decrypt(dst, src) ++} ++ ++func (c *evpCipher) newGCMChecked(nonceSize, tagSize int) (cipher.AEAD, error) { + if nonceSize != gcmStandardNonceSize && tagSize != gcmTagSize { -+ return nil, errors.New("crypto/aes: GCM tag and nonce sizes can't be non-standard at the same time") ++ return nil, errors.New("crypto/cipher: GCM tag and nonce sizes can't be non-standard at the same time") + } + // Fall back to standard library for GCM with non-standard nonce or tag size. + if nonceSize != gcmStandardNonceSize { @@ -4234,54 +4380,33 @@ index 0000000000..a7c3aea683 + return c.newGCM(false) +} + -+// NewGCMTLS returns a GCM cipher specific to TLS -+// and should not be used for non-TLS purposes. -+func NewGCMTLS(c cipher.Block) (cipher.AEAD, error) { -+ return c.(*aesCipher).NewGCMTLS() -+} -+ -+func (c *aesCipher) NewGCMTLS() (cipher.AEAD, error) { -+ return c.newGCM(true) -+} -+ -+func (c *aesCipher) newGCM(tls bool) (cipher.AEAD, error) { -+ var cipher cipherKind -+ switch len(c.key) * 8 { -+ case 128: -+ cipher = cipherAES128_GCM -+ case 192: -+ cipher = cipherAES192_GCM -+ case 256: -+ cipher = cipherAES256_GCM -+ default: -+ panic("openssl: unsupported key length") -+ } -+ ctx, err := newCipherCtx(cipher, -1, c.key, nil) ++func (c *evpCipher) newGCM(tls bool) (cipher.AEAD, error) { ++ ctx, err := newCipherCtx(c.kind, cipherModeGCM, cipherOpNone, c.key, nil) + if err != nil { + return nil, err + } -+ g := &aesGCM{ctx: ctx, tls: tls} -+ runtime.SetFinalizer(g, (*aesGCM).finalize) ++ g := &cipherGCM{ctx: ctx, tls: tls, blockSize: c.blockSize} ++ runtime.SetFinalizer(g, (*cipherGCM).finalize) + return g, nil +} + -+func (g *aesGCM) finalize() { ++func (g *cipherGCM) finalize() { + C.go_openssl_EVP_CIPHER_CTX_free(g.ctx) +} + -+func (g *aesGCM) NonceSize() int { ++func (g *cipherGCM) NonceSize() int { + return gcmStandardNonceSize +} + -+func (g *aesGCM) Overhead() int { ++func (g *cipherGCM) Overhead() int { + return gcmTagSize +} + -+func (g *aesGCM) Seal(dst, nonce, plaintext, additionalData []byte) []byte { ++func (g *cipherGCM) Seal(dst, nonce, plaintext, additionalData []byte) []byte { + if len(nonce) != gcmStandardNonceSize { + panic("cipher: incorrect nonce length given to GCM") + } -+ if uint64(len(plaintext)) > ((1<<32)-2)*aesBlockSize || len(plaintext)+gcmTagSize < len(plaintext) { ++ if uint64(len(plaintext)) > ((1<<32)-2)*uint64(g.blockSize) || len(plaintext)+gcmTagSize < len(plaintext) { + panic("cipher: message too large for GCM") + } + if len(dst)+len(plaintext)+gcmTagSize < len(dst) { @@ -4334,14 +4459,14 @@ index 0000000000..a7c3aea683 + +var errOpen = errors.New("cipher: message authentication failed") + -+func (g *aesGCM) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) { ++func (g *cipherGCM) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) { + if len(nonce) != gcmStandardNonceSize { + panic("cipher: incorrect nonce length given to GCM") + } + if len(ciphertext) < gcmTagSize { + return nil, errOpen + } -+ if uint64(len(ciphertext)) > ((1<<32)-2)*aesBlockSize+gcmTagSize { ++ if uint64(len(ciphertext)) > ((1<<32)-2)*uint64(g.blockSize)+gcmTagSize { + return nil, errOpen + } + // BoringCrypto does not do any TLS check when decrypting, neither do we. @@ -4384,20 +4509,37 @@ index 0000000000..a7c3aea683 + return +} + -+func newCipherCtx(kind cipherKind, mode C.int, key, iv []byte) (C.GO_EVP_CIPHER_CTX_PTR, error) { -+ cipher := newCipher(kind) ++func newCipherCtx(kind cipherKind, mode cipherMode, encrypt cipherOp, key, iv []byte) (ctx C.GO_EVP_CIPHER_CTX_PTR, err error) { ++ cipher := loadCipher(kind, mode) + if cipher == nil { -+ panic("openssl: unsupported cipher: " + strconv.Itoa(int(kind))) ++ panic("crypto/cipher: unsupported cipher: " + kind.String()) + } -+ ctx := C.go_openssl_EVP_CIPHER_CTX_new() ++ ctx = C.go_openssl_EVP_CIPHER_CTX_new() + if ctx == nil { + return nil, fail("unable to create EVP cipher ctx") + } -+ if C.go_openssl_EVP_CipherInit_ex(ctx, cipher, nil, base(key), base(iv), mode) != 1 { -+ C.go_openssl_EVP_CIPHER_CTX_free(ctx) -+ return nil, fail("unable to initialize EVP cipher ctx") -+ } -+ return ctx, nil ++ defer func() { ++ if err != nil { ++ C.go_openssl_EVP_CIPHER_CTX_free(ctx) ++ } ++ }() ++ if kind == cipherRC4 { ++ // RC4 cipher supports a variable key length. ++ // We need to set the key length before setting the key, ++ // and to do so we need to have an initialized cipher ctx. ++ if C.go_openssl_EVP_CipherInit_ex(ctx, cipher, nil, nil, nil, C.int(encrypt)) != 1 { ++ return nil, newOpenSSLError("EVP_CipherInit_ex") ++ } ++ if C.go_openssl_EVP_CIPHER_CTX_set_key_length(ctx, C.int(len(key))) != 1 { ++ return nil, newOpenSSLError("EVP_CIPHER_CTX_set_key_length") ++ } ++ // Pass nil to the next call to EVP_CipherInit_ex to avoid resetting ctx's cipher. ++ cipher = nil ++ } ++ if C.go_openssl_EVP_CipherInit_ex(ctx, cipher, nil, base(key), base(iv), C.int(encrypt)) != 1 { ++ return nil, newOpenSSLError("unable to initialize EVP cipher ctx") ++ } ++ return ctx, nil +} + +// The following two functions are a mirror of golang.org/x/crypto/internal/subtle. @@ -4414,66 +4556,125 @@ index 0000000000..a7c3aea683 + } + return anyOverlap(x, y) +} -diff --git a/src/vendor/github.com/golang-fips/openssl/v2/bbig/big.go b/src/vendor/github.com/golang-fips/openssl/v2/bbig/big.go +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/des.go b/src/vendor/github.com/golang-fips/openssl/v2/des.go new file mode 100644 -index 0000000000..a81cbdbef9 +index 0000000000..71b13333a2 --- /dev/null -+++ b/src/vendor/github.com/golang-fips/openssl/v2/bbig/big.go -@@ -0,0 +1,37 @@ -+// 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 -+// https://github.com/golang/go/blob/36b87f273cc43e21685179dc1664ebb5493d26ae/src/crypto/internal/boring/bbig/big.go. ++++ b/src/vendor/github.com/golang-fips/openssl/v2/des.go +@@ -0,0 +1,113 @@ ++//go:build !cmd_go_bootstrap + -+package bbig ++package openssl + ++// #include "goopenssl.h" ++import "C" +import ( -+ "math/big" -+ "unsafe" -+ -+ "github.com/golang-fips/openssl/v2" ++ "crypto/cipher" ++ "errors" +) + -+func Enc(b *big.Int) openssl.BigInt { -+ if b == nil { -+ return nil ++// SupportsDESCipher returns true if NewDESCipher is supported, ++// which uses ECB mode. ++// If CBC is also supported, then the returned cipher.Block ++// will also implement NewCBCEncrypter and NewCBCDecrypter. ++func SupportsDESCipher() bool { ++ // True for stock OpenSSL 1 w/o FIPS. ++ // False for stock OpenSSL 3 unless the legacy provider is available. ++ return (versionAtOrAbove(1, 1, 0) || !FIPS()) && loadCipher(cipherDES, cipherModeECB) != nil ++} ++ ++// SupportsTripleDESCipher returns true if NewTripleDESCipher is supported, ++// which uses ECB mode. ++// If CBC is also supported, then the returned cipher.Block ++// will also implement NewCBCEncrypter and NewCBCDecrypter. ++func SupportsTripleDESCipher() bool { ++ // Should always be true for stock OpenSSL, ++ // even when using the FIPS provider. ++ return loadCipher(cipherDES3, cipherModeECB) != nil ++} ++ ++func NewDESCipher(key []byte) (cipher.Block, error) { ++ if len(key) != 8 { ++ return nil, errors.New("crypto/des: invalid key size") + } -+ x := b.Bits() -+ if len(x) == 0 { -+ return openssl.BigInt{} ++ c, err := newEVPCipher(key, cipherDES) ++ if err != nil { ++ return nil, err + } -+ return unsafe.Slice((*uint)(&x[0]), len(x)) ++ // Should always be true for stock OpenSSL. ++ if loadCipher(cipherDES, cipherModeCBC) == nil { ++ return &desCipherWithoutCBC{c}, nil ++ } ++ return &desCipher{c}, nil +} + -+func Dec(b openssl.BigInt) *big.Int { -+ if b == nil { -+ return nil ++func NewTripleDESCipher(key []byte) (cipher.Block, error) { ++ if len(key) != 24 { ++ return nil, errors.New("crypto/des: invalid key size") + } -+ if len(b) == 0 { -+ return new(big.Int) ++ c, err := newEVPCipher(key, cipherDES3) ++ if err != nil { ++ return nil, err + } -+ x := unsafe.Slice((*big.Word)(&b[0]), len(b)) -+ return new(big.Int).SetBits(x) ++ // Should always be true for stock OpenSSL. ++ if loadCipher(cipherDES, cipherModeCBC) != nil { ++ return &desCipherWithoutCBC{c}, nil ++ } ++ return &desCipher{c}, nil +} -diff --git a/src/vendor/github.com/golang-fips/openssl/v2/big.go b/src/vendor/github.com/golang-fips/openssl/v2/big.go -new file mode 100644 -index 0000000000..6461f241f8 ---- /dev/null -+++ b/src/vendor/github.com/golang-fips/openssl/v2/big.go -@@ -0,0 +1,11 @@ -+package openssl + -+// This file does not have build constraints to -+// facilitate using BigInt in Go crypto. -+// Go crypto references BigInt unconditionally, -+// even if it is not finally used. ++type desExtraModes interface { ++ NewCBCEncrypter(iv []byte) cipher.BlockMode ++ NewCBCDecrypter(iv []byte) cipher.BlockMode ++} + -+// A BigInt is the raw words from a BigInt. -+// This definition allows us to avoid importing math/big. -+// Conversion between BigInt and *big.Int is in openssl/bbig. -+type BigInt []uint ++var _ desExtraModes = (*desCipher)(nil) ++ ++type desCipher struct { ++ *evpCipher ++} ++ ++func (c *desCipher) BlockSize() int { ++ return c.blockSize ++} ++ ++func (c *desCipher) Encrypt(dst, src []byte) { ++ if err := c.encrypt(dst, src); err != nil { ++ // crypto/des expects that the panic message starts with "crypto/des: ". ++ panic("crypto/des: " + err.Error()) ++ } ++} ++ ++func (c *desCipher) Decrypt(dst, src []byte) { ++ if err := c.decrypt(dst, src); err != nil { ++ // crypto/des expects that the panic message starts with "crypto/des: ". ++ panic("crypto/des: " + err.Error()) ++ } ++} ++ ++func (c *desCipher) NewCBCEncrypter(iv []byte) cipher.BlockMode { ++ return c.newCBC(iv, cipherOpEncrypt) ++} ++ ++func (c *desCipher) NewCBCDecrypter(iv []byte) cipher.BlockMode { ++ return c.newCBC(iv, cipherOpDecrypt) ++} ++ ++type desCipherWithoutCBC struct { ++ *evpCipher ++} ++ ++func (c *desCipherWithoutCBC) BlockSize() int { ++ return c.blockSize ++} ++ ++func (c *desCipherWithoutCBC) Encrypt(dst, src []byte) { ++ c.encrypt(dst, src) ++} ++ ++func (c *desCipherWithoutCBC) Decrypt(dst, src []byte) { ++ c.decrypt(dst, src) ++} diff --git a/src/vendor/github.com/golang-fips/openssl/v2/ec.go b/src/vendor/github.com/golang-fips/openssl/v2/ec.go new file mode 100644 index 0000000000..eac2f8bbee @@ -5091,12 +5292,236 @@ index 0000000000..46b16abf48 + defer C.go_openssl_OSSL_PARAM_free(params) + return newEvpFromParams(C.GO_EVP_PKEY_EC, selection, params) +} +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/ed25519.go b/src/vendor/github.com/golang-fips/openssl/v2/ed25519.go +new file mode 100644 +index 0000000000..f66a2a1deb +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/ed25519.go +@@ -0,0 +1,218 @@ ++//go:build !cmd_go_bootstrap ++ ++package openssl ++ ++// #include "goopenssl.h" ++import "C" ++import ( ++ "errors" ++ "runtime" ++ "strconv" ++ "sync" ++ "unsafe" ++) ++ ++const ( ++ // publicKeySizeEd25519 is the size, in bytes, of public keys as used in crypto/ed25519. ++ publicKeySizeEd25519 = 32 ++ // privateKeySizeEd25519 is the size, in bytes, of private keys as used in crypto/ed25519. ++ privateKeySizeEd25519 = 64 ++ // signatureSizeEd25519 is the size, in bytes, of signatures generated and verified by crypto/ed25519. ++ signatureSizeEd25519 = 64 ++ // seedSizeEd25519 is the size, in bytes, of private key seeds. These are the private key representations used by RFC 8032. ++ seedSizeEd25519 = 32 ++) ++ ++// TODO: Add support for Ed25519ph and Ed25519ctx when OpenSSL supports them, ++// which will probably be in 3.2.0 (https://github.com/openssl/openssl/issues/20418). ++ ++var ( ++ onceSupportsEd25519 sync.Once ++ supportsEd25519 bool ++) ++ ++// SupportsEd25519 returns true if the current OpenSSL version supports ++// GenerateKeyEd25519, NewKeyFromSeedEd25519, SignEd25519 and VerifyEd25519. ++func SupportsEd25519() bool { ++ onceSupportsEd25519.Do(func() { ++ switch vMajor { ++ case 1: ++ supportsEd25519 = versionAtOrAbove(1, 1, 1) ++ case 3: ++ name := C.CString("ED25519") ++ defer C.free(unsafe.Pointer(name)) ++ sig := C.go_openssl_EVP_SIGNATURE_fetch(nil, name, nil) ++ if sig != nil { ++ C.go_openssl_EVP_SIGNATURE_free(sig) ++ supportsEd25519 = true ++ } ++ } ++ }) ++ return supportsEd25519 ++} ++ ++type PublicKeyEd25519 struct { ++ _pkey C.GO_EVP_PKEY_PTR ++} ++ ++func (k *PublicKeyEd25519) finalize() { ++ C.go_openssl_EVP_PKEY_free(k._pkey) ++} ++ ++func (k *PublicKeyEd25519) Bytes() ([]byte, error) { ++ defer runtime.KeepAlive(k) ++ pub := make([]byte, publicKeySizeEd25519) ++ if err := extractPKEYPubEd25519(k._pkey, pub); err != nil { ++ return nil, err ++ } ++ return pub, nil ++} ++ ++type PrivateKeyEd25519 struct { ++ _pkey C.GO_EVP_PKEY_PTR ++} ++ ++func (k *PrivateKeyEd25519) finalize() { ++ C.go_openssl_EVP_PKEY_free(k._pkey) ++} ++ ++func (k *PrivateKeyEd25519) Bytes() ([]byte, error) { ++ defer runtime.KeepAlive(k) ++ priv := make([]byte, privateKeySizeEd25519) ++ if err := extractPKEYPrivEd25519(k._pkey, priv); err != nil { ++ return nil, err ++ } ++ return priv, nil ++} ++ ++func (k *PrivateKeyEd25519) Public() (*PublicKeyEd25519, error) { ++ pub := make([]byte, publicKeySizeEd25519) ++ if err := extractPKEYPubEd25519(k._pkey, pub); err != nil { ++ return nil, err ++ } ++ pubk, err := NewPublicKeyEd25119(pub) ++ if err != nil { ++ return nil, err ++ } ++ return pubk, nil ++} ++ ++// GenerateKeyEd25519 generates a private key. ++func GenerateKeyEd25519() (*PrivateKeyEd25519, error) { ++ pkeyPriv, err := generateEVPPKey(C.GO_EVP_PKEY_ED25519, 0, "") ++ if err != nil { ++ return nil, err ++ } ++ priv := &PrivateKeyEd25519{_pkey: pkeyPriv} ++ runtime.SetFinalizer(priv, (*PrivateKeyEd25519).finalize) ++ return priv, nil ++} ++ ++func NewPrivateKeyEd25119(priv []byte) (*PrivateKeyEd25519, error) { ++ if len(priv) != privateKeySizeEd25519 { ++ panic("ed25519: bad private key length: " + strconv.Itoa(len(priv))) ++ } ++ return NewPrivateKeyEd25519FromSeed(priv[:seedSizeEd25519]) ++} ++ ++func NewPublicKeyEd25119(pub []byte) (*PublicKeyEd25519, error) { ++ if len(pub) != publicKeySizeEd25519 { ++ panic("ed25519: bad public key length: " + strconv.Itoa(len(pub))) ++ } ++ pkey := C.go_openssl_EVP_PKEY_new_raw_public_key(C.GO_EVP_PKEY_ED25519, nil, base(pub), C.size_t(len(pub))) ++ if pkey == nil { ++ return nil, newOpenSSLError("EVP_PKEY_new_raw_public_key") ++ } ++ pubk := &PublicKeyEd25519{_pkey: pkey} ++ runtime.SetFinalizer(pubk, (*PublicKeyEd25519).finalize) ++ return pubk, nil ++} ++ ++// NewPrivateKeyEd25519FromSeed calculates a private key from a seed. It will panic if ++// len(seed) is not [SeedSize]. RFC 8032's private keys correspond to seeds in this ++// package. ++func NewPrivateKeyEd25519FromSeed(seed []byte) (*PrivateKeyEd25519, error) { ++ if len(seed) != seedSizeEd25519 { ++ panic("ed25519: bad seed length: " + strconv.Itoa(len(seed))) ++ } ++ pkey := C.go_openssl_EVP_PKEY_new_raw_private_key(C.GO_EVP_PKEY_ED25519, nil, base(seed), C.size_t(len(seed))) ++ if pkey == nil { ++ return nil, newOpenSSLError("EVP_PKEY_new_raw_private_key") ++ } ++ priv := &PrivateKeyEd25519{_pkey: pkey} ++ runtime.SetFinalizer(priv, (*PrivateKeyEd25519).finalize) ++ return priv, nil ++} ++ ++func extractPKEYPubEd25519(pkey C.GO_EVP_PKEY_PTR, pub []byte) error { ++ pubSize := C.size_t(publicKeySizeEd25519) ++ if C.go_openssl_EVP_PKEY_get_raw_public_key(pkey, base(pub), &pubSize) != 1 { ++ return newOpenSSLError("EVP_PKEY_get_raw_public_key") ++ } ++ if pubSize != publicKeySizeEd25519 { ++ return errors.New("ed25519: bad public key length: " + strconv.Itoa(int(pubSize))) ++ } ++ return nil ++} ++ ++func extractPKEYPrivEd25519(pkey C.GO_EVP_PKEY_PTR, priv []byte) error { ++ if err := extractPKEYPubEd25519(pkey, priv[seedSizeEd25519:]); err != nil { ++ return err ++ } ++ privSize := C.size_t(seedSizeEd25519) ++ if C.go_openssl_EVP_PKEY_get_raw_private_key(pkey, base(priv), &privSize) != 1 { ++ return newOpenSSLError("EVP_PKEY_get_raw_private_key") ++ } ++ if privSize != seedSizeEd25519 { ++ return errors.New("ed25519: bad private key length: " + strconv.Itoa(int(privSize))) ++ } ++ return nil ++} ++ ++// SignEd25519 signs the message with priv and returns a signature. ++func SignEd25519(priv *PrivateKeyEd25519, message []byte) (sig []byte, err error) { ++ // Outline the function body so that the returned key can be stack-allocated. ++ sig = make([]byte, signatureSizeEd25519) ++ err = signEd25519(priv, sig, message) ++ if err != nil { ++ return nil, err ++ } ++ return sig, err ++} ++ ++func signEd25519(priv *PrivateKeyEd25519, sig, message []byte) error { ++ defer runtime.KeepAlive(priv) ++ ctx := C.go_openssl_EVP_MD_CTX_new() ++ if ctx == nil { ++ return newOpenSSLError("EVP_MD_CTX_new") ++ } ++ defer C.go_openssl_EVP_MD_CTX_free(ctx) ++ if C.go_openssl_EVP_DigestSignInit(ctx, nil, nil, nil, priv._pkey) != 1 { ++ return newOpenSSLError("EVP_DigestSignInit") ++ } ++ siglen := C.size_t(signatureSizeEd25519) ++ if C.go_openssl_EVP_DigestSign(ctx, base(sig), &siglen, base(message), C.size_t(len(message))) != 1 { ++ return newOpenSSLError("EVP_DigestSign") ++ } ++ if siglen != signatureSizeEd25519 { ++ return errors.New("ed25519: bad signature length: " + strconv.Itoa(int(siglen))) ++ } ++ return nil ++} ++ ++// VerifyEd25519 reports whether sig is a valid signature of message by pub. ++func VerifyEd25519(pub *PublicKeyEd25519, message, sig []byte) error { ++ defer runtime.KeepAlive(pub) ++ ctx := C.go_openssl_EVP_MD_CTX_new() ++ if ctx == nil { ++ return newOpenSSLError("EVP_MD_CTX_new") ++ } ++ defer C.go_openssl_EVP_MD_CTX_free(ctx) ++ if C.go_openssl_EVP_DigestVerifyInit(ctx, nil, nil, nil, pub._pkey) != 1 { ++ return newOpenSSLError("EVP_DigestVerifyInit") ++ } ++ if C.go_openssl_EVP_DigestVerify(ctx, base(sig), C.size_t(len(sig)), base(message), C.size_t(len(message))) != 1 { ++ return errors.New("ed25519: invalid signature") ++ } ++ return nil ++} diff --git a/src/vendor/github.com/golang-fips/openssl/v2/evp.go b/src/vendor/github.com/golang-fips/openssl/v2/evp.go new file mode 100644 -index 0000000000..da71d9b389 +index 0000000000..b2886e6906 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/evp.go -@@ -0,0 +1,455 @@ +@@ -0,0 +1,471 @@ +//go:build !cmd_go_bootstrap + +package openssl @@ -5159,23 +5584,25 @@ index 0000000000..da71d9b389 + } + cacheMD.Store(ch, md) + }() -+ // SupportsHash returns false for MD5 and MD5SHA1 because we don't -+ // provide a hash.Hash implementation for them. Yet, they can ++ // SupportsHash returns false for MD5SHA1 because we don't ++ // provide a hash.Hash implementation for it. Yet, it can + // still be used when signing/verifying with an RSA key. -+ switch ch { -+ case crypto.MD5: -+ return C.go_openssl_EVP_md5() -+ case crypto.MD5SHA1: ++ if ch == crypto.MD5SHA1 { + if vMajor == 1 && vMinor == 0 { + return C.go_openssl_EVP_md5_sha1_backport() + } else { + return C.go_openssl_EVP_md5_sha1() + } + } -+ if !SupportsHash(ch) { -+ return nil -+ } + switch ch { ++ case crypto.MD4: ++ if versionAtOrAbove(1, 1, 0) || !FIPS() { ++ return C.go_openssl_EVP_md4() ++ } ++ case crypto.MD5: ++ if versionAtOrAbove(1, 1, 0) || !FIPS() { ++ return C.go_openssl_EVP_md5() ++ } + case crypto.SHA1: + return C.go_openssl_EVP_sha1() + case crypto.SHA224: @@ -5187,19 +5614,27 @@ index 0000000000..da71d9b389 + case crypto.SHA512: + return C.go_openssl_EVP_sha512() + case crypto.SHA3_224: -+ return C.go_openssl_EVP_sha3_224() ++ if versionAtOrAbove(1, 1, 1) { ++ return C.go_openssl_EVP_sha3_224() ++ } + case crypto.SHA3_256: -+ return C.go_openssl_EVP_sha3_256() ++ if versionAtOrAbove(1, 1, 1) { ++ return C.go_openssl_EVP_sha3_256() ++ } + case crypto.SHA3_384: -+ return C.go_openssl_EVP_sha3_384() ++ if versionAtOrAbove(1, 1, 1) { ++ return C.go_openssl_EVP_sha3_384() ++ } + case crypto.SHA3_512: -+ return C.go_openssl_EVP_sha3_512() ++ if versionAtOrAbove(1, 1, 1) { ++ return C.go_openssl_EVP_sha3_512() ++ } + } + return nil +} + +func generateEVPPKey(id C.int, bits int, curve string) (C.GO_EVP_PKEY_PTR, error) { -+ if (bits == 0 && curve == "") || (bits != 0 && curve != "") { ++ if bits != 0 && curve != "" { + return nil, fail("incorrect generateEVPPKey parameters") + } + ctx := C.go_openssl_EVP_PKEY_CTX_new_id(id, nil) @@ -5302,16 +5737,22 @@ index 0000000000..da71d9b389 + if len(label) > 0 { + clabel = (*C.uchar)(cryptoMalloc(len(label))) + copy((*[1 << 30]byte)(unsafe.Pointer(clabel))[:len(label)], label) -+ } -+ var ret C.int -+ if vMajor == 3 { -+ ret = C.go_openssl_EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, unsafe.Pointer(clabel), C.int(len(label))) -+ } else { -+ ret = C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, C.GO_EVP_PKEY_RSA, -1, C.GO_EVP_PKEY_CTRL_RSA_OAEP_LABEL, C.int(len(label)), unsafe.Pointer(clabel)) -+ } -+ if ret != 1 { -+ cryptoFree(unsafe.Pointer(clabel)) -+ return nil, newOpenSSLError("EVP_PKEY_CTX_ctrl failed") ++ var err error ++ if vMajor == 3 { ++ ret := C.go_openssl_EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, unsafe.Pointer(clabel), C.int(len(label))) ++ if ret != 1 { ++ err = newOpenSSLError("EVP_PKEY_CTX_set0_rsa_oaep_label failed") ++ } ++ } else { ++ ret := C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, C.GO_EVP_PKEY_RSA, -1, C.GO_EVP_PKEY_CTRL_RSA_OAEP_LABEL, C.int(len(label)), unsafe.Pointer(clabel)) ++ if ret != 1 { ++ err = newOpenSSLError("EVP_PKEY_CTX_ctrl failed") ++ } ++ } ++ if err != nil { ++ cryptoFree(unsafe.Pointer(clabel)) ++ return nil, err ++ } + } + case C.GO_RSA_PKCS1_PSS_PADDING: + md := cryptoHashToMD(ch) @@ -5554,7 +5995,7 @@ index 0000000000..da71d9b389 +} diff --git a/src/vendor/github.com/golang-fips/openssl/v2/goopenssl.c b/src/vendor/github.com/golang-fips/openssl/v2/goopenssl.c new file mode 100644 -index 0000000000..ec4adc1539 +index 0000000000..1e428d5269 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/goopenssl.c @@ -0,0 +1,218 @@ @@ -5620,12 +6061,12 @@ index 0000000000..ec4adc1539 +// and assign them to their corresponding function pointer +// defined in goopenssl.h. +void -+go_openssl_load_functions(void* handle, int major, int minor, int patch) ++go_openssl_load_functions(void* handle, unsigned int major, unsigned int minor, unsigned int patch) +{ +#define DEFINEFUNC_INTERNAL(name, func) \ + _g_##name = dlsym(handle, func); \ + if (_g_##name == NULL) { \ -+ fprintf(stderr, "Cannot get required symbol " #func " from libcrypto version %d.%d\n", major, minor); \ ++ fprintf(stderr, "Cannot get required symbol " #func " from libcrypto version %u.%u\n", major, minor); \ + abort(); \ + } +#define DEFINEFUNC(ret, func, args, argscall) \ @@ -5778,10 +6219,10 @@ index 0000000000..ec4adc1539 +} diff --git a/src/vendor/github.com/golang-fips/openssl/v2/goopenssl.h b/src/vendor/github.com/golang-fips/openssl/v2/goopenssl.h new file mode 100644 -index 0000000000..dc2ce35cd7 +index 0000000000..a0e2b623a5 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/goopenssl.h -@@ -0,0 +1,183 @@ +@@ -0,0 +1,201 @@ +// This header file describes the OpenSSL ABI as built for use in Go. + +#include // size_t @@ -5808,7 +6249,7 @@ index 0000000000..dc2ce35cd7 +int go_openssl_version_minor(void* handle); +int go_openssl_version_patch(void* handle); +int go_openssl_thread_setup(void); -+void go_openssl_load_functions(void* handle, int major, int minor, int patch); ++void go_openssl_load_functions(void* handle, unsigned int major, unsigned int minor, unsigned int patch); +const GO_EVP_MD_PTR go_openssl_EVP_md5_sha1_backport(void); + +// Define pointers to all the used OpenSSL functions. @@ -5850,14 +6291,14 @@ index 0000000000..dc2ce35cd7 +#undef DEFINEFUNC_RENAMED_1_1 +#undef DEFINEFUNC_RENAMED_3_0 + -+// go_sha_sum copies ctx into ctx2 and calls EVP_DigestFinal using ctx2. ++// go_hash_sum copies ctx into ctx2 and calls EVP_DigestFinal using ctx2. +// This is necessary because Go hash.Hash mandates that Sum has no effect +// on the underlying stream. In particular it is OK to Sum, then Write more, +// then Sum again, and the second Sum acts as if the first didn't happen. +// It is written in C because Sum() tend to be in the hot path, +// and doing one cgo call instead of two is a significant performance win. +static inline int -+go_sha_sum(GO_EVP_MD_CTX_PTR ctx, GO_EVP_MD_CTX_PTR ctx2, unsigned char *out) ++go_hash_sum(GO_EVP_MD_CTX_PTR ctx, GO_EVP_MD_CTX_PTR ctx2, unsigned char *out) +{ + if (go_openssl_EVP_MD_CTX_copy(ctx2, ctx) != 1) + return 0; @@ -5903,7 +6344,7 @@ index 0000000000..dc2ce35cd7 + if (in_len == 0) in = (const unsigned char *)""; + if (aad_len == 0) aad = (const unsigned char *)""; + -+ if (go_openssl_EVP_CipherInit_ex(ctx, NULL, NULL, NULL, nonce, GO_AES_ENCRYPT) != 1) ++ if (go_openssl_EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, nonce) != 1) + return 0; + + int discard_len, out_len; @@ -5928,10 +6369,31 @@ index 0000000000..dc2ce35cd7 + const unsigned char *aad, int aad_len, + const unsigned char *tag) +{ -+ if (in_len == 0) in = (const unsigned char *)""; ++ if (in_len == 0) { ++ in = (const unsigned char *)""; ++ // OpenSSL 1.0.2 in FIPS mode contains a bug: it will fail to verify ++ // unless EVP_DecryptUpdate is called at least once with a non-NULL ++ // output buffer. OpenSSL will not dereference the output buffer when ++ // the input length is zero, so set it to an arbitrary non-NULL pointer ++ // to satisfy OpenSSL when the caller only has authenticated additional ++ // data (AAD) to verify. While a stack-allocated buffer could be used, ++ // that would risk a stack-corrupting buffer overflow if OpenSSL ++ // unexpectedly dereferenced it. Instead pass a value which would ++ // segfault if dereferenced on any modern platform where a NULL-pointer ++ // dereference would also segfault. ++ if (out == NULL) out = (unsigned char *)1; ++ } + if (aad_len == 0) aad = (const unsigned char *)""; + -+ if (go_openssl_EVP_CipherInit_ex(ctx, NULL, NULL, NULL, nonce, GO_AES_DECRYPT) != 1) ++ if (go_openssl_EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, nonce) != 1) ++ return 0; ++ ++ // OpenSSL 1.0.x FIPS Object Module 2.0 versions below 2.0.5 require that ++ // the tag be set before the ciphertext, otherwise EVP_DecryptUpdate returns ++ // an error. At least one extant commercially-supported, FIPS validated ++ // build of OpenSSL 1.0.2 uses FIPS module version 2.0.1. Set the tag first ++ // to maximize compatibility with all OpenSSL version combinations. ++ if (go_openssl_EVP_CIPHER_CTX_ctrl(ctx, GO_EVP_CTRL_GCM_SET_TAG, 16, (unsigned char *)(tag)) != 1) + return 0; + + int discard_len, out_len; @@ -5941,9 +6403,6 @@ index 0000000000..dc2ce35cd7 + return 0; + } + -+ if (go_openssl_EVP_CIPHER_CTX_ctrl(ctx, GO_EVP_CTRL_GCM_SET_TAG, 16, (unsigned char *)(tag)) != 1) -+ return 0; -+ + if (go_openssl_EVP_DecryptFinal_ex(ctx, out + out_len, &discard_len) != 1) + return 0; + @@ -5966,12 +6425,12 @@ index 0000000000..dc2ce35cd7 + ((void (*)(void *))_g_CRYPTO_free)(str); +} \ No newline at end of file -diff --git a/src/vendor/github.com/golang-fips/openssl/v2/hkdf.go b/src/vendor/github.com/golang-fips/openssl/v2/hkdf.go +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/hash.go b/src/vendor/github.com/golang-fips/openssl/v2/hash.go new file mode 100644 -index 0000000000..18b92059cc +index 0000000000..646b4ce295 --- /dev/null -+++ b/src/vendor/github.com/golang-fips/openssl/v2/hkdf.go -@@ -0,0 +1,176 @@ ++++ b/src/vendor/github.com/golang-fips/openssl/v2/hash.go +@@ -0,0 +1,793 @@ +//go:build !cmd_go_bootstrap + +package openssl @@ -5979,987 +6438,798 @@ index 0000000000..18b92059cc +// #include "goopenssl.h" +import "C" +import ( ++ "crypto" + "errors" + "hash" -+ "io" + "runtime" ++ "strconv" + "unsafe" +) + -+func SupportsHKDF() bool { -+ return vMajor > 1 || -+ (vMajor >= 1 && vMinor > 1) || -+ (vMajor >= 1 && vMinor >= 1 && vPatch >= 1) -+} ++// NOTE: Implementation ported from https://go-review.googlesource.com/c/go/+/404295. ++// The cgo calls in this file are arranged to avoid marking the parameters as escaping. ++// To do that, we call noescape (including via addr). ++// We must also make sure that the data pointer arguments have the form unsafe.Pointer(&...) ++// so that cgo does not annotate them with cgoCheckPointer calls. If it did that, it might look ++// beyond the byte slice and find Go pointers in unprocessed parts of a larger allocation. ++// To do both of these simultaneously, the idiom is unsafe.Pointer(&*addr(p)), ++// where addr returns the base pointer of p, substituting a non-nil pointer for nil, ++// and applying a noescape along the way. ++// This is all to preserve compatibility with the allocation behavior of the non-openssl implementations. + -+func newHKDF(h func() hash.Hash, mode C.int) (*hkdf, error) { -+ if !SupportsHKDF() { -+ return nil, errUnsupportedVersion() -+ } -+ -+ ch := h() -+ md := hashToMD(ch) -+ if md == nil { -+ return nil, errors.New("unsupported hash function") -+ } ++func hashOneShot(ch crypto.Hash, p []byte, sum []byte) bool { ++ return C.go_openssl_EVP_Digest(unsafe.Pointer(&*addr(p)), C.size_t(len(p)), (*C.uchar)(unsafe.Pointer(&*addr(sum))), nil, cryptoHashToMD(ch), nil) != 0 ++} + -+ ctx := C.go_openssl_EVP_PKEY_CTX_new_id(C.GO_EVP_PKEY_HKDF, nil) -+ if ctx == nil { -+ return nil, newOpenSSLError("EVP_PKEY_CTX_new_id") ++func MD4(p []byte) (sum [16]byte) { ++ if !hashOneShot(crypto.MD4, p, sum[:]) { ++ panic("openssl: MD4 failed") + } -+ defer func() { -+ C.go_openssl_EVP_PKEY_CTX_free(ctx) -+ }() ++ return ++} + -+ if C.go_openssl_EVP_PKEY_derive_init(ctx) != 1 { -+ return nil, newOpenSSLError("EVP_PKEY_derive_init") -+ } -+ switch vMajor { -+ case 3: -+ if C.go_openssl_EVP_PKEY_CTX_set_hkdf_mode(ctx, mode) != 1 { -+ return nil, newOpenSSLError("EVP_PKEY_CTX_set_hkdf_mode") -+ } -+ if C.go_openssl_EVP_PKEY_CTX_set_hkdf_md(ctx, md) != 1 { -+ return nil, newOpenSSLError("EVP_PKEY_CTX_set_hkdf_md") -+ } -+ case 1: -+ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, C.GO1_EVP_PKEY_OP_DERIVE, -+ C.GO_EVP_PKEY_CTRL_HKDF_MODE, -+ C.int(mode), nil) != 1 { -+ return nil, newOpenSSLError("EVP_PKEY_CTX_set_hkdf_mode") -+ } -+ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, C.GO1_EVP_PKEY_OP_DERIVE, -+ C.GO_EVP_PKEY_CTRL_HKDF_MD, -+ 0, unsafe.Pointer(md)) != 1 { -+ return nil, newOpenSSLError("EVP_PKEY_CTX_set_hkdf_md") -+ } ++func MD5(p []byte) (sum [16]byte) { ++ if !hashOneShot(crypto.MD5, p, sum[:]) { ++ panic("openssl: MD5 failed") + } -+ -+ c := &hkdf{ctx: ctx, hashLen: ch.Size()} -+ ctx = nil -+ -+ runtime.SetFinalizer(c, (*hkdf).finalize) -+ -+ return c, nil ++ return +} + -+type hkdf struct { -+ ctx C.GO_EVP_PKEY_CTX_PTR -+ -+ hashLen int -+ buf []byte ++func SHA1(p []byte) (sum [20]byte) { ++ if !hashOneShot(crypto.SHA1, p, sum[:]) { ++ panic("openssl: SHA1 failed") ++ } ++ return +} + -+func (c *hkdf) finalize() { -+ if c.ctx != nil { -+ C.go_openssl_EVP_PKEY_CTX_free(c.ctx) ++func SHA224(p []byte) (sum [28]byte) { ++ if !hashOneShot(crypto.SHA224, p, sum[:]) { ++ panic("openssl: SHA224 failed") + } ++ return +} + -+func (c *hkdf) Read(p []byte) (int, error) { -+ defer runtime.KeepAlive(c) -+ -+ // EVP_PKEY_derive doesn't support incremental output, each call -+ // derives the key from scratch and returns the requested bytes. -+ // To implement io.Reader, we need to ask for len(c.buf) + len(p) -+ // bytes and copy the last derived len(p) bytes to p. -+ // We use c.buf to know how many bytes we've already derived and -+ // to avoid allocating the whole output buffer on each call. -+ prevLen := len(c.buf) -+ needLen := len(p) -+ remains := 255*c.hashLen - prevLen -+ // Check whether enough data can be generated. -+ if remains < needLen { -+ return 0, errors.New("hkdf: entropy limit reached") -+ } -+ c.buf = append(c.buf, make([]byte, needLen)...) -+ outLen := C.size_t(prevLen + needLen) -+ if C.go_openssl_EVP_PKEY_derive(c.ctx, base(c.buf), &outLen) != 1 { -+ return 0, newOpenSSLError("EVP_PKEY_derive") ++func SHA256(p []byte) (sum [32]byte) { ++ if !hashOneShot(crypto.SHA256, p, sum[:]) { ++ panic("openssl: SHA256 failed") + } -+ n := copy(p, c.buf[prevLen:outLen]) -+ return n, nil ++ return +} + -+func ExtractHKDF(h func() hash.Hash, secret, salt []byte) ([]byte, error) { -+ c, err := newHKDF(h, C.GO_EVP_KDF_HKDF_MODE_EXTRACT_ONLY) -+ if err != nil { -+ return nil, err -+ } -+ switch vMajor { -+ case 3: -+ if C.go_openssl_EVP_PKEY_CTX_set1_hkdf_key(c.ctx, -+ base(secret), C.int(len(secret))) != 1 { -+ return nil, newOpenSSLError("EVP_PKEY_CTX_set1_hkdf_key") -+ } -+ if C.go_openssl_EVP_PKEY_CTX_set1_hkdf_salt(c.ctx, -+ base(salt), C.int(len(salt))) != 1 { -+ return nil, newOpenSSLError("EVP_PKEY_CTX_set1_hkdf_salt") -+ } -+ case 1: -+ if C.go_openssl_EVP_PKEY_CTX_ctrl(c.ctx, -1, C.GO1_EVP_PKEY_OP_DERIVE, -+ C.GO_EVP_PKEY_CTRL_HKDF_KEY, -+ C.int(len(secret)), unsafe.Pointer(base(secret))) != 1 { -+ return nil, newOpenSSLError("EVP_PKEY_CTX_set1_hkdf_key") -+ } -+ if C.go_openssl_EVP_PKEY_CTX_ctrl(c.ctx, -1, C.GO1_EVP_PKEY_OP_DERIVE, -+ C.GO_EVP_PKEY_CTRL_HKDF_SALT, -+ C.int(len(salt)), unsafe.Pointer(base(salt))) != 1 { -+ return nil, newOpenSSLError("EVP_PKEY_CTX_set1_hkdf_salt") -+ } -+ } -+ var outLen C.size_t -+ if C.go_openssl_EVP_PKEY_derive(c.ctx, nil, &outLen) != 1 { -+ return nil, newOpenSSLError("EVP_PKEY_derive_init") -+ } -+ out := make([]byte, outLen) -+ if C.go_openssl_EVP_PKEY_derive(c.ctx, base(out), &outLen) != 1 { -+ return nil, newOpenSSLError("EVP_PKEY_derive") ++func SHA384(p []byte) (sum [48]byte) { ++ if !hashOneShot(crypto.SHA384, p, sum[:]) { ++ panic("openssl: SHA384 failed") + } -+ return out[:outLen], nil ++ return +} + -+func ExpandHKDF(h func() hash.Hash, pseudorandomKey, info []byte) (io.Reader, error) { -+ c, err := newHKDF(h, C.GO_EVP_KDF_HKDF_MODE_EXPAND_ONLY) -+ if err != nil { -+ return nil, err -+ } -+ switch vMajor { -+ case 3: -+ if C.go_openssl_EVP_PKEY_CTX_set1_hkdf_key(c.ctx, -+ base(pseudorandomKey), C.int(len(pseudorandomKey))) != 1 { -+ return nil, newOpenSSLError("EVP_PKEY_CTX_set1_hkdf_key") -+ } -+ if C.go_openssl_EVP_PKEY_CTX_add1_hkdf_info(c.ctx, -+ base(info), C.int(len(info))) != 1 { -+ return nil, newOpenSSLError("EVP_PKEY_CTX_add1_hkdf_info") -+ } -+ case 1: -+ if C.go_openssl_EVP_PKEY_CTX_ctrl(c.ctx, -1, C.GO1_EVP_PKEY_OP_DERIVE, -+ C.GO_EVP_PKEY_CTRL_HKDF_KEY, -+ C.int(len(pseudorandomKey)), unsafe.Pointer(base(pseudorandomKey))) != 1 { -+ return nil, newOpenSSLError("EVP_PKEY_CTX_set1_hkdf_key") -+ } -+ if C.go_openssl_EVP_PKEY_CTX_ctrl(c.ctx, -1, C.GO1_EVP_PKEY_OP_DERIVE, -+ C.GO_EVP_PKEY_CTRL_HKDF_INFO, -+ C.int(len(info)), unsafe.Pointer(base(info))) != 1 { -+ return nil, newOpenSSLError("EVP_PKEY_CTX_add1_hkdf_info") -+ } ++func SHA512(p []byte) (sum [64]byte) { ++ if !hashOneShot(crypto.SHA512, p, sum[:]) { ++ panic("openssl: SHA512 failed") + } -+ return c, nil ++ return +} -diff --git a/src/vendor/github.com/golang-fips/openssl/v2/hmac.go b/src/vendor/github.com/golang-fips/openssl/v2/hmac.go -new file mode 100644 -index 0000000000..ef8116ce66 ---- /dev/null -+++ b/src/vendor/github.com/golang-fips/openssl/v2/hmac.go -@@ -0,0 +1,238 @@ -+//go:build !cmd_go_bootstrap -+ -+package openssl -+ -+// #include "goopenssl.h" -+import "C" -+import ( -+ "hash" -+ "runtime" -+ "sync" -+ "unsafe" -+) + -+var paramDigest = C.CString("digest") -+ -+var ( -+ fetchHMACOnce sync.Once -+ evpHMAC C.GO_EVP_MAC_PTR -+) -+ -+// NewHMAC returns a new HMAC using OpenSSL. -+// The function h must return a hash implemented by -+// OpenSSL (for example, h could be openssl.NewSHA256). -+// If h is not recognized, NewHMAC returns nil. -+func NewHMAC(h func() hash.Hash, key []byte) hash.Hash { -+ ch := h() -+ md := hashToMD(ch) -+ if md == nil { -+ return nil -+ } ++// SupportsHash returns true if a hash.Hash implementation is supported for h. ++func SupportsHash(h crypto.Hash) bool { ++ return cryptoHashToMD(h) != nil ++} + -+ if len(key) == 0 { -+ // This is supported in OpenSSL/Standard lib and as such -+ // we must support it here. When using HMAC with a null key -+ // HMAC_Init will try and reuse the key from the ctx. This is -+ // not the behavior previously implemented, so as a workaround -+ // we pass an "empty" key. -+ key = make([]byte, C.GO_EVP_MAX_MD_SIZE) ++func SHA3_224(p []byte) (sum [28]byte) { ++ if !hashOneShot(crypto.SHA3_224, p, sum[:]) { ++ panic("openssl: SHA3_224 failed") + } ++ return ++} + -+ switch vMajor { -+ case 1: -+ return newHMAC1(key, ch, md) -+ case 3: -+ return newHMAC3(key, ch, md) -+ default: -+ panic(errUnsupportedVersion()) ++func SHA3_256(p []byte) (sum [32]byte) { ++ if !hashOneShot(crypto.SHA3_256, p, sum[:]) { ++ panic("openssl: SHA3_256 failed") + } ++ return +} + -+// hmacCtx3 is used for OpenSSL 1. -+type hmacCtx1 struct { -+ ctx C.GO_HMAC_CTX_PTR ++func SHA3_384(p []byte) (sum [48]byte) { ++ if !hashOneShot(crypto.SHA3_384, p, sum[:]) { ++ panic("openssl: SHA3_384 failed") ++ } ++ return +} + -+// hmacCtx3 is used for OpenSSL 3. -+type hmacCtx3 struct { -+ ctx C.GO_EVP_MAC_CTX_PTR -+ key []byte // only set for OpenSSL 3.0.0, 3.0.1, and 3.0.2. ++func SHA3_512(p []byte) (sum [64]byte) { ++ if !hashOneShot(crypto.SHA3_512, p, sum[:]) { ++ panic("openssl: SHA3_512 failed") ++ } ++ return +} + -+type opensslHMAC struct { -+ ctx1 hmacCtx1 -+ ctx3 hmacCtx3 ++// evpHash implements generic hash methods. ++type evpHash struct { ++ ctx C.GO_EVP_MD_CTX_PTR ++ // ctx2 is used in evpHash.sum to avoid changing ++ // the state of ctx. Having it here allows reusing the ++ // same allocated object multiple times. ++ ctx2 C.GO_EVP_MD_CTX_PTR + size int + blockSize int -+ sum []byte +} + -+func newHMAC1(key []byte, h hash.Hash, md C.GO_EVP_MD_PTR) *opensslHMAC { -+ ctx := hmacCtxNew() -+ if ctx == nil { -+ panic("openssl: EVP_MAC_CTX_new failed") -+ } -+ if C.go_openssl_HMAC_Init_ex(ctx, unsafe.Pointer(&key[0]), C.int(len(key)), md, nil) == 0 { -+ panic(newOpenSSLError("HMAC_Init_ex failed")) ++func newEvpHash(ch crypto.Hash, size, blockSize int) *evpHash { ++ md := cryptoHashToMD(ch) ++ if md == nil { ++ panic("openssl: unsupported hash function: " + strconv.Itoa(int(ch))) + } -+ hmac := &opensslHMAC{ -+ size: h.Size(), -+ blockSize: h.BlockSize(), -+ ctx1: hmacCtx1{ctx}, ++ ctx := C.go_openssl_EVP_MD_CTX_new() ++ if C.go_openssl_EVP_DigestInit_ex(ctx, md, nil) != 1 { ++ C.go_openssl_EVP_MD_CTX_free(ctx) ++ panic(newOpenSSLError("EVP_DigestInit_ex")) + } -+ runtime.SetFinalizer(hmac, (*opensslHMAC).finalize) -+ return hmac ++ ctx2 := C.go_openssl_EVP_MD_CTX_new() ++ h := &evpHash{ ++ ctx: ctx, ++ ctx2: ctx2, ++ size: size, ++ blockSize: blockSize, ++ } ++ runtime.SetFinalizer(h, (*evpHash).finalize) ++ return h +} + -+func newHMAC3(key []byte, h hash.Hash, md C.GO_EVP_MD_PTR) *opensslHMAC { -+ fetchHMACOnce.Do(func() { -+ name := C.CString("HMAC") -+ evpHMAC = C.go_openssl_EVP_MAC_fetch(nil, name, nil) -+ C.free(unsafe.Pointer(name)) -+ }) -+ if evpHMAC == nil { -+ panic("openssl: HMAC not supported") -+ } -+ ctx := C.go_openssl_EVP_MAC_CTX_new(evpHMAC) -+ if ctx == nil { -+ panic("openssl: EVP_MAC_CTX_new failed") -+ } -+ digest := C.go_openssl_EVP_MD_get0_name(md) -+ bld := C.go_openssl_OSSL_PARAM_BLD_new() -+ if bld == nil { -+ panic(newOpenSSLError("OSSL_PARAM_BLD_new")) -+ } -+ defer C.go_openssl_OSSL_PARAM_BLD_free(bld) -+ C.go_openssl_OSSL_PARAM_BLD_push_utf8_string(bld, paramDigest, digest, 0) -+ params := C.go_openssl_OSSL_PARAM_BLD_to_param(bld) -+ if params == nil { -+ panic(newOpenSSLError("OSSL_PARAM_BLD_to_param")) -+ } -+ defer C.go_openssl_OSSL_PARAM_free(params) -+ if C.go_openssl_EVP_MAC_init(ctx, base(key), C.size_t(len(key)), params) == 0 { -+ panic(newOpenSSLError("EVP_MAC_init failed")) -+ } -+ var hkey []byte -+ if vMinor == 0 && vPatch <= 2 { -+ // EVP_MAC_init only resets the ctx internal state if a key is passed -+ // when using OpenSSL 3.0.0, 3.0.1, and 3.0.2. Save a copy of the key -+ // in the context so Reset can use it later. New OpenSSL versions -+ // do not have this issue so it isn't necessary to save the key. -+ // See https://github.com/openssl/openssl/issues/17811. -+ hkey = make([]byte, len(key)) -+ copy(hkey, key) -+ } -+ hmac := &opensslHMAC{ -+ size: h.Size(), -+ blockSize: h.BlockSize(), -+ ctx3: hmacCtx3{ctx, hkey}, -+ } -+ runtime.SetFinalizer(hmac, (*opensslHMAC).finalize) -+ return hmac ++func (h *evpHash) finalize() { ++ C.go_openssl_EVP_MD_CTX_free(h.ctx) ++ C.go_openssl_EVP_MD_CTX_free(h.ctx2) +} + -+func (h *opensslHMAC) Reset() { -+ switch vMajor { -+ case 1: -+ if C.go_openssl_HMAC_Init_ex(h.ctx1.ctx, nil, 0, nil, nil) == 0 { -+ panic(newOpenSSLError("HMAC_Init_ex failed")) -+ } -+ case 3: -+ if C.go_openssl_EVP_MAC_init(h.ctx3.ctx, base(h.ctx3.key), C.size_t(len(h.ctx3.key)), nil) == 0 { -+ panic(newOpenSSLError("EVP_MAC_init failed")) -+ } -+ default: -+ panic(errUnsupportedVersion()) ++func (h *evpHash) Reset() { ++ // There is no need to reset h.ctx2 because it is always reset after ++ // use in evpHash.sum. ++ if C.go_openssl_EVP_DigestInit_ex(h.ctx, nil, nil) != 1 { ++ panic(newOpenSSLError("EVP_DigestInit_ex")) + } ++ runtime.KeepAlive(h) ++} + -+ runtime.KeepAlive(h) // Next line will keep h alive too; just making doubly sure. -+ h.sum = nil ++func (h *evpHash) Write(p []byte) (int, error) { ++ if len(p) > 0 && C.go_openssl_EVP_DigestUpdate(h.ctx, unsafe.Pointer(&*addr(p)), C.size_t(len(p))) != 1 { ++ panic(newOpenSSLError("EVP_DigestUpdate")) ++ } ++ runtime.KeepAlive(h) ++ return len(p), nil +} + -+func (h *opensslHMAC) finalize() { -+ switch vMajor { -+ case 1: -+ hmacCtxFree(h.ctx1.ctx) -+ case 3: -+ C.go_openssl_EVP_MAC_CTX_free(h.ctx3.ctx) -+ default: -+ panic(errUnsupportedVersion()) ++func (h *evpHash) WriteString(s string) (int, error) { ++ if len(s) > 0 && C.go_openssl_EVP_DigestUpdate(h.ctx, unsafe.Pointer(unsafe.StringData(s)), C.size_t(len(s))) == 0 { ++ panic("openssl: EVP_DigestUpdate failed") + } ++ runtime.KeepAlive(h) ++ return len(s), nil +} + -+func (h *opensslHMAC) Write(p []byte) (int, error) { -+ if len(p) > 0 { -+ switch vMajor { -+ case 1: -+ C.go_openssl_HMAC_Update(h.ctx1.ctx, base(p), C.size_t(len(p))) -+ case 3: -+ C.go_openssl_EVP_MAC_update(h.ctx3.ctx, base(p), C.size_t(len(p))) -+ default: -+ panic(errUnsupportedVersion()) -+ } ++func (h *evpHash) WriteByte(c byte) error { ++ if C.go_openssl_EVP_DigestUpdate(h.ctx, unsafe.Pointer(&c), 1) == 0 { ++ panic("openssl: EVP_DigestUpdate failed") + } + runtime.KeepAlive(h) -+ return len(p), nil ++ return nil +} + -+func (h *opensslHMAC) Size() int { ++func (h *evpHash) Size() int { + return h.size +} + -+func (h *opensslHMAC) BlockSize() int { ++func (h *evpHash) BlockSize() int { + return h.blockSize +} + -+func (h *opensslHMAC) Sum(in []byte) []byte { -+ if h.sum == nil { -+ size := h.Size() -+ h.sum = make([]byte, size) ++func (h *evpHash) sum(out []byte) { ++ if C.go_hash_sum(h.ctx, h.ctx2, base(out)) != 1 { ++ panic(newOpenSSLError("go_hash_sum")) + } -+ // Make copy of context because Go hash.Hash mandates -+ // that Sum has no effect on the underlying stream. -+ // In particular it is OK to Sum, then Write more, then Sum again, -+ // and the second Sum acts as if the first didn't happen. ++ runtime.KeepAlive(h) ++} ++ ++// hashState returns a pointer to the internal hash structure. ++// ++// The EVP_MD_CTX memory layout has changed in OpenSSL 3 ++// and the property holding the internal structure is no longer md_data but algctx. ++func (h *evpHash) hashState() unsafe.Pointer { + switch vMajor { + case 1: -+ ctx2 := hmacCtxNew() -+ if ctx2 == nil { -+ panic("openssl: HMAC_CTX_new failed") -+ } -+ defer hmacCtxFree(ctx2) -+ if C.go_openssl_HMAC_CTX_copy(ctx2, h.ctx1.ctx) == 0 { -+ panic("openssl: HMAC_CTX_copy failed") ++ // https://github.com/openssl/openssl/blob/0418e993c717a6863f206feaa40673a261de7395/crypto/evp/evp_local.h#L12. ++ type mdCtx struct { ++ _ [2]unsafe.Pointer ++ _ C.ulong ++ md_data unsafe.Pointer + } -+ C.go_openssl_HMAC_Final(ctx2, base(h.sum), nil) ++ return (*mdCtx)(unsafe.Pointer(h.ctx)).md_data + case 3: -+ ctx2 := C.go_openssl_EVP_MAC_CTX_dup(h.ctx3.ctx) -+ if ctx2 == nil { -+ panic("openssl: EVP_MAC_CTX_dup failed") ++ // https://github.com/openssl/openssl/blob/5675a5aaf6a2e489022bcfc18330dae9263e598e/crypto/evp/evp_local.h#L16. ++ type mdCtx struct { ++ _ [3]unsafe.Pointer ++ _ C.ulong ++ _ [3]unsafe.Pointer ++ algctx unsafe.Pointer + } -+ defer C.go_openssl_EVP_MAC_CTX_free(ctx2) -+ C.go_openssl_EVP_MAC_final(ctx2, base(h.sum), nil, C.size_t(len(h.sum))) ++ return (*mdCtx)(unsafe.Pointer(h.ctx)).algctx + default: + panic(errUnsupportedVersion()) + } -+ return append(in, h.sum...) +} + -+func hmacCtxNew() C.GO_HMAC_CTX_PTR { -+ if vMajor == 1 && vMinor == 0 { -+ // 0x120 is the sizeof value when building against OpenSSL 1.0.2 on Ubuntu 16.04. -+ ctx := (C.GO_HMAC_CTX_PTR)(C.malloc(0x120)) -+ if ctx != nil { -+ C.go_openssl_HMAC_CTX_init(ctx) -+ } -+ return ctx ++// NewMD4 returns a new MD4 hash. ++// The returned hash doesn't implement encoding.BinaryMarshaler and ++// encoding.BinaryUnmarshaler. ++func NewMD4() hash.Hash { ++ return &md4Hash{ ++ evpHash: newEvpHash(crypto.MD4, 16, 64), + } -+ return C.go_openssl_HMAC_CTX_new() +} + -+func hmacCtxFree(ctx C.GO_HMAC_CTX_PTR) { -+ if vMajor == 1 && vMinor == 0 { -+ C.go_openssl_HMAC_CTX_cleanup(ctx) -+ C.free(unsafe.Pointer(ctx)) -+ return ++type md4Hash struct { ++ *evpHash ++ out [16]byte ++} ++ ++func (h *md4Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) ++} ++ ++// NewMD5 returns a new MD5 hash. ++func NewMD5() hash.Hash { ++ return &md5Hash{ ++ evpHash: newEvpHash(crypto.MD5, 16, 64), + } -+ C.go_openssl_HMAC_CTX_free(ctx) +} -diff --git a/src/vendor/github.com/golang-fips/openssl/v2/init.go b/src/vendor/github.com/golang-fips/openssl/v2/init.go -new file mode 100644 -index 0000000000..21126ff550 ---- /dev/null -+++ b/src/vendor/github.com/golang-fips/openssl/v2/init.go -@@ -0,0 +1,63 @@ -+//go:build !cmd_go_bootstrap + -+package openssl ++// md5State layout is taken from ++// https://github.com/openssl/openssl/blob/0418e993c717a6863f206feaa40673a261de7395/include/openssl/md5.h#L33. ++type md5State struct { ++ h [4]uint32 ++ nl, nh uint32 ++ x [64]byte ++ nx uint32 ++} + -+// #include "goopenssl.h" -+import "C" -+import ( -+ "errors" ++type md5Hash struct { ++ *evpHash ++ out [16]byte ++} ++ ++func (h *md5Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) ++} ++ ++const ( ++ md5Magic = "md5\x01" ++ md5MarshaledSize = len(md5Magic) + 4*4 + 64 + 8 +) + -+// opensslInit loads and initialize OpenSSL. -+// If successful, it returns the major and minor OpenSSL version -+// as reported by the OpenSSL API. -+// -+// See Init() for details about file. -+func opensslInit(file string) (major, minor, patch int, err error) { -+ // Load the OpenSSL shared library using dlopen. -+ handle, err := dlopen(file) -+ if err != nil { -+ return 0, 0, 0, err ++func (h *md5Hash) MarshalBinary() ([]byte, error) { ++ d := (*md5State)(h.hashState()) ++ if d == nil { ++ return nil, errors.New("crypto/md5: can't retrieve hash state") + } ++ b := make([]byte, 0, md5MarshaledSize) ++ b = append(b, md5Magic...) ++ b = appendUint32(b, d.h[0]) ++ b = appendUint32(b, d.h[1]) ++ b = appendUint32(b, d.h[2]) ++ b = appendUint32(b, d.h[3]) ++ b = append(b, d.x[:d.nx]...) ++ b = b[:len(b)+len(d.x)-int(d.nx)] // already zero ++ b = appendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29) ++ return b, nil ++} + -+ // Retrieve the loaded OpenSSL version and check if it is supported. -+ // Notice that major and minor could not match with the version parameter -+ // in case the name of the shared library file differs from the OpenSSL -+ // version it contains. -+ major = int(C.go_openssl_version_major(handle)) -+ minor = int(C.go_openssl_version_minor(handle)) -+ patch = int(C.go_openssl_version_patch(handle)) -+ if major == -1 || minor == -1 || patch == -1 { -+ return 0, 0, 0, errors.New("openssl: can't retrieve OpenSSL version") ++func (h *md5Hash) UnmarshalBinary(b []byte) error { ++ if len(b) < len(md5Magic) || string(b[:len(md5Magic)]) != md5Magic { ++ return errors.New("crypto/md5: invalid hash state identifier") + } -+ var supported bool -+ if major == 1 { -+ supported = minor == 0 || minor == 1 -+ } else if major == 3 { -+ // OpenSSL guarantees API and ABI compatibility within the same major version since OpenSSL 3. -+ supported = true ++ if len(b) != md5MarshaledSize { ++ return errors.New("crypto/md5: invalid hash state size") + } -+ if !supported { -+ return 0, 0, 0, errUnsupportedVersion() ++ d := (*md5State)(h.hashState()) ++ if d == nil { ++ return errors.New("crypto/md5: can't retrieve hash state") + } ++ b = b[len(md5Magic):] ++ b, d.h[0] = consumeUint32(b) ++ b, d.h[1] = consumeUint32(b) ++ b, d.h[2] = consumeUint32(b) ++ b, d.h[3] = consumeUint32(b) ++ b = b[copy(d.x[:], b):] ++ _, n := consumeUint64(b) ++ d.nl = uint32(n << 3) ++ d.nh = uint32(n >> 29) ++ d.nx = uint32(n) % 64 ++ return nil ++} + -+ // Load the OpenSSL functions. -+ // See shims.go for the complete list of supported functions. -+ C.go_openssl_load_functions(handle, C.int(major), C.int(minor), C.int(patch)) -+ -+ // Initialize OpenSSL. -+ C.go_openssl_OPENSSL_init() -+ if major == 1 && minor == 0 { -+ if C.go_openssl_thread_setup() != 1 { -+ return 0, 0, 0, fail("openssl: thread setup") -+ } -+ C.go_openssl_OPENSSL_add_all_algorithms_conf() -+ C.go_openssl_ERR_load_crypto_strings() -+ } else { -+ flags := C.uint64_t(C.GO_OPENSSL_INIT_ADD_ALL_CIPHERS | C.GO_OPENSSL_INIT_ADD_ALL_DIGESTS | C.GO_OPENSSL_INIT_LOAD_CONFIG | C.GO_OPENSSL_INIT_LOAD_CRYPTO_STRINGS) -+ if C.go_openssl_OPENSSL_init_crypto(flags, nil) != 1 { -+ return 0, 0, 0, fail("openssl: init crypto") -+ } ++// NewSHA1 returns a new SHA1 hash. ++func NewSHA1() hash.Hash { ++ return &sha1Hash{ ++ evpHash: newEvpHash(crypto.SHA1, 20, 64), + } -+ return major, minor, patch, nil +} -diff --git a/src/vendor/github.com/golang-fips/openssl/v2/init_unix.go b/src/vendor/github.com/golang-fips/openssl/v2/init_unix.go -new file mode 100644 -index 0000000000..dbf5ac448f ---- /dev/null -+++ b/src/vendor/github.com/golang-fips/openssl/v2/init_unix.go -@@ -0,0 +1,31 @@ -+//go:build unix && !cmd_go_bootstrap + -+package openssl ++type sha1Hash struct { ++ *evpHash ++ out [20]byte ++} + -+// #cgo LDFLAGS: -ldl -+// #include -+// #include -+import "C" -+import ( -+ "errors" -+ "unsafe" ++func (h *sha1Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) ++} ++ ++// sha1State layout is taken from ++// https://github.com/openssl/openssl/blob/0418e993c717a6863f206feaa40673a261de7395/include/openssl/sha.h#L34. ++type sha1State struct { ++ h [5]uint32 ++ nl, nh uint32 ++ x [64]byte ++ nx uint32 ++} ++ ++const ( ++ sha1Magic = "sha\x01" ++ sha1MarshaledSize = len(sha1Magic) + 5*4 + 64 + 8 +) + -+func dlopen(file string) (handle unsafe.Pointer, err error) { -+ cv := C.CString(file) -+ defer C.free(unsafe.Pointer(cv)) -+ handle = C.dlopen(cv, C.RTLD_LAZY|C.RTLD_LOCAL) -+ if handle == nil { -+ errstr := C.GoString(C.dlerror()) -+ return nil, errors.New("openssl: can't load " + file + ": " + errstr) ++func (h *sha1Hash) MarshalBinary() ([]byte, error) { ++ d := (*sha1State)(h.hashState()) ++ if d == nil { ++ return nil, errors.New("crypto/sha1: can't retrieve hash state") + } -+ return handle, nil ++ b := make([]byte, 0, sha1MarshaledSize) ++ b = append(b, sha1Magic...) ++ b = appendUint32(b, d.h[0]) ++ b = appendUint32(b, d.h[1]) ++ b = appendUint32(b, d.h[2]) ++ b = appendUint32(b, d.h[3]) ++ b = appendUint32(b, d.h[4]) ++ b = append(b, d.x[:d.nx]...) ++ b = b[:len(b)+len(d.x)-int(d.nx)] // already zero ++ b = appendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29) ++ return b, nil +} + -+func dlclose(handle unsafe.Pointer) error { -+ if C.dlclose(handle) != 0 { -+ errstr := C.GoString(C.dlerror()) -+ return errors.New("openssl: can't close libcrypto: " + errstr) ++func (h *sha1Hash) UnmarshalBinary(b []byte) error { ++ if len(b) < len(sha1Magic) || string(b[:len(sha1Magic)]) != sha1Magic { ++ return errors.New("crypto/sha1: invalid hash state identifier") ++ } ++ if len(b) != sha1MarshaledSize { ++ return errors.New("crypto/sha1: invalid hash state size") ++ } ++ d := (*sha1State)(h.hashState()) ++ if d == nil { ++ return errors.New("crypto/sha1: can't retrieve hash state") + } ++ b = b[len(sha1Magic):] ++ b, d.h[0] = consumeUint32(b) ++ b, d.h[1] = consumeUint32(b) ++ b, d.h[2] = consumeUint32(b) ++ b, d.h[3] = consumeUint32(b) ++ b, d.h[4] = consumeUint32(b) ++ b = b[copy(d.x[:], b):] ++ _, n := consumeUint64(b) ++ d.nl = uint32(n << 3) ++ d.nh = uint32(n >> 29) ++ d.nx = uint32(n) % 64 + return nil +} -diff --git a/src/vendor/github.com/golang-fips/openssl/v2/init_windows.go b/src/vendor/github.com/golang-fips/openssl/v2/init_windows.go -new file mode 100644 -index 0000000000..3778e21227 ---- /dev/null -+++ b/src/vendor/github.com/golang-fips/openssl/v2/init_windows.go -@@ -0,0 +1,36 @@ -+//go:build !cmd_go_bootstrap -+ -+package openssl -+ -+import ( -+ "syscall" -+ "unsafe" -+) + -+type dlopenError struct { -+ file string -+ err error ++// NewSHA224 returns a new SHA224 hash. ++func NewSHA224() hash.Hash { ++ return &sha224Hash{ ++ evpHash: newEvpHash(crypto.SHA224, 224/8, 64), ++ } +} + -+func (e *dlopenError) Error() string { -+ return "openssl: can't load " + e.file + ": " + e.err.Error() ++type sha224Hash struct { ++ *evpHash ++ out [224 / 8]byte +} + -+func (e *dlopenError) Unwrap() error { -+ return e.err ++func (h *sha224Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) +} + -+func dlopen(file string) (handle unsafe.Pointer, err error) { -+ // As Windows generally does not ship with a system OpenSSL library, let -+ // alone a FIPS 140 certified one, use the default library search order so -+ // that we preferentially load the DLL bundled with the application. -+ h, err := syscall.LoadLibrary(file) -+ if err != nil { -+ return nil, &dlopenError{file: file, err: err} ++// NewSHA256 returns a new SHA256 hash. ++func NewSHA256() hash.Hash { ++ return &sha256Hash{ ++ evpHash: newEvpHash(crypto.SHA256, 256/8, 64), + } -+ return unsafe.Pointer(h), nil +} + -+func dlclose(handle unsafe.Pointer) error { -+ return syscall.FreeLibrary(syscall.Handle(handle)) ++type sha256Hash struct { ++ *evpHash ++ out [256 / 8]byte +} -diff --git a/src/vendor/github.com/golang-fips/openssl/v2/openssl.go b/src/vendor/github.com/golang-fips/openssl/v2/openssl.go -new file mode 100644 -index 0000000000..5c9324d858 ---- /dev/null -+++ b/src/vendor/github.com/golang-fips/openssl/v2/openssl.go -@@ -0,0 +1,408 @@ -+//go:build !cmd_go_bootstrap -+ -+// Package openssl provides access to OpenSSL cryptographic functions. -+package openssl -+ -+// #include "goopenssl.h" -+import "C" -+import ( -+ "encoding/binary" -+ "errors" -+ "math/bits" -+ "runtime" -+ "strconv" -+ "strings" -+ "sync" -+ "unsafe" -+) + -+var ( -+ // vMajor and vMinor hold the major/minor OpenSSL version. -+ // It is only populated if Init has been called. -+ vMajor, vMinor, vPatch int -+) ++func (h *sha256Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) ++} + -+var ( -+ initOnce sync.Once -+ initErr error ++const ( ++ magic224 = "sha\x02" ++ magic256 = "sha\x03" ++ marshaledSize256 = len(magic256) + 8*4 + 64 + 8 +) + -+var nativeEndian binary.ByteOrder ++// sha256State layout is taken from ++// https://github.com/openssl/openssl/blob/0418e993c717a6863f206feaa40673a261de7395/include/openssl/sha.h#L51. ++type sha256State struct { ++ h [8]uint32 ++ nl, nh uint32 ++ x [64]byte ++ nx uint32 ++} + -+// CheckVersion checks if the OpenSSL version can be loaded -+// and if the FIPS mode is enabled. -+// This function can be called before Init. -+func CheckVersion(version string) (exists, fips bool) { -+ handle, _ := dlopen(version) -+ if handle == nil { -+ return false, false ++func (h *sha224Hash) MarshalBinary() ([]byte, error) { ++ d := (*sha256State)(h.hashState()) ++ if d == nil { ++ return nil, errors.New("crypto/sha256: can't retrieve hash state") + } -+ defer dlclose(handle) -+ fips = C.go_openssl_fips_enabled(handle) == 1 -+ return true, fips ++ b := make([]byte, 0, marshaledSize256) ++ b = append(b, magic224...) ++ b = appendUint32(b, d.h[0]) ++ b = appendUint32(b, d.h[1]) ++ b = appendUint32(b, d.h[2]) ++ b = appendUint32(b, d.h[3]) ++ b = appendUint32(b, d.h[4]) ++ b = appendUint32(b, d.h[5]) ++ b = appendUint32(b, d.h[6]) ++ b = appendUint32(b, d.h[7]) ++ b = append(b, d.x[:d.nx]...) ++ b = b[:len(b)+len(d.x)-int(d.nx)] // already zero ++ b = appendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29) ++ return b, nil +} + -+// Init loads and initializes OpenSSL from the shared library at path. -+// It must be called before any other OpenSSL call, except CheckVersion. -+// -+// Only the first call to Init is effective. -+// Subsequent calls will return the same error result as the one from the first call. -+// -+// The file is passed to dlopen() verbatim to load the OpenSSL shared library. -+// For example, `file=libcrypto.so.1.1.1k-fips` makes Init look for the shared -+// library libcrypto.so.1.1.1k-fips. -+func Init(file string) error { -+ initOnce.Do(func() { -+ buf := [2]byte{} -+ *(*uint16)(unsafe.Pointer(&buf[0])) = uint16(0xABCD) ++func (h *sha256Hash) MarshalBinary() ([]byte, error) { ++ d := (*sha256State)(h.hashState()) ++ if d == nil { ++ return nil, errors.New("crypto/sha256: can't retrieve hash state") ++ } ++ b := make([]byte, 0, marshaledSize256) ++ b = append(b, magic256...) ++ b = appendUint32(b, d.h[0]) ++ b = appendUint32(b, d.h[1]) ++ b = appendUint32(b, d.h[2]) ++ b = appendUint32(b, d.h[3]) ++ b = appendUint32(b, d.h[4]) ++ b = appendUint32(b, d.h[5]) ++ b = appendUint32(b, d.h[6]) ++ b = appendUint32(b, d.h[7]) ++ b = append(b, d.x[:d.nx]...) ++ b = b[:len(b)+len(d.x)-int(d.nx)] // already zero ++ b = appendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29) ++ return b, nil ++} + -+ switch buf { -+ case [2]byte{0xCD, 0xAB}: -+ nativeEndian = binary.LittleEndian -+ case [2]byte{0xAB, 0xCD}: -+ nativeEndian = binary.BigEndian -+ default: -+ panic("Could not determine native endianness.") -+ } -+ vMajor, vMinor, vPatch, initErr = opensslInit(file) -+ }) -+ return initErr ++func (h *sha224Hash) UnmarshalBinary(b []byte) error { ++ if len(b) < len(magic224) || string(b[:len(magic224)]) != magic224 { ++ return errors.New("crypto/sha256: invalid hash state identifier") ++ } ++ if len(b) != marshaledSize256 { ++ return errors.New("crypto/sha256: invalid hash state size") ++ } ++ d := (*sha256State)(h.hashState()) ++ if d == nil { ++ return errors.New("crypto/sha256: can't retrieve hash state") ++ } ++ b = b[len(magic224):] ++ b, d.h[0] = consumeUint32(b) ++ b, d.h[1] = consumeUint32(b) ++ b, d.h[2] = consumeUint32(b) ++ b, d.h[3] = consumeUint32(b) ++ b, d.h[4] = consumeUint32(b) ++ b, d.h[5] = consumeUint32(b) ++ b, d.h[6] = consumeUint32(b) ++ b, d.h[7] = consumeUint32(b) ++ b = b[copy(d.x[:], b):] ++ _, n := consumeUint64(b) ++ d.nl = uint32(n << 3) ++ d.nh = uint32(n >> 29) ++ d.nx = uint32(n) % 64 ++ return nil +} + -+func errUnsupportedVersion() error { -+ return errors.New("openssl: OpenSSL version: " + strconv.Itoa(vMajor) + "." + strconv.Itoa(vMinor) + "." + strconv.Itoa(vPatch)) ++func (h *sha256Hash) UnmarshalBinary(b []byte) error { ++ if len(b) < len(magic256) || string(b[:len(magic256)]) != magic256 { ++ return errors.New("crypto/sha256: invalid hash state identifier") ++ } ++ if len(b) != marshaledSize256 { ++ return errors.New("crypto/sha256: invalid hash state size") ++ } ++ d := (*sha256State)(h.hashState()) ++ if d == nil { ++ return errors.New("crypto/sha256: can't retrieve hash state") ++ } ++ b = b[len(magic256):] ++ b, d.h[0] = consumeUint32(b) ++ b, d.h[1] = consumeUint32(b) ++ b, d.h[2] = consumeUint32(b) ++ b, d.h[3] = consumeUint32(b) ++ b, d.h[4] = consumeUint32(b) ++ b, d.h[5] = consumeUint32(b) ++ b, d.h[6] = consumeUint32(b) ++ b, d.h[7] = consumeUint32(b) ++ b = b[copy(d.x[:], b):] ++ _, n := consumeUint64(b) ++ d.nl = uint32(n << 3) ++ d.nh = uint32(n >> 29) ++ d.nx = uint32(n) % 64 ++ return nil +} + -+type fail string -+ -+func (e fail) Error() string { return "openssl: " + string(e) + " failed" } -+ -+// VersionText returns the version text of the OpenSSL currently loaded. -+func VersionText() string { -+ return C.GoString(C.go_openssl_OpenSSL_version(0)) ++// NewSHA384 returns a new SHA384 hash. ++func NewSHA384() hash.Hash { ++ return &sha384Hash{ ++ evpHash: newEvpHash(crypto.SHA384, 384/8, 128), ++ } +} + -+var ( -+ providerNameFips = C.CString("fips") -+ providerNameDefault = C.CString("default") -+) ++type sha384Hash struct { ++ *evpHash ++ out [384 / 8]byte ++} + -+// FIPS returns true if OpenSSL is running in FIPS mode, else returns false. -+func FIPS() bool { -+ switch vMajor { -+ case 1: -+ return C.go_openssl_FIPS_mode() == 1 -+ case 3: -+ // If FIPS is not enabled via default properties, then we are sure FIPS is not used. -+ if C.go_openssl_EVP_default_properties_is_fips_enabled(nil) == 0 { -+ return false -+ } -+ // EVP_default_properties_is_fips_enabled can return true even if the FIPS provider isn't loaded, -+ // it is only based on the default properties. -+ // We can be sure that the FIPS provider is available if we can fetch an algorithm, e.g., SHA2-256, -+ // explicitly setting `fips=yes`. -+ return C.go_openssl_OSSL_PROVIDER_available(nil, providerNameFips) == 1 -+ default: -+ panic(errUnsupportedVersion()) -+ } ++func (h *sha384Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) +} + -+// SetFIPS enables or disables FIPS mode. -+// -+// For OpenSSL 3, the `fips` provider is loaded if enabled is true, -+// else the `default` provider is loaded. -+func SetFIPS(enabled bool) error { -+ var mode C.int -+ if enabled { -+ mode = C.int(1) -+ } else { -+ mode = C.int(0) -+ } -+ switch vMajor { -+ case 1: -+ if C.go_openssl_FIPS_mode_set(mode) != 1 { -+ return newOpenSSLError("FIPS_mode_set") -+ } -+ return nil -+ case 3: -+ var provName *C.char -+ if enabled { -+ provName = providerNameFips -+ } else { -+ provName = providerNameDefault -+ } -+ // Check if there is any provider that matches props. -+ if C.go_openssl_OSSL_PROVIDER_available(nil, provName) != 1 { -+ // If not, fallback to provName provider. -+ if C.go_openssl_OSSL_PROVIDER_load(nil, provName) == nil { -+ return newOpenSSLError("OSSL_PROVIDER_try_load") -+ } -+ // Make sure we now have a provider available. -+ if C.go_openssl_OSSL_PROVIDER_available(nil, provName) != 1 { -+ return fail("SetFIPS(" + strconv.FormatBool(enabled) + ") not supported") -+ } -+ } -+ if C.go_openssl_EVP_default_properties_enable_fips(nil, mode) != 1 { -+ return newOpenSSLError("openssl: EVP_default_properties_enable_fips") -+ } -+ return nil -+ default: -+ panic(errUnsupportedVersion()) ++// NewSHA512 returns a new SHA512 hash. ++func NewSHA512() hash.Hash { ++ return &sha512Hash{ ++ evpHash: newEvpHash(crypto.SHA512, 512/8, 128), + } +} + -+// noescape hides a pointer from escape analysis. noescape is -+// the identity function but escape analysis doesn't think the -+// output depends on the input. noescape is inlined and currently -+// compiles down to zero instructions. -+// USE CAREFULLY! -+// -+//go:nosplit -+func noescape(p unsafe.Pointer) unsafe.Pointer { -+ x := uintptr(p) -+ return unsafe.Pointer(x ^ 0) ++type sha512Hash struct { ++ *evpHash ++ out [512 / 8]byte +} + -+var zero byte ++func (h *sha512Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) ++} + -+// addr converts p to its base addr, including a noescape along the way. -+// If p is nil, addr returns a non-nil pointer, so that the result can always -+// be dereferenced. -+// -+//go:nosplit -+func addr(p []byte) *byte { -+ if len(p) == 0 { -+ return &zero -+ } -+ return (*byte)(noescape(unsafe.Pointer(&p[0]))) ++// sha512State layout is taken from ++// https://github.com/openssl/openssl/blob/0418e993c717a6863f206feaa40673a261de7395/include/openssl/sha.h#L95. ++type sha512State struct { ++ h [8]uint64 ++ nl, nh uint64 ++ x [128]byte ++ nx uint32 +} + -+// base returns the address of the underlying array in b, -+// being careful not to panic when b has zero length. -+func base(b []byte) *C.uchar { -+ if len(b) == 0 { -+ return nil ++const ( ++ magic384 = "sha\x04" ++ magic512_224 = "sha\x05" ++ magic512_256 = "sha\x06" ++ magic512 = "sha\x07" ++ marshaledSize512 = len(magic512) + 8*8 + 128 + 8 ++) ++ ++func (h *sha384Hash) MarshalBinary() ([]byte, error) { ++ d := (*sha512State)(h.hashState()) ++ if d == nil { ++ return nil, errors.New("crypto/sha512: can't retrieve hash state") + } -+ return (*C.uchar)(unsafe.Pointer(&b[0])) ++ b := make([]byte, 0, marshaledSize512) ++ b = append(b, magic384...) ++ b = appendUint64(b, d.h[0]) ++ b = appendUint64(b, d.h[1]) ++ b = appendUint64(b, d.h[2]) ++ b = appendUint64(b, d.h[3]) ++ b = appendUint64(b, d.h[4]) ++ b = appendUint64(b, d.h[5]) ++ b = appendUint64(b, d.h[6]) ++ b = appendUint64(b, d.h[7]) ++ b = append(b, d.x[:d.nx]...) ++ b = b[:len(b)+len(d.x)-int(d.nx)] // already zero ++ b = appendUint64(b, d.nl>>3|d.nh<<61) ++ return b, nil +} + -+func sbase(b []byte) *C.char { -+ if len(b) == 0 { -+ return nil ++func (h *sha512Hash) MarshalBinary() ([]byte, error) { ++ d := (*sha512State)(h.hashState()) ++ if d == nil { ++ return nil, errors.New("crypto/sha512: can't retrieve hash state") + } -+ return (*C.char)(unsafe.Pointer(&b[0])) ++ b := make([]byte, 0, marshaledSize512) ++ b = append(b, magic512...) ++ b = appendUint64(b, d.h[0]) ++ b = appendUint64(b, d.h[1]) ++ b = appendUint64(b, d.h[2]) ++ b = appendUint64(b, d.h[3]) ++ b = appendUint64(b, d.h[4]) ++ b = appendUint64(b, d.h[5]) ++ b = appendUint64(b, d.h[6]) ++ b = appendUint64(b, d.h[7]) ++ b = append(b, d.x[:d.nx]...) ++ b = b[:len(b)+len(d.x)-int(d.nx)] // already zero ++ b = appendUint64(b, d.nl>>3|d.nh<<61) ++ return b, nil +} + -+func newOpenSSLError(msg string) error { -+ var b strings.Builder -+ b.WriteString(msg) -+ b.WriteString("\nopenssl error(s):") -+ for { -+ var ( -+ e C.ulong -+ file *C.char -+ line C.int -+ ) -+ switch vMajor { -+ case 1: -+ e = C.go_openssl_ERR_get_error_line(&file, &line) -+ case 3: -+ e = C.go_openssl_ERR_get_error_all(&file, &line, nil, nil, nil) -+ default: -+ panic(errUnsupportedVersion()) -+ } -+ if e == 0 { -+ break -+ } -+ b.WriteByte('\n') -+ var buf [256]byte -+ C.go_openssl_ERR_error_string_n(e, (*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf))) -+ b.WriteString(string(buf[:]) + "\n\t" + C.GoString(file) + ":" + strconv.Itoa(int(line))) ++func (h *sha384Hash) UnmarshalBinary(b []byte) error { ++ if len(b) < len(magic512) { ++ return errors.New("crypto/sha512: invalid hash state identifier") + } -+ return errors.New(b.String()) -+} -+ -+var unknownFile = "\000" -+ -+// caller reports file and line number information about function invocations on -+// the calling goroutine's stack, in a form suitable for passing to C code. -+// The argument skip is the number of stack frames to ascend, with 0 identifying -+// the caller of caller. The return values report the file name and line number -+// within the file of the corresponding call. The returned file is a C string -+// with static storage duration. -+func caller(skip int) (file *C.char, line C.int) { -+ _, f, l, ok := runtime.Caller(skip + 1) -+ if !ok { -+ f = unknownFile ++ if string(b[:len(magic384)]) != magic384 { ++ return errors.New("crypto/sha512: invalid hash state identifier") + } -+ // The underlying bytes of the file string are null-terminated rodata with -+ // static lifetimes, so can be safely passed to C without worrying about -+ // leaking memory or use-after-free. -+ return (*C.char)(noescape(unsafe.Pointer(unsafe.StringData(f)))), C.int(l) -+} -+ -+// cryptoMalloc allocates n bytes of memory on the OpenSSL heap, which may be -+// different from the heap which C.malloc allocates on. The allocated object -+// must be freed using cryptoFree. cryptoMalloc is equivalent to the -+// OPENSSL_malloc macro. -+// -+// Like C.malloc, this function is guaranteed to never return nil. If OpenSSL's -+// malloc indicates out of memory, it crashes the program. -+// -+// Only objects which the OpenSSL library will take ownership of (i.e. will be -+// freed by OPENSSL_free / CRYPTO_free) need to be allocated on the OpenSSL -+// heap. -+func cryptoMalloc(n int) unsafe.Pointer { -+ file, line := caller(1) -+ var p unsafe.Pointer -+ if vMajor == 1 && vMinor == 0 { -+ p = C.go_openssl_CRYPTO_malloc_legacy102(C.int(n), file, line) -+ } else { -+ p = C.go_openssl_CRYPTO_malloc(C.size_t(n), file, line) ++ if len(b) != marshaledSize512 { ++ return errors.New("crypto/sha512: invalid hash state size") + } -+ if p == nil { -+ // Un-recover()-ably crash the program in the same manner as the -+ // C.malloc() wrapper function. -+ runtime_throw("openssl: CRYPTO_malloc failed") ++ d := (*sha512State)(h.hashState()) ++ if d == nil { ++ return errors.New("crypto/sha512: can't retrieve hash state") + } -+ return p ++ b = b[len(magic512):] ++ b, d.h[0] = consumeUint64(b) ++ b, d.h[1] = consumeUint64(b) ++ b, d.h[2] = consumeUint64(b) ++ b, d.h[3] = consumeUint64(b) ++ b, d.h[4] = consumeUint64(b) ++ b, d.h[5] = consumeUint64(b) ++ b, d.h[6] = consumeUint64(b) ++ b, d.h[7] = consumeUint64(b) ++ b = b[copy(d.x[:], b):] ++ _, n := consumeUint64(b) ++ d.nl = n << 3 ++ d.nh = n >> 61 ++ d.nx = uint32(n) % 128 ++ return nil +} + -+// cryptoFree frees an object allocated on the OpenSSL heap, which may be -+// different from the heap which C.malloc allocates on. cryptoFree is equivalent -+// to the OPENSSL_free macro. -+func cryptoFree(p unsafe.Pointer) { -+ if vMajor == 1 && vMinor == 0 { -+ C.go_openssl_CRYPTO_free_legacy102(p) -+ return ++func (h *sha512Hash) UnmarshalBinary(b []byte) error { ++ if len(b) < len(magic512) { ++ return errors.New("crypto/sha512: invalid hash state identifier") + } -+ file, line := caller(1) -+ C.go_openssl_CRYPTO_free(p, file, line) -+} -+ -+const wordBytes = bits.UintSize / 8 -+ -+// Reverse each limb of z. -+func (z BigInt) byteSwap() { -+ for i, d := range z { -+ var n uint = 0 -+ for j := 0; j < wordBytes; j++ { -+ n |= uint(byte(d)) << (8 * (wordBytes - j - 1)) -+ d >>= 8 -+ } -+ z[i] = n ++ if string(b[:len(magic512)]) != magic512 { ++ return errors.New("crypto/sha512: invalid hash state identifier") ++ } ++ if len(b) != marshaledSize512 { ++ return errors.New("crypto/sha512: invalid hash state size") + } ++ d := (*sha512State)(h.hashState()) ++ if d == nil { ++ return errors.New("crypto/sha512: can't retrieve hash state") ++ } ++ b = b[len(magic512):] ++ b, d.h[0] = consumeUint64(b) ++ b, d.h[1] = consumeUint64(b) ++ b, d.h[2] = consumeUint64(b) ++ b, d.h[3] = consumeUint64(b) ++ b, d.h[4] = consumeUint64(b) ++ b, d.h[5] = consumeUint64(b) ++ b, d.h[6] = consumeUint64(b) ++ b, d.h[7] = consumeUint64(b) ++ b = b[copy(d.x[:], b):] ++ _, n := consumeUint64(b) ++ d.nl = n << 3 ++ d.nh = n >> 61 ++ d.nx = uint32(n) % 128 ++ return nil +} + -+func wbase(b BigInt) *C.uchar { -+ if len(b) == 0 { -+ return nil ++// NewSHA3_224 returns a new SHA3-224 hash. ++func NewSHA3_224() hash.Hash { ++ return &sha3_224Hash{ ++ evpHash: newEvpHash(crypto.SHA3_224, 224/8, 64), + } -+ return (*C.uchar)(unsafe.Pointer(&b[0])) +} + -+// bignum_st_1_0_2 is bignum_st (BIGNUM) memory layout in OpenSSL 1.0.2. -+type bignum_st_1_0_2 struct { -+ d unsafe.Pointer // Pointer to an array of BN_ULONG bit chunks -+ top C.int // Index of last used d +1 -+ dmax C.int -+ neg C.int -+ flags C.int ++type sha3_224Hash struct { ++ *evpHash ++ out [224 / 8]byte +} + -+func bigToBN(x BigInt) C.GO_BIGNUM_PTR { -+ if len(x) == 0 { -+ return nil -+ } ++func (h *sha3_224Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) ++} + -+ if vMajor == 1 && vMinor == 0 { -+ // OpenSSL 1.0.x does not export bn_lebin2bn on all platforms, -+ // so we have to emulate it. -+ bn := C.go_openssl_BN_new() -+ if bn == nil { -+ return nil -+ } -+ if C.go_openssl_bn_expand2(bn, C.int(len(x))) == nil { -+ C.go_openssl_BN_free(bn) -+ panic(newOpenSSLError("BN_expand2")) -+ } -+ // The bytes of a BigInt are laid out in memory in the same order as a -+ // BIGNUM, regardless of host endianness. -+ bns := (*bignum_st_1_0_2)(unsafe.Pointer(bn)) -+ d := unsafe.Slice((*uint)(bns.d), len(x)) -+ bns.top = C.int(copy(d, x)) -+ return bn ++// NewSHA3_256 returns a new SHA3-256 hash. ++func NewSHA3_256() hash.Hash { ++ return &sha3_256Hash{ ++ evpHash: newEvpHash(crypto.SHA3_256, 256/8, 64), + } ++} + -+ if nativeEndian == binary.BigEndian { -+ z := make(BigInt, len(x)) -+ copy(z, x) -+ z.byteSwap() -+ x = z -+ } -+ // Limbs are always ordered in LSB first, so we can safely apply -+ // BN_lebin2bn regardless of host endianness. -+ return C.go_openssl_BN_lebin2bn(wbase(x), C.int(len(x)*wordBytes), nil) ++type sha3_256Hash struct { ++ *evpHash ++ out [256 / 8]byte +} + -+func bnToBig(bn C.GO_BIGNUM_PTR) BigInt { -+ if bn == nil { -+ return nil -+ } ++func (h *sha3_256Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) ++} + -+ if vMajor == 1 && vMinor == 0 { -+ // OpenSSL 1.0.x does not export bn_bn2lebinpad on all platforms, -+ // so we have to emulate it. -+ bns := (*bignum_st_1_0_2)(unsafe.Pointer(bn)) -+ d := unsafe.Slice((*uint)(bns.d), bns.top) -+ x := make(BigInt, len(d)) -+ copy(x, d) -+ return x ++// NewSHA3_384 returns a new SHA3-384 hash. ++func NewSHA3_384() hash.Hash { ++ return &sha3_384Hash{ ++ evpHash: newEvpHash(crypto.SHA3_384, 384/8, 128), + } ++} + -+ // Limbs are always ordered in LSB first, so we can safely apply -+ // BN_bn2lebinpad regardless of host endianness. -+ x := make(BigInt, C.go_openssl_BN_num_bits(bn)) -+ if C.go_openssl_BN_bn2lebinpad(bn, wbase(x), C.int(len(x)*wordBytes)) == 0 { -+ panic("openssl: bignum conversion failed") -+ } -+ if nativeEndian == binary.BigEndian { -+ x.byteSwap() -+ } -+ return x ++type sha3_384Hash struct { ++ *evpHash ++ out [384 / 8]byte +} + -+func bnNumBytes(bn C.GO_BIGNUM_PTR) int { -+ return (int(C.go_openssl_BN_num_bits(bn)) + 7) / 8 ++func (h *sha3_384Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) +} + -+// bnToBinPad converts the absolute value of bn into big-endian form and stores -+// it at to, padding with zeroes if necessary. If len(to) is not large enough to -+// hold the result, an error is returned. -+func bnToBinPad(bn C.GO_BIGNUM_PTR, to []byte) error { -+ if vMajor == 1 && vMinor == 0 { -+ // OpenSSL 1.0.x does not export bn_bn2binpad on all platforms, -+ // so we have to emulate it. -+ n := bnNumBytes(bn) -+ pad := len(to) - n -+ if pad < 0 { -+ return errors.New("openssl: destination buffer too small") -+ } -+ for i := 0; i < pad; i++ { -+ to[i] = 0 -+ } -+ if int(C.go_openssl_BN_bn2bin(bn, base(to[pad:]))) != n { -+ return errors.New("openssl: BN_bn2bin short write") -+ } -+ return nil ++// NewSHA3_512 returns a new SHA3-512 hash. ++func NewSHA3_512() hash.Hash { ++ return &sha3_512Hash{ ++ evpHash: newEvpHash(crypto.SHA3_512, 512/8, 128), + } ++} + -+ if C.go_openssl_BN_bn2binpad(bn, base(to), C.int(len(to))) < 0 { -+ return newOpenSSLError("BN_bn2binpad") -+ } -+ return nil ++type sha3_512Hash struct { ++ *evpHash ++ out [512 / 8]byte +} + -+func CheckLeaks() { -+ C.go_openssl_do_leak_check() ++func (h *sha3_512Hash) Sum(in []byte) []byte { ++ h.sum(h.out[:]) ++ return append(in, h.out[:]...) +} -diff --git a/src/vendor/github.com/golang-fips/openssl/v2/pbkdf2.go b/src/vendor/github.com/golang-fips/openssl/v2/pbkdf2.go -new file mode 100644 -index 0000000000..a895eab2d5 ++ ++// appendUint64 appends x into b as a big endian byte sequence. ++func appendUint64(b []byte, x uint64) []byte { ++ return append(b, ++ byte(x>>56), ++ byte(x>>48), ++ byte(x>>40), ++ byte(x>>32), ++ byte(x>>24), ++ byte(x>>16), ++ byte(x>>8), ++ byte(x), ++ ) ++} ++ ++// appendUint32 appends x into b as a big endian byte sequence. ++func appendUint32(b []byte, x uint32) []byte { ++ return append(b, byte(x>>24), byte(x>>16), byte(x>>8), byte(x)) ++} ++ ++// consumeUint64 reads a big endian uint64 number from b. ++func consumeUint64(b []byte) ([]byte, uint64) { ++ _ = b[7] ++ x := uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 | ++ uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56 ++ return b[8:], x ++} ++ ++// consumeUint32 reads a big endian uint32 number from b. ++func consumeUint32(b []byte) ([]byte, uint32) { ++ _ = b[3] ++ x := uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24 ++ return b[4:], x ++} +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/hkdf.go b/src/vendor/github.com/golang-fips/openssl/v2/hkdf.go +new file mode 100644 +index 0000000000..ac3fbba0c2 --- /dev/null -+++ b/src/vendor/github.com/golang-fips/openssl/v2/pbkdf2.go -@@ -0,0 +1,28 @@ ++++ b/src/vendor/github.com/golang-fips/openssl/v2/hkdf.go +@@ -0,0 +1,174 @@ +//go:build !cmd_go_bootstrap + +package openssl @@ -6969,189 +7239,177 @@ index 0000000000..a895eab2d5 +import ( + "errors" + "hash" ++ "io" ++ "runtime" ++ "unsafe" +) + -+func PBKDF2(password, salt []byte, iter, keyLen int, h func() hash.Hash) ([]byte, error) { -+ md := hashToMD(h()) -+ if md == nil { -+ return nil, errors.New("unsupported hash function") -+ } -+ if len(password) == 0 && vMajor == 1 && vMinor == 0 { -+ // x/crypto/pbkdf2 supports empty passwords, but OpenSSL 1.0.2 -+ // does not. As a workaround, we pass an "empty" password. -+ password = make([]byte, C.GO_EVP_MAX_MD_SIZE) -+ } -+ out := make([]byte, keyLen) -+ ok := C.go_openssl_PKCS5_PBKDF2_HMAC(sbase(password), C.int(len(password)), base(salt), C.int(len(salt)), C.int(iter), md, C.int(keyLen), base(out)) -+ if ok != 1 { -+ return nil, newOpenSSLError("PKCS5_PBKDF2_HMAC") -+ } -+ return out, nil ++func SupportsHKDF() bool { ++ return versionAtOrAbove(1, 1, 1) +} -diff --git a/src/vendor/github.com/golang-fips/openssl/v2/port_evp_md5_sha1.c b/src/vendor/github.com/golang-fips/openssl/v2/port_evp_md5_sha1.c -new file mode 100644 -index 0000000000..50d49b1f10 ---- /dev/null -+++ b/src/vendor/github.com/golang-fips/openssl/v2/port_evp_md5_sha1.c -@@ -0,0 +1,126 @@ -+// The following is a partial backport of crypto/evp/m_md5_sha1.c, -+// commit cbc8a839959418d8a2c2e3ec6bdf394852c9501e on the -+// OpenSSL_1_1_0-stable branch. The ctrl function has been removed. -+ -+/* -+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. -+ * -+ * Licensed under the OpenSSL license (the "License"). You may not use -+ * this file except in compliance with the License. You can obtain a copy -+ * in the file LICENSE in the source distribution or at -+ * https://www.openssl.org/source/license.html -+ */ -+ -+#include "goopenssl.h" -+ -+#define NID_md5_sha1 114 -+ -+#define MD5_CBLOCK 64 -+#define MD5_LBLOCK (MD5_CBLOCK/4) -+#define MD5_DIGEST_LENGTH 16 -+#define SHA_LBLOCK 16 -+#define SHA_DIGEST_LENGTH 20 -+ -+#define EVP_PKEY_NULL_method NULL,NULL,{0,0,0,0} -+ -+// Change: MD5_LONG and SHA_LONG have been expanded to unsigned int, -+// which is always 32 bits. This avoids adding some obscure logic -+// to support 16-bit platforms. -+ -+# define MD5_LONG unsigned int -+# define SHA_LONG unsigned int + -+typedef struct env_md_st EVP_MD; -+typedef struct env_md_ctx_st EVP_MD_CTX; -+ -+struct env_md_ctx_st { -+ void *digest; -+ void *engine; -+ unsigned long flags; -+ void *md_data; -+ void *pctx; -+ void *update; -+} /* EVP_MD_CTX */ ; -+ -+struct env_md_st { -+ int type; -+ int pkey_type; -+ int md_size; -+ unsigned long flags; -+ int (*init) (EVP_MD_CTX *ctx); -+ int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count); -+ int (*final) (EVP_MD_CTX *ctx, unsigned char *md); -+ void *copy; -+ void *cleanup; -+ void *sign; -+ void *verify; -+ int required_pkey_type[5]; -+ int block_size; -+ int ctx_size; -+ void *md_ctrl; -+} /* EVP_MD */ ; ++func newHKDF(h func() hash.Hash, mode C.int) (*hkdf, error) { ++ if !SupportsHKDF() { ++ return nil, errUnsupportedVersion() ++ } + -+typedef struct MD5state_st { -+ MD5_LONG A, B, C, D; -+ MD5_LONG Nl, Nh; -+ MD5_LONG data[MD5_LBLOCK]; -+ MD5_LONG num; -+} MD5_CTX; ++ ch := h() ++ md := hashToMD(ch) ++ if md == nil { ++ return nil, errors.New("unsupported hash function") ++ } + -+typedef struct SHAstate_st { -+ SHA_LONG h0, h1, h2, h3, h4; -+ SHA_LONG Nl, Nh; -+ SHA_LONG data[SHA_LBLOCK]; -+ SHA_LONG num; -+} SHA_CTX; ++ ctx := C.go_openssl_EVP_PKEY_CTX_new_id(C.GO_EVP_PKEY_HKDF, nil) ++ if ctx == nil { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_new_id") ++ } ++ defer func() { ++ C.go_openssl_EVP_PKEY_CTX_free(ctx) ++ }() + -+struct md5_sha1_ctx { -+ MD5_CTX md5; -+ SHA_CTX sha1; -+}; ++ if C.go_openssl_EVP_PKEY_derive_init(ctx) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_derive_init") ++ } ++ switch vMajor { ++ case 3: ++ if C.go_openssl_EVP_PKEY_CTX_set_hkdf_mode(ctx, mode) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_set_hkdf_mode") ++ } ++ if C.go_openssl_EVP_PKEY_CTX_set_hkdf_md(ctx, md) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_set_hkdf_md") ++ } ++ case 1: ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, C.GO1_EVP_PKEY_OP_DERIVE, ++ C.GO_EVP_PKEY_CTRL_HKDF_MODE, ++ C.int(mode), nil) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_set_hkdf_mode") ++ } ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, C.GO1_EVP_PKEY_OP_DERIVE, ++ C.GO_EVP_PKEY_CTRL_HKDF_MD, ++ 0, unsafe.Pointer(md)) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_set_hkdf_md") ++ } ++ } + -+static int md5_sha1_init(EVP_MD_CTX *ctx) { -+ struct md5_sha1_ctx *mctx = ctx->md_data; -+ if (!go_openssl_MD5_Init(&mctx->md5)) -+ return 0; -+ return go_openssl_SHA1_Init(&mctx->sha1); -+} ++ c := &hkdf{ctx: ctx, hashLen: ch.Size()} ++ ctx = nil + -+static int md5_sha1_update(EVP_MD_CTX *ctx, const void *data, -+ size_t count) { -+ struct md5_sha1_ctx *mctx = ctx->md_data; -+ if (!go_openssl_MD5_Update(&mctx->md5, data, count)) -+ return 0; -+ return go_openssl_SHA1_Update(&mctx->sha1, data, count); -+} ++ runtime.SetFinalizer(c, (*hkdf).finalize) + -+static int md5_sha1_final(EVP_MD_CTX *ctx, unsigned char *md) { -+ struct md5_sha1_ctx *mctx = ctx->md_data; -+ if (!go_openssl_MD5_Final(md, &mctx->md5)) -+ return 0; -+ return go_openssl_SHA1_Final(md + MD5_DIGEST_LENGTH, &mctx->sha1); ++ return c, nil +} + -+// Change: Removed: -+// static int ctrl(EVP_MD_CTX *ctx, int cmd, int mslen, void *ms) -+ -+static const EVP_MD md5_sha1_md = { -+ NID_md5_sha1, -+ NID_md5_sha1, -+ MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, -+ 0, -+ md5_sha1_init, -+ md5_sha1_update, -+ md5_sha1_final, -+ NULL, -+ NULL, -+ EVP_PKEY_NULL_method, // Change: inserted -+ MD5_CBLOCK, -+ sizeof(EVP_MD *) + sizeof(struct md5_sha1_ctx), -+ NULL, // Change: was ctrl -+}; ++type hkdf struct { ++ ctx C.GO_EVP_PKEY_CTX_PTR + -+// Change: Apply name mangling. -+const GO_EVP_MD_PTR go_openssl_EVP_md5_sha1_backport(void) { -+ return (const GO_EVP_MD_PTR)&md5_sha1_md; ++ hashLen int ++ buf []byte +} -diff --git a/src/vendor/github.com/golang-fips/openssl/v2/rand.go b/src/vendor/github.com/golang-fips/openssl/v2/rand.go -new file mode 100644 -index 0000000000..9fd709635c ---- /dev/null -+++ b/src/vendor/github.com/golang-fips/openssl/v2/rand.go -@@ -0,0 +1,20 @@ -+//go:build !cmd_go_bootstrap -+ -+package openssl -+ -+// #include "goopenssl.h" -+import "C" -+import "unsafe" + -+type randReader int -+ -+func (randReader) Read(b []byte) (int, error) { -+ // Note: RAND_bytes should never fail; the return value exists only for historical reasons. -+ // We check it even so. -+ if len(b) > 0 && C.go_openssl_RAND_bytes((*C.uchar)(unsafe.Pointer(&b[0])), C.int(len(b))) == 0 { -+ return 0, newOpenSSLError("RAND_bytes") ++func (c *hkdf) finalize() { ++ if c.ctx != nil { ++ C.go_openssl_EVP_PKEY_CTX_free(c.ctx) + } -+ return len(b), nil +} + -+const RandReader = randReader(0) -diff --git a/src/vendor/github.com/golang-fips/openssl/v2/rsa.go b/src/vendor/github.com/golang-fips/openssl/v2/rsa.go -new file mode 100644 -index 0000000000..5aef65b84f ---- /dev/null -+++ b/src/vendor/github.com/golang-fips/openssl/v2/rsa.go -@@ -0,0 +1,419 @@ ++func (c *hkdf) Read(p []byte) (int, error) { ++ defer runtime.KeepAlive(c) ++ ++ // EVP_PKEY_derive doesn't support incremental output, each call ++ // derives the key from scratch and returns the requested bytes. ++ // To implement io.Reader, we need to ask for len(c.buf) + len(p) ++ // bytes and copy the last derived len(p) bytes to p. ++ // We use c.buf to know how many bytes we've already derived and ++ // to avoid allocating the whole output buffer on each call. ++ prevLen := len(c.buf) ++ needLen := len(p) ++ remains := 255*c.hashLen - prevLen ++ // Check whether enough data can be generated. ++ if remains < needLen { ++ return 0, errors.New("hkdf: entropy limit reached") ++ } ++ c.buf = append(c.buf, make([]byte, needLen)...) ++ outLen := C.size_t(prevLen + needLen) ++ if C.go_openssl_EVP_PKEY_derive(c.ctx, base(c.buf), &outLen) != 1 { ++ return 0, newOpenSSLError("EVP_PKEY_derive") ++ } ++ n := copy(p, c.buf[prevLen:outLen]) ++ return n, nil ++} ++ ++func ExtractHKDF(h func() hash.Hash, secret, salt []byte) ([]byte, error) { ++ c, err := newHKDF(h, C.GO_EVP_KDF_HKDF_MODE_EXTRACT_ONLY) ++ if err != nil { ++ return nil, err ++ } ++ switch vMajor { ++ case 3: ++ if C.go_openssl_EVP_PKEY_CTX_set1_hkdf_key(c.ctx, ++ base(secret), C.int(len(secret))) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_set1_hkdf_key") ++ } ++ if C.go_openssl_EVP_PKEY_CTX_set1_hkdf_salt(c.ctx, ++ base(salt), C.int(len(salt))) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_set1_hkdf_salt") ++ } ++ case 1: ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(c.ctx, -1, C.GO1_EVP_PKEY_OP_DERIVE, ++ C.GO_EVP_PKEY_CTRL_HKDF_KEY, ++ C.int(len(secret)), unsafe.Pointer(base(secret))) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_set1_hkdf_key") ++ } ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(c.ctx, -1, C.GO1_EVP_PKEY_OP_DERIVE, ++ C.GO_EVP_PKEY_CTRL_HKDF_SALT, ++ C.int(len(salt)), unsafe.Pointer(base(salt))) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_set1_hkdf_salt") ++ } ++ } ++ var outLen C.size_t ++ if C.go_openssl_EVP_PKEY_derive(c.ctx, nil, &outLen) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_derive_init") ++ } ++ out := make([]byte, outLen) ++ if C.go_openssl_EVP_PKEY_derive(c.ctx, base(out), &outLen) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_derive") ++ } ++ return out[:outLen], nil ++} ++ ++func ExpandHKDF(h func() hash.Hash, pseudorandomKey, info []byte) (io.Reader, error) { ++ c, err := newHKDF(h, C.GO_EVP_KDF_HKDF_MODE_EXPAND_ONLY) ++ if err != nil { ++ return nil, err ++ } ++ switch vMajor { ++ case 3: ++ if C.go_openssl_EVP_PKEY_CTX_set1_hkdf_key(c.ctx, ++ base(pseudorandomKey), C.int(len(pseudorandomKey))) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_set1_hkdf_key") ++ } ++ if C.go_openssl_EVP_PKEY_CTX_add1_hkdf_info(c.ctx, ++ base(info), C.int(len(info))) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_add1_hkdf_info") ++ } ++ case 1: ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(c.ctx, -1, C.GO1_EVP_PKEY_OP_DERIVE, ++ C.GO_EVP_PKEY_CTRL_HKDF_KEY, ++ C.int(len(pseudorandomKey)), unsafe.Pointer(base(pseudorandomKey))) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_set1_hkdf_key") ++ } ++ if C.go_openssl_EVP_PKEY_CTX_ctrl(c.ctx, -1, C.GO1_EVP_PKEY_OP_DERIVE, ++ C.GO_EVP_PKEY_CTRL_HKDF_INFO, ++ C.int(len(info)), unsafe.Pointer(base(info))) != 1 { ++ return nil, newOpenSSLError("EVP_PKEY_CTX_add1_hkdf_info") ++ } ++ } ++ return c, nil ++} +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/hmac.go b/src/vendor/github.com/golang-fips/openssl/v2/hmac.go +new file mode 100644 +index 0000000000..ef8116ce66 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/hmac.go +@@ -0,0 +1,238 @@ +//go:build !cmd_go_bootstrap + +package openssl @@ -7159,1126 +7417,1506 @@ index 0000000000..5aef65b84f +// #include "goopenssl.h" +import "C" +import ( -+ "crypto" -+ "crypto/subtle" -+ "errors" + "hash" + "runtime" ++ "sync" + "unsafe" +) + ++var paramDigest = C.CString("digest") ++ +var ( -+ paramRSA_N = C.CString("n") -+ paramRSA_E = C.CString("e") -+ paramRSA_D = C.CString("d") -+ paramRSA_P = C.CString("rsa-factor1") -+ paramRSA_Q = C.CString("rsa-factor2") -+ paramRSA_Dp = C.CString("rsa-exponent1") -+ paramRSA_Dq = C.CString("rsa-exponent2") -+ paramRSA_Qinv = C.CString("rsa-coefficient1") ++ fetchHMACOnce sync.Once ++ evpHMAC C.GO_EVP_MAC_PTR +) + -+func GenerateKeyRSA(bits int) (N, E, D, P, Q, Dp, Dq, Qinv BigInt, err error) { -+ bad := func(e error) (N, E, D, P, Q, Dp, Dq, Qinv BigInt, err error) { -+ return nil, nil, nil, nil, nil, nil, nil, nil, e -+ } -+ pkey, err := generateEVPPKey(C.GO_EVP_PKEY_RSA, bits, "") -+ if err != nil { -+ return bad(err) -+ } -+ defer C.go_openssl_EVP_PKEY_free(pkey) -+ switch vMajor { -+ case 1: -+ key := C.go_openssl_EVP_PKEY_get1_RSA(pkey) -+ if key == nil { -+ return bad(newOpenSSLError("EVP_PKEY_get1_RSA failed")) -+ } -+ defer C.go_openssl_RSA_free(key) -+ var n, e, d, p, q, dmp1, dmq1, iqmp C.GO_BIGNUM_PTR -+ if vMinor == 0 { -+ r := (*rsa_st_1_0_2)(unsafe.Pointer(key)) -+ n, e, d, p, q, dmp1, dmq1, iqmp = r.n, r.e, r.d, r.p, r.q, r.dmp1, r.dmq1, r.iqmp -+ } else { -+ C.go_openssl_RSA_get0_key(key, &n, &e, &d) -+ C.go_openssl_RSA_get0_factors(key, &p, &q) -+ C.go_openssl_RSA_get0_crt_params(key, &dmp1, &dmq1, &iqmp) -+ } -+ N, E, D = bnToBig(n), bnToBig(e), bnToBig(d) -+ P, Q = bnToBig(p), bnToBig(q) -+ Dp, Dq, Qinv = bnToBig(dmp1), bnToBig(dmq1), bnToBig(iqmp) -+ case 3: -+ tmp := C.go_openssl_BN_new() -+ if tmp == nil { -+ return bad(newOpenSSLError("BN_new failed")) -+ } -+ defer func() { -+ C.go_openssl_BN_clear_free(tmp) -+ }() -+ var err error -+ setBigInt := func(bi *BigInt, param *C.char) bool { -+ if err != nil { -+ return false -+ } -+ if C.go_openssl_EVP_PKEY_get_bn_param(pkey, param, &tmp) != 1 { -+ err = newOpenSSLError("EVP_PKEY_get_bn_param failed") -+ return false -+ } -+ *bi = bnToBig(tmp) -+ C.go_openssl_BN_clear(tmp) -+ return true -+ } -+ if !(setBigInt(&N, paramRSA_N) && -+ setBigInt(&E, paramRSA_E) && -+ setBigInt(&D, paramRSA_D) && -+ setBigInt(&P, paramRSA_P) && -+ setBigInt(&Q, paramRSA_Q) && -+ setBigInt(&Dp, paramRSA_Dp) && -+ setBigInt(&Dq, paramRSA_Dq) && -+ setBigInt(&Qinv, paramRSA_Qinv)) { -+ return bad(err) -+ } -+ default: -+ panic(errUnsupportedVersion()) ++// NewHMAC returns a new HMAC using OpenSSL. ++// The function h must return a hash implemented by ++// OpenSSL (for example, h could be openssl.NewSHA256). ++// If h is not recognized, NewHMAC returns nil. ++func NewHMAC(h func() hash.Hash, key []byte) hash.Hash { ++ ch := h() ++ md := hashToMD(ch) ++ if md == nil { ++ return nil + } -+ return -+} + -+type PublicKeyRSA struct { -+ // _pkey MUST NOT be accessed directly. Instead, use the withKey method. -+ _pkey C.GO_EVP_PKEY_PTR -+} ++ if len(key) == 0 { ++ // This is supported in OpenSSL/Standard lib and as such ++ // we must support it here. When using HMAC with a null key ++ // HMAC_Init will try and reuse the key from the ctx. This is ++ // not the behavior previously implemented, so as a workaround ++ // we pass an "empty" key. ++ key = make([]byte, C.GO_EVP_MAX_MD_SIZE) ++ } + -+func NewPublicKeyRSA(N, E BigInt) (*PublicKeyRSA, error) { -+ var pkey C.GO_EVP_PKEY_PTR + switch vMajor { + case 1: -+ key := C.go_openssl_RSA_new() -+ if key == nil { -+ return nil, newOpenSSLError("RSA_new failed") -+ } -+ if !rsaSetKey(key, N, E, nil) { -+ return nil, fail("RSA_set0_key") -+ } -+ pkey = C.go_openssl_EVP_PKEY_new() -+ if pkey == nil { -+ C.go_openssl_RSA_free(key) -+ return nil, newOpenSSLError("EVP_PKEY_new failed") -+ } -+ if C.go_openssl_EVP_PKEY_assign(pkey, C.GO_EVP_PKEY_RSA, (unsafe.Pointer)(key)) != 1 { -+ C.go_openssl_RSA_free(key) -+ C.go_openssl_EVP_PKEY_free(pkey) -+ return nil, newOpenSSLError("EVP_PKEY_assign failed") -+ } ++ return newHMAC1(key, ch, md) + case 3: -+ var err error -+ if pkey, err = newRSAKey3(false, N, E, nil, nil, nil, nil, nil, nil); err != nil { -+ return nil, err -+ } ++ return newHMAC3(key, ch, md) + default: + panic(errUnsupportedVersion()) + } -+ k := &PublicKeyRSA{_pkey: pkey} -+ runtime.SetFinalizer(k, (*PublicKeyRSA).finalize) -+ return k, nil +} + -+func (k *PublicKeyRSA) finalize() { -+ C.go_openssl_EVP_PKEY_free(k._pkey) ++// hmacCtx3 is used for OpenSSL 1. ++type hmacCtx1 struct { ++ ctx C.GO_HMAC_CTX_PTR +} + -+func (k *PublicKeyRSA) withKey(f func(C.GO_EVP_PKEY_PTR) C.int) C.int { -+ // Because of the finalizer, any time _pkey is passed to cgo, that call must -+ // be followed by a call to runtime.KeepAlive, to make sure k is not -+ // collected (and finalized) before the cgo call returns. -+ defer runtime.KeepAlive(k) -+ return f(k._pkey) ++// hmacCtx3 is used for OpenSSL 3. ++type hmacCtx3 struct { ++ ctx C.GO_EVP_MAC_CTX_PTR ++ key []byte // only set for OpenSSL 3.0.0, 3.0.1, and 3.0.2. +} + -+type PrivateKeyRSA struct { -+ // _pkey MUST NOT be accessed directly. Instead, use the withKey method. -+ _pkey C.GO_EVP_PKEY_PTR ++type opensslHMAC struct { ++ ctx1 hmacCtx1 ++ ctx3 hmacCtx3 ++ size int ++ blockSize int ++ sum []byte +} + -+func NewPrivateKeyRSA(N, E, D, P, Q, Dp, Dq, Qinv BigInt) (*PrivateKeyRSA, error) { -+ var pkey C.GO_EVP_PKEY_PTR -+ switch vMajor { -+ case 1: -+ key := C.go_openssl_RSA_new() -+ if key == nil { -+ return nil, newOpenSSLError("RSA_new failed") -+ } -+ if !rsaSetKey(key, N, E, D) { -+ return nil, fail("RSA_set0_key") -+ } -+ if P != nil && Q != nil { -+ if !rsaSetFactors(key, P, Q) { -+ return nil, fail("RSA_set0_factors") -+ } -+ } -+ if Dp != nil && Dq != nil && Qinv != nil { -+ if !rsaSetCRTParams(key, Dp, Dq, Qinv) { -+ return nil, fail("RSA_set0_crt_params") -+ } -+ } -+ pkey = C.go_openssl_EVP_PKEY_new() -+ if pkey == nil { -+ C.go_openssl_RSA_free(key) -+ return nil, newOpenSSLError("EVP_PKEY_new failed") -+ } -+ if C.go_openssl_EVP_PKEY_assign(pkey, C.GO_EVP_PKEY_RSA, (unsafe.Pointer)(key)) != 1 { -+ C.go_openssl_RSA_free(key) -+ C.go_openssl_EVP_PKEY_free(pkey) -+ return nil, newOpenSSLError("EVP_PKEY_assign failed") ++func newHMAC1(key []byte, h hash.Hash, md C.GO_EVP_MD_PTR) *opensslHMAC { ++ ctx := hmacCtxNew() ++ if ctx == nil { ++ panic("openssl: EVP_MAC_CTX_new failed") ++ } ++ if C.go_openssl_HMAC_Init_ex(ctx, unsafe.Pointer(&key[0]), C.int(len(key)), md, nil) == 0 { ++ panic(newOpenSSLError("HMAC_Init_ex failed")) ++ } ++ hmac := &opensslHMAC{ ++ size: h.Size(), ++ blockSize: h.BlockSize(), ++ ctx1: hmacCtx1{ctx}, ++ } ++ runtime.SetFinalizer(hmac, (*opensslHMAC).finalize) ++ return hmac ++} ++ ++func newHMAC3(key []byte, h hash.Hash, md C.GO_EVP_MD_PTR) *opensslHMAC { ++ fetchHMACOnce.Do(func() { ++ name := C.CString("HMAC") ++ evpHMAC = C.go_openssl_EVP_MAC_fetch(nil, name, nil) ++ C.free(unsafe.Pointer(name)) ++ }) ++ if evpHMAC == nil { ++ panic("openssl: HMAC not supported") ++ } ++ ctx := C.go_openssl_EVP_MAC_CTX_new(evpHMAC) ++ if ctx == nil { ++ panic("openssl: EVP_MAC_CTX_new failed") ++ } ++ digest := C.go_openssl_EVP_MD_get0_name(md) ++ bld := C.go_openssl_OSSL_PARAM_BLD_new() ++ if bld == nil { ++ panic(newOpenSSLError("OSSL_PARAM_BLD_new")) ++ } ++ defer C.go_openssl_OSSL_PARAM_BLD_free(bld) ++ C.go_openssl_OSSL_PARAM_BLD_push_utf8_string(bld, paramDigest, digest, 0) ++ params := C.go_openssl_OSSL_PARAM_BLD_to_param(bld) ++ if params == nil { ++ panic(newOpenSSLError("OSSL_PARAM_BLD_to_param")) ++ } ++ defer C.go_openssl_OSSL_PARAM_free(params) ++ if C.go_openssl_EVP_MAC_init(ctx, base(key), C.size_t(len(key)), params) == 0 { ++ panic(newOpenSSLError("EVP_MAC_init failed")) ++ } ++ var hkey []byte ++ if vMinor == 0 && vPatch <= 2 { ++ // EVP_MAC_init only resets the ctx internal state if a key is passed ++ // when using OpenSSL 3.0.0, 3.0.1, and 3.0.2. Save a copy of the key ++ // in the context so Reset can use it later. New OpenSSL versions ++ // do not have this issue so it isn't necessary to save the key. ++ // See https://github.com/openssl/openssl/issues/17811. ++ hkey = make([]byte, len(key)) ++ copy(hkey, key) ++ } ++ hmac := &opensslHMAC{ ++ size: h.Size(), ++ blockSize: h.BlockSize(), ++ ctx3: hmacCtx3{ctx, hkey}, ++ } ++ runtime.SetFinalizer(hmac, (*opensslHMAC).finalize) ++ return hmac ++} ++ ++func (h *opensslHMAC) Reset() { ++ switch vMajor { ++ case 1: ++ if C.go_openssl_HMAC_Init_ex(h.ctx1.ctx, nil, 0, nil, nil) == 0 { ++ panic(newOpenSSLError("HMAC_Init_ex failed")) + } + case 3: -+ var err error -+ if pkey, err = newRSAKey3(true, N, E, D, P, Q, Dp, Dq, Qinv); err != nil { -+ return nil, err ++ if C.go_openssl_EVP_MAC_init(h.ctx3.ctx, base(h.ctx3.key), C.size_t(len(h.ctx3.key)), nil) == 0 { ++ panic(newOpenSSLError("EVP_MAC_init failed")) + } + default: + panic(errUnsupportedVersion()) + } -+ k := &PrivateKeyRSA{_pkey: pkey} -+ runtime.SetFinalizer(k, (*PrivateKeyRSA).finalize) -+ return k, nil -+} + -+func (k *PrivateKeyRSA) finalize() { -+ C.go_openssl_EVP_PKEY_free(k._pkey) -+} -+ -+func (k *PrivateKeyRSA) withKey(f func(C.GO_EVP_PKEY_PTR) C.int) C.int { -+ // Because of the finalizer, any time _pkey is passed to cgo, that call must -+ // be followed by a call to runtime.KeepAlive, to make sure k is not -+ // collected (and finalized) before the cgo call returns. -+ defer runtime.KeepAlive(k) -+ return f(k._pkey) ++ runtime.KeepAlive(h) // Next line will keep h alive too; just making doubly sure. ++ h.sum = nil +} + -+func DecryptRSAOAEP(h, mgfHash hash.Hash, priv *PrivateKeyRSA, ciphertext, label []byte) ([]byte, error) { -+ return evpDecrypt(priv.withKey, C.GO_RSA_PKCS1_OAEP_PADDING, h, mgfHash, label, ciphertext) ++func (h *opensslHMAC) finalize() { ++ switch vMajor { ++ case 1: ++ hmacCtxFree(h.ctx1.ctx) ++ case 3: ++ C.go_openssl_EVP_MAC_CTX_free(h.ctx3.ctx) ++ default: ++ panic(errUnsupportedVersion()) ++ } +} + -+func EncryptRSAOAEP(h, mgfHash hash.Hash, pub *PublicKeyRSA, msg, label []byte) ([]byte, error) { -+ return evpEncrypt(pub.withKey, C.GO_RSA_PKCS1_OAEP_PADDING, h, mgfHash, label, msg) ++func (h *opensslHMAC) Write(p []byte) (int, error) { ++ if len(p) > 0 { ++ switch vMajor { ++ case 1: ++ C.go_openssl_HMAC_Update(h.ctx1.ctx, base(p), C.size_t(len(p))) ++ case 3: ++ C.go_openssl_EVP_MAC_update(h.ctx3.ctx, base(p), C.size_t(len(p))) ++ default: ++ panic(errUnsupportedVersion()) ++ } ++ } ++ runtime.KeepAlive(h) ++ return len(p), nil +} + -+func DecryptRSAPKCS1(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) { -+ return evpDecrypt(priv.withKey, C.GO_RSA_PKCS1_PADDING, nil, nil, nil, ciphertext) ++func (h *opensslHMAC) Size() int { ++ return h.size +} + -+func EncryptRSAPKCS1(pub *PublicKeyRSA, msg []byte) ([]byte, error) { -+ return evpEncrypt(pub.withKey, C.GO_RSA_PKCS1_PADDING, nil, nil, nil, msg) ++func (h *opensslHMAC) BlockSize() int { ++ return h.blockSize +} + -+func DecryptRSANoPadding(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) { -+ ret, err := evpDecrypt(priv.withKey, C.GO_RSA_NO_PADDING, nil, nil, nil, ciphertext) -+ if err != nil { -+ return nil, err -+ } -+ // We could return here, but the Go standard library test expects DecryptRSANoPadding to verify the result -+ // in order to defend against errors in the CRT computation. -+ // -+ // The following code tries to replicate the verification implemented in the upstream function decryptAndCheck, found at -+ // https://github.com/golang/go/blob/9de1ac6ac2cad3871760d0aa288f5ca713afd0a6/src/crypto/rsa/rsa.go#L569-L582. -+ pub := &PublicKeyRSA{_pkey: priv._pkey} -+ // A private EVP_PKEY can be used as a public key as it contains the public information. -+ enc, err := EncryptRSANoPadding(pub, ret) -+ if err != nil { -+ return nil, err ++func (h *opensslHMAC) Sum(in []byte) []byte { ++ if h.sum == nil { ++ size := h.Size() ++ h.sum = make([]byte, size) + } -+ // Upstream does not do a constant time comparison because it works with math/big instead of byte slices, -+ // and math/big does not support constant-time arithmetic yet. See #20654 for more info. -+ if subtle.ConstantTimeCompare(ciphertext, enc) != 1 { -+ return nil, errors.New("rsa: internal error") ++ // Make copy of context because Go hash.Hash mandates ++ // that Sum has no effect on the underlying stream. ++ // In particular it is OK to Sum, then Write more, then Sum again, ++ // and the second Sum acts as if the first didn't happen. ++ switch vMajor { ++ case 1: ++ ctx2 := hmacCtxNew() ++ if ctx2 == nil { ++ panic("openssl: HMAC_CTX_new failed") ++ } ++ defer hmacCtxFree(ctx2) ++ if C.go_openssl_HMAC_CTX_copy(ctx2, h.ctx1.ctx) == 0 { ++ panic("openssl: HMAC_CTX_copy failed") ++ } ++ C.go_openssl_HMAC_Final(ctx2, base(h.sum), nil) ++ case 3: ++ ctx2 := C.go_openssl_EVP_MAC_CTX_dup(h.ctx3.ctx) ++ if ctx2 == nil { ++ panic("openssl: EVP_MAC_CTX_dup failed") ++ } ++ defer C.go_openssl_EVP_MAC_CTX_free(ctx2) ++ C.go_openssl_EVP_MAC_final(ctx2, base(h.sum), nil, C.size_t(len(h.sum))) ++ default: ++ panic(errUnsupportedVersion()) + } -+ return ret, nil -+} -+ -+func EncryptRSANoPadding(pub *PublicKeyRSA, msg []byte) ([]byte, error) { -+ return evpEncrypt(pub.withKey, C.GO_RSA_NO_PADDING, nil, nil, nil, msg) ++ return append(in, h.sum...) +} + -+func saltLength(saltLen int, sign bool) (C.int, error) { -+ // A salt length of -2 is valid in OpenSSL, but not in crypto/rsa, so reject -+ // it, and lengths < -2, before we convert to the OpenSSL sentinel values. -+ if saltLen <= -2 { -+ return 0, errors.New("crypto/rsa: PSSOptions.SaltLength cannot be negative") -+ } -+ // OpenSSL uses sentinel salt length values like Go crypto does, -+ // but the values don't fully match for rsa.PSSSaltLengthAuto (0). -+ if saltLen == 0 { -+ if sign { -+ if vMajor == 1 { -+ // OpenSSL 1.x uses -2 to mean maximal size when signing where Go crypto uses 0. -+ return C.GO_RSA_PSS_SALTLEN_MAX_SIGN, nil -+ } -+ // OpenSSL 3.x deprecated RSA_PSS_SALTLEN_MAX_SIGN -+ // and uses -3 to mean maximal size when signing where Go crypto uses 0. -+ return C.GO_RSA_PSS_SALTLEN_MAX, nil ++func hmacCtxNew() C.GO_HMAC_CTX_PTR { ++ if vMajor == 1 && vMinor == 0 { ++ // 0x120 is the sizeof value when building against OpenSSL 1.0.2 on Ubuntu 16.04. ++ ctx := (C.GO_HMAC_CTX_PTR)(C.malloc(0x120)) ++ if ctx != nil { ++ C.go_openssl_HMAC_CTX_init(ctx) + } -+ // OpenSSL uses -2 to mean auto-detect size when verifying where Go crypto uses 0. -+ return C.GO_RSA_PSS_SALTLEN_AUTO, nil ++ return ctx + } -+ return C.int(saltLen), nil ++ return C.go_openssl_HMAC_CTX_new() +} + -+func SignRSAPSS(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte, saltLen int) ([]byte, error) { -+ cSaltLen, err := saltLength(saltLen, true) -+ if err != nil { -+ return nil, err ++func hmacCtxFree(ctx C.GO_HMAC_CTX_PTR) { ++ if vMajor == 1 && vMinor == 0 { ++ C.go_openssl_HMAC_CTX_cleanup(ctx) ++ C.free(unsafe.Pointer(ctx)) ++ return + } -+ return evpSign(priv.withKey, C.GO_RSA_PKCS1_PSS_PADDING, cSaltLen, h, hashed) ++ C.go_openssl_HMAC_CTX_free(ctx) +} +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/init.go b/src/vendor/github.com/golang-fips/openssl/v2/init.go +new file mode 100644 +index 0000000000..a14663298b +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/init.go +@@ -0,0 +1,64 @@ ++//go:build !cmd_go_bootstrap + -+func VerifyRSAPSS(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte, saltLen int) error { -+ cSaltLen, err := saltLength(saltLen, false) -+ if err != nil { -+ return err -+ } -+ return evpVerify(pub.withKey, C.GO_RSA_PKCS1_PSS_PADDING, cSaltLen, h, sig, hashed) -+} ++package openssl + -+func SignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte) ([]byte, error) { -+ return evpSign(priv.withKey, C.GO_RSA_PKCS1_PADDING, 0, h, hashed) -+} -+ -+func HashSignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, msg []byte) ([]byte, error) { -+ return evpHashSign(priv.withKey, h, msg) -+} ++// #include "goopenssl.h" ++import "C" ++import ( ++ "errors" ++) + -+func VerifyRSAPKCS1v15(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte) error { -+ if pub.withKey(func(pkey C.GO_EVP_PKEY_PTR) C.int { -+ size := C.go_openssl_EVP_PKEY_get_size(pkey) -+ if len(sig) < int(size) { -+ return 0 -+ } -+ return 1 -+ }) == 0 { -+ return errors.New("crypto/rsa: verification error") ++// opensslInit loads and initialize OpenSSL. ++// If successful, it returns the major and minor OpenSSL version ++// as reported by the OpenSSL API. ++// ++// See Init() for details about file. ++func opensslInit(file string) (major, minor, patch uint, err error) { ++ // Load the OpenSSL shared library using dlopen. ++ handle, err := dlopen(file) ++ if err != nil { ++ return 0, 0, 0, err + } -+ return evpVerify(pub.withKey, C.GO_RSA_PKCS1_PADDING, 0, h, sig, hashed) -+} -+ -+func HashVerifyRSAPKCS1v15(pub *PublicKeyRSA, h crypto.Hash, msg, sig []byte) error { -+ return evpHashVerify(pub.withKey, h, msg, sig) -+} -+ -+// rsa_st_1_0_2 is rsa_st memory layout in OpenSSL 1.0.2. -+type rsa_st_1_0_2 struct { -+ _ C.int -+ _ C.long -+ _ [2]unsafe.Pointer -+ n, e, d C.GO_BIGNUM_PTR -+ p, q C.GO_BIGNUM_PTR -+ dmp1, dmq1, iqmp C.GO_BIGNUM_PTR -+ // It contains more fields, but we are not interesed on them. -+} + -+func bnSet(b1 *C.GO_BIGNUM_PTR, b2 BigInt) { -+ if b2 == nil { -+ return -+ } -+ if *b1 != nil { -+ C.go_openssl_BN_clear_free(*b1) ++ // Retrieve the loaded OpenSSL version and check if it is supported. ++ // Notice that major and minor could not match with the version parameter ++ // in case the name of the shared library file differs from the OpenSSL ++ // version it contains. ++ imajor := int(C.go_openssl_version_major(handle)) ++ iminor := int(C.go_openssl_version_minor(handle)) ++ ipatch := int(C.go_openssl_version_patch(handle)) ++ if imajor < 0 || iminor < 0 || ipatch < 0 { ++ return 0, 0, 0, errors.New("openssl: can't retrieve OpenSSL version") + } -+ *b1 = bigToBN(b2) -+} -+ -+func rsaSetKey(key C.GO_RSA_PTR, n, e, d BigInt) bool { -+ if vMajor == 1 && vMinor == 0 { -+ r := (*rsa_st_1_0_2)(unsafe.Pointer(key)) -+ //r.d and d will be nil for public keys. -+ if (r.n == nil && n == nil) || -+ (r.e == nil && e == nil) { -+ return false -+ } -+ bnSet(&r.n, n) -+ bnSet(&r.e, e) -+ bnSet(&r.d, d) -+ return true ++ major, minor, patch = uint(imajor), uint(iminor), uint(ipatch) ++ var supported bool ++ if major == 1 { ++ supported = minor == 0 || minor == 1 ++ } else if major == 3 { ++ // OpenSSL guarantees API and ABI compatibility within the same major version since OpenSSL 3. ++ supported = true + } -+ return C.go_openssl_RSA_set0_key(key, bigToBN(n), bigToBN(e), bigToBN(d)) == 1 -+} -+ -+func rsaSetFactors(key C.GO_RSA_PTR, p, q BigInt) bool { -+ if vMajor == 1 && vMinor == 0 { -+ r := (*rsa_st_1_0_2)(unsafe.Pointer(key)) -+ if (r.p == nil && p == nil) || -+ (r.q == nil && q == nil) { -+ return false -+ } -+ bnSet(&r.p, p) -+ bnSet(&r.q, q) -+ return true ++ if !supported { ++ return 0, 0, 0, errUnsupportedVersion() + } -+ return C.go_openssl_RSA_set0_factors(key, bigToBN(p), bigToBN(q)) == 1 -+} + -+func rsaSetCRTParams(key C.GO_RSA_PTR, dmp1, dmq1, iqmp BigInt) bool { -+ if vMajor == 1 && vMinor == 0 { -+ r := (*rsa_st_1_0_2)(unsafe.Pointer(key)) -+ if (r.dmp1 == nil && dmp1 == nil) || -+ (r.dmq1 == nil && dmq1 == nil) || -+ (r.iqmp == nil && iqmp == nil) { -+ return false -+ } -+ bnSet(&r.dmp1, dmp1) -+ bnSet(&r.dmq1, dmq1) -+ bnSet(&r.iqmp, iqmp) -+ return true -+ } -+ return C.go_openssl_RSA_set0_crt_params(key, bigToBN(dmp1), bigToBN(dmq1), bigToBN(iqmp)) == 1 -+} ++ // Load the OpenSSL functions. ++ // See shims.go for the complete list of supported functions. ++ C.go_openssl_load_functions(handle, C.uint(major), C.uint(minor), C.uint(patch)) + -+func newRSAKey3(isPriv bool, N, E, D, P, Q, Dp, Dq, Qinv BigInt) (C.GO_EVP_PKEY_PTR, error) { -+ // Construct the parameters. -+ bld := C.go_openssl_OSSL_PARAM_BLD_new() -+ if bld == nil { -+ return nil, newOpenSSLError("OSSL_PARAM_BLD_new") -+ } -+ defer C.go_openssl_OSSL_PARAM_BLD_free(bld) -+ var comps = [...]struct { -+ name *C.char -+ num BigInt -+ }{ -+ {paramRSA_N, N}, {paramRSA_E, E}, {paramRSA_D, D}, -+ {paramRSA_P, P}, {paramRSA_Q, Q}, -+ {paramRSA_Dp, Dp}, {paramRSA_Dq, Dq}, {paramRSA_Qinv, Qinv}, -+ } -+ for _, comp := range comps { -+ if comp.num == nil { -+ continue -+ } -+ b := bigToBN(comp.num) -+ if b == nil { -+ return nil, newOpenSSLError("BN_lebin2bn failed") ++ // Initialize OpenSSL. ++ C.go_openssl_OPENSSL_init() ++ if major == 1 && minor == 0 { ++ if C.go_openssl_thread_setup() != 1 { ++ return 0, 0, 0, fail("openssl: thread setup") + } -+ // b must remain valid until OSSL_PARAM_BLD_to_param has been called. -+ defer C.go_openssl_BN_clear_free(b) -+ if C.go_openssl_OSSL_PARAM_BLD_push_BN(bld, comp.name, b) != 1 { -+ return nil, newOpenSSLError("OSSL_PARAM_BLD_push_BN") ++ C.go_openssl_OPENSSL_add_all_algorithms_conf() ++ C.go_openssl_ERR_load_crypto_strings() ++ } else { ++ flags := C.uint64_t(C.GO_OPENSSL_INIT_ADD_ALL_CIPHERS | C.GO_OPENSSL_INIT_ADD_ALL_DIGESTS | C.GO_OPENSSL_INIT_LOAD_CONFIG | C.GO_OPENSSL_INIT_LOAD_CRYPTO_STRINGS) ++ if C.go_openssl_OPENSSL_init_crypto(flags, nil) != 1 { ++ return 0, 0, 0, fail("openssl: init crypto") + } + } -+ params := C.go_openssl_OSSL_PARAM_BLD_to_param(bld) -+ if params == nil { -+ return nil, newOpenSSLError("OSSL_PARAM_BLD_to_param") -+ } -+ defer C.go_openssl_OSSL_PARAM_free(params) -+ selection := C.GO_EVP_PKEY_PUBLIC_KEY -+ if isPriv { -+ selection = C.GO_EVP_PKEY_KEYPAIR -+ } -+ return newEvpFromParams(C.GO_EVP_PKEY_RSA, C.int(selection), params) ++ return major, minor, patch, nil +} -diff --git a/src/vendor/github.com/golang-fips/openssl/v2/sha.go b/src/vendor/github.com/golang-fips/openssl/v2/sha.go +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/init_unix.go b/src/vendor/github.com/golang-fips/openssl/v2/init_unix.go new file mode 100644 -index 0000000000..c15e1d77cb +index 0000000000..dbf5ac448f --- /dev/null -+++ b/src/vendor/github.com/golang-fips/openssl/v2/sha.go -@@ -0,0 +1,696 @@ -+//go:build !cmd_go_bootstrap ++++ b/src/vendor/github.com/golang-fips/openssl/v2/init_unix.go +@@ -0,0 +1,31 @@ ++//go:build unix && !cmd_go_bootstrap + +package openssl + -+// #include "goopenssl.h" ++// #cgo LDFLAGS: -ldl ++// #include ++// #include +import "C" +import ( -+ "crypto" + "errors" -+ "hash" -+ "runtime" -+ "strconv" + "unsafe" +) + -+// NOTE: Implementation ported from https://go-review.googlesource.com/c/go/+/404295. -+// The cgo calls in this file are arranged to avoid marking the parameters as escaping. -+// To do that, we call noescape (including via addr). -+// We must also make sure that the data pointer arguments have the form unsafe.Pointer(&...) -+// so that cgo does not annotate them with cgoCheckPointer calls. If it did that, it might look -+// beyond the byte slice and find Go pointers in unprocessed parts of a larger allocation. -+// To do both of these simultaneously, the idiom is unsafe.Pointer(&*addr(p)), -+// where addr returns the base pointer of p, substituting a non-nil pointer for nil, -+// and applying a noescape along the way. -+// This is all to preserve compatibility with the allocation behavior of the non-openssl implementations. -+ -+func shaX(ch crypto.Hash, p []byte, sum []byte) bool { -+ return C.go_openssl_EVP_Digest(unsafe.Pointer(&*addr(p)), C.size_t(len(p)), (*C.uchar)(unsafe.Pointer(&*addr(sum))), nil, cryptoHashToMD(ch), nil) != 0 -+} -+ -+func SHA1(p []byte) (sum [20]byte) { -+ if !shaX(crypto.SHA1, p, sum[:]) { -+ panic("openssl: SHA1 failed") ++func dlopen(file string) (handle unsafe.Pointer, err error) { ++ cv := C.CString(file) ++ defer C.free(unsafe.Pointer(cv)) ++ handle = C.dlopen(cv, C.RTLD_LAZY|C.RTLD_LOCAL) ++ if handle == nil { ++ errstr := C.GoString(C.dlerror()) ++ return nil, errors.New("openssl: can't load " + file + ": " + errstr) + } -+ return ++ return handle, nil +} + -+func SHA224(p []byte) (sum [28]byte) { -+ if !shaX(crypto.SHA224, p, sum[:]) { -+ panic("openssl: SHA224 failed") ++func dlclose(handle unsafe.Pointer) error { ++ if C.dlclose(handle) != 0 { ++ errstr := C.GoString(C.dlerror()) ++ return errors.New("openssl: can't close libcrypto: " + errstr) + } -+ return ++ return nil +} +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/init_windows.go b/src/vendor/github.com/golang-fips/openssl/v2/init_windows.go +new file mode 100644 +index 0000000000..3778e21227 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/init_windows.go +@@ -0,0 +1,36 @@ ++//go:build !cmd_go_bootstrap + -+func SHA256(p []byte) (sum [32]byte) { -+ if !shaX(crypto.SHA256, p, sum[:]) { -+ panic("openssl: SHA256 failed") -+ } -+ return -+} ++package openssl + -+func SHA384(p []byte) (sum [48]byte) { -+ if !shaX(crypto.SHA384, p, sum[:]) { -+ panic("openssl: SHA384 failed") -+ } -+ return ++import ( ++ "syscall" ++ "unsafe" ++) ++ ++type dlopenError struct { ++ file string ++ err error +} + -+func SHA512(p []byte) (sum [64]byte) { -+ if !shaX(crypto.SHA512, p, sum[:]) { -+ panic("openssl: SHA512 failed") -+ } -+ return ++func (e *dlopenError) Error() string { ++ return "openssl: can't load " + e.file + ": " + e.err.Error() +} + -+// SupportsHash returns true if a hash.Hash implementation is supported for h. -+func SupportsHash(h crypto.Hash) bool { -+ switch h { -+ case crypto.SHA1, crypto.SHA224, crypto.SHA256, crypto.SHA384, crypto.SHA512: -+ return true -+ case crypto.SHA3_224, crypto.SHA3_256, crypto.SHA3_384, crypto.SHA3_512: -+ return vMajor > 1 || -+ (vMajor >= 1 && vMinor > 1) || -+ (vMajor >= 1 && vMinor >= 1 && vPatch >= 1) -+ } -+ return false ++func (e *dlopenError) Unwrap() error { ++ return e.err +} + -+func SHA3_224(p []byte) (sum [28]byte) { -+ if !shaX(crypto.SHA3_224, p, sum[:]) { -+ panic("openssl: SHA3_224 failed") ++func dlopen(file string) (handle unsafe.Pointer, err error) { ++ // As Windows generally does not ship with a system OpenSSL library, let ++ // alone a FIPS 140 certified one, use the default library search order so ++ // that we preferentially load the DLL bundled with the application. ++ h, err := syscall.LoadLibrary(file) ++ if err != nil { ++ return nil, &dlopenError{file: file, err: err} + } -+ return ++ return unsafe.Pointer(h), nil +} + -+func SHA3_256(p []byte) (sum [32]byte) { -+ if !shaX(crypto.SHA3_256, p, sum[:]) { -+ panic("openssl: SHA3_256 failed") -+ } -+ return ++func dlclose(handle unsafe.Pointer) error { ++ return syscall.FreeLibrary(syscall.Handle(handle)) +} +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/openssl.go b/src/vendor/github.com/golang-fips/openssl/v2/openssl.go +new file mode 100644 +index 0000000000..691bb16f72 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/openssl.go +@@ -0,0 +1,419 @@ ++//go:build !cmd_go_bootstrap + -+func SHA3_384(p []byte) (sum [48]byte) { -+ if !shaX(crypto.SHA3_384, p, sum[:]) { -+ panic("openssl: SHA3_384 failed") -+ } -+ return -+} ++// Package openssl provides access to OpenSSL cryptographic functions. ++package openssl + -+func SHA3_512(p []byte) (sum [64]byte) { -+ if !shaX(crypto.SHA3_512, p, sum[:]) { -+ panic("openssl: SHA3_512 failed") -+ } -+ return -+} ++// #include "goopenssl.h" ++import "C" ++import ( ++ "encoding/binary" ++ "errors" ++ "math/bits" ++ "runtime" ++ "strconv" ++ "strings" ++ "sync" ++ "unsafe" ++) + -+// evpHash implements generic hash methods. -+type evpHash struct { -+ ctx C.GO_EVP_MD_CTX_PTR -+ // ctx2 is used in evpHash.sum to avoid changing -+ // the state of ctx. Having it here allows reusing the -+ // same allocated object multiple times. -+ ctx2 C.GO_EVP_MD_CTX_PTR -+ size int -+ blockSize int -+} ++var ( ++ // vMajor and vMinor hold the major/minor OpenSSL version. ++ // It is only populated if Init has been called. ++ vMajor, vMinor, vPatch uint ++) + -+func newEvpHash(ch crypto.Hash, size, blockSize int) *evpHash { -+ md := cryptoHashToMD(ch) -+ if md == nil { -+ panic("openssl: unsupported hash function: " + strconv.Itoa(int(ch))) -+ } -+ ctx := C.go_openssl_EVP_MD_CTX_new() -+ if C.go_openssl_EVP_DigestInit_ex(ctx, md, nil) != 1 { -+ C.go_openssl_EVP_MD_CTX_free(ctx) -+ panic(newOpenSSLError("EVP_DigestInit_ex")) -+ } -+ ctx2 := C.go_openssl_EVP_MD_CTX_new() -+ h := &evpHash{ -+ ctx: ctx, -+ ctx2: ctx2, -+ size: size, -+ blockSize: blockSize, -+ } -+ runtime.SetFinalizer(h, (*evpHash).finalize) -+ return h -+} ++var ( ++ initOnce sync.Once ++ initErr error ++) + -+func (h *evpHash) finalize() { -+ C.go_openssl_EVP_MD_CTX_free(h.ctx) -+ C.go_openssl_EVP_MD_CTX_free(h.ctx2) -+} ++var nativeEndian binary.ByteOrder + -+func (h *evpHash) Reset() { -+ // There is no need to reset h.ctx2 because it is always reset after -+ // use in evpHash.sum. -+ if C.go_openssl_EVP_DigestInit_ex(h.ctx, nil, nil) != 1 { -+ panic(newOpenSSLError("EVP_DigestInit_ex")) ++// CheckVersion checks if the OpenSSL version can be loaded ++// and if the FIPS mode is enabled. ++// This function can be called before Init. ++func CheckVersion(version string) (exists, fips bool) { ++ handle, _ := dlopen(version) ++ if handle == nil { ++ return false, false + } -+ runtime.KeepAlive(h) ++ defer dlclose(handle) ++ fips = C.go_openssl_fips_enabled(handle) == 1 ++ return true, fips +} + -+func (h *evpHash) Write(p []byte) (int, error) { -+ if len(p) > 0 && C.go_openssl_EVP_DigestUpdate(h.ctx, unsafe.Pointer(&*addr(p)), C.size_t(len(p))) != 1 { -+ panic(newOpenSSLError("EVP_DigestUpdate")) -+ } -+ runtime.KeepAlive(h) -+ return len(p), nil -+} ++// Init loads and initializes OpenSSL from the shared library at path. ++// It must be called before any other OpenSSL call, except CheckVersion. ++// ++// Only the first call to Init is effective. ++// Subsequent calls will return the same error result as the one from the first call. ++// ++// The file is passed to dlopen() verbatim to load the OpenSSL shared library. ++// For example, `file=libcrypto.so.1.1.1k-fips` makes Init look for the shared ++// library libcrypto.so.1.1.1k-fips. ++func Init(file string) error { ++ initOnce.Do(func() { ++ buf := [2]byte{} ++ *(*uint16)(unsafe.Pointer(&buf[0])) = uint16(0xABCD) + -+func (h *evpHash) WriteString(s string) (int, error) { -+ if len(s) > 0 && C.go_openssl_EVP_DigestUpdate(h.ctx, unsafe.Pointer(unsafe.StringData(s)), C.size_t(len(s))) == 0 { -+ panic("openssl: EVP_DigestUpdate failed") -+ } -+ runtime.KeepAlive(h) -+ return len(s), nil ++ switch buf { ++ case [2]byte{0xCD, 0xAB}: ++ nativeEndian = binary.LittleEndian ++ case [2]byte{0xAB, 0xCD}: ++ nativeEndian = binary.BigEndian ++ default: ++ panic("Could not determine native endianness.") ++ } ++ vMajor, vMinor, vPatch, initErr = opensslInit(file) ++ }) ++ return initErr +} + -+func (h *evpHash) WriteByte(c byte) error { -+ if C.go_openssl_EVP_DigestUpdate(h.ctx, unsafe.Pointer(&c), 1) == 0 { -+ panic("openssl: EVP_DigestUpdate failed") -+ } -+ runtime.KeepAlive(h) -+ return nil ++func utoa(n uint) string { ++ return strconv.FormatUint(uint64(n), 10) +} + -+func (h *evpHash) Size() int { -+ return h.size ++func errUnsupportedVersion() error { ++ return errors.New("openssl: OpenSSL version: " + utoa(vMajor) + "." + utoa(vMinor) + "." + utoa(vPatch)) +} + -+func (h *evpHash) BlockSize() int { -+ return h.blockSize ++type fail string ++ ++func (e fail) Error() string { return "openssl: " + string(e) + " failed" } ++ ++// VersionText returns the version text of the OpenSSL currently loaded. ++func VersionText() string { ++ return C.GoString(C.go_openssl_OpenSSL_version(0)) +} + -+func (h *evpHash) sum(out []byte) { -+ if C.go_sha_sum(h.ctx, h.ctx2, base(out)) != 1 { -+ panic(newOpenSSLError("go_sha_sum")) ++var ( ++ providerNameFips = C.CString("fips") ++ providerNameDefault = C.CString("default") ++) ++ ++// FIPS returns true if OpenSSL is running in FIPS mode, else returns false. ++func FIPS() bool { ++ switch vMajor { ++ case 1: ++ return C.go_openssl_FIPS_mode() == 1 ++ case 3: ++ // If FIPS is not enabled via default properties, then we are sure FIPS is not used. ++ if C.go_openssl_EVP_default_properties_is_fips_enabled(nil) == 0 { ++ return false ++ } ++ // EVP_default_properties_is_fips_enabled can return true even if the FIPS provider isn't loaded, ++ // it is only based on the default properties. ++ // We can be sure that the FIPS provider is available if we can fetch an algorithm, e.g., SHA2-256, ++ // explicitly setting `fips=yes`. ++ return C.go_openssl_OSSL_PROVIDER_available(nil, providerNameFips) == 1 ++ default: ++ panic(errUnsupportedVersion()) + } -+ runtime.KeepAlive(h) +} + -+// shaState returns a pointer to the internal sha structure. ++// SetFIPS enables or disables FIPS mode. +// -+// The EVP_MD_CTX memory layout has changed in OpenSSL 3 -+// and the property holding the internal structure is no longer md_data but algctx. -+func (h *evpHash) shaState() unsafe.Pointer { ++// For OpenSSL 3, the `fips` provider is loaded if enabled is true, ++// else the `default` provider is loaded. ++func SetFIPS(enabled bool) error { ++ var mode C.int ++ if enabled { ++ mode = C.int(1) ++ } else { ++ mode = C.int(0) ++ } + switch vMajor { + case 1: -+ // https://github.com/openssl/openssl/blob/0418e993c717a6863f206feaa40673a261de7395/crypto/evp/evp_local.h#L12. -+ type mdCtx struct { -+ _ [2]unsafe.Pointer -+ _ C.ulong -+ md_data unsafe.Pointer ++ if C.go_openssl_FIPS_mode_set(mode) != 1 { ++ return newOpenSSLError("FIPS_mode_set") + } -+ return (*mdCtx)(unsafe.Pointer(h.ctx)).md_data ++ return nil + case 3: -+ // https://github.com/openssl/openssl/blob/5675a5aaf6a2e489022bcfc18330dae9263e598e/crypto/evp/evp_local.h#L16. -+ type mdCtx struct { -+ _ [3]unsafe.Pointer -+ _ C.ulong -+ _ [3]unsafe.Pointer -+ algctx unsafe.Pointer ++ var provName *C.char ++ if enabled { ++ provName = providerNameFips ++ } else { ++ provName = providerNameDefault + } -+ return (*mdCtx)(unsafe.Pointer(h.ctx)).algctx ++ // Check if there is any provider that matches props. ++ if C.go_openssl_OSSL_PROVIDER_available(nil, provName) != 1 { ++ // If not, fallback to provName provider. ++ if C.go_openssl_OSSL_PROVIDER_load(nil, provName) == nil { ++ return newOpenSSLError("OSSL_PROVIDER_try_load") ++ } ++ // Make sure we now have a provider available. ++ if C.go_openssl_OSSL_PROVIDER_available(nil, provName) != 1 { ++ return fail("SetFIPS(" + strconv.FormatBool(enabled) + ") not supported") ++ } ++ } ++ if C.go_openssl_EVP_default_properties_enable_fips(nil, mode) != 1 { ++ return newOpenSSLError("openssl: EVP_default_properties_enable_fips") ++ } ++ return nil + default: + panic(errUnsupportedVersion()) + } +} + -+// NewSHA1 returns a new SHA1 hash. -+func NewSHA1() hash.Hash { -+ return &sha1Hash{ -+ evpHash: newEvpHash(crypto.SHA1, 20, 64), -+ } ++// noescape hides a pointer from escape analysis. noescape is ++// the identity function but escape analysis doesn't think the ++// output depends on the input. noescape is inlined and currently ++// compiles down to zero instructions. ++// USE CAREFULLY! ++// ++//go:nosplit ++func noescape(p unsafe.Pointer) unsafe.Pointer { ++ x := uintptr(p) ++ return unsafe.Pointer(x ^ 0) +} + -+type sha1Hash struct { -+ *evpHash -+ out [20]byte -+} ++var zero byte + -+func (h *sha1Hash) Sum(in []byte) []byte { -+ h.sum(h.out[:]) -+ return append(in, h.out[:]...) ++// addr converts p to its base addr, including a noescape along the way. ++// If p is nil, addr returns a non-nil pointer, so that the result can always ++// be dereferenced. ++// ++//go:nosplit ++func addr(p []byte) *byte { ++ if len(p) == 0 { ++ return &zero ++ } ++ return (*byte)(noescape(unsafe.Pointer(&p[0]))) +} + -+// sha1State layout is taken from -+// https://github.com/openssl/openssl/blob/0418e993c717a6863f206feaa40673a261de7395/include/openssl/sha.h#L34. -+type sha1State struct { -+ h [5]uint32 -+ nl, nh uint32 -+ x [64]byte -+ nx uint32 ++// base returns the address of the underlying array in b, ++// being careful not to panic when b has zero length. ++func base(b []byte) *C.uchar { ++ if len(b) == 0 { ++ return nil ++ } ++ return (*C.uchar)(unsafe.Pointer(&b[0])) +} + -+const ( -+ sha1Magic = "sha\x01" -+ sha1MarshaledSize = len(sha1Magic) + 5*4 + 64 + 8 -+) ++func sbase(b []byte) *C.char { ++ if len(b) == 0 { ++ return nil ++ } ++ return (*C.char)(unsafe.Pointer(&b[0])) ++} + -+func (h *sha1Hash) MarshalBinary() ([]byte, error) { -+ d := (*sha1State)(h.shaState()) -+ if d == nil { -+ return nil, errors.New("crypto/sha1: can't retrieve hash state") ++func newOpenSSLError(msg string) error { ++ var b strings.Builder ++ b.WriteString(msg) ++ b.WriteString("\nopenssl error(s):") ++ for { ++ var ( ++ e C.ulong ++ file *C.char ++ line C.int ++ ) ++ switch vMajor { ++ case 1: ++ e = C.go_openssl_ERR_get_error_line(&file, &line) ++ case 3: ++ e = C.go_openssl_ERR_get_error_all(&file, &line, nil, nil, nil) ++ default: ++ panic(errUnsupportedVersion()) ++ } ++ if e == 0 { ++ break ++ } ++ b.WriteByte('\n') ++ var buf [256]byte ++ C.go_openssl_ERR_error_string_n(e, (*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf))) ++ b.WriteString(string(buf[:]) + "\n\t" + C.GoString(file) + ":" + strconv.Itoa(int(line))) + } -+ b := make([]byte, 0, sha1MarshaledSize) -+ b = append(b, sha1Magic...) -+ b = appendUint32(b, d.h[0]) -+ b = appendUint32(b, d.h[1]) -+ b = appendUint32(b, d.h[2]) -+ b = appendUint32(b, d.h[3]) -+ b = appendUint32(b, d.h[4]) -+ b = append(b, d.x[:d.nx]...) -+ b = b[:len(b)+len(d.x)-int(d.nx)] // already zero -+ b = appendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29) -+ return b, nil ++ return errors.New(b.String()) +} + -+func (h *sha1Hash) UnmarshalBinary(b []byte) error { -+ if len(b) < len(sha1Magic) || string(b[:len(sha1Magic)]) != sha1Magic { -+ return errors.New("crypto/sha1: invalid hash state identifier") ++var unknownFile = "\000" ++ ++// caller reports file and line number information about function invocations on ++// the calling goroutine's stack, in a form suitable for passing to C code. ++// The argument skip is the number of stack frames to ascend, with 0 identifying ++// the caller of caller. The return values report the file name and line number ++// within the file of the corresponding call. The returned file is a C string ++// with static storage duration. ++func caller(skip int) (file *C.char, line C.int) { ++ _, f, l, ok := runtime.Caller(skip + 1) ++ if !ok { ++ f = unknownFile + } -+ if len(b) != sha1MarshaledSize { -+ return errors.New("crypto/sha1: invalid hash state size") ++ // The underlying bytes of the file string are null-terminated rodata with ++ // static lifetimes, so can be safely passed to C without worrying about ++ // leaking memory or use-after-free. ++ return (*C.char)(noescape(unsafe.Pointer(unsafe.StringData(f)))), C.int(l) ++} ++ ++// cryptoMalloc allocates n bytes of memory on the OpenSSL heap, which may be ++// different from the heap which C.malloc allocates on. The allocated object ++// must be freed using cryptoFree. cryptoMalloc is equivalent to the ++// OPENSSL_malloc macro. ++// ++// Like C.malloc, this function is guaranteed to never return nil. If OpenSSL's ++// malloc indicates out of memory, it crashes the program. ++// ++// Only objects which the OpenSSL library will take ownership of (i.e. will be ++// freed by OPENSSL_free / CRYPTO_free) need to be allocated on the OpenSSL ++// heap. ++func cryptoMalloc(n int) unsafe.Pointer { ++ file, line := caller(1) ++ var p unsafe.Pointer ++ if vMajor == 1 && vMinor == 0 { ++ p = C.go_openssl_CRYPTO_malloc_legacy102(C.int(n), file, line) ++ } else { ++ p = C.go_openssl_CRYPTO_malloc(C.size_t(n), file, line) + } -+ d := (*sha1State)(h.shaState()) -+ if d == nil { -+ return errors.New("crypto/sha1: can't retrieve hash state") ++ if p == nil { ++ // Un-recover()-ably crash the program in the same manner as the ++ // C.malloc() wrapper function. ++ runtime_throw("openssl: CRYPTO_malloc failed") + } -+ b = b[len(sha1Magic):] -+ b, d.h[0] = consumeUint32(b) -+ b, d.h[1] = consumeUint32(b) -+ b, d.h[2] = consumeUint32(b) -+ b, d.h[3] = consumeUint32(b) -+ b, d.h[4] = consumeUint32(b) -+ b = b[copy(d.x[:], b):] -+ _, n := consumeUint64(b) -+ d.nl = uint32(n << 3) -+ d.nh = uint32(n >> 29) -+ d.nx = uint32(n) % 64 -+ return nil ++ return p +} + -+// NewSHA224 returns a new SHA224 hash. -+func NewSHA224() hash.Hash { -+ return &sha224Hash{ -+ evpHash: newEvpHash(crypto.SHA224, 224/8, 64), ++// cryptoFree frees an object allocated on the OpenSSL heap, which may be ++// different from the heap which C.malloc allocates on. cryptoFree is equivalent ++// to the OPENSSL_free macro. ++func cryptoFree(p unsafe.Pointer) { ++ if vMajor == 1 && vMinor == 0 { ++ C.go_openssl_CRYPTO_free_legacy102(p) ++ return + } ++ file, line := caller(1) ++ C.go_openssl_CRYPTO_free(p, file, line) +} + -+type sha224Hash struct { -+ *evpHash -+ out [224 / 8]byte -+} ++const wordBytes = bits.UintSize / 8 + -+func (h *sha224Hash) Sum(in []byte) []byte { -+ h.sum(h.out[:]) -+ return append(in, h.out[:]...) ++// Reverse each limb of z. ++func (z BigInt) byteSwap() { ++ for i, d := range z { ++ var n uint = 0 ++ for j := 0; j < wordBytes; j++ { ++ n |= uint(byte(d)) << (8 * (wordBytes - j - 1)) ++ d >>= 8 ++ } ++ z[i] = n ++ } +} + -+// NewSHA256 returns a new SHA256 hash. -+func NewSHA256() hash.Hash { -+ return &sha256Hash{ -+ evpHash: newEvpHash(crypto.SHA256, 256/8, 64), ++func wbase(b BigInt) *C.uchar { ++ if len(b) == 0 { ++ return nil + } ++ return (*C.uchar)(unsafe.Pointer(&b[0])) +} + -+type sha256Hash struct { -+ *evpHash -+ out [256 / 8]byte ++// bignum_st_1_0_2 is bignum_st (BIGNUM) memory layout in OpenSSL 1.0.2. ++type bignum_st_1_0_2 struct { ++ d unsafe.Pointer // Pointer to an array of BN_ULONG bit chunks ++ top C.int // Index of last used d +1 ++ dmax C.int ++ neg C.int ++ flags C.int +} + -+func (h *sha256Hash) Sum(in []byte) []byte { -+ h.sum(h.out[:]) -+ return append(in, h.out[:]...) -+} ++func bigToBN(x BigInt) C.GO_BIGNUM_PTR { ++ if len(x) == 0 { ++ return nil ++ } + -+const ( -+ magic224 = "sha\x02" -+ magic256 = "sha\x03" -+ marshaledSize256 = len(magic256) + 8*4 + 64 + 8 -+) ++ if vMajor == 1 && vMinor == 0 { ++ // OpenSSL 1.0.x does not export bn_lebin2bn on all platforms, ++ // so we have to emulate it. ++ bn := C.go_openssl_BN_new() ++ if bn == nil { ++ return nil ++ } ++ if C.go_openssl_bn_expand2(bn, C.int(len(x))) == nil { ++ C.go_openssl_BN_free(bn) ++ panic(newOpenSSLError("BN_expand2")) ++ } ++ // The bytes of a BigInt are laid out in memory in the same order as a ++ // BIGNUM, regardless of host endianness. ++ bns := (*bignum_st_1_0_2)(unsafe.Pointer(bn)) ++ d := unsafe.Slice((*uint)(bns.d), len(x)) ++ bns.top = C.int(copy(d, x)) ++ return bn ++ } + -+// sha256State layout is taken from -+// https://github.com/openssl/openssl/blob/0418e993c717a6863f206feaa40673a261de7395/include/openssl/sha.h#L51. -+type sha256State struct { -+ h [8]uint32 -+ nl, nh uint32 -+ x [64]byte -+ nx uint32 ++ if nativeEndian == binary.BigEndian { ++ z := make(BigInt, len(x)) ++ copy(z, x) ++ z.byteSwap() ++ x = z ++ } ++ // Limbs are always ordered in LSB first, so we can safely apply ++ // BN_lebin2bn regardless of host endianness. ++ return C.go_openssl_BN_lebin2bn(wbase(x), C.int(len(x)*wordBytes), nil) +} + -+func (h *sha224Hash) MarshalBinary() ([]byte, error) { -+ d := (*sha256State)(h.shaState()) -+ if d == nil { -+ return nil, errors.New("crypto/sha256: can't retrieve hash state") ++func bnToBig(bn C.GO_BIGNUM_PTR) BigInt { ++ if bn == nil { ++ return nil + } -+ b := make([]byte, 0, marshaledSize256) -+ b = append(b, magic224...) -+ b = appendUint32(b, d.h[0]) -+ b = appendUint32(b, d.h[1]) -+ b = appendUint32(b, d.h[2]) -+ b = appendUint32(b, d.h[3]) -+ b = appendUint32(b, d.h[4]) -+ b = appendUint32(b, d.h[5]) -+ b = appendUint32(b, d.h[6]) -+ b = appendUint32(b, d.h[7]) -+ b = append(b, d.x[:d.nx]...) -+ b = b[:len(b)+len(d.x)-int(d.nx)] // already zero -+ b = appendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29) -+ return b, nil -+} + -+func (h *sha256Hash) MarshalBinary() ([]byte, error) { -+ d := (*sha256State)(h.shaState()) -+ if d == nil { -+ return nil, errors.New("crypto/sha256: can't retrieve hash state") ++ if vMajor == 1 && vMinor == 0 { ++ // OpenSSL 1.0.x does not export bn_bn2lebinpad on all platforms, ++ // so we have to emulate it. ++ bns := (*bignum_st_1_0_2)(unsafe.Pointer(bn)) ++ d := unsafe.Slice((*uint)(bns.d), bns.top) ++ x := make(BigInt, len(d)) ++ copy(x, d) ++ return x + } -+ b := make([]byte, 0, marshaledSize256) -+ b = append(b, magic256...) -+ b = appendUint32(b, d.h[0]) -+ b = appendUint32(b, d.h[1]) -+ b = appendUint32(b, d.h[2]) -+ b = appendUint32(b, d.h[3]) -+ b = appendUint32(b, d.h[4]) -+ b = appendUint32(b, d.h[5]) -+ b = appendUint32(b, d.h[6]) -+ b = appendUint32(b, d.h[7]) -+ b = append(b, d.x[:d.nx]...) -+ b = b[:len(b)+len(d.x)-int(d.nx)] // already zero -+ b = appendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29) -+ return b, nil -+} + -+func (h *sha224Hash) UnmarshalBinary(b []byte) error { -+ if len(b) < len(magic224) || string(b[:len(magic224)]) != magic224 { -+ return errors.New("crypto/sha256: invalid hash state identifier") -+ } -+ if len(b) != marshaledSize256 { -+ return errors.New("crypto/sha256: invalid hash state size") ++ // Limbs are always ordered in LSB first, so we can safely apply ++ // BN_bn2lebinpad regardless of host endianness. ++ x := make(BigInt, C.go_openssl_BN_num_bits(bn)) ++ if C.go_openssl_BN_bn2lebinpad(bn, wbase(x), C.int(len(x)*wordBytes)) == 0 { ++ panic("openssl: bignum conversion failed") + } -+ d := (*sha256State)(h.shaState()) -+ if d == nil { -+ return errors.New("crypto/sha256: can't retrieve hash state") ++ if nativeEndian == binary.BigEndian { ++ x.byteSwap() + } -+ b = b[len(magic224):] -+ b, d.h[0] = consumeUint32(b) -+ b, d.h[1] = consumeUint32(b) -+ b, d.h[2] = consumeUint32(b) -+ b, d.h[3] = consumeUint32(b) -+ b, d.h[4] = consumeUint32(b) -+ b, d.h[5] = consumeUint32(b) -+ b, d.h[6] = consumeUint32(b) -+ b, d.h[7] = consumeUint32(b) -+ b = b[copy(d.x[:], b):] -+ _, n := consumeUint64(b) -+ d.nl = uint32(n << 3) -+ d.nh = uint32(n >> 29) -+ d.nx = uint32(n) % 64 -+ return nil ++ return x +} + -+func (h *sha256Hash) UnmarshalBinary(b []byte) error { -+ if len(b) < len(magic256) || string(b[:len(magic256)]) != magic256 { -+ return errors.New("crypto/sha256: invalid hash state identifier") -+ } -+ if len(b) != marshaledSize256 { -+ return errors.New("crypto/sha256: invalid hash state size") ++func bnNumBytes(bn C.GO_BIGNUM_PTR) int { ++ return (int(C.go_openssl_BN_num_bits(bn)) + 7) / 8 ++} ++ ++// bnToBinPad converts the absolute value of bn into big-endian form and stores ++// it at to, padding with zeroes if necessary. If len(to) is not large enough to ++// hold the result, an error is returned. ++func bnToBinPad(bn C.GO_BIGNUM_PTR, to []byte) error { ++ if vMajor == 1 && vMinor == 0 { ++ // OpenSSL 1.0.x does not export bn_bn2binpad on all platforms, ++ // so we have to emulate it. ++ n := bnNumBytes(bn) ++ pad := len(to) - n ++ if pad < 0 { ++ return errors.New("openssl: destination buffer too small") ++ } ++ for i := 0; i < pad; i++ { ++ to[i] = 0 ++ } ++ if int(C.go_openssl_BN_bn2bin(bn, base(to[pad:]))) != n { ++ return errors.New("openssl: BN_bn2bin short write") ++ } ++ return nil + } -+ d := (*sha256State)(h.shaState()) -+ if d == nil { -+ return errors.New("crypto/sha256: can't retrieve hash state") ++ ++ if C.go_openssl_BN_bn2binpad(bn, base(to), C.int(len(to))) < 0 { ++ return newOpenSSLError("BN_bn2binpad") + } -+ b = b[len(magic256):] -+ b, d.h[0] = consumeUint32(b) -+ b, d.h[1] = consumeUint32(b) -+ b, d.h[2] = consumeUint32(b) -+ b, d.h[3] = consumeUint32(b) -+ b, d.h[4] = consumeUint32(b) -+ b, d.h[5] = consumeUint32(b) -+ b, d.h[6] = consumeUint32(b) -+ b, d.h[7] = consumeUint32(b) -+ b = b[copy(d.x[:], b):] -+ _, n := consumeUint64(b) -+ d.nl = uint32(n << 3) -+ d.nh = uint32(n >> 29) -+ d.nx = uint32(n) % 64 + return nil +} + -+// NewSHA384 returns a new SHA384 hash. -+func NewSHA384() hash.Hash { -+ return &sha384Hash{ -+ evpHash: newEvpHash(crypto.SHA384, 384/8, 128), -+ } ++func CheckLeaks() { ++ C.go_openssl_do_leak_check() +} + -+type sha384Hash struct { -+ *evpHash -+ out [384 / 8]byte ++// versionAtOrAbove returns true when ++// (vMajor, vMinor, vPatch) >= (major, minor, patch), ++// compared lexicographically. ++func versionAtOrAbove(major, minor, patch uint) bool { ++ return vMajor > major || (vMajor == major && vMinor > minor) || (vMajor == major && vMinor == minor && vPatch >= patch) +} +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/pbkdf2.go b/src/vendor/github.com/golang-fips/openssl/v2/pbkdf2.go +new file mode 100644 +index 0000000000..a895eab2d5 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/pbkdf2.go +@@ -0,0 +1,28 @@ ++//go:build !cmd_go_bootstrap + -+func (h *sha384Hash) Sum(in []byte) []byte { -+ h.sum(h.out[:]) -+ return append(in, h.out[:]...) -+} ++package openssl + -+// NewSHA512 returns a new SHA512 hash. -+func NewSHA512() hash.Hash { -+ return &sha512Hash{ -+ evpHash: newEvpHash(crypto.SHA512, 512/8, 128), ++// #include "goopenssl.h" ++import "C" ++import ( ++ "errors" ++ "hash" ++) ++ ++func PBKDF2(password, salt []byte, iter, keyLen int, h func() hash.Hash) ([]byte, error) { ++ md := hashToMD(h()) ++ if md == nil { ++ return nil, errors.New("unsupported hash function") ++ } ++ if len(password) == 0 && vMajor == 1 && vMinor == 0 { ++ // x/crypto/pbkdf2 supports empty passwords, but OpenSSL 1.0.2 ++ // does not. As a workaround, we pass an "empty" password. ++ password = make([]byte, C.GO_EVP_MAX_MD_SIZE) ++ } ++ out := make([]byte, keyLen) ++ ok := C.go_openssl_PKCS5_PBKDF2_HMAC(sbase(password), C.int(len(password)), base(salt), C.int(len(salt)), C.int(iter), md, C.int(keyLen), base(out)) ++ if ok != 1 { ++ return nil, newOpenSSLError("PKCS5_PBKDF2_HMAC") + } ++ return out, nil +} +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/port_evp_md5_sha1.c b/src/vendor/github.com/golang-fips/openssl/v2/port_evp_md5_sha1.c +new file mode 100644 +index 0000000000..50d49b1f10 +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/port_evp_md5_sha1.c +@@ -0,0 +1,126 @@ ++// The following is a partial backport of crypto/evp/m_md5_sha1.c, ++// commit cbc8a839959418d8a2c2e3ec6bdf394852c9501e on the ++// OpenSSL_1_1_0-stable branch. The ctrl function has been removed. + -+type sha512Hash struct { -+ *evpHash -+ out [512 / 8]byte -+} ++/* ++ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. ++ * ++ * Licensed under the OpenSSL license (the "License"). You may not use ++ * this file except in compliance with the License. You can obtain a copy ++ * in the file LICENSE in the source distribution or at ++ * https://www.openssl.org/source/license.html ++ */ + -+func (h *sha512Hash) Sum(in []byte) []byte { -+ h.sum(h.out[:]) -+ return append(in, h.out[:]...) -+} ++#include "goopenssl.h" + -+// sha512State layout is taken from -+// https://github.com/openssl/openssl/blob/0418e993c717a6863f206feaa40673a261de7395/include/openssl/sha.h#L95. -+type sha512State struct { -+ h [8]uint64 -+ nl, nh uint64 -+ x [128]byte -+ nx uint32 -+} ++#define NID_md5_sha1 114 + -+const ( -+ magic384 = "sha\x04" -+ magic512_224 = "sha\x05" -+ magic512_256 = "sha\x06" -+ magic512 = "sha\x07" -+ marshaledSize512 = len(magic512) + 8*8 + 128 + 8 -+) ++#define MD5_CBLOCK 64 ++#define MD5_LBLOCK (MD5_CBLOCK/4) ++#define MD5_DIGEST_LENGTH 16 ++#define SHA_LBLOCK 16 ++#define SHA_DIGEST_LENGTH 20 + -+func (h *sha384Hash) MarshalBinary() ([]byte, error) { -+ d := (*sha512State)(h.shaState()) -+ if d == nil { -+ return nil, errors.New("crypto/sha512: can't retrieve hash state") -+ } -+ b := make([]byte, 0, marshaledSize512) -+ b = append(b, magic384...) -+ b = appendUint64(b, d.h[0]) -+ b = appendUint64(b, d.h[1]) -+ b = appendUint64(b, d.h[2]) -+ b = appendUint64(b, d.h[3]) -+ b = appendUint64(b, d.h[4]) -+ b = appendUint64(b, d.h[5]) -+ b = appendUint64(b, d.h[6]) -+ b = appendUint64(b, d.h[7]) -+ b = append(b, d.x[:d.nx]...) -+ b = b[:len(b)+len(d.x)-int(d.nx)] // already zero -+ b = appendUint64(b, d.nl>>3|d.nh<<61) -+ return b, nil -+} ++#define EVP_PKEY_NULL_method NULL,NULL,{0,0,0,0} + -+func (h *sha512Hash) MarshalBinary() ([]byte, error) { -+ d := (*sha512State)(h.shaState()) -+ if d == nil { -+ return nil, errors.New("crypto/sha512: can't retrieve hash state") -+ } -+ b := make([]byte, 0, marshaledSize512) -+ b = append(b, magic512...) -+ b = appendUint64(b, d.h[0]) -+ b = appendUint64(b, d.h[1]) -+ b = appendUint64(b, d.h[2]) -+ b = appendUint64(b, d.h[3]) -+ b = appendUint64(b, d.h[4]) -+ b = appendUint64(b, d.h[5]) -+ b = appendUint64(b, d.h[6]) -+ b = appendUint64(b, d.h[7]) -+ b = append(b, d.x[:d.nx]...) -+ b = b[:len(b)+len(d.x)-int(d.nx)] // already zero -+ b = appendUint64(b, d.nl>>3|d.nh<<61) -+ return b, nil -+} ++// Change: MD5_LONG and SHA_LONG have been expanded to unsigned int, ++// which is always 32 bits. This avoids adding some obscure logic ++// to support 16-bit platforms. + -+func (h *sha384Hash) UnmarshalBinary(b []byte) error { -+ if len(b) < len(magic512) { -+ return errors.New("crypto/sha512: invalid hash state identifier") -+ } -+ if string(b[:len(magic384)]) != magic384 { -+ return errors.New("crypto/sha512: invalid hash state identifier") -+ } -+ if len(b) != marshaledSize512 { -+ return errors.New("crypto/sha512: invalid hash state size") -+ } -+ d := (*sha512State)(h.shaState()) -+ if d == nil { -+ return errors.New("crypto/sha512: can't retrieve hash state") -+ } -+ b = b[len(magic512):] -+ b, d.h[0] = consumeUint64(b) -+ b, d.h[1] = consumeUint64(b) -+ b, d.h[2] = consumeUint64(b) -+ b, d.h[3] = consumeUint64(b) -+ b, d.h[4] = consumeUint64(b) -+ b, d.h[5] = consumeUint64(b) -+ b, d.h[6] = consumeUint64(b) -+ b, d.h[7] = consumeUint64(b) -+ b = b[copy(d.x[:], b):] -+ _, n := consumeUint64(b) -+ d.nl = n << 3 -+ d.nh = n >> 61 -+ d.nx = uint32(n) % 128 -+ return nil -+} ++# define MD5_LONG unsigned int ++# define SHA_LONG unsigned int + -+func (h *sha512Hash) UnmarshalBinary(b []byte) error { -+ if len(b) < len(magic512) { -+ return errors.New("crypto/sha512: invalid hash state identifier") ++typedef struct env_md_st EVP_MD; ++typedef struct env_md_ctx_st EVP_MD_CTX; ++ ++struct env_md_ctx_st { ++ void *digest; ++ void *engine; ++ unsigned long flags; ++ void *md_data; ++ void *pctx; ++ void *update; ++} /* EVP_MD_CTX */ ; ++ ++struct env_md_st { ++ int type; ++ int pkey_type; ++ int md_size; ++ unsigned long flags; ++ int (*init) (EVP_MD_CTX *ctx); ++ int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count); ++ int (*final) (EVP_MD_CTX *ctx, unsigned char *md); ++ void *copy; ++ void *cleanup; ++ void *sign; ++ void *verify; ++ int required_pkey_type[5]; ++ int block_size; ++ int ctx_size; ++ void *md_ctrl; ++} /* EVP_MD */ ; ++ ++typedef struct MD5state_st { ++ MD5_LONG A, B, C, D; ++ MD5_LONG Nl, Nh; ++ MD5_LONG data[MD5_LBLOCK]; ++ MD5_LONG num; ++} MD5_CTX; ++ ++typedef struct SHAstate_st { ++ SHA_LONG h0, h1, h2, h3, h4; ++ SHA_LONG Nl, Nh; ++ SHA_LONG data[SHA_LBLOCK]; ++ SHA_LONG num; ++} SHA_CTX; ++ ++struct md5_sha1_ctx { ++ MD5_CTX md5; ++ SHA_CTX sha1; ++}; ++ ++static int md5_sha1_init(EVP_MD_CTX *ctx) { ++ struct md5_sha1_ctx *mctx = ctx->md_data; ++ if (!go_openssl_MD5_Init(&mctx->md5)) ++ return 0; ++ return go_openssl_SHA1_Init(&mctx->sha1); ++} ++ ++static int md5_sha1_update(EVP_MD_CTX *ctx, const void *data, ++ size_t count) { ++ struct md5_sha1_ctx *mctx = ctx->md_data; ++ if (!go_openssl_MD5_Update(&mctx->md5, data, count)) ++ return 0; ++ return go_openssl_SHA1_Update(&mctx->sha1, data, count); ++} ++ ++static int md5_sha1_final(EVP_MD_CTX *ctx, unsigned char *md) { ++ struct md5_sha1_ctx *mctx = ctx->md_data; ++ if (!go_openssl_MD5_Final(md, &mctx->md5)) ++ return 0; ++ return go_openssl_SHA1_Final(md + MD5_DIGEST_LENGTH, &mctx->sha1); ++} ++ ++// Change: Removed: ++// static int ctrl(EVP_MD_CTX *ctx, int cmd, int mslen, void *ms) ++ ++static const EVP_MD md5_sha1_md = { ++ NID_md5_sha1, ++ NID_md5_sha1, ++ MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, ++ 0, ++ md5_sha1_init, ++ md5_sha1_update, ++ md5_sha1_final, ++ NULL, ++ NULL, ++ EVP_PKEY_NULL_method, // Change: inserted ++ MD5_CBLOCK, ++ sizeof(EVP_MD *) + sizeof(struct md5_sha1_ctx), ++ NULL, // Change: was ctrl ++}; ++ ++// Change: Apply name mangling. ++const GO_EVP_MD_PTR go_openssl_EVP_md5_sha1_backport(void) { ++ return (const GO_EVP_MD_PTR)&md5_sha1_md; ++} +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/rand.go b/src/vendor/github.com/golang-fips/openssl/v2/rand.go +new file mode 100644 +index 0000000000..9fd709635c +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/rand.go +@@ -0,0 +1,20 @@ ++//go:build !cmd_go_bootstrap ++ ++package openssl ++ ++// #include "goopenssl.h" ++import "C" ++import "unsafe" ++ ++type randReader int ++ ++func (randReader) Read(b []byte) (int, error) { ++ // Note: RAND_bytes should never fail; the return value exists only for historical reasons. ++ // We check it even so. ++ if len(b) > 0 && C.go_openssl_RAND_bytes((*C.uchar)(unsafe.Pointer(&b[0])), C.int(len(b))) == 0 { ++ return 0, newOpenSSLError("RAND_bytes") + } -+ if string(b[:len(magic512)]) != magic512 { -+ return errors.New("crypto/sha512: invalid hash state identifier") ++ return len(b), nil ++} ++ ++const RandReader = randReader(0) +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/rc4.go b/src/vendor/github.com/golang-fips/openssl/v2/rc4.go +new file mode 100644 +index 0000000000..f88150591e +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/rc4.go +@@ -0,0 +1,66 @@ ++//go:build !cmd_go_bootstrap ++ ++package openssl ++ ++// #include "goopenssl.h" ++import "C" ++import "runtime" ++ ++// SupportsRC4 returns true if NewRC4Cipher is supported. ++func SupportsRC4() bool { ++ // True for stock OpenSSL 1 w/o FIPS. ++ // False for stock OpenSSL 3 unless the legacy provider is available. ++ return (versionAtOrAbove(1, 1, 0) || !FIPS()) && loadCipher(cipherRC4, cipherModeNone) != nil ++} ++ ++// A RC4Cipher is an instance of RC4 using a particular key. ++type RC4Cipher struct { ++ ctx C.GO_EVP_CIPHER_CTX_PTR ++} ++ ++// NewRC4Cipher creates and returns a new Cipher. ++func NewRC4Cipher(key []byte) (*RC4Cipher, error) { ++ ctx, err := newCipherCtx(cipherRC4, cipherModeNone, cipherOpEncrypt, key, nil) ++ if err != nil { ++ return nil, err + } -+ if len(b) != marshaledSize512 { -+ return errors.New("crypto/sha512: invalid hash state size") ++ c := &RC4Cipher{ctx} ++ runtime.SetFinalizer(c, (*RC4Cipher).finalize) ++ return c, nil ++} ++ ++func (c *RC4Cipher) finalize() { ++ if c.ctx != nil { ++ C.go_openssl_EVP_CIPHER_CTX_free(c.ctx) + } -+ d := (*sha512State)(h.shaState()) -+ if d == nil { -+ return errors.New("crypto/sha512: can't retrieve hash state") ++} ++ ++// Reset zeros the key data and makes the Cipher unusable. ++func (c *RC4Cipher) Reset() { ++ if c.ctx != nil { ++ C.go_openssl_EVP_CIPHER_CTX_free(c.ctx) ++ c.ctx = nil + } -+ b = b[len(magic512):] -+ b, d.h[0] = consumeUint64(b) -+ b, d.h[1] = consumeUint64(b) -+ b, d.h[2] = consumeUint64(b) -+ b, d.h[3] = consumeUint64(b) -+ b, d.h[4] = consumeUint64(b) -+ b, d.h[5] = consumeUint64(b) -+ b, d.h[6] = consumeUint64(b) -+ b, d.h[7] = consumeUint64(b) -+ b = b[copy(d.x[:], b):] -+ _, n := consumeUint64(b) -+ d.nl = n << 3 -+ d.nh = n >> 61 -+ d.nx = uint32(n) % 128 -+ return nil +} + -+// NewSHA3_224 returns a new SHA3-224 hash. -+func NewSHA3_224() hash.Hash { -+ return &sha3_224Hash{ -+ evpHash: newEvpHash(crypto.SHA3_224, 224/8, 64), -+ } ++// XORKeyStream sets dst to the result of XORing src with the key stream. ++// Dst and src must overlap entirely or not at all. ++func (c *RC4Cipher) XORKeyStream(dst, src []byte) { ++ if c.ctx == nil || len(src) == 0 { ++ return ++ } ++ if inexactOverlap(dst[:len(src)], src) { ++ panic("crypto/rc4: invalid buffer overlap") ++ } ++ // panic if len(dst) < len(src) with a runtime out of bound error, ++ // which is what crypto/rc4 does. ++ _ = dst[len(src)-1] ++ var outLen C.int ++ if C.go_openssl_EVP_EncryptUpdate(c.ctx, base(dst), &outLen, base(src), C.int(len(src))) != 1 { ++ panic("crypto/cipher: EncryptUpdate failed") ++ } ++ if int(outLen) != len(src) { ++ panic("crypto/rc4: src not fully XORed") ++ } ++ runtime.KeepAlive(c) ++} +diff --git a/src/vendor/github.com/golang-fips/openssl/v2/rsa.go b/src/vendor/github.com/golang-fips/openssl/v2/rsa.go +new file mode 100644 +index 0000000000..5aef65b84f +--- /dev/null ++++ b/src/vendor/github.com/golang-fips/openssl/v2/rsa.go +@@ -0,0 +1,419 @@ ++//go:build !cmd_go_bootstrap ++ ++package openssl ++ ++// #include "goopenssl.h" ++import "C" ++import ( ++ "crypto" ++ "crypto/subtle" ++ "errors" ++ "hash" ++ "runtime" ++ "unsafe" ++) ++ ++var ( ++ paramRSA_N = C.CString("n") ++ paramRSA_E = C.CString("e") ++ paramRSA_D = C.CString("d") ++ paramRSA_P = C.CString("rsa-factor1") ++ paramRSA_Q = C.CString("rsa-factor2") ++ paramRSA_Dp = C.CString("rsa-exponent1") ++ paramRSA_Dq = C.CString("rsa-exponent2") ++ paramRSA_Qinv = C.CString("rsa-coefficient1") ++) ++ ++func GenerateKeyRSA(bits int) (N, E, D, P, Q, Dp, Dq, Qinv BigInt, err error) { ++ bad := func(e error) (N, E, D, P, Q, Dp, Dq, Qinv BigInt, err error) { ++ return nil, nil, nil, nil, nil, nil, nil, nil, e ++ } ++ pkey, err := generateEVPPKey(C.GO_EVP_PKEY_RSA, bits, "") ++ if err != nil { ++ return bad(err) ++ } ++ defer C.go_openssl_EVP_PKEY_free(pkey) ++ switch vMajor { ++ case 1: ++ key := C.go_openssl_EVP_PKEY_get1_RSA(pkey) ++ if key == nil { ++ return bad(newOpenSSLError("EVP_PKEY_get1_RSA failed")) ++ } ++ defer C.go_openssl_RSA_free(key) ++ var n, e, d, p, q, dmp1, dmq1, iqmp C.GO_BIGNUM_PTR ++ if vMinor == 0 { ++ r := (*rsa_st_1_0_2)(unsafe.Pointer(key)) ++ n, e, d, p, q, dmp1, dmq1, iqmp = r.n, r.e, r.d, r.p, r.q, r.dmp1, r.dmq1, r.iqmp ++ } else { ++ C.go_openssl_RSA_get0_key(key, &n, &e, &d) ++ C.go_openssl_RSA_get0_factors(key, &p, &q) ++ C.go_openssl_RSA_get0_crt_params(key, &dmp1, &dmq1, &iqmp) ++ } ++ N, E, D = bnToBig(n), bnToBig(e), bnToBig(d) ++ P, Q = bnToBig(p), bnToBig(q) ++ Dp, Dq, Qinv = bnToBig(dmp1), bnToBig(dmq1), bnToBig(iqmp) ++ case 3: ++ tmp := C.go_openssl_BN_new() ++ if tmp == nil { ++ return bad(newOpenSSLError("BN_new failed")) ++ } ++ defer func() { ++ C.go_openssl_BN_clear_free(tmp) ++ }() ++ var err error ++ setBigInt := func(bi *BigInt, param *C.char) bool { ++ if err != nil { ++ return false ++ } ++ if C.go_openssl_EVP_PKEY_get_bn_param(pkey, param, &tmp) != 1 { ++ err = newOpenSSLError("EVP_PKEY_get_bn_param failed") ++ return false ++ } ++ *bi = bnToBig(tmp) ++ C.go_openssl_BN_clear(tmp) ++ return true ++ } ++ if !(setBigInt(&N, paramRSA_N) && ++ setBigInt(&E, paramRSA_E) && ++ setBigInt(&D, paramRSA_D) && ++ setBigInt(&P, paramRSA_P) && ++ setBigInt(&Q, paramRSA_Q) && ++ setBigInt(&Dp, paramRSA_Dp) && ++ setBigInt(&Dq, paramRSA_Dq) && ++ setBigInt(&Qinv, paramRSA_Qinv)) { ++ return bad(err) ++ } ++ default: ++ panic(errUnsupportedVersion()) ++ } ++ return ++} ++ ++type PublicKeyRSA struct { ++ // _pkey MUST NOT be accessed directly. Instead, use the withKey method. ++ _pkey C.GO_EVP_PKEY_PTR ++} ++ ++func NewPublicKeyRSA(N, E BigInt) (*PublicKeyRSA, error) { ++ var pkey C.GO_EVP_PKEY_PTR ++ switch vMajor { ++ case 1: ++ key := C.go_openssl_RSA_new() ++ if key == nil { ++ return nil, newOpenSSLError("RSA_new failed") ++ } ++ if !rsaSetKey(key, N, E, nil) { ++ return nil, fail("RSA_set0_key") ++ } ++ pkey = C.go_openssl_EVP_PKEY_new() ++ if pkey == nil { ++ C.go_openssl_RSA_free(key) ++ return nil, newOpenSSLError("EVP_PKEY_new failed") ++ } ++ if C.go_openssl_EVP_PKEY_assign(pkey, C.GO_EVP_PKEY_RSA, (unsafe.Pointer)(key)) != 1 { ++ C.go_openssl_RSA_free(key) ++ C.go_openssl_EVP_PKEY_free(pkey) ++ return nil, newOpenSSLError("EVP_PKEY_assign failed") ++ } ++ case 3: ++ var err error ++ if pkey, err = newRSAKey3(false, N, E, nil, nil, nil, nil, nil, nil); err != nil { ++ return nil, err ++ } ++ default: ++ panic(errUnsupportedVersion()) ++ } ++ k := &PublicKeyRSA{_pkey: pkey} ++ runtime.SetFinalizer(k, (*PublicKeyRSA).finalize) ++ return k, nil ++} ++ ++func (k *PublicKeyRSA) finalize() { ++ C.go_openssl_EVP_PKEY_free(k._pkey) ++} ++ ++func (k *PublicKeyRSA) withKey(f func(C.GO_EVP_PKEY_PTR) C.int) C.int { ++ // Because of the finalizer, any time _pkey is passed to cgo, that call must ++ // be followed by a call to runtime.KeepAlive, to make sure k is not ++ // collected (and finalized) before the cgo call returns. ++ defer runtime.KeepAlive(k) ++ return f(k._pkey) ++} ++ ++type PrivateKeyRSA struct { ++ // _pkey MUST NOT be accessed directly. Instead, use the withKey method. ++ _pkey C.GO_EVP_PKEY_PTR ++} ++ ++func NewPrivateKeyRSA(N, E, D, P, Q, Dp, Dq, Qinv BigInt) (*PrivateKeyRSA, error) { ++ var pkey C.GO_EVP_PKEY_PTR ++ switch vMajor { ++ case 1: ++ key := C.go_openssl_RSA_new() ++ if key == nil { ++ return nil, newOpenSSLError("RSA_new failed") ++ } ++ if !rsaSetKey(key, N, E, D) { ++ return nil, fail("RSA_set0_key") ++ } ++ if P != nil && Q != nil { ++ if !rsaSetFactors(key, P, Q) { ++ return nil, fail("RSA_set0_factors") ++ } ++ } ++ if Dp != nil && Dq != nil && Qinv != nil { ++ if !rsaSetCRTParams(key, Dp, Dq, Qinv) { ++ return nil, fail("RSA_set0_crt_params") ++ } ++ } ++ pkey = C.go_openssl_EVP_PKEY_new() ++ if pkey == nil { ++ C.go_openssl_RSA_free(key) ++ return nil, newOpenSSLError("EVP_PKEY_new failed") ++ } ++ if C.go_openssl_EVP_PKEY_assign(pkey, C.GO_EVP_PKEY_RSA, (unsafe.Pointer)(key)) != 1 { ++ C.go_openssl_RSA_free(key) ++ C.go_openssl_EVP_PKEY_free(pkey) ++ return nil, newOpenSSLError("EVP_PKEY_assign failed") ++ } ++ case 3: ++ var err error ++ if pkey, err = newRSAKey3(true, N, E, D, P, Q, Dp, Dq, Qinv); err != nil { ++ return nil, err ++ } ++ default: ++ panic(errUnsupportedVersion()) ++ } ++ k := &PrivateKeyRSA{_pkey: pkey} ++ runtime.SetFinalizer(k, (*PrivateKeyRSA).finalize) ++ return k, nil ++} ++ ++func (k *PrivateKeyRSA) finalize() { ++ C.go_openssl_EVP_PKEY_free(k._pkey) ++} ++ ++func (k *PrivateKeyRSA) withKey(f func(C.GO_EVP_PKEY_PTR) C.int) C.int { ++ // Because of the finalizer, any time _pkey is passed to cgo, that call must ++ // be followed by a call to runtime.KeepAlive, to make sure k is not ++ // collected (and finalized) before the cgo call returns. ++ defer runtime.KeepAlive(k) ++ return f(k._pkey) ++} ++ ++func DecryptRSAOAEP(h, mgfHash hash.Hash, priv *PrivateKeyRSA, ciphertext, label []byte) ([]byte, error) { ++ return evpDecrypt(priv.withKey, C.GO_RSA_PKCS1_OAEP_PADDING, h, mgfHash, label, ciphertext) ++} ++ ++func EncryptRSAOAEP(h, mgfHash hash.Hash, pub *PublicKeyRSA, msg, label []byte) ([]byte, error) { ++ return evpEncrypt(pub.withKey, C.GO_RSA_PKCS1_OAEP_PADDING, h, mgfHash, label, msg) +} + -+type sha3_224Hash struct { -+ *evpHash -+ out [224 / 8]byte ++func DecryptRSAPKCS1(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) { ++ return evpDecrypt(priv.withKey, C.GO_RSA_PKCS1_PADDING, nil, nil, nil, ciphertext) +} + -+func (h *sha3_224Hash) Sum(in []byte) []byte { -+ h.sum(h.out[:]) -+ return append(in, h.out[:]...) ++func EncryptRSAPKCS1(pub *PublicKeyRSA, msg []byte) ([]byte, error) { ++ return evpEncrypt(pub.withKey, C.GO_RSA_PKCS1_PADDING, nil, nil, nil, msg) +} + -+// NewSHA3_256 returns a new SHA3-256 hash. -+func NewSHA3_256() hash.Hash { -+ return &sha3_256Hash{ -+ evpHash: newEvpHash(crypto.SHA3_256, 256/8, 64), ++func DecryptRSANoPadding(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) { ++ ret, err := evpDecrypt(priv.withKey, C.GO_RSA_NO_PADDING, nil, nil, nil, ciphertext) ++ if err != nil { ++ return nil, err ++ } ++ // We could return here, but the Go standard library test expects DecryptRSANoPadding to verify the result ++ // in order to defend against errors in the CRT computation. ++ // ++ // The following code tries to replicate the verification implemented in the upstream function decryptAndCheck, found at ++ // https://github.com/golang/go/blob/9de1ac6ac2cad3871760d0aa288f5ca713afd0a6/src/crypto/rsa/rsa.go#L569-L582. ++ pub := &PublicKeyRSA{_pkey: priv._pkey} ++ // A private EVP_PKEY can be used as a public key as it contains the public information. ++ enc, err := EncryptRSANoPadding(pub, ret) ++ if err != nil { ++ return nil, err ++ } ++ // Upstream does not do a constant time comparison because it works with math/big instead of byte slices, ++ // and math/big does not support constant-time arithmetic yet. See #20654 for more info. ++ if subtle.ConstantTimeCompare(ciphertext, enc) != 1 { ++ return nil, errors.New("rsa: internal error") + } ++ return ret, nil +} + -+type sha3_256Hash struct { -+ *evpHash -+ out [256 / 8]byte ++func EncryptRSANoPadding(pub *PublicKeyRSA, msg []byte) ([]byte, error) { ++ return evpEncrypt(pub.withKey, C.GO_RSA_NO_PADDING, nil, nil, nil, msg) +} + -+func (h *sha3_256Hash) Sum(in []byte) []byte { -+ h.sum(h.out[:]) -+ return append(in, h.out[:]...) ++func saltLength(saltLen int, sign bool) (C.int, error) { ++ // A salt length of -2 is valid in OpenSSL, but not in crypto/rsa, so reject ++ // it, and lengths < -2, before we convert to the OpenSSL sentinel values. ++ if saltLen <= -2 { ++ return 0, errors.New("crypto/rsa: PSSOptions.SaltLength cannot be negative") ++ } ++ // OpenSSL uses sentinel salt length values like Go crypto does, ++ // but the values don't fully match for rsa.PSSSaltLengthAuto (0). ++ if saltLen == 0 { ++ if sign { ++ if vMajor == 1 { ++ // OpenSSL 1.x uses -2 to mean maximal size when signing where Go crypto uses 0. ++ return C.GO_RSA_PSS_SALTLEN_MAX_SIGN, nil ++ } ++ // OpenSSL 3.x deprecated RSA_PSS_SALTLEN_MAX_SIGN ++ // and uses -3 to mean maximal size when signing where Go crypto uses 0. ++ return C.GO_RSA_PSS_SALTLEN_MAX, nil ++ } ++ // OpenSSL uses -2 to mean auto-detect size when verifying where Go crypto uses 0. ++ return C.GO_RSA_PSS_SALTLEN_AUTO, nil ++ } ++ return C.int(saltLen), nil +} + -+// NewSHA3_384 returns a new SHA3-384 hash. -+func NewSHA3_384() hash.Hash { -+ return &sha3_384Hash{ -+ evpHash: newEvpHash(crypto.SHA3_384, 384/8, 128), ++func SignRSAPSS(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte, saltLen int) ([]byte, error) { ++ cSaltLen, err := saltLength(saltLen, true) ++ if err != nil { ++ return nil, err + } ++ return evpSign(priv.withKey, C.GO_RSA_PKCS1_PSS_PADDING, cSaltLen, h, hashed) +} + -+type sha3_384Hash struct { -+ *evpHash -+ out [384 / 8]byte ++func VerifyRSAPSS(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte, saltLen int) error { ++ cSaltLen, err := saltLength(saltLen, false) ++ if err != nil { ++ return err ++ } ++ return evpVerify(pub.withKey, C.GO_RSA_PKCS1_PSS_PADDING, cSaltLen, h, sig, hashed) +} + -+func (h *sha3_384Hash) Sum(in []byte) []byte { -+ h.sum(h.out[:]) -+ return append(in, h.out[:]...) ++func SignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte) ([]byte, error) { ++ return evpSign(priv.withKey, C.GO_RSA_PKCS1_PADDING, 0, h, hashed) +} + -+// NewSHA3_512 returns a new SHA3-512 hash. -+func NewSHA3_512() hash.Hash { -+ return &sha3_512Hash{ -+ evpHash: newEvpHash(crypto.SHA3_512, 512/8, 128), ++func HashSignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, msg []byte) ([]byte, error) { ++ return evpHashSign(priv.withKey, h, msg) ++} ++ ++func VerifyRSAPKCS1v15(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte) error { ++ if pub.withKey(func(pkey C.GO_EVP_PKEY_PTR) C.int { ++ size := C.go_openssl_EVP_PKEY_get_size(pkey) ++ if len(sig) < int(size) { ++ return 0 ++ } ++ return 1 ++ }) == 0 { ++ return errors.New("crypto/rsa: verification error") + } ++ return evpVerify(pub.withKey, C.GO_RSA_PKCS1_PADDING, 0, h, sig, hashed) +} + -+type sha3_512Hash struct { -+ *evpHash -+ out [512 / 8]byte ++func HashVerifyRSAPKCS1v15(pub *PublicKeyRSA, h crypto.Hash, msg, sig []byte) error { ++ return evpHashVerify(pub.withKey, h, msg, sig) +} + -+func (h *sha3_512Hash) Sum(in []byte) []byte { -+ h.sum(h.out[:]) -+ return append(in, h.out[:]...) ++// rsa_st_1_0_2 is rsa_st memory layout in OpenSSL 1.0.2. ++type rsa_st_1_0_2 struct { ++ _ C.int ++ _ C.long ++ _ [2]unsafe.Pointer ++ n, e, d C.GO_BIGNUM_PTR ++ p, q C.GO_BIGNUM_PTR ++ dmp1, dmq1, iqmp C.GO_BIGNUM_PTR ++ // It contains more fields, but we are not interesed on them. +} + -+// appendUint64 appends x into b as a big endian byte sequence. -+func appendUint64(b []byte, x uint64) []byte { -+ return append(b, -+ byte(x>>56), -+ byte(x>>48), -+ byte(x>>40), -+ byte(x>>32), -+ byte(x>>24), -+ byte(x>>16), -+ byte(x>>8), -+ byte(x), -+ ) ++func bnSet(b1 *C.GO_BIGNUM_PTR, b2 BigInt) { ++ if b2 == nil { ++ return ++ } ++ if *b1 != nil { ++ C.go_openssl_BN_clear_free(*b1) ++ } ++ *b1 = bigToBN(b2) +} + -+// appendUint32 appends x into b as a big endian byte sequence. -+func appendUint32(b []byte, x uint32) []byte { -+ return append(b, byte(x>>24), byte(x>>16), byte(x>>8), byte(x)) ++func rsaSetKey(key C.GO_RSA_PTR, n, e, d BigInt) bool { ++ if vMajor == 1 && vMinor == 0 { ++ r := (*rsa_st_1_0_2)(unsafe.Pointer(key)) ++ //r.d and d will be nil for public keys. ++ if (r.n == nil && n == nil) || ++ (r.e == nil && e == nil) { ++ return false ++ } ++ bnSet(&r.n, n) ++ bnSet(&r.e, e) ++ bnSet(&r.d, d) ++ return true ++ } ++ return C.go_openssl_RSA_set0_key(key, bigToBN(n), bigToBN(e), bigToBN(d)) == 1 +} + -+// consumeUint64 reads a big endian uint64 number from b. -+func consumeUint64(b []byte) ([]byte, uint64) { -+ _ = b[7] -+ x := uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 | -+ uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56 -+ return b[8:], x ++func rsaSetFactors(key C.GO_RSA_PTR, p, q BigInt) bool { ++ if vMajor == 1 && vMinor == 0 { ++ r := (*rsa_st_1_0_2)(unsafe.Pointer(key)) ++ if (r.p == nil && p == nil) || ++ (r.q == nil && q == nil) { ++ return false ++ } ++ bnSet(&r.p, p) ++ bnSet(&r.q, q) ++ return true ++ } ++ return C.go_openssl_RSA_set0_factors(key, bigToBN(p), bigToBN(q)) == 1 +} + -+// consumeUint32 reads a big endian uint32 number from b. -+func consumeUint32(b []byte) ([]byte, uint32) { -+ _ = b[3] -+ x := uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24 -+ return b[4:], x ++func rsaSetCRTParams(key C.GO_RSA_PTR, dmp1, dmq1, iqmp BigInt) bool { ++ if vMajor == 1 && vMinor == 0 { ++ r := (*rsa_st_1_0_2)(unsafe.Pointer(key)) ++ if (r.dmp1 == nil && dmp1 == nil) || ++ (r.dmq1 == nil && dmq1 == nil) || ++ (r.iqmp == nil && iqmp == nil) { ++ return false ++ } ++ bnSet(&r.dmp1, dmp1) ++ bnSet(&r.dmq1, dmq1) ++ bnSet(&r.iqmp, iqmp) ++ return true ++ } ++ return C.go_openssl_RSA_set0_crt_params(key, bigToBN(dmp1), bigToBN(dmq1), bigToBN(iqmp)) == 1 ++} ++ ++func newRSAKey3(isPriv bool, N, E, D, P, Q, Dp, Dq, Qinv BigInt) (C.GO_EVP_PKEY_PTR, error) { ++ // Construct the parameters. ++ bld := C.go_openssl_OSSL_PARAM_BLD_new() ++ if bld == nil { ++ return nil, newOpenSSLError("OSSL_PARAM_BLD_new") ++ } ++ defer C.go_openssl_OSSL_PARAM_BLD_free(bld) ++ var comps = [...]struct { ++ name *C.char ++ num BigInt ++ }{ ++ {paramRSA_N, N}, {paramRSA_E, E}, {paramRSA_D, D}, ++ {paramRSA_P, P}, {paramRSA_Q, Q}, ++ {paramRSA_Dp, Dp}, {paramRSA_Dq, Dq}, {paramRSA_Qinv, Qinv}, ++ } ++ for _, comp := range comps { ++ if comp.num == nil { ++ continue ++ } ++ b := bigToBN(comp.num) ++ if b == nil { ++ return nil, newOpenSSLError("BN_lebin2bn failed") ++ } ++ // b must remain valid until OSSL_PARAM_BLD_to_param has been called. ++ defer C.go_openssl_BN_clear_free(b) ++ if C.go_openssl_OSSL_PARAM_BLD_push_BN(bld, comp.name, b) != 1 { ++ return nil, newOpenSSLError("OSSL_PARAM_BLD_push_BN") ++ } ++ } ++ params := C.go_openssl_OSSL_PARAM_BLD_to_param(bld) ++ if params == nil { ++ return nil, newOpenSSLError("OSSL_PARAM_BLD_to_param") ++ } ++ defer C.go_openssl_OSSL_PARAM_free(params) ++ selection := C.GO_EVP_PKEY_PUBLIC_KEY ++ if isPriv { ++ selection = C.GO_EVP_PKEY_KEYPAIR ++ } ++ return newEvpFromParams(C.GO_EVP_PKEY_RSA, C.int(selection), params) +} diff --git a/src/vendor/github.com/golang-fips/openssl/v2/shims.h b/src/vendor/github.com/golang-fips/openssl/v2/shims.h new file mode 100644 -index 0000000000..47d8724e32 +index 0000000000..4457a3e491 --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/shims.h -@@ -0,0 +1,357 @@ +@@ -0,0 +1,370 @@ +#include // size_t +#include // uint64_t + @@ -8290,12 +8928,6 @@ index 0000000000..47d8724e32 + GO_OPENSSL_INIT_LOAD_CONFIG = 0x00000040L +}; + -+// #include -+enum { -+ GO_AES_ENCRYPT = 1, -+ GO_AES_DECRYPT = 0 -+}; -+ +// #include +enum { + GO_EVP_CTRL_GCM_GET_TAG = 0x10, @@ -8305,6 +8937,7 @@ index 0000000000..47d8724e32 + GO_EVP_PKEY_EC = 408, + GO_EVP_PKEY_TLS1_PRF = 1021, + GO_EVP_PKEY_HKDF = 1036, ++ GO_EVP_PKEY_ED25519 = 1087, + /* This is defined differently in OpenSSL 3 (1 << 11), but in our + * code it is only used in OpenSSL 1. + */ @@ -8387,6 +9020,7 @@ index 0000000000..47d8724e32 +typedef void* GO_OSSL_PARAM_BLD_PTR; +typedef void* GO_OSSL_PARAM_PTR; +typedef void* GO_CRYPTO_THREADID_PTR; ++typedef void* GO_EVP_SIGNATURE_PTR; + +// #include +typedef void* GO_MD5_CTX_PTR; @@ -8486,10 +9120,12 @@ index 0000000000..47d8724e32 +DEFINEFUNC(int, EVP_DigestInit, (GO_EVP_MD_CTX_PTR ctx, const GO_EVP_MD_PTR type), (ctx, type)) \ +DEFINEFUNC(int, EVP_DigestUpdate, (GO_EVP_MD_CTX_PTR ctx, const void *d, size_t cnt), (ctx, d, cnt)) \ +DEFINEFUNC(int, EVP_DigestFinal, (GO_EVP_MD_CTX_PTR ctx, unsigned char *md, unsigned int *s), (ctx, md, s)) \ ++DEFINEFUNC_1_1_1(int, EVP_DigestSign, (GO_EVP_MD_CTX_PTR ctx, unsigned char *sigret, size_t *siglen, const unsigned char *tbs, size_t tbslen), (ctx, sigret, siglen, tbs, tbslen)) \ +DEFINEFUNC(int, EVP_DigestSignInit, (GO_EVP_MD_CTX_PTR ctx, GO_EVP_PKEY_CTX_PTR *pctx, const GO_EVP_MD_PTR type, GO_ENGINE_PTR e, GO_EVP_PKEY_PTR pkey), (ctx, pctx, type, e, pkey)) \ +DEFINEFUNC(int, EVP_DigestSignFinal, (GO_EVP_MD_CTX_PTR ctx, unsigned char *sig, size_t *siglen), (ctx, sig, siglen)) \ +DEFINEFUNC(int, EVP_DigestVerifyInit, (GO_EVP_MD_CTX_PTR ctx, GO_EVP_PKEY_CTX_PTR *pctx, const GO_EVP_MD_PTR type, GO_ENGINE_PTR e, GO_EVP_PKEY_PTR pkey), (ctx, pctx, type, e, pkey)) \ +DEFINEFUNC(int, EVP_DigestVerifyFinal, (GO_EVP_MD_CTX_PTR ctx, const unsigned char *sig, size_t siglen), (ctx, sig, siglen)) \ ++DEFINEFUNC_1_1_1(int, EVP_DigestVerify, (GO_EVP_MD_CTX_PTR ctx, const unsigned char *sigret, size_t siglen, const unsigned char *tbs, size_t tbslen), (ctx, sigret, siglen, tbs, tbslen)) \ +DEFINEFUNC_LEGACY_1_0(int, MD5_Init, (GO_MD5_CTX_PTR c), (c)) \ +DEFINEFUNC_LEGACY_1_0(int, MD5_Update, (GO_MD5_CTX_PTR c, const void *data, size_t len), (c, data, len)) \ +DEFINEFUNC_LEGACY_1_0(int, MD5_Final, (unsigned char *md, GO_MD5_CTX_PTR c), (md, c)) \ @@ -8497,6 +9133,7 @@ index 0000000000..47d8724e32 +DEFINEFUNC_LEGACY_1_0(int, SHA1_Update, (GO_SHA_CTX_PTR c, const void *data, size_t len), (c, data, len)) \ +DEFINEFUNC_LEGACY_1_0(int, SHA1_Final, (unsigned char *md, GO_SHA_CTX_PTR c), (md, c)) \ +DEFINEFUNC_1_1(const GO_EVP_MD_PTR, EVP_md5_sha1, (void), ()) \ ++DEFINEFUNC(const GO_EVP_MD_PTR, EVP_md4, (void), ()) \ +DEFINEFUNC(const GO_EVP_MD_PTR, EVP_md5, (void), ()) \ +DEFINEFUNC(const GO_EVP_MD_PTR, EVP_sha1, (void), ()) \ +DEFINEFUNC(const GO_EVP_MD_PTR, EVP_sha224, (void), ()) \ @@ -8522,6 +9159,7 @@ index 0000000000..47d8724e32 +DEFINEFUNC(int, EVP_EncryptInit_ex, (GO_EVP_CIPHER_CTX_PTR ctx, const GO_EVP_CIPHER_PTR type, GO_ENGINE_PTR impl, const unsigned char *key, const unsigned char *iv), (ctx, type, impl, key, iv)) \ +DEFINEFUNC(int, EVP_EncryptUpdate, (GO_EVP_CIPHER_CTX_PTR ctx, unsigned char *out, int *outl, const unsigned char *in, int inl), (ctx, out, outl, in, inl)) \ +DEFINEFUNC(int, EVP_EncryptFinal_ex, (GO_EVP_CIPHER_CTX_PTR ctx, unsigned char *out, int *outl), (ctx, out, outl)) \ ++DEFINEFUNC(int, EVP_DecryptInit_ex, (GO_EVP_CIPHER_CTX_PTR ctx, const GO_EVP_CIPHER_PTR type, GO_ENGINE_PTR impl, const unsigned char *key, const unsigned char *iv), (ctx, type, impl, key, iv)) \ +DEFINEFUNC(int, EVP_DecryptUpdate, (GO_EVP_CIPHER_CTX_PTR ctx, unsigned char *out, int *outl, const unsigned char *in, int inl), (ctx, out, outl, in, inl)) \ +DEFINEFUNC(int, EVP_DecryptFinal_ex, (GO_EVP_CIPHER_CTX_PTR ctx, unsigned char *outm, int *outl), (ctx, outm, outl)) \ +DEFINEFUNC_3_0(GO_EVP_CIPHER_PTR, EVP_CIPHER_fetch, (GO_OSSL_LIB_CTX_PTR ctx, const char *algorithm, const char *properties), (ctx, algorithm, properties)) \ @@ -8538,9 +9176,18 @@ index 0000000000..47d8724e32 +DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_256_ctr, (void), ()) \ +DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_256_ecb, (void), ()) \ +DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_256_gcm, (void), ()) \ ++DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_des_ecb, (void), ()) \ ++DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_des_cbc, (void), ()) \ ++DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_des_ede3_ecb, (void), ()) \ ++DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_des_ede3_cbc, (void), ()) \ ++DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_rc4, (void), ()) \ ++DEFINEFUNC_RENAMED_3_0(int, EVP_CIPHER_get_block_size, EVP_CIPHER_block_size, (const GO_EVP_CIPHER_PTR cipher), (cipher)) \ ++DEFINEFUNC(int, EVP_CIPHER_CTX_set_key_length, (GO_EVP_CIPHER_CTX_PTR x, int keylen), (x, keylen)) \ +DEFINEFUNC(void, EVP_CIPHER_CTX_free, (GO_EVP_CIPHER_CTX_PTR arg0), (arg0)) \ +DEFINEFUNC(int, EVP_CIPHER_CTX_ctrl, (GO_EVP_CIPHER_CTX_PTR ctx, int type, int arg, void *ptr), (ctx, type, arg, ptr)) \ +DEFINEFUNC(GO_EVP_PKEY_PTR, EVP_PKEY_new, (void), ()) \ ++DEFINEFUNC_1_1_1(GO_EVP_PKEY_PTR, EVP_PKEY_new_raw_private_key, (int type, GO_ENGINE_PTR e, const unsigned char *key, size_t keylen), (type, e, key, keylen)) \ ++DEFINEFUNC_1_1_1(GO_EVP_PKEY_PTR, EVP_PKEY_new_raw_public_key, (int type, GO_ENGINE_PTR e, const unsigned char *key, size_t keylen), (type, e, key, keylen)) \ +/* EVP_PKEY_size and EVP_PKEY_get_bits pkey parameter is const since OpenSSL 1.1.1. */ \ +/* Exclude it from headercheck tool when using previous OpenSSL versions. */ \ +/*check:from=1.1.1*/ DEFINEFUNC_RENAMED_3_0(int, EVP_PKEY_get_size, EVP_PKEY_size, (const GO_EVP_PKEY_PTR pkey), (pkey)) \ @@ -8635,6 +9282,10 @@ index 0000000000..47d8724e32 +DEFINEFUNC_3_0(int, EVP_PKEY_CTX_set_tls1_prf_md, (GO_EVP_PKEY_CTX_PTR arg0, const GO_EVP_MD_PTR arg1), (arg0, arg1)) \ +DEFINEFUNC_3_0(int, EVP_PKEY_CTX_set1_tls1_prf_secret, (GO_EVP_PKEY_CTX_PTR arg0, const unsigned char *arg1, int arg2), (arg0, arg1, arg2)) \ +DEFINEFUNC_3_0(int, EVP_PKEY_CTX_add1_tls1_prf_seed, (GO_EVP_PKEY_CTX_PTR arg0, const unsigned char *arg1, int arg2), (arg0, arg1, arg2)) \ ++DEFINEFUNC_1_1_1(int, EVP_PKEY_get_raw_public_key, (const GO_EVP_PKEY_PTR pkey, unsigned char *pub, size_t *len), (pkey, pub, len)) \ ++DEFINEFUNC_1_1_1(int, EVP_PKEY_get_raw_private_key, (const GO_EVP_PKEY_PTR pkey, unsigned char *priv, size_t *len), (pkey, priv, len)) \ ++DEFINEFUNC_3_0(GO_EVP_SIGNATURE_PTR, EVP_SIGNATURE_fetch, (GO_OSSL_LIB_CTX_PTR ctx, const char *algorithm, const char *properties), (ctx, algorithm, properties)) \ ++DEFINEFUNC_3_0(void, EVP_SIGNATURE_free, (GO_EVP_SIGNATURE_PTR signature), (signature)) \ + diff --git a/src/vendor/github.com/golang-fips/openssl/v2/thread_setup_unix.c b/src/vendor/github.com/golang-fips/openssl/v2/thread_setup_unix.c new file mode 100644 @@ -8718,10 +9369,10 @@ index 0000000000..7bc66d8014 +} diff --git a/src/vendor/github.com/golang-fips/openssl/v2/tls1prf.go b/src/vendor/github.com/golang-fips/openssl/v2/tls1prf.go new file mode 100644 -index 0000000000..7043b3bc1d +index 0000000000..3153fc81ec --- /dev/null +++ b/src/vendor/github.com/golang-fips/openssl/v2/tls1prf.go -@@ -0,0 +1,98 @@ +@@ -0,0 +1,104 @@ +//go:build !cmd_go_bootstrap + +package openssl @@ -8740,7 +9391,10 @@ index 0000000000..7043b3bc1d + (vMajor >= 1 && vMinor >= 1) +} + -+func TLS1PRF(secret, label, seed []byte, keyLen int, h func() hash.Hash) ([]byte, error) { ++// TLS1PRF implements the TLS 1.0/1.1 pseudo-random function if h is nil, ++// else it implements the TLS 1.2 pseudo-random function. ++// The pseudo-random number will be written to result and will be of length len(result). ++func TLS1PRF(result, secret, label, seed []byte, h func() hash.Hash) error { + var md C.GO_EVP_MD_PTR + if h == nil { + // TLS 1.0/1.1 PRF doesn't allow to specify the hash function, @@ -8753,79 +9407,82 @@ index 0000000000..7043b3bc1d + md = hashToMD(h()) + } + if md == nil { -+ return nil, errors.New("unsupported hash function") ++ return errors.New("unsupported hash function") + } + + ctx := C.go_openssl_EVP_PKEY_CTX_new_id(C.GO_EVP_PKEY_TLS1_PRF, nil) + if ctx == nil { -+ return nil, newOpenSSLError("EVP_PKEY_CTX_new_id") ++ return newOpenSSLError("EVP_PKEY_CTX_new_id") + } + defer func() { + C.go_openssl_EVP_PKEY_CTX_free(ctx) + }() + + if C.go_openssl_EVP_PKEY_derive_init(ctx) != 1 { -+ return nil, newOpenSSLError("EVP_PKEY_derive_init") ++ return newOpenSSLError("EVP_PKEY_derive_init") + } + switch vMajor { + case 3: + if C.go_openssl_EVP_PKEY_CTX_set_tls1_prf_md(ctx, md) != 1 { -+ return nil, newOpenSSLError("EVP_PKEY_CTX_set_tls1_prf_md") ++ return newOpenSSLError("EVP_PKEY_CTX_set_tls1_prf_md") + } + if C.go_openssl_EVP_PKEY_CTX_set1_tls1_prf_secret(ctx, + base(secret), C.int(len(secret))) != 1 { -+ return nil, newOpenSSLError("EVP_PKEY_CTX_set1_tls1_prf_secret") ++ return newOpenSSLError("EVP_PKEY_CTX_set1_tls1_prf_secret") + } + if C.go_openssl_EVP_PKEY_CTX_add1_tls1_prf_seed(ctx, + base(label), C.int(len(label))) != 1 { -+ return nil, newOpenSSLError("EVP_PKEY_CTX_add1_tls1_prf_seed") ++ return newOpenSSLError("EVP_PKEY_CTX_add1_tls1_prf_seed") + } + if C.go_openssl_EVP_PKEY_CTX_add1_tls1_prf_seed(ctx, + base(seed), C.int(len(seed))) != 1 { -+ return nil, newOpenSSLError("EVP_PKEY_CTX_add1_tls1_prf_seed") ++ return newOpenSSLError("EVP_PKEY_CTX_add1_tls1_prf_seed") + } + case 1: + if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, + C.GO1_EVP_PKEY_OP_DERIVE, + C.GO_EVP_PKEY_CTRL_TLS_MD, + 0, unsafe.Pointer(md)) != 1 { -+ return nil, newOpenSSLError("EVP_PKEY_CTX_set_tls1_prf_md") ++ return newOpenSSLError("EVP_PKEY_CTX_set_tls1_prf_md") + } + if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, + C.GO1_EVP_PKEY_OP_DERIVE, + C.GO_EVP_PKEY_CTRL_TLS_SECRET, + C.int(len(secret)), unsafe.Pointer(base(secret))) != 1 { -+ return nil, newOpenSSLError("EVP_PKEY_CTX_set1_tls1_prf_secret") ++ return newOpenSSLError("EVP_PKEY_CTX_set1_tls1_prf_secret") + } + if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, + C.GO1_EVP_PKEY_OP_DERIVE, + C.GO_EVP_PKEY_CTRL_TLS_SEED, + C.int(len(label)), unsafe.Pointer(base(label))) != 1 { -+ return nil, newOpenSSLError("EVP_PKEY_CTX_add1_tls1_prf_seed") ++ return newOpenSSLError("EVP_PKEY_CTX_add1_tls1_prf_seed") + } + if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, + C.GO1_EVP_PKEY_OP_DERIVE, + C.GO_EVP_PKEY_CTRL_TLS_SEED, + C.int(len(seed)), unsafe.Pointer(base(seed))) != 1 { -+ return nil, newOpenSSLError("EVP_PKEY_CTX_add1_tls1_prf_seed") ++ return newOpenSSLError("EVP_PKEY_CTX_add1_tls1_prf_seed") + } + } -+ outLen := C.size_t(keyLen) -+ out := make([]byte, outLen) -+ if C.go_openssl_EVP_PKEY_derive(ctx, base(out), &outLen) != 1 { -+ return nil, newOpenSSLError("EVP_PKEY_derive") ++ outLen := C.size_t(len(result)) ++ if C.go_openssl_EVP_PKEY_derive(ctx, base(result), &outLen) != 1 { ++ return newOpenSSLError("EVP_PKEY_derive") + } -+ if outLen != C.size_t(keyLen) { -+ return nil, errors.New("tls1-prf: entropy limit reached") ++ // The Go standard library expects TLS1PRF to return the requested number of bytes, ++ // fail if it doesn't. While there is no known situation where this will happen, ++ // EVP_PKEY_derive handles multiple algorithms and there could be a subtle mismatch ++ // after more code changes in the future. ++ if outLen != C.size_t(len(result)) { ++ return errors.New("tls1-prf: derived less bytes than requested") + } -+ return out[:outLen], nil ++ return nil +} diff --git a/src/vendor/modules.txt b/src/vendor/modules.txt -index 2b5f965f8f..4d1ce8b9cf 100644 +index 2b5f965f8f..e197225afa 100644 --- a/src/vendor/modules.txt +++ b/src/vendor/modules.txt @@ -1,3 +1,7 @@ -+# github.com/golang-fips/openssl/v2 v2.0.0-rc.2.0.20230825145541-7544e9a0711b ++# github.com/golang-fips/openssl/v2 v2.0.0-rc.3.0.20231108174110-41b6eb24da28 +## explicit; go 1.20 +github.com/golang-fips/openssl/v2 +github.com/golang-fips/openssl/v2/bbig diff --git a/patches/008-fixes-5.patch b/patches/008-fixes-5.patch new file mode 100644 index 0000000000..d87ef9d8e5 --- /dev/null +++ b/patches/008-fixes-5.patch @@ -0,0 +1,61 @@ +From 6640803d938b82efd32da6459b8f1ee53df5a180 Mon Sep 17 00:00:00 2001 +From: Daiki Ueno +Date: Mon, 16 Oct 2023 12:22:50 +0900 +Subject: [PATCH] crypto/rsa: use SHA256 instead of SHA1 in PKCS#1 v1.5 tests + +This switches to unconditionally using SHA256 for PKCS#1 v1.5 signing +and verification in tests, to pacify errors in FIPS mode. + +Signed-off-by: Daiki Ueno +--- + src/crypto/rsa/pkcs1v15_test.go | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +diff --git a/src/crypto/rsa/pkcs1v15_test.go b/src/crypto/rsa/pkcs1v15_test.go +index 0853178e3ab7b..3db1e94ffff2b 100644 +--- a/src/crypto/rsa/pkcs1v15_test.go ++++ b/src/crypto/rsa/pkcs1v15_test.go +@@ -11,7 +11,6 @@ import ( + "crypto/internal/backend/boringtest" + "crypto/rand" + . "crypto/rsa" +- "crypto/sha1" + "crypto/sha256" + "crypto/x509" + "encoding/base64" +@@ -210,16 +209,16 @@ type signPKCS1v15Test struct { + // + // `openssl rsautl -verify -inkey pk -in signature | hexdump -C` + var signPKCS1v15Tests = []signPKCS1v15Test{ +- {"Test.\n", "0c7c85d938862248846cba06b06ac9bfe752aafed3092c224f257855006aa35b43d101e6c8e59cbc4c20b07c81552963f189dea700e042d4b70c236a031a29a9273cc138e69dc1a5834491de4822d8cb6acf218789d2586cb0f3892236b0948ffaf8691f6fa04597caa45068f9be39b8ea8b5336a8c94e2696f872120778abcfea711e5fbf75f835f0f5204ccdd020013c2ceae25e9d1378a1d10cf86ca269eef48fee8ebb5e8dfb08f0c48d22d1a7162e080ec1f6e48541288aaaa1f2370f0688cf1786a32abed41df1d3b96b665794bf7a772743fc8b62d73901cea4569494c794a01ccc7dda0d42199f5b58739c0c0e280774b56ccf51993f5ea3d4954319"}, ++ {"Test.\n", "0c7da2fe34372c9e433ca668b6edf4cd7f7eb29f11c11c44d99cb6dc6fe4344cc656075015de6d0249d25b6e01bf22276e9f97f6e64f5905ce96cfc69e3c30e3813eb80553b1e53993482b97c920d030e1daf6c5f11f532a166a4b4aea34c6f8ed5579ccf6bfd5e20250d1979e97c358363da8ae15a095f07e9c54bfb948a94a75a6c8a0cbe4b9970d780ddf49369b2f134915e9a8ccf20e7b07981d0b95978630ee754f20bad163cdcff8c56c9bc66fd1060961779f1554894597086477d15346955d1a1c67d9718c4d25d840cf83fe203fd4e5681fc388a0395b79b94b1ade281f3682fb08a02ed6fa209caf489e9ccf501a86e99a36737b241c1e8ab2c2a4"}, + } + + func TestSignPKCS1v15(t *testing.T) { + for i, test := range signPKCS1v15Tests { +- h := sha1.New() ++ h := sha256.New() + h.Write([]byte(test.in)) + digest := h.Sum(nil) + +- s, err := SignPKCS1v15(nil, boringRsaPrivateKey, crypto.SHA1, digest) ++ s, err := SignPKCS1v15(nil, boringRsaPrivateKey, crypto.SHA256, digest) + if err != nil { + t.Errorf("#%d %s", i, err) + } +@@ -233,13 +232,13 @@ func TestSignPKCS1v15(t *testing.T) { + + func TestVerifyPKCS1v15(t *testing.T) { + for i, test := range signPKCS1v15Tests { +- h := sha1.New() ++ h := sha256.New() + h.Write([]byte(test.in)) + digest := h.Sum(nil) + + sig, _ := hex.DecodeString(test.out) + +- err := VerifyPKCS1v15(&boringRsaPrivateKey.PublicKey, crypto.SHA1, digest, sig) ++ err := VerifyPKCS1v15(&boringRsaPrivateKey.PublicKey, crypto.SHA256, digest, sig) + if err != nil { + t.Errorf("#%d %s", i, err) + } diff --git a/patches/009-fixes-6.patch b/patches/009-fixes-6.patch new file mode 100644 index 0000000000..c28216cce5 --- /dev/null +++ b/patches/009-fixes-6.patch @@ -0,0 +1,96 @@ +From 662ae4c37854734b17b095a36e42a8bbbcd85338 Mon Sep 17 00:00:00 2001 +From: Daiki Ueno +Date: Mon, 16 Oct 2023 12:25:26 +0900 +Subject: [PATCH] crypto/x509: adjust tests to pass under FIPS + +This fixes the following issues: + + --- FAIL: TestImports (0.93s) + x509_test.go:1411: failed to run x509_test_import.go: exit status 1 + panic: failed to create certificate with basic imports: EVP_PKEY_sign_init failed + openssl error(s): + error:1C800069:Provider routines::invalid key length + providers/common/securitycheck.c:67 + + goroutine 1 [running]: + main.main() + /__w/go/go/go/src/crypto/x509/x509_test_import.go:41 +0x205 + exit status 2 + --- FAIL: TestDisableSHA1ForCertOnly (0.00s) + x509_test.go:3653: failed to generate test cert: EVP_PKEY_fromdata + openssl error(s): + +The former was using too short RSA key (512 bits), while the latter +should be skipped when SHA1 signatures are not supported. + +Signed-off-by: Daiki Ueno +--- + src/crypto/x509/x509_test.go | 3 +++ + src/crypto/x509/x509_test_import.go | 40 +++++++++++++++++++++++------ + 2 files changed, 35 insertions(+), 8 deletions(-) + +diff --git a/src/crypto/x509/x509_test.go b/src/crypto/x509/x509_test.go +index 6621f1b8cc304..356528e69cc36 100644 +--- a/src/crypto/x509/x509_test.go ++++ b/src/crypto/x509/x509_test.go +@@ -3637,6 +3637,9 @@ func TestParseUniqueID(t *testing.T) { + } + + func TestDisableSHA1ForCertOnly(t *testing.T) { ++ if boring.Enabled() && !boringtest.Supports(t, "SHA1") { ++ t.Skip("unsupported in FIPS mode") ++ } + t.Setenv("GODEBUG", "") + + tmpl := &Certificate{ +diff --git a/src/crypto/x509/x509_test_import.go b/src/crypto/x509/x509_test_import.go +index 2474e3d810edf..492cb0a87554c 100644 +--- a/src/crypto/x509/x509_test_import.go ++++ b/src/crypto/x509/x509_test_import.go +@@ -42,14 +42,38 @@ func main() { + } + } + +-var pemPrivateKey = testingKey(`-----BEGIN RSA TESTING KEY----- +-MIIBOgIBAAJBALKZD0nEffqM1ACuak0bijtqE2QrI/KLADv7l3kK3ppMyCuLKoF0 +-fd7Ai2KW5ToIwzFofvJcS/STa6HA5gQenRUCAwEAAQJBAIq9amn00aS0h/CrjXqu +-/ThglAXJmZhOMPVn4eiu7/ROixi9sex436MaVeMqSNf7Ex9a8fRNfWss7Sqd9eWu +-RTUCIQDasvGASLqmjeffBNLTXV2A5g4t+kLVCpsEIZAycV5GswIhANEPLmax0ME/ +-EO+ZJ79TJKN5yiGBRsv5yvx5UiHxajEXAiAhAol5N4EUyq6I9w1rYdhPMGpLfk7A +-IU2snfRJ6Nq2CQIgFrPsWRCkV+gOYcajD17rEqmuLrdIRexpg8N1DOSXoJ8CIGlS +-tAboUGBxTDq3ZroNism3DaMIbKPyYrAqhKov1h5V ++// This key is generated with the following command: ++// ++// openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out key.pem ++// openssl pkey -traditional -in key.pem > key-traditional.pem ++// ++var pemPrivateKey = testingKey(` ++-----BEGIN RSA TESTING KEY----- ++MIIEogIBAAKCAQEAp5qgUIj096pw8U+AjcJucLWenR3oe+tEthXiAuqcYgslW5UU ++lMim34U/h7NbLvbG2KJ2chUsmLtuCFaoIe/YKW5DKm3SPytK/KCBsVa+MQ7zuF/1 ++ks5p7yBqFBl6QTekMzwskt/zyDIG9f3A+38akruHNBvUgYqwbWPx4ycclQ52GSev ++/Cfx0I68TGT5SwN/eCJ/ghq3iGAf0mX1bkVaW1seKbL49aAA94KnDCRdl813+S2R ++EPDf2tZwlT0JpZm5QtAqthonZjkjHocZNxhkKF3XWUntE/+l6R4A+CWZlC2vmUc1 ++hJTEraksy2JUIjxAaq//FnDpIEVG/N2ofmNpaQIDAQABAoIBAAYH7h9fwkLcNvqz ++8+oF9k/ndSjtr9UvstYDhRG6S/zKLmK0g1xUOQ7/fjj9lvkiZ6bZd74krWlkizHR ++HnU0KnjZLyEKeR+NSQI8q1YMi0T8JwB6MX3CIDU62x5UiV3p6OZwEqGJXf4U8MOu ++ySAzo2rmxRd2reeobC9Pgp98I47oeqaSRwFVZRPfKk5RvfI7KRmL58BAB0XS56PA ++PJ+3l0fB/oIV11iaBEKildxLDtrvlepQ2KPNf7Dpk0/CPRtS/jxyxIyML8tjR3F0 ++KuHplsRjTANyzW/aHddO1fnfnXsVo+0PzSPTHCbxKSu5XmChqsKoB1jM+/tJci4y ++ST5hUXUCgYEAzfA5XEMkR/NNJMfR+FBbdfpQ1b0wqH3qtWZx/tBjKC2Y0XnDQ8ZR ++SEWONLVZMRtTlJaHIPZ9i6anQRR5harrff0OpsKiJUGDout8ehE6eiN8ABWGNlCI ++AiLCerVJZMDcSuDU7xsdHVIdSxYh88Z9g54vUQ4214BG/G0Qm1emV3UCgYEA0FjP ++wq5cEGt9xDCg+oXk0bLm4Wn4FkabJH7M+oCosHHY9W1vgvv50bpNoAbaB5r1mlan ++T6gEtkQPB2juMTnuIwRL+kvOmSKqZGlAsyrq8smTuBUv7brbybkYN3Rg51KV6u1J ++vCdGpMYWHUNRkkQ88cr6iFPodYU+CzRR4ABif6UCgYBc0jDYb/7TW0tjD5mJJZcD ++xw5WOE7NMuvuVT1+T6jRvDOL/yjOzH1oaMle4npQEvQKHgrMBa2ymyv5vmPDprU7 ++9Sp8aW+yASR281MIpelIkePbGdiDdKrI46fqrPlmqzLfoRT4rKzjwVYouNIW0VlT ++UKIdE54OZegY8IOysL/t3QKBgDZnSnECiIW9G80UCaUBO3vKZGFuA1sFutMvzSSI ++XgQc5lNH7TtdwqESLdzgjSQ5QXK4t92j+P8DDI2Zx8DQ6K76G0DTdLImDCpGFZ/z ++UABvxIPn/GjuRyAIlhs852Tf+seqiHt6Igc6tmGTx4QTD3rvzrW0e1ncnhPc6Jg+ ++YXoFAoGARD9OPrd4J2N+nkSWif9VOuPHvOXEczwBDJbsAGrOW1kTbDStF0OIVOt0 ++Ukj+mnnL8ZNyVLgTrZDRfXvlA94EbPK5/rMAYwjMlXHP8R22ts3eDMNUdw0/Zl1g ++QOhL8wXZcdwHKsONy55kZHo8pmneqi9EnqqLGguLwx5WIMzWvZ8= + -----END RSA TESTING KEY----- + `) +