Blob Blame History Raw
diff --git a/src/cmd/api/goapi_boring_test.go b/src/cmd/api/goapi_boring_test.go
index f0e3575..a413916 100644
--- a/src/cmd/api/goapi_boring_test.go
+++ b/src/cmd/api/goapi_boring_test.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build boringcrypto
+//go:build !no_openssl
 
 package main
 
@@ -12,6 +12,6 @@ import (
 )
 
 func init() {
-	fmt.Printf("SKIP with boringcrypto enabled\n")
+	fmt.Printf("SKIP with !no_openssl enabled\n")
 	os.Exit(0)
 }
diff --git a/src/crypto/aes/cipher.go b/src/crypto/aes/cipher.go
index db0ee38..67c32c0 100644
--- a/src/crypto/aes/cipher.go
+++ b/src/crypto/aes/cipher.go
@@ -6,7 +6,7 @@ package aes
 
 import (
 	"crypto/cipher"
-	"crypto/internal/boring"
+	boring "crypto/internal/backend"
 	"crypto/internal/subtle"
 	"strconv"
 )
@@ -38,7 +38,7 @@ func NewCipher(key []byte) (cipher.Block, error) {
 	case 16, 24, 32:
 		break
 	}
-	if boring.Enabled {
+	if boring.Enabled() {
 		return boring.NewAESCipher(key)
 	}
 	return newCipher(key)
diff --git a/src/crypto/aes/cipher_asm.go b/src/crypto/aes/cipher_asm.go
index 1482b22..5f54514 100644
--- a/src/crypto/aes/cipher_asm.go
+++ b/src/crypto/aes/cipher_asm.go
@@ -8,7 +8,7 @@ package aes
 
 import (
 	"crypto/cipher"
-	"crypto/internal/boring"
+	boring "crypto/internal/backend"
 	"crypto/internal/subtle"
 	"internal/cpu"
 	"internal/goarch"
diff --git a/src/crypto/boring/boring.go b/src/crypto/boring/boring.go
index 097c37e..47618fe 100644
--- a/src/crypto/boring/boring.go
+++ b/src/crypto/boring/boring.go
@@ -13,9 +13,9 @@
 // is satisfied, so that applications can tag files that use this package.
 package boring
 
-import "crypto/internal/boring"
+import boring "crypto/internal/backend"
 
 // Enabled reports whether BoringCrypto handles supported crypto operations.
 func Enabled() bool {
-	return boring.Enabled
+	return boring.Enabled()
 }
diff --git a/src/crypto/boring/boring_test.go b/src/crypto/boring/boring_test.go
deleted file mode 100644
index 9e8fd35..0000000
--- a/src/crypto/boring/boring_test.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build boringcrypto
-
-package boring_test
-
-import (
-	"crypto/boring"
-	"runtime"
-	"testing"
-)
-
-func TestEnabled(t *testing.T) {
-	supportedPlatform := runtime.GOOS == "linux" && runtime.GOARCH == "amd64"
-	if supportedPlatform && !boring.Enabled() {
-		t.Error("Enabled returned false on a supported platform")
-	} else if !supportedPlatform && boring.Enabled() {
-		t.Error("Enabled returned true on an unsupported platform")
-	}
-}
diff --git a/src/crypto/boring/notboring_test.go b/src/crypto/boring/notboring_test.go
deleted file mode 100644
index ffe18e9..0000000
--- a/src/crypto/boring/notboring_test.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build (goexperiment.boringcrypto && !boringcrypto) || (!goexperiment.boringcrypto && boringcrypto)
-// +build goexperiment.boringcrypto,!boringcrypto !goexperiment.boringcrypto,boringcrypto
-
-package boring_test
-
-import "testing"
-
-func TestNotBoring(t *testing.T) {
-	t.Error("goexperiment.boringcrypto and boringcrypto should be equivalent build tags")
-}
diff --git a/src/crypto/ecdsa/boring.go b/src/crypto/ecdsa/boring.go
index 4495730..c2137d6 100644
--- a/src/crypto/ecdsa/boring.go
+++ b/src/crypto/ecdsa/boring.go
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build boringcrypto
+//go:build !no_openssl
 
 package ecdsa
 
 import (
-	"crypto/internal/boring"
-	"crypto/internal/boring/bbig"
+	boring "crypto/internal/backend"
+	"crypto/internal/backend/bbig"
 	"crypto/internal/boring/bcache"
 	"math/big"
 	"unsafe"
diff --git a/src/crypto/ecdsa/ecdsa.go b/src/crypto/ecdsa/ecdsa.go
index d0e52ad..9b76595 100644
--- a/src/crypto/ecdsa/ecdsa.go
+++ b/src/crypto/ecdsa/ecdsa.go
@@ -24,8 +24,8 @@ import (
 	"crypto/aes"
 	"crypto/cipher"
 	"crypto/elliptic"
-	"crypto/internal/boring"
-	"crypto/internal/boring/bbig"
+	boring "crypto/internal/backend"
+	"crypto/internal/backend/bbig"
 	"crypto/internal/randutil"
 	"crypto/sha512"
 	"errors"
@@ -109,7 +109,7 @@ func (priv *PrivateKey) Equal(x crypto.PrivateKey) bool {
 // where the private part is kept in, for example, a hardware module. Common
 // uses can use the SignASN1 function in this package directly.
 func (priv *PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
-	if boring.Enabled && rand == boring.RandReader {
+	if boring.Enabled() && rand == boring.RandReader {
 		b, err := boringPrivateKey(priv)
 		if err != nil {
 			return nil, err
@@ -154,7 +154,7 @@ func randFieldElement(c elliptic.Curve, rand io.Reader) (k *big.Int, err error)
 
 // GenerateKey generates a public and private key pair.
 func GenerateKey(c elliptic.Curve, rand io.Reader) (*PrivateKey, error) {
-	if boring.Enabled && rand == boring.RandReader {
+	if boring.Enabled() && rand == boring.RandReader {
 		x, y, d, err := boring.GenerateKeyECDSA(c.Params().Name)
 		if err != nil {
 			return nil, err
@@ -214,7 +214,7 @@ var errZeroParam = errors.New("zero parameter")
 func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error) {
 	randutil.MaybeReadByte(rand)
 
-	if boring.Enabled && rand == boring.RandReader {
+	if boring.Enabled() && rand == boring.RandReader {
 		b, err := boringPrivateKey(priv)
 		if err != nil {
 			return nil, nil, err
@@ -231,7 +231,7 @@ func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err err
 			!inner.ReadASN1Integer(&r) ||
 			!inner.ReadASN1Integer(&s) ||
 			!inner.Empty() {
-			return nil, nil, errors.New("invalid ASN.1 from boringcrypto")
+			return nil, nil, errors.New("invalid ASN.1 from !no_openssl")
 		}
 		return &r, &s, nil
 	}
@@ -333,7 +333,7 @@ func SignASN1(rand io.Reader, priv *PrivateKey, hash []byte) ([]byte, error) {
 // return value records whether the signature is valid. Most applications should
 // use VerifyASN1 instead of dealing directly with r, s.
 func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool {
-	if boring.Enabled {
+	if boring.Enabled() {
 		key, err := boringPublicKey(pub)
 		if err != nil {
 			return false
diff --git a/src/crypto/ecdsa/notboring.go b/src/crypto/ecdsa/notboring.go
index 039bd82..21a35b7 100644
--- a/src/crypto/ecdsa/notboring.go
+++ b/src/crypto/ecdsa/notboring.go
@@ -2,15 +2,15 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build !boringcrypto
+//go:build no_openssl
 
 package ecdsa
 
-import "crypto/internal/boring"
+import boring "crypto/internal/backend"
 
 func boringPublicKey(*PublicKey) (*boring.PublicKeyECDSA, error) {
-	panic("boringcrypto: not available")
+	panic("!no_openssl: not available")
 }
 func boringPrivateKey(*PrivateKey) (*boring.PrivateKeyECDSA, error) {
-	panic("boringcrypto: not available")
+	panic("!no_openssl: not available")
 }
diff --git a/src/crypto/ed25519/ed25519_test.go b/src/crypto/ed25519/ed25519_test.go
index 102c4e5..e442bcc 100644
--- a/src/crypto/ed25519/ed25519_test.go
+++ b/src/crypto/ed25519/ed25519_test.go
@@ -9,7 +9,7 @@ import (
 	"bytes"
 	"compress/gzip"
 	"crypto"
-	"crypto/internal/boring"
+	boring "crypto/internal/backend"
 	"crypto/rand"
 	"encoding/hex"
 	"os"
@@ -188,7 +188,7 @@ func TestMalleability(t *testing.T) {
 
 func TestAllocations(t *testing.T) {
 	t.Skip("Allocations test broken with openssl linkage")
-	if boring.Enabled {
+	if boring.Enabled() {
 		t.Skip("skipping allocations test with BoringCrypto")
 	}
 	if strings.HasSuffix(os.Getenv("GO_BUILDER_NAME"), "-noopt") {
diff --git a/src/crypto/hmac/hmac.go b/src/crypto/hmac/hmac.go
index ed3ebc0..9941228 100644
--- a/src/crypto/hmac/hmac.go
+++ b/src/crypto/hmac/hmac.go
@@ -22,7 +22,7 @@ timing side-channels:
 package hmac
 
 import (
-	"crypto/internal/boring"
+	boring "crypto/internal/backend"
 	"crypto/subtle"
 	"hash"
 )
@@ -127,7 +127,7 @@ func (h *hmac) Reset() {
 // the returned Hash does not implement encoding.BinaryMarshaler
 // or encoding.BinaryUnmarshaler.
 func New(h func() hash.Hash, key []byte) hash.Hash {
-	if boring.Enabled {
+	if boring.Enabled() {
 		hm := boring.NewHMAC(h, key)
 		if hm != nil {
 			return hm
diff --git a/src/crypto/hmac/hmac_test.go b/src/crypto/hmac/hmac_test.go
index 55415ab..0edd7a6 100644
--- a/src/crypto/hmac/hmac_test.go
+++ b/src/crypto/hmac/hmac_test.go
@@ -6,7 +6,7 @@ package hmac
 
 import (
 	"bytes"
-	"crypto/internal/boring"
+	boring "crypto/internal/backend"
 	"crypto/md5"
 	"crypto/sha1"
 	"crypto/sha256"
@@ -584,8 +584,8 @@ func TestHMAC(t *testing.T) {
 }
 
 func TestNonUniqueHash(t *testing.T) {
-	if boring.Enabled {
-		t.Skip("hash.Hash provided by boringcrypto are not comparable")
+	if boring.Enabled() {
+		t.Skip("hash.Hash provided by !no_openssl are not comparable")
 	}
 	sha := sha256.New()
 	defer func() {
diff --git a/src/crypto/internal/boring/aes.go b/src/crypto/internal/boring/aes.go
deleted file mode 100644
index eaa1adc..0000000
--- a/src/crypto/internal/boring/aes.go
+++ /dev/null
@@ -1,386 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build boringcrypto && linux && amd64 && !android && !cmd_go_bootstrap && !msan
-// +build boringcrypto,linux,amd64,!android,!cmd_go_bootstrap,!msan
-
-package boring
-
-/*
-
-#include "goboringcrypto.h"
-
-// These wrappers allocate out_len on the C stack, and check that it matches the expected
-// value, to avoid having to pass a pointer from Go, which would escape to the heap.
-
-int EVP_AEAD_CTX_seal_wrapper(const GO_EVP_AEAD_CTX *ctx, uint8_t *out,
-							  size_t exp_out_len,
-							  const uint8_t *nonce, size_t nonce_len,
-							  const uint8_t *in, size_t in_len,
-							  const uint8_t *ad, size_t ad_len) {
-	size_t out_len;
-	int ok = _goboringcrypto_EVP_AEAD_CTX_seal(ctx, out, &out_len, exp_out_len,
-		nonce, nonce_len, in, in_len, ad, ad_len);
-	if (out_len != exp_out_len) {
-		return 0;
-	}
-	return ok;
-};
-
-int EVP_AEAD_CTX_open_wrapper(const GO_EVP_AEAD_CTX *ctx, uint8_t *out,
-							  size_t exp_out_len,
-							  const uint8_t *nonce, size_t nonce_len,
-							  const uint8_t *in, size_t in_len,
-							  const uint8_t *ad, size_t ad_len) {
-	size_t out_len;
-	int ok = _goboringcrypto_EVP_AEAD_CTX_open(ctx, out, &out_len, exp_out_len,
-		nonce, nonce_len, in, in_len, ad, ad_len);
-	if (out_len != exp_out_len) {
-		return 0;
-	}
-	return ok;
-};
-
-*/
-import "C"
-import (
-	"crypto/cipher"
-	"errors"
-	"runtime"
-	"strconv"
-	"unsafe"
-)
-
-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 C.GO_AES_KEY
-	dec C.GO_AES_KEY
-}
-
-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)
-}
-
-var _ extraModes = (*aesCipher)(nil)
-
-func NewAESCipher(key []byte) (cipher.Block, error) {
-	c := &aesCipher{key: make([]byte, len(key))}
-	copy(c.key, key)
-	// Note: 0 is success, contradicting the usual BoringCrypto convention.
-	if C._goboringcrypto_AES_set_decrypt_key((*C.uint8_t)(unsafe.Pointer(&c.key[0])), C.uint(8*len(c.key)), &c.dec) != 0 ||
-		C._goboringcrypto_AES_set_encrypt_key((*C.uint8_t)(unsafe.Pointer(&c.key[0])), C.uint(8*len(c.key)), &c.enc) != 0 {
-		return nil, aesKeySizeError(len(key))
-	}
-	return c, nil
-}
-
-func (c *aesCipher) BlockSize() int { return aesBlockSize }
-
-func (c *aesCipher) Encrypt(dst, src []byte) {
-	if inexactOverlap(dst, src) {
-		panic("crypto/cipher: invalid buffer overlap")
-	}
-	if len(src) < aesBlockSize {
-		panic("crypto/aes: input not full block")
-	}
-	if len(dst) < aesBlockSize {
-		panic("crypto/aes: output not full block")
-	}
-	C._goboringcrypto_AES_encrypt(
-		(*C.uint8_t)(unsafe.Pointer(&src[0])),
-		(*C.uint8_t)(unsafe.Pointer(&dst[0])),
-		&c.enc)
-}
-
-func (c *aesCipher) Decrypt(dst, src []byte) {
-	if inexactOverlap(dst, src) {
-		panic("crypto/cipher: invalid buffer overlap")
-	}
-	if len(src) < aesBlockSize {
-		panic("crypto/aes: input not full block")
-	}
-	if len(dst) < aesBlockSize {
-		panic("crypto/aes: output not full block")
-	}
-	C._goboringcrypto_AES_decrypt(
-		(*C.uint8_t)(unsafe.Pointer(&src[0])),
-		(*C.uint8_t)(unsafe.Pointer(&dst[0])),
-		&c.dec)
-}
-
-type aesCBC struct {
-	key  *C.GO_AES_KEY
-	mode C.int
-	iv   [aesBlockSize]byte
-}
-
-func (x *aesCBC) BlockSize() int { return aesBlockSize }
-
-func (x *aesCBC) CryptBlocks(dst, src []byte) {
-	if inexactOverlap(dst, src) {
-		panic("crypto/cipher: invalid buffer overlap")
-	}
-	if len(src)%aesBlockSize != 0 {
-		panic("crypto/cipher: input not full blocks")
-	}
-	if len(dst) < len(src) {
-		panic("crypto/cipher: output smaller than input")
-	}
-	if len(src) > 0 {
-		C._goboringcrypto_AES_cbc_encrypt(
-			(*C.uint8_t)(unsafe.Pointer(&src[0])),
-			(*C.uint8_t)(unsafe.Pointer(&dst[0])),
-			C.size_t(len(src)), x.key,
-			(*C.uint8_t)(unsafe.Pointer(&x.iv[0])), x.mode)
-	}
-}
-
-func (x *aesCBC) SetIV(iv []byte) {
-	if len(iv) != aesBlockSize {
-		panic("cipher: incorrect length IV")
-	}
-	copy(x.iv[:], iv)
-}
-
-func (c *aesCipher) NewCBCEncrypter(iv []byte) cipher.BlockMode {
-	x := &aesCBC{key: &c.enc, mode: C.GO_AES_ENCRYPT}
-	copy(x.iv[:], iv)
-	return x
-}
-
-func (c *aesCipher) NewCBCDecrypter(iv []byte) cipher.BlockMode {
-	x := &aesCBC{key: &c.dec, mode: C.GO_AES_DECRYPT}
-	copy(x.iv[:], iv)
-	return x
-}
-
-type aesCTR struct {
-	key        *C.GO_AES_KEY
-	iv         [aesBlockSize]byte
-	num        C.uint
-	ecount_buf [16]C.uint8_t
-}
-
-func (x *aesCTR) XORKeyStream(dst, src []byte) {
-	if inexactOverlap(dst, src) {
-		panic("crypto/cipher: invalid buffer overlap")
-	}
-	if len(dst) < len(src) {
-		panic("crypto/cipher: output smaller than input")
-	}
-	if len(src) == 0 {
-		return
-	}
-	C._goboringcrypto_AES_ctr128_encrypt(
-		(*C.uint8_t)(unsafe.Pointer(&src[0])),
-		(*C.uint8_t)(unsafe.Pointer(&dst[0])),
-		C.size_t(len(src)), x.key, (*C.uint8_t)(unsafe.Pointer(&x.iv[0])),
-		&x.ecount_buf[0], &x.num)
-}
-
-func (c *aesCipher) NewCTR(iv []byte) cipher.Stream {
-	x := &aesCTR{key: &c.enc}
-	copy(x.iv[:], iv)
-	return x
-}
-
-type aesGCM struct {
-	ctx  C.GO_EVP_AEAD_CTX
-	aead *C.GO_EVP_AEAD
-}
-
-const (
-	gcmBlockSize         = 16
-	gcmTagSize           = 16
-	gcmStandardNonceSize = 12
-)
-
-type aesNonceSizeError int
-
-func (n aesNonceSizeError) Error() string {
-	return "crypto/aes: invalid GCM nonce size " + strconv.Itoa(int(n))
-}
-
-type noGCM struct {
-	cipher.Block
-}
-
-func (c *aesCipher) NewGCM(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")
-	}
-	// Fall back to standard library for GCM with non-standard nonce or tag size.
-	if nonceSize != gcmStandardNonceSize {
-		return cipher.NewGCMWithNonceSize(&noGCM{c}, nonceSize)
-	}
-	if tagSize != gcmTagSize {
-		return cipher.NewGCMWithTagSize(&noGCM{c}, tagSize)
-	}
-	return c.newGCM(false)
-}
-
-func NewGCMTLS(c cipher.Block) (cipher.AEAD, error) {
-	return c.(*aesCipher).newGCM(true)
-}
-
-func (c *aesCipher) newGCM(tls bool) (cipher.AEAD, error) {
-	var aead *C.GO_EVP_AEAD
-	switch len(c.key) * 8 {
-	case 128:
-		if tls {
-			aead = C._goboringcrypto_EVP_aead_aes_128_gcm_tls12()
-		} else {
-			aead = C._goboringcrypto_EVP_aead_aes_128_gcm()
-		}
-	case 256:
-		if tls {
-			aead = C._goboringcrypto_EVP_aead_aes_256_gcm_tls12()
-		} else {
-			aead = C._goboringcrypto_EVP_aead_aes_256_gcm()
-		}
-	default:
-		// Fall back to standard library for GCM with non-standard key size.
-		return cipher.NewGCMWithNonceSize(&noGCM{c}, gcmStandardNonceSize)
-	}
-
-	g := &aesGCM{aead: aead}
-	if C._goboringcrypto_EVP_AEAD_CTX_init(&g.ctx, aead, (*C.uint8_t)(unsafe.Pointer(&c.key[0])), C.size_t(len(c.key)), C.GO_EVP_AEAD_DEFAULT_TAG_LENGTH, nil) == 0 {
-		return nil, fail("EVP_AEAD_CTX_init")
-	}
-	// Note: Because of the finalizer, any time g.ctx is passed to cgo,
-	// that call must be followed by a call to runtime.KeepAlive(g),
-	// to make sure g is not collected (and finalized) before the cgo
-	// call returns.
-	runtime.SetFinalizer(g, (*aesGCM).finalize)
-	if g.NonceSize() != gcmStandardNonceSize {
-		panic("boringcrypto: internal confusion about nonce size")
-	}
-	if g.Overhead() != gcmTagSize {
-		panic("boringcrypto: internal confusion about tag size")
-	}
-
-	return g, nil
-}
-
-func (g *aesGCM) finalize() {
-	C._goboringcrypto_EVP_AEAD_CTX_cleanup(&g.ctx)
-}
-
-func (g *aesGCM) NonceSize() int {
-	return int(C._goboringcrypto_EVP_AEAD_nonce_length(g.aead))
-}
-
-func (g *aesGCM) Overhead() int {
-	return int(C._goboringcrypto_EVP_AEAD_max_overhead(g.aead))
-}
-
-// 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.uint8_t {
-	if len(b) == 0 {
-		return nil
-	}
-	return (*C.uint8_t)(unsafe.Pointer(&b[0]))
-}
-
-func (g *aesGCM) 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) {
-		panic("cipher: message too large for GCM")
-	}
-	if len(dst)+len(plaintext)+gcmTagSize < len(dst) {
-		panic("cipher: message too large for buffer")
-	}
-
-	// Make room in dst to append plaintext+overhead.
-	n := len(dst)
-	for cap(dst) < n+len(plaintext)+gcmTagSize {
-		dst = append(dst[:cap(dst)], 0)
-	}
-	dst = dst[:n+len(plaintext)+gcmTagSize]
-
-	// Check delayed until now to make sure len(dst) is accurate.
-	if inexactOverlap(dst[n:], plaintext) {
-		panic("cipher: invalid buffer overlap")
-	}
-
-	outLen := C.size_t(len(plaintext) + gcmTagSize)
-	ok := C.EVP_AEAD_CTX_seal_wrapper(
-		&g.ctx,
-		(*C.uint8_t)(unsafe.Pointer(&dst[n])), outLen,
-		base(nonce), C.size_t(len(nonce)),
-		base(plaintext), C.size_t(len(plaintext)),
-		base(additionalData), C.size_t(len(additionalData)))
-	runtime.KeepAlive(g)
-	if ok == 0 {
-		panic(fail("EVP_AEAD_CTX_seal"))
-	}
-	return dst[:n+int(outLen)]
-}
-
-var errOpen = errors.New("cipher: message authentication failed")
-
-func (g *aesGCM) 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 {
-		return nil, errOpen
-	}
-
-	// Make room in dst to append ciphertext without tag.
-	n := len(dst)
-	for cap(dst) < n+len(ciphertext)-gcmTagSize {
-		dst = append(dst[:cap(dst)], 0)
-	}
-	dst = dst[:n+len(ciphertext)-gcmTagSize]
-
-	// Check delayed until now to make sure len(dst) is accurate.
-	if inexactOverlap(dst[n:], ciphertext) {
-		panic("cipher: invalid buffer overlap")
-	}
-
-	outLen := C.size_t(len(ciphertext) - gcmTagSize)
-	ok := C.EVP_AEAD_CTX_open_wrapper(
-		&g.ctx,
-		base(dst[n:]), outLen,
-		base(nonce), C.size_t(len(nonce)),
-		base(ciphertext), C.size_t(len(ciphertext)),
-		base(additionalData), C.size_t(len(additionalData)))
-	runtime.KeepAlive(g)
-	if ok == 0 {
-		return nil, errOpen
-	}
-	return dst[:n+int(outLen)], nil
-}
-
-func anyOverlap(x, y []byte) bool {
-	return len(x) > 0 && len(y) > 0 &&
-		uintptr(unsafe.Pointer(&x[0])) <= uintptr(unsafe.Pointer(&y[len(y)-1])) &&
-		uintptr(unsafe.Pointer(&y[0])) <= uintptr(unsafe.Pointer(&x[len(x)-1]))
-}
-
-func inexactOverlap(x, y []byte) bool {
-	if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] {
-		return false
-	}
-	return anyOverlap(x, y)
-}
diff --git a/src/crypto/internal/boring/bbig/big.go b/src/crypto/internal/boring/bbig/big.go
deleted file mode 100644
index 5ce4697..0000000
--- a/src/crypto/internal/boring/bbig/big.go
+++ /dev/null
@@ -1,33 +0,0 @@
-// 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.
-
-package bbig
-
-import (
-	"crypto/internal/boring"
-	"math/big"
-	"unsafe"
-)
-
-func Enc(b *big.Int) boring.BigInt {
-	if b == nil {
-		return nil
-	}
-	x := b.Bits()
-	if len(x) == 0 {
-		return boring.BigInt{}
-	}
-	return unsafe.Slice((*uint)(&x[0]), len(x))
-}
-
-func Dec(b boring.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/crypto/internal/boring/boring.go b/src/crypto/internal/boring/boring.go
deleted file mode 100644
index c560679..0000000
--- a/src/crypto/internal/boring/boring.go
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build boringcrypto && linux && amd64 && !android && !cmd_go_bootstrap && !msan
-// +build boringcrypto,linux,amd64,!android,!cmd_go_bootstrap,!msan
-
-package boring
-
-/*
-// goboringcrypto_linux_amd64.syso references pthread functions.
-#cgo LDFLAGS: "-pthread"
-
-#include "goboringcrypto.h"
-*/
-import "C"
-import (
-	"crypto/internal/boring/sig"
-	_ "crypto/internal/boring/syso"
-	"math/bits"
-	"unsafe"
-)
-
-const available = true
-
-func init() {
-	C._goboringcrypto_BORINGSSL_bcm_power_on_self_test()
-	if C._goboringcrypto_FIPS_mode() != 1 {
-		panic("boringcrypto: not in FIPS mode")
-	}
-	sig.BoringCrypto()
-}
-
-// Unreachable marks code that should be unreachable
-// when BoringCrypto is in use. It panics.
-func Unreachable() {
-	panic("boringcrypto: invalid code execution")
-}
-
-// provided by runtime to avoid os import
-func runtime_arg0() string
-
-func hasSuffix(s, t string) bool {
-	return len(s) > len(t) && s[len(s)-len(t):] == t
-}
-
-// UnreachableExceptTests marks code that should be unreachable
-// when BoringCrypto is in use. It panics.
-func UnreachableExceptTests() {
-	name := runtime_arg0()
-	// If BoringCrypto ran on Windows we'd need to allow _test.exe and .test.exe as well.
-	if !hasSuffix(name, "_test") && !hasSuffix(name, ".test") {
-		println("boringcrypto: unexpected code execution in", name)
-		panic("boringcrypto: invalid code execution")
-	}
-}
-
-type fail string
-
-func (e fail) Error() string { return "boringcrypto: " + string(e) + " failed" }
-
-func wbase(b BigInt) *C.uint8_t {
-	if len(b) == 0 {
-		return nil
-	}
-	return (*C.uint8_t)(unsafe.Pointer(&b[0]))
-}
-
-const wordBytes = bits.UintSize / 8
-
-func bigToBN(x BigInt) *C.GO_BIGNUM {
-	return C._goboringcrypto_BN_le2bn(wbase(x), C.size_t(len(x)*wordBytes), nil)
-}
-
-func bnToBig(bn *C.GO_BIGNUM) BigInt {
-	x := make(BigInt, (C._goboringcrypto_BN_num_bytes(bn)+wordBytes-1)/wordBytes)
-	if C._goboringcrypto_BN_bn2le_padded(wbase(x), C.size_t(len(x)*wordBytes), bn) == 0 {
-		panic("boringcrypto: bignum conversion failed")
-	}
-	return x
-}
-
-func bigToBn(bnp **C.GO_BIGNUM, b BigInt) bool {
-	if *bnp != nil {
-		C._goboringcrypto_BN_free(*bnp)
-		*bnp = nil
-	}
-	if b == nil {
-		return true
-	}
-	bn := bigToBN(b)
-	if bn == nil {
-		return false
-	}
-	*bnp = bn
-	return true
-}
-
-// 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)
-}
-
-var zero byte
-
-// 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])))
-}
diff --git a/src/crypto/internal/boring/boring_test.go b/src/crypto/internal/boring/boring_test.go
deleted file mode 100644
index 83bbbd3..0000000
--- a/src/crypto/internal/boring/boring_test.go
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Most functionality in this package is tested by replacing existing code
-// and inheriting that code's tests.
-
-package boring
-
-import "testing"
-
-// Test that func init does not panic.
-func TestInit(t *testing.T) {}
-
-// Test that Unreachable panics.
-func TestUnreachable(t *testing.T) {
-	defer func() {
-		if Enabled {
-			if err := recover(); err == nil {
-				t.Fatal("expected Unreachable to panic")
-			}
-		} else {
-			if err := recover(); err != nil {
-				t.Fatalf("expected Unreachable to be a no-op")
-			}
-		}
-	}()
-	Unreachable()
-}
-
-// Test that UnreachableExceptTests does not panic (this is a test).
-func TestUnreachableExceptTests(t *testing.T) {
-	UnreachableExceptTests()
-}
diff --git a/src/crypto/internal/boring/doc.go b/src/crypto/internal/boring/doc.go
deleted file mode 100644
index 6060fe5..0000000
--- a/src/crypto/internal/boring/doc.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package boring provides access to BoringCrypto implementation functions.
-// Check the constant Enabled to find out whether BoringCrypto is available.
-// If BoringCrypto is not available, the functions in this package all panic.
-package boring
-
-// Enabled reports whether BoringCrypto is available.
-// When enabled is false, all functions in this package panic.
-//
-// BoringCrypto is only available on linux/amd64 systems.
-const Enabled = available
-
-// 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 crypto/internal/boring/bbig.
-type BigInt []uint
diff --git a/src/crypto/internal/boring/fipstls/stub.s b/src/crypto/internal/boring/fipstls/stub.s
index f2e5a50..65918a4 100644
--- a/src/crypto/internal/boring/fipstls/stub.s
+++ b/src/crypto/internal/boring/fipstls/stub.s
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build boringcrypto
+//go:build !no_openssl
 
 // runtime_arg0 is declared in tls.go without a body.
 // It's provided by package runtime,
diff --git a/src/crypto/internal/boring/fipstls/tls.go b/src/crypto/internal/boring/fipstls/tls.go
index 701700e..c840d98 100644
--- a/src/crypto/internal/boring/fipstls/tls.go
+++ b/src/crypto/internal/boring/fipstls/tls.go
@@ -2,10 +2,10 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build boringcrypto
+//go:build !no_openssl
 
 // Package fipstls allows control over whether crypto/tls requires FIPS-approved settings.
-// This package only exists with GOEXPERIMENT=boringcrypto, but the effects are independent
+// This package only exists with GOEXPERIMENT=!no_openssl, but the effects are independent
 // of the use of BoringCrypto.
 package fipstls
 
diff --git a/src/crypto/rand/rand_unix.go b/src/crypto/rand/rand_unix.go
index 746e90c..c9233bd 100644
--- a/src/crypto/rand/rand_unix.go
+++ b/src/crypto/rand/rand_unix.go
@@ -10,7 +10,7 @@
 package rand
 
 import (
-	"crypto/internal/boring"
+	boring "crypto/internal/backend"
 	"errors"
 	"io"
 	"os"
@@ -23,7 +23,7 @@ import (
 const urandomDevice = "/dev/urandom"
 
 func init() {
-	if boring.Enabled {
+	if boring.Enabled() {
 		Reader = boring.RandReader
 		return
 	}
diff --git a/src/crypto/rsa/boring.go b/src/crypto/rsa/boring.go
index 9b1db56..a984f76 100644
--- a/src/crypto/rsa/boring.go
+++ b/src/crypto/rsa/boring.go
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build boringcrypto
+//go:build !no_openssl
 
 package rsa
 
 import (
-	"crypto/internal/boring"
-	"crypto/internal/boring/bbig"
+	boring "crypto/internal/backend"
+	"crypto/internal/backend/bbig"
 	"crypto/internal/boring/bcache"
 	"math/big"
 	"unsafe"
diff --git a/src/crypto/rsa/boring_test.go b/src/crypto/rsa/boring_test.go
index 6223244..ad76d6a 100644
--- a/src/crypto/rsa/boring_test.go
+++ b/src/crypto/rsa/boring_test.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build boringcrypto
+//go:build !no_openssl
 
 // Note: Can run these tests against the non-BoringCrypto
 // version of the code by using "CGO_ENABLED=0 go test".
diff --git a/src/crypto/rsa/notboring.go b/src/crypto/rsa/notboring.go
index 2abc043..a83be6d 100644
--- a/src/crypto/rsa/notboring.go
+++ b/src/crypto/rsa/notboring.go
@@ -2,15 +2,15 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build !boringcrypto
+//go:build no_openssl
 
 package rsa
 
-import "crypto/internal/boring"
+import boring "crypto/internal/backend"
 
 func boringPublicKey(*PublicKey) (*boring.PublicKeyRSA, error) {
-	panic("boringcrypto: not available")
+	panic("!no_openssl: not available")
 }
 func boringPrivateKey(*PrivateKey) (*boring.PrivateKeyRSA, error) {
-	panic("boringcrypto: not available")
+	panic("!no_openssl: not available")
 }
diff --git a/src/crypto/rsa/pkcs1v15.go b/src/crypto/rsa/pkcs1v15.go
index ab19229..87b0ec9 100644
--- a/src/crypto/rsa/pkcs1v15.go
+++ b/src/crypto/rsa/pkcs1v15.go
@@ -6,7 +6,7 @@ package rsa
 
 import (
 	"crypto"
-	"crypto/internal/boring"
+	boring "crypto/internal/backend"
 	"crypto/internal/randutil"
 	"crypto/subtle"
 	"errors"
@@ -47,7 +47,7 @@ func EncryptPKCS1v15(random io.Reader, pub *PublicKey, msg []byte) ([]byte, erro
 		return nil, ErrMessageTooLong
 	}
 
-	if boring.Enabled && random == boring.RandReader {
+	if boring.Enabled() && random == boring.RandReader {
 		bkey, err := boringPublicKey(pub)
 		if err != nil {
 			return nil, err
@@ -67,7 +67,7 @@ func EncryptPKCS1v15(random io.Reader, pub *PublicKey, msg []byte) ([]byte, erro
 	em[len(em)-len(msg)-1] = 0
 	copy(mm, msg)
 
-	if boring.Enabled {
+	if boring.Enabled() {
 		var bkey *boring.PublicKeyRSA
 		bkey, err = boringPublicKey(pub)
 		if err != nil {
@@ -94,7 +94,7 @@ func DecryptPKCS1v15(random io.Reader, priv *PrivateKey, ciphertext []byte) ([]b
 		return nil, err
 	}
 
-	if boring.Enabled {
+	if boring.Enabled() {
 		bkey, err := boringPrivateKey(priv)
 		if err != nil {
 			return nil, err
@@ -173,7 +173,7 @@ func decryptPKCS1v15(random io.Reader, priv *PrivateKey, ciphertext []byte) (val
 		return
 	}
 
-	if boring.Enabled {
+	if boring.Enabled() {
 		var bkey *boring.PrivateKeyRSA
 		bkey, err = boringPrivateKey(priv)
 		if err != nil {
@@ -285,12 +285,12 @@ func SignPKCS1v15(random io.Reader, priv *PrivateKey, hash crypto.Hash, hashed [
 		return nil, ErrMessageTooLong
 	}
 
-	if boring.Enabled {
+	if boring.Enabled() {
 		bkey, err := boringPrivateKey(priv)
 		if err != nil {
 			return nil, err
 		}
-		return boring.SignRSAPKCS1v15(bkey, hash, hashed)
+		return boring.SignRSAPKCS1v15(bkey, hash, hashed, true)
 	}
 
 	// EM = 0x00 || 0x01 || PS || 0x00 || T
@@ -317,12 +317,12 @@ func SignPKCS1v15(random io.Reader, priv *PrivateKey, hash crypto.Hash, hashed [
 // returning a nil error. If hash is zero then hashed is used directly. This
 // isn't advisable except for interoperability.
 func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) error {
-	if boring.Enabled {
+	if boring.Enabled() {
 		bkey, err := boringPublicKey(pub)
 		if err != nil {
 			return err
 		}
-		if err := boring.VerifyRSAPKCS1v15(bkey, hash, hashed, sig); err != nil {
+		if err := boring.VerifyRSAPKCS1v15(bkey, hash, hashed, sig, hash != crypto.Hash(0)); err != nil {
 			return ErrVerification
 		}
 		return nil
diff --git a/src/crypto/rsa/pss.go b/src/crypto/rsa/pss.go
index 29e79bd..e7431e8 100644
--- a/src/crypto/rsa/pss.go
+++ b/src/crypto/rsa/pss.go
@@ -9,7 +9,7 @@ package rsa
 import (
 	"bytes"
 	"crypto"
-	"crypto/internal/boring"
+	boring "crypto/internal/backend"
 	"errors"
 	"hash"
 	"io"
@@ -215,7 +215,7 @@ func signPSSWithSalt(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed,
 		return nil, err
 	}
 
-	if boring.Enabled {
+	if boring.Enabled() {
 		bkey, err := boringPrivateKey(priv)
 		if err != nil {
 			return nil, err
@@ -290,7 +290,7 @@ func SignPSS(rand io.Reader, priv *PrivateKey, hash crypto.Hash, digest []byte,
 		saltLength = hash.Size()
 	}
 
-	if boring.Enabled && rand == boring.RandReader {
+	if boring.Enabled() && rand == boring.RandReader {
 		bkey, err := boringPrivateKey(priv)
 		if err != nil {
 			return nil, err
@@ -313,7 +313,7 @@ func SignPSS(rand io.Reader, priv *PrivateKey, hash crypto.Hash, digest []byte,
 // argument may be nil, in which case sensible defaults are used. opts.Hash is
 // ignored.
 func VerifyPSS(pub *PublicKey, hash crypto.Hash, digest []byte, sig []byte, opts *PSSOptions) error {
-	if boring.Enabled {
+	if boring.Enabled() {
 		bkey, err := boringPublicKey(pub)
 		if err != nil {
 			return err
diff --git a/src/crypto/rsa/rsa.go b/src/crypto/rsa/rsa.go
index c941124..7ea291c 100644
--- a/src/crypto/rsa/rsa.go
+++ b/src/crypto/rsa/rsa.go
@@ -24,8 +24,8 @@ package rsa
 
 import (
 	"crypto"
-	"crypto/internal/boring"
-	"crypto/internal/boring/bbig"
+	boring "crypto/internal/backend"
+	"crypto/internal/backend/bbig"
 	"crypto/internal/randutil"
 	"crypto/rand"
 	"crypto/subtle"
@@ -257,7 +257,7 @@ func GenerateKey(random io.Reader, bits int) (*PrivateKey, error) {
 func GenerateMultiPrimeKey(random io.Reader, nprimes int, bits int) (*PrivateKey, error) {
 	randutil.MaybeReadByte(random)
 
-	if boring.Enabled && random == boring.RandReader && nprimes == 2 && (bits == 2048 || bits == 3072) {
+	if boring.Enabled() && random == boring.RandReader && nprimes == 2 && (bits == 2048 || bits == 3072) {
 		bN, bE, bD, bP, bQ, bDp, bDq, bQinv, err := boring.GenerateKeyRSA(bits)
 		if err != nil {
 			return nil, err
@@ -453,7 +453,7 @@ func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, l
 		return nil, ErrMessageTooLong
 	}
 
-	if boring.Enabled && random == boring.RandReader {
+	if boring.Enabled() && random == boring.RandReader {
 		bkey, err := boringPublicKey(pub)
 		if err != nil {
 			return nil, err
@@ -482,7 +482,7 @@ func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, l
 	mgf1XOR(db, hash, seed)
 	mgf1XOR(seed, hash, db)
 
-	if boring.Enabled {
+	if boring.Enabled() {
 		var bkey *boring.PublicKeyRSA
 		bkey, err = boringPublicKey(pub)
 		if err != nil {
@@ -660,7 +660,7 @@ func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext
 		return nil, ErrDecryption
 	}
 
-	if boring.Enabled {
+	if boring.Enabled() {
 		bkey, err := boringPrivateKey(priv)
 		if err != nil {
 			return nil, err
diff --git a/src/crypto/rsa/rsa_test.go b/src/crypto/rsa/rsa_test.go
index 766d9a9..608110d 100644
--- a/src/crypto/rsa/rsa_test.go
+++ b/src/crypto/rsa/rsa_test.go
@@ -15,7 +15,7 @@ import (
 	"testing"
 )
 
-import "crypto/internal/boring"
+import boring "crypto/internal/backend"
 
 func TestKeyGeneration(t *testing.T) {
 	for _, size := range []int{128, 1024, 2048, 3072} {
@@ -114,7 +114,7 @@ func testKeyBasics(t *testing.T, priv *PrivateKey) {
 		t.Errorf("private exponent too large")
 	}
 
-	if boring.Enabled {
+	if boring.Enabled() {
 		// Cannot call encrypt/decrypt directly. Test via PKCS1v15.
 		msg := []byte("hi!")
 		enc, err := EncryptPKCS1v15(rand.Reader, &priv.PublicKey, msg)
@@ -181,7 +181,7 @@ func init() {
 }
 
 func BenchmarkRSA2048Decrypt(b *testing.B) {
-	if boring.Enabled {
+	if boring.Enabled() {
 		b.Skip("no raw decrypt in BoringCrypto")
 	}
 
@@ -207,7 +207,7 @@ func BenchmarkRSA2048Sign(b *testing.B) {
 }
 
 func Benchmark3PrimeRSA2048Decrypt(b *testing.B) {
-	if boring.Enabled {
+	if boring.Enabled() {
 		b.Skip("no raw decrypt in BoringCrypto")
 	}
 
diff --git a/src/crypto/sha1/boring.go b/src/crypto/sha1/boring.go
index b5786d1..9bd03f3 100644
--- a/src/crypto/sha1/boring.go
+++ b/src/crypto/sha1/boring.go
@@ -12,11 +12,11 @@
 package sha1
 
 import (
-	"crypto/internal/boring"
+	boring "crypto/internal/backend"
 	"hash"
 )
 
-const boringEnabled = boring.Enabled
+var boringEnabled = boring.Enabled()
 
 func boringNewSHA1() hash.Hash { return boring.NewSHA1() }
 
diff --git a/src/crypto/sha1/notboring.go b/src/crypto/sha1/notboring.go
index 42ef879..c1a3205 100644
--- a/src/crypto/sha1/notboring.go
+++ b/src/crypto/sha1/notboring.go
@@ -11,10 +11,10 @@ import (
 	"hash"
 )
 
-const boringEnabled = false
+var boringEnabled = false
 
-func boringNewSHA1() hash.Hash { panic("boringcrypto: not available") }
+func boringNewSHA1() hash.Hash { panic("!no_openssl: not available") }
 
 func boringUnreachable() {}
 
-func boringSHA1([]byte) [20]byte { panic("boringcrypto: not available") }
+func boringSHA1([]byte) [20]byte { panic("!no_openssl: not available") }
diff --git a/src/crypto/sha1/sha1_test.go b/src/crypto/sha1/sha1_test.go
index 85ed126..71f4b46 100644
--- a/src/crypto/sha1/sha1_test.go
+++ b/src/crypto/sha1/sha1_test.go
@@ -8,7 +8,7 @@ package sha1
 
 import (
 	"bytes"
-	"crypto/internal/boring"
+	boring "crypto/internal/backend"
 	"crypto/rand"
 	"encoding"
 	"fmt"
@@ -78,7 +78,7 @@ func TestGolden(t *testing.T) {
 				io.WriteString(c, g.in[len(g.in)/2:])
 				sum = c.Sum(nil)
 			case 3:
-				if boring.Enabled {
+				if boring.Enabled() {
 					continue
 				}
 				io.WriteString(c, g.in[0:len(g.in)/2])
@@ -145,7 +145,7 @@ func TestBlockSize(t *testing.T) {
 
 // Tests that blockGeneric (pure Go) and block (in assembly for some architectures) match.
 func TestBlockGeneric(t *testing.T) {
-	if boring.Enabled {
+	if boring.Enabled() {
 		t.Skip("BoringCrypto doesn't expose digest")
 	}
 	for i := 1; i < 30; i++ { // arbitrary factor
@@ -218,7 +218,7 @@ func TestLargeHashes(t *testing.T) {
 }
 
 func TestAllocations(t *testing.T) {
-	if boring.Enabled {
+	if boring.Enabled() {
 		t.Skip("BoringCrypto doesn't allocate the same way as stdlib")
 	}
 	in := []byte("hello, world!")
diff --git a/src/crypto/sha256/sha256.go b/src/crypto/sha256/sha256.go
index e3c15e6..9a98baa 100644
--- a/src/crypto/sha256/sha256.go
+++ b/src/crypto/sha256/sha256.go
@@ -8,7 +8,7 @@ package sha256
 
 import (
 	"crypto"
-	"crypto/internal/boring"
+	boring "crypto/internal/backend"
 	"encoding/binary"
 	"errors"
 	"hash"
@@ -160,7 +160,7 @@ func (d *digest) Reset() {
 // encoding.BinaryUnmarshaler to marshal and unmarshal the internal
 // state of the hash.
 func New() hash.Hash {
-	if boring.Enabled {
+	if boring.Enabled() {
 		return boring.NewSHA256()
 	}
 	d := new(digest)
@@ -170,7 +170,7 @@ func New() hash.Hash {
 
 // New224 returns a new hash.Hash computing the SHA224 checksum.
 func New224() hash.Hash {
-	if boring.Enabled {
+	if boring.Enabled() {
 		return boring.NewSHA224()
 	}
 	d := new(digest)
@@ -261,7 +261,7 @@ func (d *digest) checkSum() [Size]byte {
 
 // Sum256 returns the SHA256 checksum of the data.
 func Sum256(data []byte) [Size]byte {
-	if boring.Enabled {
+	if boring.Enabled() {
 		return boring.SHA256(data)
 	}
 	var d digest
@@ -272,7 +272,7 @@ func Sum256(data []byte) [Size]byte {
 
 // Sum224 returns the SHA224 checksum of the data.
 func Sum224(data []byte) [Size224]byte {
-	if boring.Enabled {
+	if boring.Enabled() {
 		return boring.SHA224(data)
 	}
 	var d digest
diff --git a/src/crypto/sha256/sha256_test.go b/src/crypto/sha256/sha256_test.go
index 7304678..a073d31 100644
--- a/src/crypto/sha256/sha256_test.go
+++ b/src/crypto/sha256/sha256_test.go
@@ -8,7 +8,7 @@ package sha256
 
 import (
 	"bytes"
-	"crypto/internal/boring"
+	boring "crypto/internal/backend"
 	"crypto/rand"
 	"encoding"
 	"fmt"
@@ -217,7 +217,7 @@ func TestBlockSize(t *testing.T) {
 
 // Tests that blockGeneric (pure Go) and block (in assembly for some architectures) match.
 func TestBlockGeneric(t *testing.T) {
-	if boring.Enabled {
+	if boring.Enabled() {
 		t.Skip("BoringCrypto doesn't expose digest")
 	}
 	gen, asm := New().(*digest), New().(*digest)
@@ -294,7 +294,7 @@ func TestLargeHashes(t *testing.T) {
 }
 
 func TestAllocations(t *testing.T) {
-	if boring.Enabled {
+	if boring.Enabled() {
 		t.Skip("BoringCrypto doesn't allocate the same way as stdlib")
 	}
 	in := []byte("hello, world!")
diff --git a/src/crypto/sha512/sha512.go b/src/crypto/sha512/sha512.go
index c800a29..cab2477 100644
--- a/src/crypto/sha512/sha512.go
+++ b/src/crypto/sha512/sha512.go
@@ -12,7 +12,7 @@ package sha512
 
 import (
 	"crypto"
-	"crypto/internal/boring"
+	boring "crypto/internal/backend"
 	"encoding/binary"
 	"errors"
 	"hash"
@@ -212,7 +212,7 @@ func consumeUint64(b []byte) ([]byte, uint64) {
 
 // New returns a new hash.Hash computing the SHA-512 checksum.
 func New() hash.Hash {
-	if boring.Enabled {
+	if boring.Enabled() {
 		return boring.NewSHA512()
 	}
 	d := &digest{function: crypto.SHA512}
@@ -236,7 +236,7 @@ func New512_256() hash.Hash {
 
 // New384 returns a new hash.Hash computing the SHA-384 checksum.
 func New384() hash.Hash {
-	if boring.Enabled {
+	if boring.Enabled() {
 		return boring.NewSHA384()
 	}
 	d := &digest{function: crypto.SHA384}
@@ -343,7 +343,7 @@ func (d *digest) checkSum() [Size]byte {
 
 // Sum512 returns the SHA512 checksum of the data.
 func Sum512(data []byte) [Size]byte {
-	if boring.Enabled {
+	if boring.Enabled() {
 		return boring.SHA512(data)
 	}
 	d := digest{function: crypto.SHA512}
@@ -354,7 +354,7 @@ func Sum512(data []byte) [Size]byte {
 
 // Sum384 returns the SHA384 checksum of the data.
 func Sum384(data []byte) [Size384]byte {
-	if boring.Enabled {
+	if boring.Enabled() {
 		return boring.SHA384(data)
 	}
 	d := digest{function: crypto.SHA384}
diff --git a/src/crypto/sha512/sha512_test.go b/src/crypto/sha512/sha512_test.go
index 921cdbb..a35165b 100644
--- a/src/crypto/sha512/sha512_test.go
+++ b/src/crypto/sha512/sha512_test.go
@@ -8,7 +8,7 @@ package sha512
 
 import (
 	"bytes"
-	"crypto/internal/boring"
+	boring "crypto/internal/backend"
 	"crypto/rand"
 	"encoding"
 	"encoding/hex"
@@ -823,7 +823,7 @@ func TestBlockSize(t *testing.T) {
 
 // Tests that blockGeneric (pure Go) and block (in assembly for some architectures) match.
 func TestBlockGeneric(t *testing.T) {
-	if boring.Enabled {
+	if boring.Enabled() {
 		t.Skip("BoringCrypto doesn't expose digest")
 	}
 	gen, asm := New().(*digest), New().(*digest)
@@ -893,7 +893,7 @@ func TestLargeHashes(t *testing.T) {
 }
 
 func TestAllocations(t *testing.T) {
-	if boring.Enabled {
+	if boring.Enabled() {
 		t.Skip("BoringCrypto doesn't allocate the same way as stdlib")
 	}
 	in := []byte("hello, world!")
diff --git a/src/crypto/tls/boring.go b/src/crypto/tls/boring.go
index 239e6a2..28462e0 100644
--- a/src/crypto/tls/boring.go
+++ b/src/crypto/tls/boring.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build boringcrypto
+//go:build !no_openssl
 
 package tls
 
@@ -12,7 +12,7 @@ import (
 )
 
 func init() {
-       if boring.Enabled && !boring.ExecutingTest() {
+       if boring.Enabled() && !boring.ExecutingTest() {
                fipstls.Force()
        }
 }
diff --git a/src/crypto/tls/boring_test.go b/src/crypto/tls/boring_test.go
index f743fc8..e56d96d 100644
--- a/src/crypto/tls/boring_test.go
+++ b/src/crypto/tls/boring_test.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build boringcrypto
+//go:build !no_openssl
 
 package tls
 
diff --git a/src/crypto/tls/cipher_suites.go b/src/crypto/tls/cipher_suites.go
index 9a1fa31..b0b6052 100644
--- a/src/crypto/tls/cipher_suites.go
+++ b/src/crypto/tls/cipher_suites.go
@@ -10,7 +10,7 @@ import (
 	"crypto/cipher"
 	"crypto/des"
 	"crypto/hmac"
-	"crypto/internal/boring"
+	boring "crypto/internal/backend"
 	"crypto/rc4"
 	"crypto/sha1"
 	"crypto/sha256"
@@ -425,7 +425,7 @@ func macSHA1(key []byte) hash.Hash {
 	h := sha1.New
 	// The BoringCrypto SHA1 does not have a constant-time
 	// checksum function, so don't try to use it.
-	if !boring.Enabled {
+	if !boring.Enabled() {
 		h = newConstantTimeHash(h)
 	}
 	return hmac.New(h, key)
@@ -517,7 +517,7 @@ func aeadAESGCM(key, noncePrefix []byte) aead {
 		panic(err)
 	}
 	var aead cipher.AEAD
-	if boring.Enabled {
+	if boring.Enabled() {
 		aead, err = boring.NewGCMTLS(aes)
 	} else {
 		boring.Unreachable()
diff --git a/src/crypto/tls/notboring.go b/src/crypto/tls/notboring.go
index 7d85b39..fe27194 100644
--- a/src/crypto/tls/notboring.go
+++ b/src/crypto/tls/notboring.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build !boringcrypto
+//go:build no_openssl
 
 package tls
 
diff --git a/src/crypto/x509/boring.go b/src/crypto/x509/boring.go
index 4aae905..4f7c0ad 100644
--- a/src/crypto/x509/boring.go
+++ b/src/crypto/x509/boring.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build boringcrypto
+//go:build !no_openssl
 
 package x509
 
diff --git a/src/crypto/x509/boring_test.go b/src/crypto/x509/boring_test.go
index 7010f44..22efb08 100644
--- a/src/crypto/x509/boring_test.go
+++ b/src/crypto/x509/boring_test.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build boringcrypto
+//go:build !no_openssl
 
 package x509
 
diff --git a/src/crypto/x509/notboring.go b/src/crypto/x509/notboring.go
index c83a727..0c7dea2 100644
--- a/src/crypto/x509/notboring.go
+++ b/src/crypto/x509/notboring.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build !boringcrypto
+//go:build no_openssl
 
 package x509
 
diff --git a/src/go.mod b/src/go.mod
index 94380d6..0768c57 100644
--- a/src/go.mod
+++ b/src/go.mod
@@ -3,6 +3,7 @@ module std
 go 1.19
 
 require (
+	github.com/golang-fips/openssl-fips v0.0.0-20220914203141-60f04d7f65e2
 	golang.org/x/crypto v0.0.0-20220516162934-403b01795ae8
 	golang.org/x/net v0.0.0-20220517181318-183a9ca12b87
 )
diff --git a/src/go.sum b/src/go.sum
index a54b056..ddd5d69 100644
--- a/src/go.sum
+++ b/src/go.sum
@@ -1,3 +1,5 @@
+github.com/golang-fips/openssl-fips v0.0.0-20220914203141-60f04d7f65e2 h1:ZnpZRmIMhfs/ubxzWizPBAGhdHBkjb9DCDmtiWUGV84=
+github.com/golang-fips/openssl-fips v0.0.0-20220914203141-60f04d7f65e2/go.mod h1:V2IU8imz/VkScnIbTOrdYsZ5R88ZFypCE0LzhRJ3HsI=
 golang.org/x/crypto v0.0.0-20220516162934-403b01795ae8 h1:y+mHpWoQJNAHt26Nhh6JP7hvM71IRZureyvZhoVALIs=
 golang.org/x/crypto v0.0.0-20220516162934-403b01795ae8/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
 golang.org/x/net v0.0.0-20220517181318-183a9ca12b87 h1:cCR+9mKLOGyX4Zx+uBZDXEDAQsvKQ/XbW4vreG5v1jU=
diff --git a/src/vendor/github.com/golang-fips/openssl-fips/LICENSE b/src/vendor/github.com/golang-fips/openssl-fips/LICENSE
new file mode 100644
index 0000000..093267e
--- /dev/null
+++ b/src/vendor/github.com/golang-fips/openssl-fips/LICENSE
@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright (c) 2022 Red Hat, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/src/vendor/github.com/golang-fips/openssl-fips/openssl/aes.go b/src/vendor/github.com/golang-fips/openssl-fips/openssl/aes.go
new file mode 100644
index 0000000..079fc3c
--- /dev/null
+++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/aes.go
@@ -0,0 +1,516 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build linux && !android && !cmd_go_bootstrap && !msan && !no_openssl
+// +build linux,!android,!cmd_go_bootstrap,!msan,!no_openssl
+
+package openssl
+
+// #include "goopenssl.h"
+import "C"
+import (
+	"crypto/cipher"
+	"errors"
+	"runtime"
+	"strconv"
+	"unsafe"
+)
+
+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.EVP_CIPHER_CTX
+	dec_ctx *C.EVP_CIPHER_CTX
+	cipher  *C.EVP_CIPHER
+}
+
+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) {
+	c := &aesCipher{key: make([]byte, len(key))}
+	copy(c.key, key)
+
+	switch len(c.key) * 8 {
+	case 128:
+		c.cipher = C._goboringcrypto_EVP_aes_128_ecb()
+	case 192:
+		c.cipher = C._goboringcrypto_EVP_aes_192_ecb()
+	case 256:
+		c.cipher = C._goboringcrypto_EVP_aes_256_ecb()
+	default:
+		return nil, errors.New("crypto/cipher: Invalid key size")
+	}
+
+	runtime.SetFinalizer(c, (*aesCipher).finalize)
+
+	return c, nil
+}
+
+func (c *aesCipher) finalize() {
+	if c.enc_ctx != nil {
+		C._goboringcrypto_EVP_CIPHER_CTX_free(c.enc_ctx)
+	}
+	if c.dec_ctx != nil {
+		C._goboringcrypto_EVP_CIPHER_CTX_free(c.dec_ctx)
+	}
+}
+
+func (c *aesCipher) BlockSize() int { return aesBlockSize }
+
+func (c *aesCipher) Encrypt(dst, src []byte) {
+	if inexactOverlap(dst, src) {
+		panic("crypto/cipher: invalid buffer overlap")
+	}
+	if len(src) < aesBlockSize {
+		panic("crypto/aes: input not full block")
+	}
+	if len(dst) < aesBlockSize {
+		panic("crypto/aes: output not full block")
+	}
+
+	if c.enc_ctx == nil {
+		c.enc_ctx = C._goboringcrypto_EVP_CIPHER_CTX_new()
+		if c.enc_ctx == nil {
+			panic("cipher: unable to create EVP cipher ctx")
+		}
+
+		k := (*C.uchar)(unsafe.Pointer(&c.key[0]))
+
+		if C.int(1) != C._goboringcrypto_EVP_CipherInit_ex(c.enc_ctx, c.cipher, nil, k, nil, C.GO_AES_ENCRYPT) {
+			panic("cipher: unable to initialize EVP cipher ctx")
+		}
+	}
+
+	outlen := C.int(0)
+	C._goboringcrypto_EVP_CipherUpdate(c.enc_ctx, (*C.uchar)(unsafe.Pointer(&dst[0])), &outlen, (*C.uchar)(unsafe.Pointer(&src[0])), C.int(aesBlockSize))
+	runtime.KeepAlive(c)
+}
+
+func (c *aesCipher) Decrypt(dst, src []byte) {
+	if inexactOverlap(dst, src) {
+		panic("crypto/cipher: invalid buffer overlap")
+	}
+	if len(src) < aesBlockSize {
+		panic("crypto/aes: input not full block")
+	}
+	if len(dst) < aesBlockSize {
+		panic("crypto/aes: output not full block")
+	}
+	if c.dec_ctx == nil {
+		c.dec_ctx = C._goboringcrypto_EVP_CIPHER_CTX_new()
+		if c.dec_ctx == nil {
+			panic("cipher: unable to create EVP cipher ctx")
+		}
+
+		k := (*C.uchar)(unsafe.Pointer(&c.key[0]))
+
+		if C.int(1) != C._goboringcrypto_EVP_CipherInit_ex(c.dec_ctx, c.cipher, nil, k, nil, C.GO_AES_DECRYPT) {
+			panic("cipher: unable to initialize EVP cipher ctx")
+		}
+	}
+	// Workaround - padding detection is broken but we don't need it
+	// since we check for full blocks
+	if C._goboringcrypto_EVP_CIPHER_CTX_set_padding(c.dec_ctx, 0) != 1 {
+		panic("crypto/cipher: could not disable cipher padding")
+	}
+	outlen := C.int(0)
+	C._goboringcrypto_EVP_CipherUpdate(c.dec_ctx, (*C.uchar)(unsafe.Pointer(&dst[0])), &outlen, (*C.uchar)(unsafe.Pointer(&src[0])), C.int(aesBlockSize))
+	runtime.KeepAlive(c)
+}
+
+type aesCBC struct {
+	key  []byte
+	mode C.int
+	iv   [aesBlockSize]byte
+	ctx  *C.EVP_CIPHER_CTX
+}
+
+func (x *aesCBC) BlockSize() int { return aesBlockSize }
+
+func (x *aesCBC) CryptBlocks(dst, src []byte) {
+	if inexactOverlap(dst, src) {
+		panic("crypto/cipher: invalid buffer overlap")
+	}
+	if len(src)%aesBlockSize != 0 {
+		panic("crypto/cipher: input not full blocks")
+	}
+	if len(dst) < len(src) {
+		panic("crypto/cipher: output smaller than input")
+	}
+	if len(src) > 0 {
+		outlen := C.int(0)
+		// Workaround - padding detection is broken but we don't need it
+		// since we check for full blocks
+		if C._goboringcrypto_EVP_CIPHER_CTX_set_padding(x.ctx, 0) != 1 {
+			panic("crypto/cipher: could not disable cipher padding")
+		}
+		if C._goboringcrypto_EVP_CipherUpdate(
+			x.ctx,
+			base(dst), &outlen,
+			base(src), C.int(len(src)),
+		) != 1 {
+			panic("crypto/cipher: CipherUpdate failed")
+		}
+		runtime.KeepAlive(x)
+	}
+}
+
+func (x *aesCBC) SetIV(iv []byte) {
+	if len(iv) != aesBlockSize {
+		panic("cipher: incorrect length IV")
+	}
+	copy(x.iv[:], iv)
+	if C.int(1) != C._goboringcrypto_EVP_CipherInit_ex(x.ctx, nil, nil, nil, (*C.uchar)(unsafe.Pointer(&x.iv[0])), -1) {
+		panic("cipher: unable to initialize EVP cipher ctx")
+	}
+}
+
+func (c *aesCipher) NewCBCEncrypter(iv []byte) cipher.BlockMode {
+	x := &aesCBC{key: c.key, mode: C.GO_AES_ENCRYPT}
+	copy(x.iv[:], iv)
+
+	x.ctx = C._goboringcrypto_EVP_CIPHER_CTX_new()
+	if x.ctx == nil {
+		panic("cipher: unable to create EVP cipher ctx")
+	}
+
+	k := (*C.uchar)(unsafe.Pointer(&x.key[0]))
+	vec := (*C.uchar)(unsafe.Pointer(&x.iv[0]))
+
+	var cipher *C.EVP_CIPHER
+	switch len(c.key) * 8 {
+	case 128:
+		cipher = C._goboringcrypto_EVP_aes_128_cbc()
+	case 192:
+		cipher = C._goboringcrypto_EVP_aes_192_cbc()
+	case 256:
+		cipher = C._goboringcrypto_EVP_aes_256_cbc()
+	default:
+		panic("crypto/boring: unsupported key length")
+	}
+	if C.int(1) != C._goboringcrypto_EVP_CipherInit_ex(x.ctx, cipher, nil, k, vec, x.mode) {
+		panic("cipher: unable to initialize EVP cipher ctx")
+	}
+
+	runtime.SetFinalizer(x, (*aesCBC).finalize)
+
+	return x
+}
+
+func (c *aesCBC) finalize() {
+	C._goboringcrypto_EVP_CIPHER_CTX_free(c.ctx)
+}
+
+func (c *aesCipher) NewCBCDecrypter(iv []byte) cipher.BlockMode {
+	x := &aesCBC{key: c.key, mode: C.GO_AES_DECRYPT}
+	copy(x.iv[:], iv)
+
+	x.ctx = C._goboringcrypto_EVP_CIPHER_CTX_new()
+	if x.ctx == nil {
+		panic("cipher: unable to create EVP cipher ctx")
+	}
+
+	k := (*C.uchar)(unsafe.Pointer(&x.key[0]))
+	vec := (*C.uchar)(unsafe.Pointer(&x.iv[0]))
+
+	var cipher *C.EVP_CIPHER
+	switch len(c.key) * 8 {
+	case 128:
+		cipher = C._goboringcrypto_EVP_aes_128_cbc()
+	case 192:
+		cipher = C._goboringcrypto_EVP_aes_192_cbc()
+	case 256:
+		cipher = C._goboringcrypto_EVP_aes_256_cbc()
+	default:
+		panic("crypto/boring: unsupported key length")
+	}
+	if C.int(1) != C._goboringcrypto_EVP_CipherInit_ex(x.ctx, cipher, nil, k, vec, x.mode) {
+		panic("cipher: unable to initialize EVP cipher ctx")
+	}
+	if C.int(1) != C._goboringcrypto_EVP_CIPHER_CTX_set_padding(x.ctx, 0) {
+		panic("cipher: unable to set padding")
+	}
+
+	runtime.SetFinalizer(x, (*aesCBC).finalize)
+	return x
+}
+
+type aesCTR struct {
+	key        []byte
+	iv         [aesBlockSize]byte
+	ctx        *C.EVP_CIPHER_CTX
+	num        C.uint
+	ecount_buf [16]C.uint8_t
+}
+
+func (x *aesCTR) XORKeyStream(dst, src []byte) {
+	if inexactOverlap(dst, src) {
+		panic("crypto/cipher: invalid buffer overlap")
+	}
+	if len(dst) < len(src) {
+		panic("crypto/cipher: output smaller than input")
+	}
+	if len(src) == 0 {
+		return
+	}
+	C._goboringcrypto_EVP_AES_ctr128_enc(
+		x.ctx,
+		(*C.uint8_t)(unsafe.Pointer(&src[0])),
+		(*C.uint8_t)(unsafe.Pointer(&dst[0])),
+		C.size_t(len(src)))
+	runtime.KeepAlive(x)
+}
+
+func (c *aesCipher) NewCTR(iv []byte) cipher.Stream {
+	x := &aesCTR{key: c.key}
+	copy(x.iv[:], iv)
+
+	x.ctx = C._goboringcrypto_EVP_CIPHER_CTX_new()
+	if x.ctx == nil {
+		panic("cipher: unable to create EVP cipher ctx")
+	}
+
+	k := (*C.uchar)(unsafe.Pointer(&x.key[0]))
+	vec := (*C.uchar)(unsafe.Pointer(&x.iv[0]))
+
+	switch len(c.key) * 8 {
+	case 128:
+		if C.int(1) != C._goboringcrypto_EVP_EncryptInit_ex(x.ctx, C._goboringcrypto_EVP_aes_128_ctr(), nil, k, vec) {
+			panic("cipher: unable to initialize EVP cipher ctx")
+		}
+	case 192:
+		if C.int(1) != C._goboringcrypto_EVP_EncryptInit_ex(x.ctx, C._goboringcrypto_EVP_aes_192_ctr(), nil, k, vec) {
+			panic("cipher: unable to initialize EVP cipher ctx")
+		}
+	case 256:
+		if C.int(1) != C._goboringcrypto_EVP_EncryptInit_ex(x.ctx, C._goboringcrypto_EVP_aes_256_ctr(), nil, k, vec) {
+			panic("cipher: unable to initialize EVP cipher ctx")
+		}
+	}
+
+	runtime.SetFinalizer(x, (*aesCTR).finalize)
+
+	return x
+}
+
+func (c *aesCTR) finalize() {
+	C._goboringcrypto_EVP_CIPHER_CTX_free(c.ctx)
+}
+
+type aesGCM struct {
+	key []byte
+	tls bool
+}
+
+const (
+	gcmBlockSize         = 16
+	gcmTagSize           = 16
+	gcmStandardNonceSize = 12
+)
+
+type aesNonceSizeError int
+
+func (n aesNonceSizeError) Error() string {
+	return "crypto/aes: invalid GCM nonce size " + strconv.Itoa(int(n))
+}
+
+type noGCM struct {
+	cipher.Block
+}
+
+func (c *aesCipher) NewGCM(nonceSize, tagSize int) (cipher.AEAD, error) {
+	if !ExecutingTest() || IsStrictFips() {
+		if nonceSize != gcmStandardNonceSize {
+			return nil, errors.New("crypto/aes: GCM nonce size can't be non-standard")
+		}
+		if tagSize != gcmTagSize {
+			return nil, errors.New("crypto/aes: GCM tag size can't be non-standard")
+		}
+	} else {
+		// Be more lenient if we're running via a test binary so that
+		// we don't have to be as invasive with skipping tests in the standard
+		// library.
+		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")
+		}
+		// Fall back to standard library for GCM with non-standard nonce or tag size.
+		if nonceSize != gcmStandardNonceSize {
+			return cipher.NewGCMWithNonceSize(&noGCM{c}, nonceSize)
+		}
+		if tagSize != gcmTagSize {
+			return cipher.NewGCMWithTagSize(&noGCM{c}, tagSize)
+		}
+	}
+	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) {
+	keyLen := len(c.key) * 8
+
+	if keyLen != 128 && keyLen != 256 {
+		if ExecutingTest() {
+			// Fall back to standard library for GCM with non-standard key size.
+			return cipher.NewGCMWithNonceSize(&noGCM{c}, gcmStandardNonceSize)
+		}
+		// Return error for GCM with non-standard key size.
+		return nil, fail("GCM invoked with non-standard key size")
+	}
+
+	g := &aesGCM{key: c.key, tls: tls}
+	if g.NonceSize() != gcmStandardNonceSize {
+		panic("boringcrypto: internal confusion about nonce size")
+	}
+	if g.Overhead() != gcmTagSize {
+		panic("boringcrypto: internal confusion about tag size")
+	}
+
+	return g, nil
+}
+
+func (g *aesGCM) NonceSize() int {
+	return gcmStandardNonceSize
+}
+
+func (g *aesGCM) Overhead() int {
+	return gcmTagSize
+}
+
+// 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.uint8_t {
+	if len(b) == 0 {
+		return nil
+	}
+	return (*C.uint8_t)(unsafe.Pointer(&b[0]))
+}
+
+func (g *aesGCM) 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) {
+		panic("cipher: message too large for GCM")
+	}
+	if len(dst)+len(plaintext)+gcmTagSize < len(dst) {
+		panic("cipher: message too large for buffer")
+	}
+
+	// Make room in dst to append plaintext+overhead.
+	n := len(dst)
+	for cap(dst) < n+len(plaintext)+gcmTagSize {
+		dst = append(dst[:cap(dst)], 0)
+	}
+	dst = dst[:n+len(plaintext)+gcmTagSize]
+
+	// Check delayed until now to make sure len(dst) is accurate.
+	if inexactOverlap(dst[n:], plaintext) {
+		panic("cipher: invalid buffer overlap")
+	}
+
+	var ciphertextLen C.size_t
+
+	if ok := C._goboringcrypto_EVP_CIPHER_CTX_seal(
+		(*C.uint8_t)(unsafe.Pointer(&dst[n])),
+		base(nonce), base(additionalData), C.size_t(len(additionalData)),
+		base(plaintext), C.size_t(len(plaintext)), &ciphertextLen,
+		base(g.key), C.int(len(g.key)*8)); ok != 1 {
+		panic("boringcrypto: EVP_CIPHER_CTX_seal fail")
+	}
+	runtime.KeepAlive(g)
+
+	if ciphertextLen != C.size_t(len(plaintext)+gcmTagSize) {
+		panic("boringcrypto: [seal] internal confusion about GCM tag size")
+	}
+	return dst[:n+int(ciphertextLen)]
+}
+
+var errOpen = errors.New("cipher: message authentication failed")
+
+func (g *aesGCM) 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 {
+		return nil, errOpen
+	}
+
+	// Make room in dst to append ciphertext without tag.
+	n := len(dst)
+	for cap(dst) < n+len(ciphertext)-gcmTagSize {
+		dst = append(dst[:cap(dst)], 0)
+	}
+	dst = dst[:n+len(ciphertext)-gcmTagSize]
+
+	// Check delayed until now to make sure len(dst) is accurate.
+	if inexactOverlap(dst[n:], ciphertext) {
+		panic("cipher: invalid buffer overlap")
+	}
+
+	tag := ciphertext[len(ciphertext)-gcmTagSize:]
+
+	var outLen C.size_t
+
+	ok := C._goboringcrypto_EVP_CIPHER_CTX_open(
+		base(ciphertext), C.int(len(ciphertext)-gcmTagSize),
+		base(additionalData), C.int(len(additionalData)),
+		base(tag), base(g.key), C.int(len(g.key)*8),
+		base(nonce), C.int(len(nonce)),
+		base(dst[n:]), &outLen)
+	runtime.KeepAlive(g)
+	if ok == 0 {
+		// Zero output buffer on error.
+		for i := range dst {
+			dst[i] = 0
+		}
+		return nil, errOpen
+	}
+	if outLen != C.size_t(len(ciphertext)-gcmTagSize) {
+		panic("boringcrypto: [open] internal confusion about GCM tag size")
+	}
+	return dst[:n+int(outLen)], nil
+}
+
+func anyOverlap(x, y []byte) bool {
+	return len(x) > 0 && len(y) > 0 &&
+		uintptr(unsafe.Pointer(&x[0])) <= uintptr(unsafe.Pointer(&y[len(y)-1])) &&
+		uintptr(unsafe.Pointer(&y[0])) <= uintptr(unsafe.Pointer(&x[len(x)-1]))
+}
+
+func inexactOverlap(x, y []byte) bool {
+	if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] {
+		return false
+	}
+	return anyOverlap(x, y)
+}
diff --git a/src/vendor/github.com/golang-fips/openssl-fips/openssl/doc.go b/src/vendor/github.com/golang-fips/openssl-fips/openssl/doc.go
new file mode 100644
index 0000000..cdc7f6a
--- /dev/null
+++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/doc.go
@@ -0,0 +1,17 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// package openssl provides access to OpenSSL implementation functions.
+package openssl
+
+// Enabled returns whether or not the boring package is enabled. When
+// the boring package is enabled that means FIPS mode is enabled.
+func Enabled() bool {
+	return enabled
+}
+
+// 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 crypto/internal/boring/bbig.
+type BigInt []uint
diff --git a/src/vendor/github.com/golang-fips/openssl-fips/openssl/ecdh.go b/src/vendor/github.com/golang-fips/openssl-fips/openssl/ecdh.go
new file mode 100644
index 0000000..0b61e79
--- /dev/null
+++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/ecdh.go
@@ -0,0 +1,108 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build linux && !android && !cmd_go_bootstrap && !msan && !no_openssl
+// +build linux,!android,!cmd_go_bootstrap,!msan,!no_openssl
+
+package openssl
+
+// #include "goopenssl.h"
+import "C"
+import "runtime"
+
+// ECDH keys are compatible with ECDSA
+type PublicKeyECDH = PublicKeyECDSA
+type PrivateKeyECDH = PrivateKeyECDSA
+
+var NewPublicKeyECDH = NewPublicKeyECDSA
+var NewPrivateKeyECDH = NewPrivateKeyECDSA
+var GenerateKeyECDH = GenerateKeyECDSA
+
+func (k *PrivateKeyECDH) withKey(f func(*C.GO_EC_KEY) C.int) C.int {
+	// Because of the finalizer, any time _key 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.key)
+}
+
+func (k *PublicKeyECDH) withKey(f func(*C.GO_EC_KEY) C.int) C.int {
+	// Because of the finalizer, any time _key 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.key)
+}
+
+func getPeerKey(priv *PrivateKeyECDH, pubBytes []byte) (*PublicKeyECDH, error) {
+	eckey := C._goboringcrypto_EC_KEY_new()
+	if priv.withKey(func(key *C.GO_EC_KEY) C.int {
+		group := C._goboringcrypto_EC_KEY_get0_group(key)
+		return C._goboringcrypto_EC_KEY_set_group(eckey, group)
+	}) != 1 {
+		return nil, NewOpenSSLError("EC_KEY_set_group")
+	}
+	if C._goboringcrypto_EC_KEY_oct2key(eckey,
+		base(pubBytes), C.size_t(len(pubBytes)),
+		nil) != 1 {
+		return nil, NewOpenSSLError("EC_KEY_oct2key")
+	}
+	k := &PublicKeyECDSA{eckey}
+	// Note: Because of the finalizer, any time k.key is passed to cgo,
+	// that call must be followed by a call to runtime.KeepAlive(k),
+	// to make sure k is not collected (and finalized) before the cgo
+	// call returns.
+	runtime.SetFinalizer(k, (*PublicKeyECDH).finalize)
+	return k, nil
+}
+
+func SharedKeyECDH(priv *PrivateKeyECDH, peerPublicKey []byte) ([]byte, error) {
+	pkeyOurs := C._goboringcrypto_EVP_PKEY_new()
+	if pkeyOurs == nil {
+		return nil, NewOpenSSLError("EVP_PKEY_new failed")
+	}
+	defer C._goboringcrypto_EVP_PKEY_free(pkeyOurs)
+	if priv.withKey(func(key *C.GO_EC_KEY) C.int {
+		return C._goboringcrypto_EVP_PKEY_set1_EC_KEY(pkeyOurs, key)
+	}) != 1 {
+		return nil, NewOpenSSLError("EVP_PKEY_set1_EC_KEY")
+	}
+
+	pub, err := getPeerKey(priv, peerPublicKey)
+	if err != nil {
+		return nil, err
+	}
+
+	pkeyPeers := C._goboringcrypto_EVP_PKEY_new()
+	if pkeyPeers == nil {
+		return nil, NewOpenSSLError("EVP_PKEY_new failed")
+	}
+	defer C._goboringcrypto_EVP_PKEY_free(pkeyPeers)
+	if pub.withKey(func(key *C.GO_EC_KEY) C.int {
+		return C._goboringcrypto_EVP_PKEY_set1_EC_KEY(pkeyPeers, key)
+	}) != 1 {
+		return nil, NewOpenSSLError("EVP_PKEY_set1_EC_KEY")
+	}
+
+	ctx := C._goboringcrypto_EVP_PKEY_CTX_new(pkeyOurs, nil)
+	if ctx == nil {
+		return nil, NewOpenSSLError("EVP_PKEY_CTX_new failed")
+	}
+	defer C._goboringcrypto_EVP_PKEY_CTX_free(ctx)
+	if C._goboringcrypto_EVP_PKEY_derive_init(ctx) != 1 {
+		return nil, NewOpenSSLError("EVP_PKEY_derive_init failed")
+	}
+	if C._goboringcrypto_EVP_PKEY_derive_set_peer_ex(ctx, pkeyPeers, 1) != 1 {
+		return nil, NewOpenSSLError("EVP_PKEY_derive_set_peer_ex failed")
+	}
+	var outLen C.size_t
+	if C._goboringcrypto_EVP_PKEY_derive(ctx, nil, &outLen) != 1 {
+		return nil, NewOpenSSLError("EVP_PKEY_derive_init failed")
+	}
+	out := make([]byte, outLen)
+	if C._goboringcrypto_EVP_PKEY_derive(ctx, base(out), &outLen) != 1 {
+		return nil, NewOpenSSLError("EVP_PKEY_derive_init failed")
+	}
+	return out[:outLen], nil
+}
diff --git a/src/crypto/internal/boring/ecdsa.go b/src/vendor/github.com/golang-fips/openssl-fips/openssl/ecdsa.go
similarity index 73%
rename from src/crypto/internal/boring/ecdsa.go
rename to src/vendor/github.com/golang-fips/openssl-fips/openssl/ecdsa.go
index 884c4b7..eb63507 100644
--- a/src/crypto/internal/boring/ecdsa.go
+++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/ecdsa.go
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build boringcrypto && linux && amd64 && !android && !cmd_go_bootstrap && !msan
-// +build boringcrypto,linux,amd64,!android,!cmd_go_bootstrap,!msan
+//go:build linux && !android && !cmd_go_bootstrap && !msan && !no_openssl
+// +build linux,!android,!cmd_go_bootstrap,!msan,!no_openssl
 
-package boring
+package openssl
 
-// #include "goboringcrypto.h"
+// #include "goopenssl.h"
 import "C"
 import (
 	"errors"
@@ -36,11 +36,15 @@ func (k *PublicKeyECDSA) finalize() {
 }
 
 var errUnknownCurve = errors.New("boringcrypto: unknown elliptic curve")
+var errUnsupportedCurve = errors.New("boringcrypto: unsupported elliptic curve")
 
 func curveNID(curve string) (C.int, error) {
 	switch curve {
 	case "P-224":
-		return C.GO_NID_secp224r1, nil
+		if ExecutingTest() {
+			return C.GO_NID_secp224r1, nil
+		}
+		return 0, errUnsupportedCurve
 	case "P-256":
 		return C.GO_NID_X9_62_prime256v1, nil
 	case "P-384":
@@ -72,13 +76,13 @@ func newECKey(curve string, X, Y BigInt) (*C.GO_EC_KEY, error) {
 	}
 	key := C._goboringcrypto_EC_KEY_new_by_curve_name(nid)
 	if key == nil {
-		return nil, fail("EC_KEY_new_by_curve_name")
+		return nil, NewOpenSSLError("EC_KEY_new_by_curve_name failed")
 	}
 	group := C._goboringcrypto_EC_KEY_get0_group(key)
 	pt := C._goboringcrypto_EC_POINT_new(group)
 	if pt == nil {
 		C._goboringcrypto_EC_KEY_free(key)
-		return nil, fail("EC_POINT_new")
+		return nil, NewOpenSSLError("EC_POINT_new failed")
 	}
 	bx := bigToBN(X)
 	by := bigToBN(Y)
@@ -93,7 +97,7 @@ func newECKey(curve string, X, Y BigInt) (*C.GO_EC_KEY, error) {
 	C._goboringcrypto_EC_POINT_free(pt)
 	if !ok {
 		C._goboringcrypto_EC_KEY_free(key)
-		return nil, fail("EC_POINT_set_affine_coordinates_GFp")
+		return nil, NewOpenSSLError("EC_POINT_free failed")
 	}
 	return key, nil
 }
@@ -110,7 +114,7 @@ func NewPrivateKeyECDSA(curve string, X, Y BigInt, D BigInt) (*PrivateKeyECDSA,
 	}
 	if !ok {
 		C._goboringcrypto_EC_KEY_free(key)
-		return nil, fail("EC_KEY_set_private_key")
+		return nil, NewOpenSSLError("EC_KEY_set_private_key failed")
 	}
 	k := &PrivateKeyECDSA{key}
 	// Note: Because of the finalizer, any time k.key is passed to cgo,
@@ -125,15 +129,16 @@ func SignMarshalECDSA(priv *PrivateKeyECDSA, hash []byte) ([]byte, error) {
 	size := C._goboringcrypto_ECDSA_size(priv.key)
 	sig := make([]byte, size)
 	var sigLen C.uint
-	if C._goboringcrypto_ECDSA_sign(0, base(hash), C.size_t(len(hash)), (*C.uint8_t)(unsafe.Pointer(&sig[0])), &sigLen, priv.key) == 0 {
-		return nil, fail("ECDSA_sign")
+	ok := C._goboringcrypto_internal_ECDSA_sign(0, base(hash), C.size_t(len(hash)), (*C.uint8_t)(unsafe.Pointer(&sig[0])), &sigLen, priv.key) > 0
+	if !ok {
+		return nil, NewOpenSSLError(("ECDSA_sign failed"))
 	}
+
 	runtime.KeepAlive(priv)
 	return sig[:sigLen], nil
 }
-
 func VerifyECDSA(pub *PublicKeyECDSA, hash []byte, sig []byte) bool {
-	ok := C._goboringcrypto_ECDSA_verify(0, base(hash), C.size_t(len(hash)), (*C.uint8_t)(unsafe.Pointer(&sig[0])), C.size_t(len(sig)), pub.key) != 0
+	ok := C._goboringcrypto_internal_ECDSA_verify(0, base(hash), C.size_t(len(hash)), (*C.uint8_t)(unsafe.Pointer(&sig[0])), C.uint(len(sig)), pub.key) > 0
 	runtime.KeepAlive(pub)
 	return ok
 }
@@ -145,30 +150,30 @@ func GenerateKeyECDSA(curve string) (X, Y, D BigInt, err error) {
 	}
 	key := C._goboringcrypto_EC_KEY_new_by_curve_name(nid)
 	if key == nil {
-		return nil, nil, nil, fail("EC_KEY_new_by_curve_name")
+		return nil, nil, nil, NewOpenSSLError("EC_KEY_new_by_curve_name failed")
 	}
 	defer C._goboringcrypto_EC_KEY_free(key)
-	if C._goboringcrypto_EC_KEY_generate_key_fips(key) == 0 {
-		return nil, nil, nil, fail("EC_KEY_generate_key_fips")
+	if C._goboringcrypto_EC_KEY_generate_key(key) == 0 {
+		return nil, nil, nil, NewOpenSSLError("EC_KEY_generate_key failed")
 	}
 	group := C._goboringcrypto_EC_KEY_get0_group(key)
 	pt := C._goboringcrypto_EC_KEY_get0_public_key(key)
 	bd := C._goboringcrypto_EC_KEY_get0_private_key(key)
 	if pt == nil || bd == nil {
-		return nil, nil, nil, fail("EC_KEY_get0_private_key")
+		return nil, nil, nil, NewOpenSSLError("EC_KEY_get0_private_key failed")
 	}
 	bx := C._goboringcrypto_BN_new()
 	if bx == nil {
-		return nil, nil, nil, fail("BN_new")
+		return nil, nil, nil, NewOpenSSLError("BN_new failed")
 	}
 	defer C._goboringcrypto_BN_free(bx)
 	by := C._goboringcrypto_BN_new()
 	if by == nil {
-		return nil, nil, nil, fail("BN_new")
+		return nil, nil, nil, NewOpenSSLError("BN_new failed")
 	}
 	defer C._goboringcrypto_BN_free(by)
 	if C._goboringcrypto_EC_POINT_get_affine_coordinates_GFp(group, pt, bx, by, nil) == 0 {
-		return nil, nil, nil, fail("EC_POINT_get_affine_coordinates_GFp")
+		return nil, nil, nil, NewOpenSSLError("EC_POINT_get_affine_coordinates_GFp failed")
 	}
 	return bnToBig(bx), bnToBig(by), bnToBig(bd), nil
 }
diff --git a/src/vendor/github.com/golang-fips/openssl-fips/openssl/goopenssl.h b/src/vendor/github.com/golang-fips/openssl-fips/openssl/goopenssl.h
new file mode 100644
index 0000000..6d6a562
--- /dev/null
+++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/goopenssl.h
@@ -0,0 +1,869 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+// +build linux
+// +build !android
+// +build !no_openssl
+// +build !cmd_go_bootstrap
+// +build !msan
+
+// This header file describes the OpenSSL ABI as built for use in Go.
+
+#include <stdlib.h> // size_t
+#include <stdint.h> // uint8_t
+
+#include <openssl/ossl_typ.h>
+
+#if OPENSSL_VERSION_NUMBER < 0x30000000
+#define OPENSSL_DLSYM_CALL(handle, func) dlsym(handle, func)
+#else
+#define __USE_GNU
+#define OPENSSL_DLSYM_CALL(handle, func) dlvsym(handle, func, "OPENSSL_3.0.0")
+#endif
+
+#include <dlfcn.h>
+
+#define unlikely(x) __builtin_expect(!!(x), 0)
+#define DEFINEFUNC(ret, func, args, argscall)        \
+	typedef ret(*_goboringcrypto_PTR_##func) args;   \
+	static _goboringcrypto_PTR_##func _g_##func = 0; \
+	static inline ret _goboringcrypto_##func args    \
+	{                                                \
+		if (unlikely(!_g_##func))                    \
+		{                                            \
+			_g_##func = OPENSSL_DLSYM_CALL(handle, #func); \
+		}                                            \
+		return _g_##func argscall;                   \
+	}
+
+#define DEFINEFUNCINTERNAL(ret, func, args, argscall)        \
+	typedef ret(*_goboringcrypto_internal_PTR_##func) args;   \
+	static _goboringcrypto_internal_PTR_##func _g_internal_##func = 0; \
+	static inline ret _goboringcrypto_internal_##func args    \
+	{                                                \
+		if (unlikely(!_g_internal_##func))                    \
+		{                                            \
+			_g_internal_##func = OPENSSL_DLSYM_CALL(handle, #func); \
+		}                                            \
+		return _g_internal_##func argscall;                   \
+	}
+
+#define DEFINEMACRO(ret, func, args, argscall)    \
+	static inline ret _goboringcrypto_##func args \
+	{                                             \
+		return func argscall;                     \
+	}
+
+
+static void* handle;
+static void*
+_goboringcrypto_DLOPEN_OPENSSL(void)
+{
+	if (handle)
+	{
+		return handle;
+	}
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+	handle = dlopen("libcrypto.so.10", RTLD_NOW | RTLD_GLOBAL);
+#elif OPENSSL_VERSION_NUMBER < 0x30000000L
+	handle = dlopen("libcrypto.so.1.1", RTLD_NOW | RTLD_GLOBAL);
+#else
+	handle = dlopen("libcrypto.so.3", RTLD_NOW | RTLD_GLOBAL);
+#endif
+	return handle;
+}
+
+#include <openssl/opensslv.h>
+#include <openssl/ssl.h>
+
+DEFINEFUNCINTERNAL(void, OPENSSL_init, (void), ())
+
+static unsigned long _goboringcrypto_internal_OPENSSL_VERSION_NUMBER(void) {
+	return OPENSSL_VERSION_NUMBER;
+}
+
+static void
+_goboringcrypto_OPENSSL_setup(void) {
+	_goboringcrypto_internal_OPENSSL_init();
+}
+
+#include <openssl/err.h>
+DEFINEFUNCINTERNAL(void, ERR_print_errors_fp, (FILE* fp), (fp))
+#if OPENSSL_VERSION_NUMBER < 0x30000000
+DEFINEFUNCINTERNAL(unsigned long, ERR_get_error_line_data,
+		   (const char **file, int *line, const char **data, int *flags),
+		   (file, line, data, flags))
+static inline unsigned long
+_goboringcrypto_internal_ERR_get_error_all(const char **file, int *line, const char **func, const char **data, int *flags)
+{
+	unsigned long e = _goboringcrypto_internal_ERR_get_error_line_data(file, line, data, flags);
+	if (e == 0 && func != NULL) {
+		*func = "unknown";
+	}
+	return e;
+}
+#else
+DEFINEFUNCINTERNAL(unsigned long, ERR_get_error_all,
+		(const char **file, int *line, const char **func, const char **data, int *flags),
+		(file, line, func, data, flags))
+#endif
+DEFINEFUNCINTERNAL(void, ERR_error_string_n, (unsigned long e, unsigned char *buf, size_t len), (e, buf, len))
+
+#include <openssl/crypto.h>
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+DEFINEFUNC(int, CRYPTO_num_locks, (void), ())
+#else
+static inline int
+_goboringcrypto_CRYPTO_num_locks(void) {
+	return CRYPTO_num_locks(); /* defined as macro */
+}
+#endif
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+DEFINEFUNC(void, CRYPTO_set_id_callback, (unsigned long (*id_function)(void)), (id_function))
+#else
+static inline void
+_goboringcrypto_CRYPTO_set_id_callback(unsigned long (*id_function)(void)) {
+	CRYPTO_set_id_callback(id_function); /* defined as macro */
+}
+#endif
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+DEFINEFUNC(void, CRYPTO_set_locking_callback,
+	(void (*locking_function)(int mode, int n, const char *file, int line)), 
+	(locking_function))
+#else
+static inline void
+_goboringcrypto_CRYPTO_set_locking_callback(void (*locking_function)(int mode, int n, const char *file, int line)) {
+	CRYPTO_set_locking_callback(locking_function); /* defined as macro */
+}
+#endif
+
+int _goboringcrypto_OPENSSL_thread_setup(void);
+
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
+DEFINEFUNC(int, FIPS_mode, (void), ())
+DEFINEFUNC(int, FIPS_mode_set, (int r), (r))
+#else
+DEFINEFUNC(int, EVP_default_properties_is_fips_enabled, (OSSL_LIB_CTX *libctx), (libctx))
+static inline int _goboringcrypto_FIPS_mode(void) {
+	return _goboringcrypto_EVP_default_properties_is_fips_enabled(NULL);
+}
+#endif
+
+#include <openssl/rand.h>
+
+DEFINEFUNC(int, RAND_set_rand_method, (const RAND_METHOD *rand), (rand))
+DEFINEFUNC(const RAND_METHOD*, RAND_get_rand_method, (void), ())
+DEFINEFUNC(int, RAND_bytes, (uint8_t * arg0, size_t arg1), (arg0, arg1))
+
+int _goboringcrypto_stub_openssl_rand(void);
+int _goboringcrypto_restore_openssl_rand(void);
+int fbytes(unsigned char *buf, int num);
+
+
+#include <openssl/obj_mac.h>
+
+enum
+{
+	GO_NID_md5_sha1 = NID_md5_sha1,
+
+	GO_NID_secp224r1 = NID_secp224r1,
+	GO_NID_X9_62_prime256v1 = NID_X9_62_prime256v1,
+	GO_NID_secp384r1 = NID_secp384r1,
+	GO_NID_secp521r1 = NID_secp521r1,
+
+	GO_NID_sha224 = NID_sha224,
+	GO_NID_sha256 = NID_sha256,
+	GO_NID_sha384 = NID_sha384,
+	GO_NID_sha512 = NID_sha512,
+};
+
+#include <openssl/sha.h>
+
+typedef SHA_CTX GO_SHA_CTX;
+
+DEFINEFUNC(int, SHA1_Init, (GO_SHA_CTX * arg0), (arg0))
+DEFINEFUNC(int, SHA1_Update, (GO_SHA_CTX * arg0, const void *arg1, size_t arg2), (arg0, arg1, arg2))
+DEFINEFUNC(int, SHA1_Final, (uint8_t * arg0, GO_SHA_CTX *arg1), (arg0, arg1))
+
+typedef SHA256_CTX GO_SHA256_CTX;
+
+DEFINEFUNC(int, SHA224_Init, (GO_SHA256_CTX * arg0), (arg0))
+DEFINEFUNC(int, SHA224_Update, (GO_SHA256_CTX * arg0, const void *arg1, size_t arg2), (arg0, arg1, arg2))
+DEFINEFUNC(int, SHA224_Final, (uint8_t * arg0, GO_SHA256_CTX *arg1), (arg0, arg1))
+
+DEFINEFUNC(int, SHA256_Init, (GO_SHA256_CTX * arg0), (arg0))
+DEFINEFUNC(int, SHA256_Update, (GO_SHA256_CTX * arg0, const void *arg1, size_t arg2), (arg0, arg1, arg2))
+DEFINEFUNC(int, SHA256_Final, (uint8_t * arg0, GO_SHA256_CTX *arg1), (arg0, arg1))
+
+typedef SHA512_CTX GO_SHA512_CTX;
+DEFINEFUNC(int, SHA384_Init, (GO_SHA512_CTX * arg0), (arg0))
+DEFINEFUNC(int, SHA384_Update, (GO_SHA512_CTX * arg0, const void *arg1, size_t arg2), (arg0, arg1, arg2))
+DEFINEFUNC(int, SHA384_Final, (uint8_t * arg0, GO_SHA512_CTX *arg1), (arg0, arg1))
+
+DEFINEFUNC(int, SHA512_Init, (GO_SHA512_CTX * arg0), (arg0))
+DEFINEFUNC(int, SHA512_Update, (GO_SHA512_CTX * arg0, const void *arg1, size_t arg2), (arg0, arg1, arg2))
+DEFINEFUNC(int, SHA512_Final, (uint8_t * arg0, GO_SHA512_CTX *arg1), (arg0, arg1))
+
+#include <openssl/evp.h>
+
+typedef EVP_MD GO_EVP_MD;
+DEFINEFUNC(const GO_EVP_MD *, EVP_md4, (void), ())
+DEFINEFUNC(const GO_EVP_MD *, EVP_md5, (void), ())
+DEFINEFUNC(const GO_EVP_MD *, EVP_sha1, (void), ())
+DEFINEFUNC(const GO_EVP_MD *, EVP_sha224, (void), ())
+DEFINEFUNC(const GO_EVP_MD *, EVP_sha256, (void), ())
+DEFINEFUNC(const GO_EVP_MD *, EVP_sha384, (void), ())
+DEFINEFUNC(const GO_EVP_MD *, EVP_sha512, (void), ())
+DEFINEFUNC(const GO_EVP_MD *, EVP_md_null, (void), ())
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
+DEFINEFUNCINTERNAL(int, EVP_MD_type, (const GO_EVP_MD *arg0), (arg0))
+#else
+DEFINEFUNCINTERNAL(int, EVP_MD_get_type, (const GO_EVP_MD *arg0), (arg0))
+#endif
+DEFINEFUNCINTERNAL(size_t, EVP_MD_size, (const GO_EVP_MD *arg0), (arg0))
+DEFINEFUNCINTERNAL(const GO_EVP_MD*, EVP_md5_sha1, (void), ())
+
+# include <openssl/md5.h>
+DEFINEFUNCINTERNAL(int, MD5_Init, (MD5_CTX *c), (c))
+DEFINEFUNCINTERNAL(int, MD5_Update, (MD5_CTX *c, const void *data, size_t len), (c, data, len))
+DEFINEFUNCINTERNAL(int, MD5_Final, (unsigned char *md, MD5_CTX *c), (md, c))
+
+static inline int
+_goboringcrypto_EVP_MD_type(const GO_EVP_MD *md) {
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
+	return _goboringcrypto_internal_EVP_MD_type(md);
+#else
+	return _goboringcrypto_internal_EVP_MD_get_type(md);
+#endif
+}
+
+const GO_EVP_MD* _goboringcrypto_backport_EVP_md5_sha1(void);
+static inline const GO_EVP_MD*
+_goboringcrypto_EVP_md5_sha1(void) {
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+	return _goboringcrypto_backport_EVP_md5_sha1();
+#else
+	return _goboringcrypto_internal_EVP_md5_sha1();
+#endif
+}
+
+#include <openssl/hmac.h>
+
+typedef HMAC_CTX GO_HMAC_CTX;
+
+DEFINEFUNC(int, HMAC_Init_ex,
+		   (GO_HMAC_CTX * arg0, const void *arg1, int arg2, const GO_EVP_MD *arg3, ENGINE *arg4),
+		   (arg0, arg1, arg2, arg3, arg4))
+DEFINEFUNC(int, HMAC_Update, (GO_HMAC_CTX * arg0, const uint8_t *arg1, size_t arg2), (arg0, arg1, arg2))
+DEFINEFUNC(int, HMAC_Final, (GO_HMAC_CTX * arg0, uint8_t *arg1, unsigned int *arg2), (arg0, arg1, arg2))
+DEFINEFUNC(size_t, HMAC_CTX_copy, (GO_HMAC_CTX *dest, GO_HMAC_CTX *src), (dest, src))
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+DEFINEFUNCINTERNAL(void, HMAC_CTX_cleanup, (GO_HMAC_CTX * arg0), (arg0))
+static inline void
+_goboringcrypto_HMAC_CTX_free(HMAC_CTX *ctx) {
+   if (ctx != NULL) {
+       _goboringcrypto_HMAC_CTX_cleanup(ctx);
+       free(ctx);
+   }
+}
+#else
+DEFINEFUNC(void, HMAC_CTX_free, (GO_HMAC_CTX * arg0), (arg0))
+#endif
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+static inline size_t
+_goboringcrypto_HMAC_size(const GO_HMAC_CTX* arg0) {
+	return _goboringcrypto_internal_EVP_MD_size(arg0->md);
+}
+#else
+DEFINEFUNCINTERNAL(const EVP_MD*, HMAC_CTX_get_md, (const GO_HMAC_CTX* ctx), (ctx))
+# if OPENSSL_VERSION_NUMBER < 0x30000000L
+static inline size_t
+_goboringcrypto_HMAC_size(const GO_HMAC_CTX* arg0) {
+	const EVP_MD* md;
+	md = _goboringcrypto_internal_HMAC_CTX_get_md(arg0);
+	return _goboringcrypto_internal_EVP_MD_size(md);
+}
+# else
+DEFINEFUNCINTERNAL(size_t, EVP_MD_get_size, (const GO_EVP_MD *arg0), (arg0))
+static inline size_t
+_goboringcrypto_HMAC_size(const GO_HMAC_CTX* arg0) {
+	const EVP_MD* md;
+	md = _goboringcrypto_internal_HMAC_CTX_get_md(arg0);
+	return _goboringcrypto_internal_EVP_MD_get_size(md);
+}
+# endif
+#endif
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+DEFINEFUNCINTERNAL(void, HMAC_CTX_init, (GO_HMAC_CTX * arg0), (arg0))
+static inline GO_HMAC_CTX*
+_goboringcrypto_HMAC_CTX_new(void) {
+	GO_HMAC_CTX* ctx = malloc(sizeof(GO_HMAC_CTX));
+	if (ctx != NULL)
+		_goboringcrypto_internal_HMAC_CTX_init(ctx);
+	return ctx;
+}
+#else
+DEFINEFUNC(GO_HMAC_CTX*, HMAC_CTX_new, (void), ())
+#endif
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+static inline int
+_goboringcrypto_HMAC_CTX_reset(GO_HMAC_CTX* ctx) {
+	_goboringcrypto_HMAC_CTX_cleanup(ctx);
+	_goboringcrypto_HMAC_CTX_init(ctx);
+	return 0;
+}
+#else
+DEFINEFUNC(int, HMAC_CTX_reset, (GO_HMAC_CTX * arg0), (arg0))
+#endif
+
+int _goboringcrypto_HMAC_CTX_copy_ex(GO_HMAC_CTX *dest, const GO_HMAC_CTX *src);
+
+#include <openssl/evp.h>
+#include <openssl/aes.h>
+
+DEFINEFUNC(EVP_CIPHER_CTX *, EVP_CIPHER_CTX_new, (void), ())
+DEFINEFUNC(int, EVP_CIPHER_CTX_set_padding, (EVP_CIPHER_CTX *x, int padding), (x, padding))
+DEFINEFUNC(int, EVP_CipherInit_ex,
+		   (EVP_CIPHER_CTX * ctx, const EVP_CIPHER *type, ENGINE *impl, const unsigned char *key, const unsigned char *iv, int enc),
+		   (ctx, type, impl, key, iv, enc))
+DEFINEFUNC(int, EVP_CipherUpdate,
+		   (EVP_CIPHER_CTX * ctx, unsigned char *out, int *outl, const unsigned char *in, int inl),
+		   (ctx, out, outl, in, inl))
+
+void _goboringcrypto_EVP_AES_ctr128_enc(EVP_CIPHER_CTX *ctx, const uint8_t *in, uint8_t *out, size_t len);
+
+int _goboringcrypto_EVP_AES_encrypt(EVP_CIPHER_CTX *ctx, const uint8_t *in, size_t in_len, uint8_t *out);
+
+enum
+{
+	GO_AES_ENCRYPT = 1,
+	GO_AES_DECRYPT = 0
+};
+void _goboringcrypto_EVP_AES_cbc_encrypt(EVP_CIPHER_CTX *ctx, const uint8_t *arg0, uint8_t *arg1, size_t arg2, const uint8_t *a, const int arg5);
+DEFINEFUNC(void, AES_cbc_encrypt,
+		   (const unsigned char *in, unsigned char *out,
+                     size_t length, const AES_KEY *key,
+                     unsigned char *ivec, const int enc),
+		   (in, out, length, key, ivec, enc))
+
+void EVP_AES_cbc_enc(EVP_CIPHER_CTX *ctx, const uint8_t *in, uint8_t *out, size_t len);
+
+void EVP_AES_cbc_dec(EVP_CIPHER_CTX *ctx, const uint8_t *in, uint8_t *out, size_t len);
+
+typedef ENGINE GO_ENGINE;
+
+#include <openssl/bn.h>
+
+typedef BN_CTX GO_BN_CTX;
+typedef BIGNUM GO_BIGNUM;
+
+DEFINEFUNC(GO_BIGNUM *, BN_new, (void), ())
+DEFINEFUNC(void, BN_free, (GO_BIGNUM * arg0), (arg0))
+DEFINEFUNC(void, BN_clear_free, (GO_BIGNUM * arg0), (arg0))
+DEFINEFUNC(int, BN_set_word, (BIGNUM *a, BN_ULONG w), (a, w))
+DEFINEFUNC(unsigned int, BN_num_bits, (const GO_BIGNUM *arg0), (arg0))
+DEFINEFUNC(int, BN_is_negative, (const GO_BIGNUM *arg0), (arg0))
+DEFINEFUNC(GO_BIGNUM *, BN_bin2bn, (const uint8_t *arg0, size_t arg1, GO_BIGNUM *arg2), (arg0, arg1, arg2))
+DEFINEFUNC(GO_BIGNUM *, BN_lebin2bn, (const unsigned char *s, size_t len, BIGNUM *ret), (s, len, ret))
+DEFINEFUNC(int, BN_bn2lebinpad, (const BIGNUM *a, unsigned char *to, size_t tolen), (a, to, tolen))
+
+static inline unsigned int
+_goboringcrypto_BN_num_bytes(const GO_BIGNUM* a) {
+	return ((_goboringcrypto_BN_num_bits(a)+7)/8);
+}
+
+#include <openssl/ec.h>
+
+typedef EC_GROUP GO_EC_GROUP;
+
+DEFINEFUNC(GO_EC_GROUP *, EC_GROUP_new_by_curve_name, (int arg0), (arg0))
+DEFINEFUNC(void, EC_GROUP_free, (GO_EC_GROUP * arg0), (arg0))
+
+typedef EC_POINT GO_EC_POINT;
+
+DEFINEFUNC(GO_EC_POINT *, EC_POINT_new, (const GO_EC_GROUP *arg0), (arg0))
+DEFINEFUNC(void, EC_POINT_free, (GO_EC_POINT * arg0), (arg0))
+DEFINEFUNC(int, EC_POINT_get_affine_coordinates_GFp,
+		   (const GO_EC_GROUP *arg0, const GO_EC_POINT *arg1, GO_BIGNUM *arg2, GO_BIGNUM *arg3, GO_BN_CTX *arg4),
+		   (arg0, arg1, arg2, arg3, arg4))
+DEFINEFUNC(int, EC_POINT_set_affine_coordinates_GFp,
+		   (const GO_EC_GROUP *arg0, GO_EC_POINT *arg1, const GO_BIGNUM *arg2, const GO_BIGNUM *arg3, GO_BN_CTX *arg4),
+		   (arg0, arg1, arg2, arg3, arg4))
+
+typedef EC_KEY GO_EC_KEY;
+
+DEFINEFUNC(GO_EC_KEY *, EC_KEY_new, (void), ())
+DEFINEFUNC(GO_EC_KEY *, EC_KEY_new_by_curve_name, (int arg0), (arg0))
+DEFINEFUNC(int, EC_KEY_oct2key, (GO_EC_KEY *arg0, const unsigned char *arg1, size_t arg2, BN_CTX *arg3), (arg0, arg1, arg2, arg3))
+DEFINEFUNC(void, EC_KEY_free, (GO_EC_KEY * arg0), (arg0))
+DEFINEFUNC(const GO_EC_GROUP *, EC_KEY_get0_group, (const GO_EC_KEY *arg0), (arg0))
+DEFINEFUNC(int, EC_KEY_set_group, (GO_EC_KEY *arg0, const EC_GROUP *arg1), (arg0, arg1))
+DEFINEFUNC(int, EC_KEY_generate_key, (GO_EC_KEY * arg0), (arg0))
+DEFINEFUNC(int, EC_KEY_set_private_key, (GO_EC_KEY * arg0, const GO_BIGNUM *arg1), (arg0, arg1))
+DEFINEFUNC(int, EC_KEY_set_public_key, (GO_EC_KEY * arg0, const GO_EC_POINT *arg1), (arg0, arg1))
+DEFINEFUNC(const GO_BIGNUM *, EC_KEY_get0_private_key, (const GO_EC_KEY *arg0), (arg0))
+DEFINEFUNC(const GO_EC_POINT *, EC_KEY_get0_public_key, (const GO_EC_KEY *arg0), (arg0))
+
+// TODO: EC_KEY_check_fips?
+
+#include <openssl/ecdsa.h>
+
+typedef ECDSA_SIG GO_ECDSA_SIG;
+
+DEFINEFUNC(GO_ECDSA_SIG *, ECDSA_SIG_new, (void), ())
+DEFINEFUNC(void, ECDSA_SIG_free, (GO_ECDSA_SIG * arg0), (arg0))
+DEFINEFUNC(GO_ECDSA_SIG *, ECDSA_do_sign, (const uint8_t *arg0, size_t arg1, const GO_EC_KEY *arg2), (arg0, arg1, arg2))
+DEFINEFUNC(int, ECDSA_do_verify, (const uint8_t *arg0, size_t arg1, const GO_ECDSA_SIG *arg2, const GO_EC_KEY *arg3), (arg0, arg1, arg2, arg3))
+DEFINEFUNC(size_t, ECDSA_size, (const GO_EC_KEY *arg0), (arg0))
+
+DEFINEFUNCINTERNAL(int, ECDSA_sign, 
+	(int type, const unsigned char *dgst, size_t dgstlen, unsigned char *sig, unsigned int *siglen, EC_KEY *eckey),
+	(type, dgst, dgstlen, sig, siglen, eckey))
+
+DEFINEFUNCINTERNAL(int, ECDSA_verify, 
+	(int type, const unsigned char *dgst, size_t dgstlen, const unsigned char *sig, unsigned int siglen, EC_KEY *eckey),
+	(type, dgst, dgstlen, sig, siglen, eckey))
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+DEFINEFUNC(EVP_MD_CTX*, EVP_MD_CTX_create, (void), ())
+#else
+DEFINEFUNCINTERNAL(EVP_MD_CTX*, EVP_MD_CTX_new, (void), ())
+static inline EVP_MD_CTX* _goboringcrypto_EVP_MD_CTX_create(void) {
+	return _goboringcrypto_internal_EVP_MD_CTX_new();
+}
+#endif
+
+DEFINEFUNCINTERNAL(int, EVP_PKEY_assign,
+	(EVP_PKEY *pkey, int type, void *eckey),
+	(pkey, type, eckey))
+
+static inline int
+_goboringcrypto_EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, GO_EC_KEY *eckey) {
+	return _goboringcrypto_internal_EVP_PKEY_assign(pkey, EVP_PKEY_EC, (char *)(eckey));
+}
+
+static inline int
+_goboringcrypto_EVP_PKEY_assign_RSA(EVP_PKEY *pkey, RSA *rsa) {
+	return _goboringcrypto_internal_EVP_PKEY_assign(pkey, EVP_PKEY_RSA, (char *)(rsa));
+}
+
+DEFINEFUNC(int, EVP_DigestSignInit,
+	(EVP_MD_CTX* ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, const EVP_PKEY *pkey),
+	(ctx, pctx, type, e, pkey))
+
+DEFINEFUNC(int, EVP_DigestUpdate,
+	(EVP_MD_CTX* ctx, const void *d, size_t cnt),
+	(ctx, d, cnt))
+DEFINEFUNC(int, EVP_DigestSignFinal,
+	(EVP_MD_CTX* ctx, unsigned char *sig, unsigned int *siglen),
+	(ctx, sig, siglen))
+
+DEFINEFUNC(int, EVP_DigestVerifyInit,
+	(EVP_MD_CTX* ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, const EVP_PKEY *pkey),
+	(ctx, pctx, type, e, pkey))
+DEFINEFUNC(int, EVP_DigestVerifyFinal,
+	(EVP_MD_CTX* ctx, const uint8_t *sig, unsigned int siglen),
+	(ctx, sig, siglen))
+
+typedef RSA GO_RSA;
+int _goboringcrypto_EVP_sign(EVP_MD* md, EVP_PKEY_CTX *ctx, const uint8_t *msg, size_t msgLen, uint8_t *sig, unsigned int *slen, EVP_PKEY *eckey);
+int _goboringcrypto_EVP_sign_raw(EVP_MD *md, EVP_PKEY_CTX *ctx, const uint8_t *msg,
+                                                              size_t msgLen, uint8_t *sig, size_t *slen,
+                                                              GO_RSA *key);
+
+int _goboringcrypto_EVP_verify(EVP_MD* md, EVP_PKEY_CTX *ctx, const uint8_t *msg, size_t msgLen, const uint8_t *sig, unsigned int slen, EVP_PKEY *key);
+int _goboringcrypto_EVP_verify_raw(const uint8_t *msg, size_t msgLen,
+                               const uint8_t *sig, unsigned int slen,
+                               GO_RSA *key);
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+DEFINEFUNC(void, EVP_MD_CTX_destroy, (EVP_MD_CTX *ctx), (ctx))
+#else
+DEFINEFUNCINTERNAL(void, EVP_MD_CTX_free, (EVP_MD_CTX *ctx), (ctx))
+static inline void _goboringcrypto_EVP_MD_CTX_free(EVP_MD_CTX *ctx) {
+	return _goboringcrypto_internal_EVP_MD_CTX_free(ctx);
+}
+#endif
+
+int _goboringcrypto_ECDSA_sign(EVP_MD *md, const uint8_t *arg1, size_t arg2, uint8_t *arg3, unsigned int *arg4, GO_EC_KEY *arg5);
+int _goboringcrypto_ECDSA_verify(EVP_MD *md, const uint8_t *arg1, size_t arg2, const uint8_t *arg3, unsigned int arg4, GO_EC_KEY *arg5);
+
+#include <openssl/rsa.h>
+
+// Note: order of struct fields here is unchecked.
+typedef BN_GENCB GO_BN_GENCB;
+
+int _goboringcrypto_EVP_RSA_sign(EVP_MD* md, const uint8_t *msg, unsigned int msgLen, uint8_t *sig, unsigned int *slen, RSA *rsa);
+int _goboringcrypto_EVP_RSA_verify(EVP_MD* md, const uint8_t *msg, unsigned int msgLen, const uint8_t *sig, unsigned int slen, GO_RSA *rsa);
+
+DEFINEFUNC(GO_RSA *, RSA_new, (void), ())
+DEFINEFUNC(void, RSA_free, (GO_RSA * arg0), (arg0))
+DEFINEFUNC(int, RSA_private_encrypt,
+	(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding),
+	(flen, from, to, rsa, padding))
+DEFINEFUNC(int, RSA_public_decrypt,
+	(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding),
+	(flen, from, to, rsa, padding))
+DEFINEFUNC(int, RSA_sign,
+	(int arg0, const uint8_t *arg1, unsigned int arg2, uint8_t *arg3, unsigned int *arg4, GO_RSA *arg5),
+	(arg0, arg1, arg2, arg3, arg4, arg5))
+DEFINEFUNC(int, RSA_verify,
+	(int arg0, const uint8_t *arg1, unsigned int arg2, const uint8_t *arg3, unsigned int arg4, GO_RSA *arg5),
+	(arg0, arg1, arg2, arg3, arg4, arg5))
+DEFINEFUNC(int, RSA_generate_key_ex,
+	(GO_RSA * arg0, int arg1, GO_BIGNUM *arg2, GO_BN_GENCB *arg3),
+	(arg0, arg1, arg2, arg3))
+
+DEFINEFUNCINTERNAL(int, RSA_set0_factors,
+	(GO_RSA * rsa, GO_BIGNUM *p, GO_BIGNUM *q),
+	(rsa, p, q))
+
+static inline int
+_goboringcrypto_RSA_set0_factors(GO_RSA * r, GO_BIGNUM *p, GO_BIGNUM *q) {
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+    /* If the fields p and q in r are NULL, the corresponding input
+     * parameters MUST be non-NULL.
+     */
+    if ((r->p == NULL && p == NULL)
+        || (r->q == NULL && q == NULL))
+        return 0;
+
+    if (p != NULL) {
+        _goboringcrypto_BN_clear_free(r->p);
+        r->p = p;
+    }
+    if (q != NULL) {
+        _goboringcrypto_BN_clear_free(r->q);
+        r->q = q;
+    }
+
+    return 1;
+#else
+	return _goboringcrypto_internal_RSA_set0_factors(r, p, q);
+#endif
+}
+
+DEFINEFUNCINTERNAL(int, RSA_set0_crt_params,
+		   (GO_RSA * rsa, GO_BIGNUM *dmp1, GO_BIGNUM *dmp2, GO_BIGNUM *iqmp),
+		   (rsa, dmp1, dmp2, iqmp))
+
+static inline int
+_goboringcrypto_RSA_set0_crt_params(GO_RSA * r, GO_BIGNUM *dmp1, GO_BIGNUM *dmq1, GO_BIGNUM *iqmp) {
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+    /* If the fields dmp1, dmq1 and iqmp in r are NULL, the corresponding input
+     * parameters MUST be non-NULL.
+     */
+    if ((r->dmp1 == NULL && dmp1 == NULL)
+        || (r->dmq1 == NULL && dmq1 == NULL)
+        || (r->iqmp == NULL && iqmp == NULL))
+        return 0;
+
+    if (dmp1 != NULL) {
+        _goboringcrypto_BN_clear_free(r->dmp1);
+        r->dmp1 = dmp1;
+    }
+    if (dmq1 != NULL) {
+        _goboringcrypto_BN_clear_free(r->dmq1);
+        r->dmq1 = dmq1;
+    }
+    if (iqmp != NULL) {
+        _goboringcrypto_BN_clear_free(r->iqmp);
+        r->iqmp = iqmp;
+    }
+
+    return 1;
+#else
+	return _goboringcrypto_internal_RSA_set0_crt_params(r, dmp1, dmq1, iqmp);
+#endif
+}
+
+DEFINEFUNCINTERNAL(void, RSA_get0_crt_params,
+		   (const GO_RSA *r, const GO_BIGNUM **dmp1, const GO_BIGNUM **dmq1, const GO_BIGNUM **iqmp),
+		   (r, dmp1, dmq1, iqmp))
+static inline void
+_goboringcrypto_RSA_get0_crt_params(const GO_RSA *r, const GO_BIGNUM **dmp1, const GO_BIGNUM **dmq1, const GO_BIGNUM **iqmp) {
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+    if (dmp1 != NULL)
+        *dmp1 = r->dmp1;
+    if (dmq1 != NULL)
+        *dmq1 = r->dmq1;
+    if (iqmp != NULL)
+        *iqmp = r->iqmp;
+#else
+	_goboringcrypto_internal_RSA_get0_crt_params(r, dmp1, dmq1, iqmp);
+#endif
+}
+
+
+DEFINEFUNCINTERNAL(int, RSA_set0_key,
+		   (GO_RSA * r, GO_BIGNUM *n, GO_BIGNUM *e, GO_BIGNUM *d),
+		   (r, n, e, d))
+static inline int
+_goboringcrypto_RSA_set0_key(GO_RSA * r, GO_BIGNUM *n, GO_BIGNUM *e, GO_BIGNUM *d) {
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+    /* If the fields n and e in r are NULL, the corresponding input
+     * parameters MUST be non-NULL for n and e.  d may be
+     * left NULL (in case only the public key is used).
+     */
+    if ((r->n == NULL && n == NULL)
+        || (r->e == NULL && e == NULL))
+        return 0;
+
+    if (n != NULL) {
+        _goboringcrypto_BN_free(r->n);
+        r->n = n;
+    }
+    if (e != NULL) {
+        _goboringcrypto_BN_free(r->e);
+        r->e = e;
+    }
+    if (d != NULL) {
+        _goboringcrypto_BN_clear_free(r->d);
+        r->d = d;
+    }
+
+    return 1;
+#else
+	return _goboringcrypto_internal_RSA_set0_key(r, n, e, d);
+#endif
+}
+
+DEFINEFUNCINTERNAL(void, RSA_get0_factors,
+		   (const GO_RSA *rsa, const GO_BIGNUM **p, const GO_BIGNUM **q),
+		   (rsa, p, q))
+static inline void 
+_goboringcrypto_RSA_get0_factors(const GO_RSA *rsa, const GO_BIGNUM **p, const GO_BIGNUM **q) {
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+	if (p)
+		*p = rsa->p;
+	if (q)
+		*q = rsa->q;
+#else
+	_goboringcrypto_internal_RSA_get0_factors(rsa, p, q);
+#endif
+}
+
+DEFINEFUNCINTERNAL(void, RSA_get0_key,
+		   (const GO_RSA *rsa, const GO_BIGNUM **n, const GO_BIGNUM **e, const GO_BIGNUM **d),
+		   (rsa, n, e, d))
+static inline void 
+_goboringcrypto_RSA_get0_key(const GO_RSA *rsa, const GO_BIGNUM **n, const GO_BIGNUM **e, const GO_BIGNUM **d) {
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+	if (n)
+		*n = rsa->n;
+	if (e)
+		*e = rsa->e;
+	if (d)
+		*d = rsa->d;
+#else
+	_goboringcrypto_internal_RSA_get0_key(rsa, n, e, d);
+#endif
+}
+
+int _goboringcrypto_RSA_generate_key_fips(GO_RSA *, int, GO_BN_GENCB *);
+enum
+{
+	GO_RSA_PKCS1_PADDING = 1,
+	GO_RSA_NO_PADDING = 3,
+	GO_RSA_PKCS1_OAEP_PADDING = 4,
+	GO_RSA_PKCS1_PSS_PADDING = 6,
+};
+
+int _goboringcrypto_RSA_sign_pss_mgf1(GO_RSA *, unsigned int *out_len, uint8_t *out, unsigned int max_out, const uint8_t *in, unsigned int in_len, GO_EVP_MD *md, const GO_EVP_MD *mgf1_md, int salt_len);
+
+int _goboringcrypto_RSA_verify_pss_mgf1(GO_RSA *, const uint8_t *msg, unsigned int msg_len, GO_EVP_MD *md, const GO_EVP_MD *mgf1_md, int salt_len, const uint8_t *sig, unsigned int sig_len);
+
+DEFINEFUNC(unsigned int, RSA_size, (const GO_RSA *arg0), (arg0))
+DEFINEFUNC(int, RSA_check_key, (const GO_RSA *arg0), (arg0))
+
+DEFINEFUNC(int, EVP_EncryptInit_ex,
+	(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, ENGINE *impl, const unsigned char *key, const unsigned char *iv),
+	(ctx, type, impl, key, iv))
+DEFINEFUNC(int, EVP_EncryptUpdate,
+	(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl),
+	(ctx, out, outl, in, inl))
+DEFINEFUNC(int, EVP_EncryptFinal_ex,
+	(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl),
+	(ctx, out, outl))
+
+DEFINEFUNC(int, EVP_DecryptInit_ex,
+	(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, ENGINE *impl, const unsigned char *key, const unsigned char *iv),
+	(ctx, type, impl, key, iv))
+DEFINEFUNC(int, EVP_DecryptUpdate,
+	(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl),
+	(ctx, out, outl, in, inl))
+DEFINEFUNC(int, EVP_DecryptFinal_ex,
+	(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl),
+	(ctx, outm, outl))
+
+DEFINEFUNC(const EVP_CIPHER*, EVP_aes_128_gcm, (void), ())
+DEFINEFUNC(const EVP_CIPHER*, EVP_aes_128_cbc, (void), ())
+DEFINEFUNC(const EVP_CIPHER*, EVP_aes_128_ctr, (void), ())
+DEFINEFUNC(const EVP_CIPHER*, EVP_aes_128_ecb, (void), ())
+DEFINEFUNC(const EVP_CIPHER*, EVP_aes_192_cbc, (void), ())
+DEFINEFUNC(const EVP_CIPHER*, EVP_aes_192_ctr, (void), ())
+DEFINEFUNC(const EVP_CIPHER*, EVP_aes_192_ecb, (void), ())
+DEFINEFUNC(const EVP_CIPHER*, EVP_aes_192_gcm, (void), ())
+DEFINEFUNC(const EVP_CIPHER*, EVP_aes_256_cbc, (void), ())
+DEFINEFUNC(const EVP_CIPHER*, EVP_aes_256_ctr, (void), ())
+DEFINEFUNC(const EVP_CIPHER*, EVP_aes_256_ecb, (void), ())
+DEFINEFUNC(const EVP_CIPHER*, EVP_aes_256_gcm, (void), ())
+
+DEFINEFUNC(void, EVP_CIPHER_CTX_free, (EVP_CIPHER_CTX* arg0), (arg0))
+DEFINEFUNC(int, EVP_CIPHER_CTX_ctrl, (EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr), (ctx, type, arg, ptr))
+
+int _goboringcrypto_EVP_CIPHER_CTX_seal(
+	uint8_t *out, uint8_t *nonce,
+	uint8_t *aad, size_t aad_len,
+	uint8_t *plaintext, size_t plaintext_len,
+	size_t *ciphertext_len, uint8_t *key, int key_size);
+
+int _goboringcrypto_EVP_CIPHER_CTX_open(
+	uint8_t *ciphertext, int ciphertext_len,
+	uint8_t *aad, int aad_len,
+	uint8_t *tag, uint8_t *key, int key_size,
+	uint8_t *nonce, int nonce_len,
+	uint8_t *plaintext, size_t *plaintext_len);
+
+typedef EVP_PKEY GO_EVP_PKEY;
+
+DEFINEFUNC(GO_EVP_PKEY *, EVP_PKEY_new, (void), ())
+DEFINEFUNC(void, EVP_PKEY_free, (GO_EVP_PKEY * arg0), (arg0))
+DEFINEFUNC(int, EVP_PKEY_set1_RSA, (GO_EVP_PKEY * arg0, GO_RSA *arg1), (arg0, arg1))
+DEFINEFUNC(int, EVP_PKEY_set1_EC_KEY, (GO_EVP_PKEY * arg0, GO_EC_KEY *arg1), (arg0, arg1))
+DEFINEFUNC(int, EVP_PKEY_verify,
+	(EVP_PKEY_CTX *ctx, const unsigned char *sig, unsigned int siglen, const unsigned char *tbs, size_t tbslen),
+	(ctx, sig, siglen, tbs, tbslen))
+
+typedef EVP_PKEY_CTX GO_EVP_PKEY_CTX;
+
+DEFINEFUNC(GO_EVP_PKEY_CTX *, EVP_PKEY_CTX_new, (GO_EVP_PKEY * arg0, ENGINE *arg1), (arg0, arg1))
+DEFINEFUNC(void, EVP_PKEY_CTX_free, (GO_EVP_PKEY_CTX * arg0), (arg0))
+DEFINEFUNC(int, EVP_PKEY_CTX_ctrl,
+		   (EVP_PKEY_CTX * ctx, int keytype, int optype, int cmd, int p1, void *p2),
+		   (ctx, keytype, optype, cmd, p1, p2))
+DEFINEFUNCINTERNAL(int, RSA_pkey_ctx_ctrl,
+		   (EVP_PKEY_CTX *ctx, int optype, int cmd, int p1, void *p2),
+		   (ctx, optype, cmd, p1, p2))
+
+static inline int
+_goboringcrypto_EVP_PKEY_CTX_set_rsa_padding(GO_EVP_PKEY_CTX* ctx, int pad) {
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+	return _goboringcrypto_EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, pad, NULL);
+#else
+    return _goboringcrypto_internal_RSA_pkey_ctx_ctrl(ctx, -1, EVP_PKEY_CTRL_RSA_PADDING, pad, NULL);
+#endif
+}
+
+#if OPENSSL_VERSION_NUMBER < 0x30000000
+static inline int
+_goboringcrypto_EVP_PKEY_CTX_set0_rsa_oaep_label(GO_EVP_PKEY_CTX *ctx, uint8_t *l, int llen)
+{
+       return _goboringcrypto_EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, EVP_PKEY_CTRL_RSA_OAEP_LABEL, llen, (void *)l);
+}
+#else
+DEFINEFUNC(int, EVP_PKEY_CTX_set0_rsa_oaep_label,
+		(GO_EVP_PKEY_CTX *ctx, uint8_t *l, int llen),
+		(ctx, l, llen))
+#endif
+
+static inline int
+_goboringcrypto_EVP_PKEY_CTX_set_rsa_oaep_md(GO_EVP_PKEY_CTX *ctx, const GO_EVP_MD *md)
+{
+	return _goboringcrypto_EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, EVP_PKEY_CTRL_RSA_OAEP_MD, 0, (void *)md);
+}
+
+static inline int
+_goboringcrypto_EVP_PKEY_CTX_set_rsa_pss_saltlen(GO_EVP_PKEY_CTX * arg0, int arg1) {
+	return _goboringcrypto_EVP_PKEY_CTX_ctrl(arg0, EVP_PKEY_RSA, 
+		(EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), 
+		EVP_PKEY_CTRL_RSA_PSS_SALTLEN, 
+		arg1, NULL);
+}
+
+static inline int
+_goboringcrypto_EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) {
+	return _goboringcrypto_EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, EVP_PKEY_CTRL_MD, 0, (void *)md);
+}
+
+static inline int
+_goboringcrypto_EVP_PKEY_CTX_set_rsa_mgf1_md(GO_EVP_PKEY_CTX * ctx, const GO_EVP_MD *md) {
+	return _goboringcrypto_EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA,
+                        EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT,
+                                EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void *)md);
+}
+
+DEFINEFUNC(int, EVP_PKEY_decrypt,
+		   (GO_EVP_PKEY_CTX * arg0, uint8_t *arg1, unsigned int *arg2, const uint8_t *arg3, unsigned int arg4),
+		   (arg0, arg1, arg2, arg3, arg4))
+DEFINEFUNC(int, EVP_PKEY_encrypt,
+		   (GO_EVP_PKEY_CTX * arg0, uint8_t *arg1, unsigned int *arg2, const uint8_t *arg3, unsigned int arg4),
+		   (arg0, arg1, arg2, arg3, arg4))
+DEFINEFUNC(int, EVP_PKEY_decrypt_init, (GO_EVP_PKEY_CTX * arg0), (arg0))
+DEFINEFUNC(int, EVP_PKEY_encrypt_init, (GO_EVP_PKEY_CTX * arg0), (arg0))
+DEFINEFUNC(int, EVP_PKEY_sign_init, (GO_EVP_PKEY_CTX * arg0), (arg0))
+DEFINEFUNC(int, EVP_PKEY_verify_init, (GO_EVP_PKEY_CTX * arg0), (arg0))
+DEFINEFUNC(int, EVP_PKEY_sign,
+		   (GO_EVP_PKEY_CTX * arg0, uint8_t *arg1, size_t *arg2, const uint8_t *arg3, size_t arg4),
+		   (arg0, arg1, arg2, arg3, arg4))
+
+DEFINEFUNC(int, EVP_PKEY_derive_init, (GO_EVP_PKEY_CTX *arg0), (arg0))
+DEFINEFUNC(int, EVP_PKEY_derive, (GO_EVP_PKEY_CTX *arg0, unsigned char *arg1, size_t *arg2), (arg0, arg1, arg2))
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+DEFINEFUNC(int, EVP_PKEY_derive_set_peer_ex, (GO_EVP_PKEY_CTX *arg0, GO_EVP_PKEY *arg1, int arg2), (arg0, arg1, arg2))
+#else
+DEFINEFUNC(int, EVP_PKEY_derive_set_peer, (GO_EVP_PKEY_CTX *arg0, GO_EVP_PKEY *arg1), (arg0, arg1))
+
+# if OPENSSL_VERSION_NUMBER >= 0x10100000L
+DEFINEFUNC(int, EVP_PKEY_public_check, (EVP_PKEY_CTX *arg0), (arg0))
+
+static inline int
+_goboringcrypto_EVP_PKEY_derive_set_peer_ex(GO_EVP_PKEY_CTX *ctx, GO_EVP_PKEY *key, int validate)
+{
+        EVP_PKEY_CTX *check_ctx = _goboringcrypto_EVP_PKEY_CTX_new(key, NULL);
+        if (check_ctx == NULL) {
+		return -1;
+	}
+        int ok = _goboringcrypto_EVP_PKEY_public_check(check_ctx);
+        _goboringcrypto_EVP_PKEY_CTX_free(check_ctx);
+        if (ok != 1) {
+		return -1;
+	}
+	return _goboringcrypto_EVP_PKEY_derive_set_peer(ctx, key);
+}
+# else
+static inline int
+_goboringcrypto_EVP_PKEY_derive_set_peer_ex(GO_EVP_PKEY_CTX *ctx, GO_EVP_PKEY *key, int validate)
+{
+	/* No way to validate public key in OpenSSL 1.0.2 */
+	(void)validate;
+	return _goboringcrypto_EVP_PKEY_derive_set_peer(ctx, key);
+}
+# endif
+#endif
+
+#if OPENSSL_VERSION_NUMBER >= 0x10101000L
+#include <openssl/kdf.h>
+
+enum {
+	GO_EVP_PKEY_HKDF = EVP_PKEY_HKDF,
+};
+
+DEFINEFUNC(GO_EVP_PKEY_CTX *, EVP_PKEY_CTX_new_id, (int arg0, ENGINE *arg1), (arg0, arg1))
+
+enum {
+	GO_EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY = EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY,
+	GO_EVP_PKEY_HKDEF_MODE_EXPAND_ONLY = EVP_PKEY_HKDEF_MODE_EXPAND_ONLY,
+};
+
+DEFINEFUNC(int, EVP_PKEY_CTX_set_hkdf_mode, (GO_EVP_PKEY_CTX *arg0, int arg1), (arg0, arg1))
+DEFINEFUNC(int, EVP_PKEY_CTX_set_hkdf_md, (GO_EVP_PKEY_CTX *arg0, const GO_EVP_MD *arg1), (arg0, arg1))
+DEFINEFUNC(int, EVP_PKEY_CTX_set1_hkdf_salt, (GO_EVP_PKEY_CTX *arg0, unsigned char *arg1, int arg2), (arg0, arg1, arg2))
+DEFINEFUNC(int, EVP_PKEY_CTX_set1_hkdf_key, (GO_EVP_PKEY_CTX *arg0, unsigned char *arg1, int arg2), (arg0, arg1, arg2))
+DEFINEFUNC(int, EVP_PKEY_CTX_add1_hkdf_info, (GO_EVP_PKEY_CTX *arg0, unsigned char *arg1, int arg2), (arg0, arg1, arg2))
+#endif
diff --git a/src/vendor/github.com/golang-fips/openssl-fips/openssl/hkdf.go b/src/vendor/github.com/golang-fips/openssl-fips/openssl/hkdf.go
new file mode 100644
index 0000000..ae40b93
--- /dev/null
+++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/hkdf.go
@@ -0,0 +1,100 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build linux && !android && !cmd_go_bootstrap && !msan && !no_openssl
+// +build linux,!android,!cmd_go_bootstrap,!msan,!no_openssl
+
+package openssl
+
+// #include "goopenssl.h"
+import "C"
+import (
+	"hash"
+	"io"
+	"runtime"
+)
+
+type hkdf struct {
+	ctx *C.GO_EVP_PKEY_CTX
+}
+
+func newHKDF(h func() hash.Hash, mode C.int) (*hkdf, error) {
+	ch := h()
+	md := hashToMD(ch)
+	if md == nil {
+		return nil, NewOpenSSLError("Unknown hash algorithm")
+	}
+
+	ctx := C._goboringcrypto_EVP_PKEY_CTX_new_id(C.GO_EVP_PKEY_HKDF, nil)
+	if ctx == nil {
+		return nil, NewOpenSSLError("EVP_PKEY_CTX_new_id failed")
+	}
+	c := &hkdf{ctx: ctx}
+	runtime.SetFinalizer(c, (*hkdf).finalize)
+	defer runtime.KeepAlive(c)
+
+	if C._goboringcrypto_EVP_PKEY_derive_init(ctx) != 1 {
+		return nil, NewOpenSSLError("EVP_PKEY_derive_init failed")
+	}
+	if C._goboringcrypto_EVP_PKEY_CTX_set_hkdf_mode(ctx, mode) != 1 {
+		return nil, NewOpenSSLError("EVP_PKEY_CTX_set_hkdf_mode failed")
+	}
+	if C._goboringcrypto_EVP_PKEY_CTX_set_hkdf_md(ctx, md) != 1 {
+		return nil, NewOpenSSLError("EVP_PKEY_CTX_set_hkdf_md failed")
+	}
+
+	return c, nil
+}
+
+func (c *hkdf) finalize() {
+	if c.ctx != nil {
+		C._goboringcrypto_EVP_PKEY_CTX_free(c.ctx)
+	}
+}
+
+func (c *hkdf) Read(p []byte) (int, error) {
+	defer runtime.KeepAlive(c)
+
+	outLen := C.size_t(len(p))
+	if C._goboringcrypto_EVP_PKEY_derive(c.ctx, base(p), &outLen) != 1 {
+		return 0, NewOpenSSLError("EVP_PKEY_derive failed")
+	}
+	return int(outLen), nil
+}
+
+func ExtractHKDF(h func() hash.Hash, secret, salt []byte) ([]byte, error) {
+	c, err := newHKDF(h, C.GO_EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY)
+	if err != nil {
+		return nil, err
+	}
+	if C._goboringcrypto_EVP_PKEY_CTX_set1_hkdf_key(c.ctx, base(secret), C.int(len(secret))) != 1 {
+		return nil, NewOpenSSLError("EVP_PKEY_CTX_set1_hkdf_key failed")
+	}
+	if C._goboringcrypto_EVP_PKEY_CTX_set1_hkdf_salt(c.ctx, base(salt), C.int(len(salt))) != 1 {
+		return nil, NewOpenSSLError("EVP_PKEY_CTX_set1_hkdf_salt failed")
+	}
+	var outLen C.size_t
+	if C._goboringcrypto_EVP_PKEY_derive(c.ctx, nil, &outLen) != 1 {
+		return nil, NewOpenSSLError("EVP_PKEY_derive_init failed")
+	}
+	out := make([]byte, outLen)
+	if C._goboringcrypto_EVP_PKEY_derive(c.ctx, base(out), &outLen) != 1 {
+		return nil, NewOpenSSLError("EVP_PKEY_derive failed")
+	}
+	return out[:outLen], nil
+}
+
+func ExpandHKDF(h func() hash.Hash, pseudorandomKey, info []byte) (io.Reader, error) {
+	c, err := newHKDF(h, C.GO_EVP_PKEY_HKDEF_MODE_EXPAND_ONLY)
+	if err != nil {
+		return nil, err
+	}
+	if C._goboringcrypto_EVP_PKEY_CTX_set1_hkdf_key(c.ctx, base(pseudorandomKey), C.int(len(pseudorandomKey))) != 1 {
+		return nil, NewOpenSSLError("EVP_PKEY_CTX_set1_hkdf_key failed")
+	}
+	if C._goboringcrypto_EVP_PKEY_CTX_add1_hkdf_info(c.ctx, base(info), C.int(len(info))) != 1 {
+		return nil, NewOpenSSLError("EVP_PKEY_CTX_add1_hkdf_info failed")
+	}
+	return c, nil
+}
diff --git a/src/crypto/internal/boring/hmac.go b/src/vendor/github.com/golang-fips/openssl-fips/openssl/hmac.go
similarity index 69%
rename from src/crypto/internal/boring/hmac.go
rename to src/vendor/github.com/golang-fips/openssl-fips/openssl/hmac.go
index c36fe6b..6f00177 100644
--- a/src/crypto/internal/boring/hmac.go
+++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/hmac.go
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build boringcrypto && linux && amd64 && !android && !cmd_go_bootstrap && !msan
-// +build boringcrypto,linux,amd64,!android,!cmd_go_bootstrap,!msan
+//go:build linux && !android && !cmd_go_bootstrap && !msan && !no_openssl
+// +build linux,!android,!cmd_go_bootstrap,!msan,!no_openssl
 
-package boring
+package openssl
 
-// #include "goboringcrypto.h"
+// #include "goopenssl.h"
 import "C"
 import (
 	"crypto"
@@ -67,14 +67,25 @@ func NewHMAC(h func() hash.Hash, key []byte) hash.Hash {
 		return nil
 	}
 
-	// Note: Could hash down long keys here using EVP_Digest.
-	hkey := make([]byte, len(key))
-	copy(hkey, key)
+	var hkey []byte
+	if key != nil && len(key) > 0 {
+		// Note: Could hash down long keys here using EVP_Digest.
+		hkey = make([]byte, len(key))
+		copy(hkey, key)
+	} else {
+		// This is supported in BoringSSL/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 bahavior previously implemented, so as a workaround
+		// we pass an "empty" key.
+		hkey = make([]byte, C.EVP_MAX_MD_SIZE)
+	}
 	hmac := &boringHMAC{
 		md:        md,
 		size:      ch.Size(),
 		blockSize: ch.BlockSize(),
 		key:       hkey,
+		ctx:       C._goboringcrypto_HMAC_CTX_new(),
 	}
 	hmac.Reset()
 	return hmac
@@ -82,8 +93,8 @@ func NewHMAC(h func() hash.Hash, key []byte) hash.Hash {
 
 type boringHMAC struct {
 	md          *C.GO_EVP_MD
-	ctx         C.GO_HMAC_CTX
-	ctx2        C.GO_HMAC_CTX
+	ctx         *C.GO_HMAC_CTX
+	ctx2        *C.GO_HMAC_CTX
 	size        int
 	blockSize   int
 	key         []byte
@@ -92,9 +103,7 @@ type boringHMAC struct {
 }
 
 func (h *boringHMAC) Reset() {
-	if h.needCleanup {
-		C._goboringcrypto_HMAC_CTX_cleanup(&h.ctx)
-	} else {
+	if !h.needCleanup {
 		h.needCleanup = true
 		// Note: Because of the finalizer, any time h.ctx is passed to cgo,
 		// that call must be followed by a call to runtime.KeepAlive(h),
@@ -102,13 +111,13 @@ func (h *boringHMAC) Reset() {
 		// call returns.
 		runtime.SetFinalizer(h, (*boringHMAC).finalize)
 	}
-	C._goboringcrypto_HMAC_CTX_init(&h.ctx)
+	C._goboringcrypto_HMAC_CTX_reset(h.ctx)
 
-	if C._goboringcrypto_HMAC_Init(&h.ctx, unsafe.Pointer(base(h.key)), C.int(len(h.key)), h.md) == 0 {
+	if C._goboringcrypto_HMAC_Init_ex(h.ctx, unsafe.Pointer(base(h.key)), C.int(len(h.key)), h.md, nil) == 0 {
 		panic("boringcrypto: HMAC_Init failed")
 	}
-	if int(C._goboringcrypto_HMAC_size(&h.ctx)) != h.size {
-		println("boringcrypto: HMAC size:", C._goboringcrypto_HMAC_size(&h.ctx), "!=", h.size)
+	if int(C._goboringcrypto_HMAC_size(h.ctx)) != h.size {
+		println("boringcrypto: HMAC size:", C._goboringcrypto_HMAC_size(h.ctx), "!=", h.size)
 		panic("boringcrypto: HMAC size mismatch")
 	}
 	runtime.KeepAlive(h) // Next line will keep h alive too; just making doubly sure.
@@ -116,12 +125,12 @@ func (h *boringHMAC) Reset() {
 }
 
 func (h *boringHMAC) finalize() {
-	C._goboringcrypto_HMAC_CTX_cleanup(&h.ctx)
+	C._goboringcrypto_HMAC_CTX_free(h.ctx)
 }
 
 func (h *boringHMAC) Write(p []byte) (int, error) {
 	if len(p) > 0 {
-		C._goboringcrypto_HMAC_Update(&h.ctx, (*C.uint8_t)(unsafe.Pointer(&p[0])), C.size_t(len(p)))
+		C._goboringcrypto_HMAC_Update(h.ctx, (*C.uint8_t)(unsafe.Pointer(&p[0])), C.size_t(len(p)))
 	}
 	runtime.KeepAlive(h)
 	return len(p), nil
@@ -144,11 +153,11 @@ func (h *boringHMAC) Sum(in []byte) []byte {
 	// 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.
-	C._goboringcrypto_HMAC_CTX_init(&h.ctx2)
-	if C._goboringcrypto_HMAC_CTX_copy_ex(&h.ctx2, &h.ctx) == 0 {
+	h.ctx2 = C._goboringcrypto_HMAC_CTX_new()
+	if C._goboringcrypto_HMAC_CTX_copy_ex(h.ctx2, h.ctx) == 0 {
 		panic("boringcrypto: HMAC_CTX_copy_ex failed")
 	}
-	C._goboringcrypto_HMAC_Final(&h.ctx2, (*C.uint8_t)(unsafe.Pointer(&h.sum[0])), nil)
-	C._goboringcrypto_HMAC_CTX_cleanup(&h.ctx2)
+	C._goboringcrypto_HMAC_Final(h.ctx2, (*C.uint8_t)(unsafe.Pointer(&h.sum[0])), nil)
+	C._goboringcrypto_HMAC_CTX_free(h.ctx2)
 	return append(in, h.sum...)
 }
diff --git a/src/crypto/internal/boring/notboring.go b/src/vendor/github.com/golang-fips/openssl-fips/openssl/notboring.go
similarity index 69%
rename from src/crypto/internal/boring/notboring.go
rename to src/vendor/github.com/golang-fips/openssl-fips/openssl/notboring.go
index 53096a6..7c0b5d6 100644
--- a/src/crypto/internal/boring/notboring.go
+++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/notboring.go
@@ -2,33 +2,34 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build !boringcrypto || !linux || !amd64 || !cgo || android || cmd_go_bootstrap || msan
-// +build !boringcrypto !linux !amd64 !cgo android cmd_go_bootstrap msan
+//go:build !linux || !cgo || android || cmd_go_bootstrap || msan || no_openssl
+// +build !linux !cgo android cmd_go_bootstrap msan no_openssl
 
-package boring
+package openssl
 
 import (
 	"crypto"
 	"crypto/cipher"
-	"crypto/internal/boring/sig"
 	"hash"
+	"io"
 )
 
-const available = false
+var enabled = false
 
 // Unreachable marks code that should be unreachable
 // when BoringCrypto is in use. It is a no-op without BoringCrypto.
 func Unreachable() {
-	// Code that's unreachable when using BoringCrypto
-	// is exactly the code we want to detect for reporting
-	// standard Go crypto.
-	sig.StandardCrypto()
 }
 
 // UnreachableExceptTests marks code that should be unreachable
 // when BoringCrypto is in use. It is a no-op without BoringCrypto.
 func UnreachableExceptTests() {}
 
+func ExecutingTest() bool { return false }
+
+// This is a noop withotu BoringCrytpo.
+func PanicIfStrictFIPS(v interface{}) {}
+
 type randReader int
 
 func (randReader) Read(b []byte) (int, error) { panic("boringcrypto: not available") }
@@ -41,16 +42,9 @@ func NewSHA256() hash.Hash { panic("boringcrypto: not available") }
 func NewSHA384() hash.Hash { panic("boringcrypto: not available") }
 func NewSHA512() hash.Hash { panic("boringcrypto: not available") }
 
-func SHA1([]byte) [20]byte   { panic("boringcrypto: not available") }
-func SHA224([]byte) [28]byte { panic("boringcrypto: not available") }
-func SHA256([]byte) [32]byte { panic("boringcrypto: not available") }
-func SHA384([]byte) [48]byte { panic("boringcrypto: not available") }
-func SHA512([]byte) [64]byte { panic("boringcrypto: not available") }
-
 func NewHMAC(h func() hash.Hash, key []byte) hash.Hash { panic("boringcrypto: not available") }
 
 func NewAESCipher(key []byte) (cipher.Block, error) { panic("boringcrypto: not available") }
-func NewGCMTLS(cipher.Block) (cipher.AEAD, error)   { panic("boringcrypto: not available") }
 
 type PublicKeyECDSA struct{ _ int }
 type PrivateKeyECDSA struct{ _ int }
@@ -64,10 +58,29 @@ func NewPrivateKeyECDSA(curve string, X, Y, D BigInt) (*PrivateKeyECDSA, error)
 func NewPublicKeyECDSA(curve string, X, Y BigInt) (*PublicKeyECDSA, error) {
 	panic("boringcrypto: not available")
 }
-func SignMarshalECDSA(priv *PrivateKeyECDSA, hash []byte) ([]byte, error) {
+func SignECDSA(priv *PrivateKeyECDSA, hash []byte, h crypto.Hash) (r, s BigInt, err error) {
 	panic("boringcrypto: not available")
 }
-func VerifyECDSA(pub *PublicKeyECDSA, hash []byte, sig []byte) bool {
+func SignMarshalECDSA(priv *PrivateKeyECDSA, hash []byte, h crypto.Hash) ([]byte, error) {
+	panic("boringcrypto: not available")
+}
+func VerifyECDSA(pub *PublicKeyECDSA, hash []byte, r, s BigInt, h crypto.Hash) bool {
+	panic("boringcrypto: not available")
+}
+
+type PublicKeyECDH struct{ _ int }
+type PrivateKeyECDH struct{ _ int }
+
+func GenerateKeyECDH(curve string) (X, Y, D BigInt, err error) {
+	panic("boringcrypto: not available")
+}
+func NewPrivateKeyECDH(curve string, X, Y, D BigInt) (*PrivateKeyECDH, error) {
+	panic("boringcrypto: not available")
+}
+func NewPublicKeyECDH(curve string, X, Y BigInt) (*PublicKeyECDH, error) {
+	panic("boringcrypto: not available")
+}
+func SharedKeyECDH(priv *PrivateKeyECDH, peerPublicKey []byte) ([]byte, error) {
 	panic("boringcrypto: not available")
 }
 
@@ -99,15 +112,23 @@ func NewPrivateKeyRSA(N, E, D, P, Q, Dp, Dq, Qinv BigInt) (*PrivateKeyRSA, error
 	panic("boringcrypto: not available")
 }
 func NewPublicKeyRSA(N, E BigInt) (*PublicKeyRSA, error) { panic("boringcrypto: not available") }
-func SignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte) ([]byte, error) {
+func SignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte, msgHashed bool) ([]byte, error) {
 	panic("boringcrypto: not available")
 }
 func SignRSAPSS(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte, saltLen int) ([]byte, error) {
 	panic("boringcrypto: not available")
 }
-func VerifyRSAPKCS1v15(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte) error {
+func VerifyRSAPKCS1v15(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte, msgHashed bool) error {
 	panic("boringcrypto: not available")
 }
 func VerifyRSAPSS(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte, saltLen int) error {
 	panic("boringcrypto: not available")
 }
+
+func ExtractHKDF(h func() hash.Hash, secret, salt []byte) []byte {
+	panic("boringcrypto: not available")
+}
+
+func ExpandHKDF(h func() hash.Hash, pseudorandomKey, info []byte) io.Reader {
+	panic("boringcrypto: not available")
+}
diff --git a/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl.go b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl.go
new file mode 100644
index 0000000..d49194d
--- /dev/null
+++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl.go
@@ -0,0 +1,247 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build linux && !android && !cmd_go_bootstrap && !msan && !no_openssl
+// +build linux,!android,!cmd_go_bootstrap,!msan,!no_openssl
+
+package openssl
+
+/*
+#cgo LDFLAGS: -ldl
+
+#include "goopenssl.h"
+*/
+import "C"
+import (
+	"errors"
+	"fmt"
+	"math/bits"
+	"os"
+	"runtime"
+	"unsafe"
+)
+
+const (
+	fipsOn  = C.int(1)
+	fipsOff = C.int(0)
+)
+
+const GoStrictFipsEnv = "GOLANG_STRICT_FIPS"
+
+const (
+	OPENSSL_VERSION_1_1_0 = uint64(C.ulong(0x10100000))
+	OPENSSL_VERSION_3_0_0 = uint64(C.ulong(0x30000000))
+)
+
+// Enabled controls whether FIPS crypto is enabled.
+var enabled = false
+
+// When this variable is true, the go crypto API will panic when a caller
+// tries to use the API in a non-compliant manner.  When this is false, the
+// go crypto API will allow existing go crypto APIs to be used even
+// if they aren't FIPS compliant.  However, all the underlying crypto operations
+// will still be done by OpenSSL.
+var strictFIPS = false
+
+func init() {
+	runtime.LockOSThread()
+	defer runtime.UnlockOSThread()
+
+	// Check if we can `dlopen` OpenSSL
+	if C._goboringcrypto_DLOPEN_OPENSSL() == C.NULL {
+		return
+	}
+
+	// Initialize the OpenSSL library.
+	C._goboringcrypto_OPENSSL_setup()
+
+	// Check to see if the system is running in FIPS mode, if so
+	// enable "boring" mode to call into OpenSSL for FIPS compliance.
+	if fipsModeEnabled() {
+		enableBoringFIPSMode()
+	}
+}
+
+func openSSLVersion() uint64 {
+	return uint64(C._goboringcrypto_internal_OPENSSL_VERSION_NUMBER())
+}
+
+func enableBoringFIPSMode() {
+	enabled = true
+
+	if os.Getenv(GoStrictFipsEnv) == "1" {
+		strictFIPS = true
+	}
+
+	if C._goboringcrypto_OPENSSL_thread_setup() != 1 {
+		panic("boringcrypto: OpenSSL thread setup failed")
+	}
+}
+
+func fipsModeEnabled() bool {
+	// Due to the way providers work in openssl 3, the FIPS methods are not
+	// necessarily going to be available for us to load based on the GOLANG_FIPS
+	// environment variable alone. For now, we must rely on the config to tell
+	// us if the provider is configured and active.
+	fipsConfigured := C._goboringcrypto_FIPS_mode() == fipsOn
+	openSSLVersion := openSSLVersion()
+	if openSSLVersion >= OPENSSL_VERSION_3_0_0 {
+		if !fipsConfigured && os.Getenv("GOLANG_FIPS") == "1" {
+			panic("GOLANG_FIPS=1 specified but OpenSSL FIPS provider is not configured")
+		}
+		return fipsConfigured
+
+	} else {
+		return os.Getenv("GOLANG_FIPS") == "1" || fipsConfigured
+	}
+}
+
+var randstub bool
+
+func RandStubbed() bool {
+	return randstub
+}
+
+func StubOpenSSLRand() {
+	if !randstub {
+		randstub = true
+		C._goboringcrypto_stub_openssl_rand()
+	}
+}
+
+func RestoreOpenSSLRand() {
+	if randstub {
+		randstub = false
+		C._goboringcrypto_restore_openssl_rand()
+	}
+}
+
+func hasSuffix(s, t string) bool {
+	return len(s) > len(t) && s[len(s)-len(t):] == t
+}
+
+func PanicIfStrictFIPS(msg string) {
+	if IsStrictFips() {
+		panic(msg)
+	}
+}
+
+func IsStrictFips() bool {
+	return os.Getenv(GoStrictFipsEnv) == "1" || strictFIPS
+}
+
+func NewOpenSSLError(msg string) error {
+	var e C.ulong
+	message := fmt.Sprintf("\n%v\nopenssl error(s):", msg)
+	for {
+		var buf [256]C.char
+		var file, fnc, data *C.char
+		var line, flags C.int
+		e = C._goboringcrypto_internal_ERR_get_error_all(&file, &line, &fnc, &data, &flags)
+		if e == 0 {
+			break
+		}
+
+		C._goboringcrypto_internal_ERR_error_string_n(e, (*C.uchar)(unsafe.Pointer(&buf[0])), C.size_t(len(buf)))
+		message = fmt.Sprintf(
+			"%v\nfile: %v\nline: %v\nfunction: %v\nflags: %v\nerror string: %s\n",
+			message, C.GoString(file), line, C.GoString(fnc), flags, C.GoString(&(buf[0])))
+
+	}
+	return errors.New(message)
+}
+
+// Unreachable marks code that should be unreachable
+// when FIPS mode. It panics only when
+// the system is in FIPS mode.
+func Unreachable() {
+	if Enabled() {
+		panic("openssl: invalid code execution")
+	}
+}
+
+// UnreachableExceptTests marks code that should be unreachable
+// when FIPS mode is active. It panics only when the system is in FIPS mode
+// and not executing under tests.
+func UnreachableExceptTests() {
+	name := os.Args[0]
+	if Enabled() && !ExecutingTest() {
+		println("openssl: unexpected code execution in", name)
+		panic("openssl: invalid code execution")
+	}
+}
+
+// ExecutingTest returns a boolean indicating if we're
+// executing under a test binary or not.
+func ExecutingTest() bool {
+	name := os.Args[0]
+	return hasSuffix(name, "_test") || hasSuffix(name, ".test")
+}
+
+type fail string
+
+func (e fail) Error() string { return "boringcrypto: " + string(e) + " failed" }
+
+func wbase(b BigInt) *C.uint8_t {
+	if len(b) == 0 {
+		return nil
+	}
+	return (*C.uint8_t)(unsafe.Pointer(&b[0]))
+}
+
+const wordBytes = bits.UintSize / 8
+
+func bigToBN(x BigInt) *C.GO_BIGNUM {
+	return C._goboringcrypto_BN_lebin2bn(wbase(x), C.size_t(len(x)*wordBytes), nil)
+}
+
+func bnToBig(bn *C.GO_BIGNUM) BigInt {
+	x := make(BigInt, (C._goboringcrypto_BN_num_bytes(bn)+wordBytes-1)/wordBytes)
+	if C._goboringcrypto_BN_bn2lebinpad(bn, wbase(x), C.size_t(len(x)*wordBytes)) == 0 {
+		panic("boringcrypto: bignum conversion failed")
+	}
+	return x
+}
+
+func bigToBn(bnp **C.GO_BIGNUM, b BigInt) bool {
+	if *bnp != nil {
+		C._goboringcrypto_BN_free(*bnp)
+		*bnp = nil
+	}
+	if b == nil {
+		return true
+	}
+	bn := bigToBN(b)
+	if bn == nil {
+		return false
+	}
+	*bnp = bn
+	return true
+}
+
+// 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)
+}
+
+var zero byte
+
+// 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])))
+}
diff --git a/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_ecdsa_signature.c b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_ecdsa_signature.c
new file mode 100644
index 0000000..2349db1
--- /dev/null
+++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_ecdsa_signature.c
@@ -0,0 +1,46 @@
+// +build linux
+// +build !android
+// +build !no_openssl
+// +build !cmd_go_bootstrap
+// +build !msan
+
+#include "goopenssl.h"
+
+int _goboringcrypto_ECDSA_sign(EVP_MD *md, const uint8_t *msg, size_t msgLen,
+                               uint8_t *sig, unsigned int *slen,
+                               GO_EC_KEY *eckey) {
+  int result;
+  EVP_PKEY *key = _goboringcrypto_EVP_PKEY_new();
+  if (!key) {
+    return 0;
+  }
+  if (!_goboringcrypto_EVP_PKEY_set1_EC_KEY(key, eckey)) {
+    result = 0;
+    goto err;
+  }
+  result = _goboringcrypto_EVP_sign(md, NULL, msg, msgLen, sig, slen, key);
+err:
+  _goboringcrypto_EVP_PKEY_free(key);
+  return result;
+}
+
+int _goboringcrypto_ECDSA_verify(EVP_MD *md, const uint8_t *msg, size_t msgLen,
+                                 const uint8_t *sig, unsigned int slen,
+                                 GO_EC_KEY *eckey) {
+
+  int result;
+  EVP_PKEY *key = _goboringcrypto_EVP_PKEY_new();
+  if (!key) {
+    return 0;
+  }
+  if (!_goboringcrypto_EVP_PKEY_set1_EC_KEY(key, eckey)) {
+    result = 0;
+    goto err;
+  }
+
+  result = _goboringcrypto_EVP_verify(md, NULL, msg, msgLen, sig, slen, key);
+
+err:
+  _goboringcrypto_EVP_PKEY_free(key);
+  return result;
+}
diff --git a/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_evp.c b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_evp.c
new file mode 100644
index 0000000..4379019
--- /dev/null
+++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_evp.c
@@ -0,0 +1,128 @@
+// +build linux
+// +build !android
+// +build !no_openssl
+// +build !cmd_go_bootstrap
+// +build !msan
+
+#include "goopenssl.h"
+
+int _goboringcrypto_EVP_sign(EVP_MD *md, EVP_PKEY_CTX *ctx, const uint8_t *msg,
+                             size_t msgLen, uint8_t *sig, unsigned int *slen,
+                             EVP_PKEY *key) {
+  EVP_MD_CTX *mdctx = NULL;
+  int ret = 0;
+
+  if (!(mdctx = _goboringcrypto_EVP_MD_CTX_create()))
+    goto err;
+
+  if (1 != _goboringcrypto_EVP_DigestSignInit(mdctx, &ctx, md, NULL, key))
+    goto err;
+
+  if (1 != _goboringcrypto_EVP_DigestUpdate(mdctx, msg, msgLen))
+    goto err;
+
+  /* Obtain the signature length */
+  if (1 != _goboringcrypto_EVP_DigestSignFinal(mdctx, NULL, slen))
+    goto err;
+  /* Obtain the signature */
+  if (1 != _goboringcrypto_EVP_DigestSignFinal(mdctx, sig, slen))
+    goto err;
+
+  /* Success */
+  ret = 1;
+
+err:
+  if (mdctx)
+    _goboringcrypto_EVP_MD_CTX_free(mdctx);
+
+  return ret;
+}
+
+int _goboringcrypto_EVP_sign_raw(EVP_MD *md, EVP_PKEY_CTX *ctx, const uint8_t *msg,
+                             size_t msgLen, uint8_t *sig, size_t *slen,
+                             GO_RSA *rsa_key) {
+  int ret = 0;
+  GO_EVP_PKEY *pk = _goboringcrypto_EVP_PKEY_new();
+  _goboringcrypto_EVP_PKEY_assign_RSA(pk, rsa_key);
+
+  if (!ctx && !(ctx = _goboringcrypto_EVP_PKEY_CTX_new(pk, NULL)))
+    goto err;
+
+  if (1 != _goboringcrypto_EVP_PKEY_sign_init(ctx))
+    goto err;
+
+  if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)
+    goto err;
+
+  if (1 != _goboringcrypto_EVP_PKEY_sign(ctx, sig, slen, msg, msgLen))
+    goto err;
+
+  /* Success */
+  ret = 1;
+
+err:
+  if (ctx)
+    _goboringcrypto_EVP_PKEY_CTX_free(ctx);
+
+  return ret;
+}
+
+int _goboringcrypto_EVP_verify(EVP_MD *md, EVP_PKEY_CTX *ctx,
+                               const uint8_t *msg, size_t msgLen,
+                               const uint8_t *sig, unsigned int slen,
+                               EVP_PKEY *key) {
+  EVP_MD_CTX *mdctx = NULL;
+  int ret = 0;
+
+  if (!(mdctx = _goboringcrypto_EVP_MD_CTX_create()))
+    goto err;
+  if (1 != _goboringcrypto_EVP_DigestVerifyInit(mdctx, &ctx, md, NULL, key))
+    goto err;
+
+  if (1 != _goboringcrypto_EVP_DigestUpdate(mdctx, msg, msgLen))
+    goto err;
+
+  if (1 != _goboringcrypto_EVP_DigestVerifyFinal(mdctx, sig, slen)) {
+    goto err;
+  }
+
+  /* Success */
+  ret = 1;
+
+err:
+  if (mdctx)
+    _goboringcrypto_EVP_MD_CTX_free(mdctx);
+
+  return ret;
+}
+
+int _goboringcrypto_EVP_verify_raw(const uint8_t *msg, size_t msgLen,
+                               const uint8_t *sig, unsigned int slen,
+                               GO_RSA *rsa_key) {
+
+  int ret = 0;
+  EVP_PKEY_CTX *ctx;
+  GO_EVP_PKEY *pk = _goboringcrypto_EVP_PKEY_new();
+  _goboringcrypto_EVP_PKEY_assign_RSA(pk, rsa_key);
+
+  if (!(ctx = _goboringcrypto_EVP_PKEY_CTX_new(pk, NULL)))
+    goto err;
+
+  if (1 != _goboringcrypto_EVP_PKEY_verify_init(ctx))
+    goto err;
+
+  if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)
+    goto err;
+
+  if (1 != _goboringcrypto_EVP_PKEY_verify(ctx, sig, slen, msg, msgLen))
+    goto err;
+
+  /* Success */
+  ret = 1;
+
+err:
+  if (ctx)
+    _goboringcrypto_EVP_PKEY_CTX_free(ctx);
+
+  return ret;
+}
diff --git a/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_lock_setup.c b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_lock_setup.c
new file mode 100644
index 0000000..49d40a7
--- /dev/null
+++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_lock_setup.c
@@ -0,0 +1,49 @@
+// +build linux
+// +build !android
+// +build !no_openssl
+// +build !cmd_go_bootstrap
+// +build !msan
+
+#include "goopenssl.h"
+#include <openssl/err.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+
+#define _GNU_SOURCE
+#include <unistd.h>
+
+#define MUTEX_TYPE pthread_mutex_t
+#define MUTEX_SETUP(x) pthread_mutex_init(&(x), NULL)
+#define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x))
+#define MUTEX_LOCK(x) pthread_mutex_lock(&(x))
+#define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x))
+#define THREAD_ID pthread_self()
+
+/* This array will store all of the mutexes available to OpenSSL. */
+static MUTEX_TYPE *mutex_buf = NULL;
+
+static void locking_function(int mode, int n, const char *file, int line) {
+  if (mode & CRYPTO_LOCK)
+    MUTEX_LOCK(mutex_buf[n]);
+  else
+    MUTEX_UNLOCK(mutex_buf[n]);
+}
+
+static unsigned long id_function(void) {
+  return ((unsigned long)syscall(__NR_gettid));
+}
+
+int _goboringcrypto_OPENSSL_thread_setup(void) {
+  int i;
+
+  mutex_buf = malloc(_goboringcrypto_CRYPTO_num_locks() * sizeof(MUTEX_TYPE));
+  if (!mutex_buf)
+    return 0;
+  for (i = 0; i < _goboringcrypto_CRYPTO_num_locks(); i++)
+    MUTEX_SETUP(mutex_buf[i]);
+  _goboringcrypto_CRYPTO_set_id_callback(id_function);
+  _goboringcrypto_CRYPTO_set_locking_callback(locking_function);
+  return 1;
+}
diff --git a/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_port_aead_gcm.c b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_port_aead_gcm.c
new file mode 100644
index 0000000..7eb645e
--- /dev/null
+++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_port_aead_gcm.c
@@ -0,0 +1,171 @@
+// This file contains a port of the BoringSSL AEAD interface.
+// +build linux
+// +build !android
+// +build !no_openssl
+// +build !cmd_go_bootstrap
+// +build !msan
+
+#include "goopenssl.h"
+#include <openssl/err.h>
+
+int _goboringcrypto_EVP_CIPHER_CTX_seal(uint8_t *out, uint8_t *iv, uint8_t *aad,
+                                        size_t aad_len, uint8_t *plaintext,
+                                        size_t plaintext_len,
+                                        size_t *ciphertext_len, uint8_t *key,
+                                        int key_size) {
+
+  EVP_CIPHER_CTX *ctx;
+  int len;
+  int ret;
+
+  if (plaintext_len == 0) {
+    plaintext = "";
+  }
+
+  if (aad_len == 0) {
+    aad = "";
+  }
+
+  // Create and initialise the context.
+  if (!(ctx = _goboringcrypto_EVP_CIPHER_CTX_new())) {
+    goto err;
+  }
+
+  switch (key_size) {
+  case 128:
+    if (!_goboringcrypto_EVP_EncryptInit_ex(
+            ctx, _goboringcrypto_EVP_aes_128_gcm(), NULL, NULL, NULL)) {
+      goto err;
+    }
+    break;
+  case 256:
+    if (!_goboringcrypto_EVP_EncryptInit_ex(
+            ctx, _goboringcrypto_EVP_aes_256_gcm(), NULL, NULL, NULL)) {
+      goto err;
+    }
+    break;
+  default:
+    goto err;
+  }
+
+  // Initialize IV.
+  if (!_goboringcrypto_EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL)) {
+    goto err;
+  }
+  if (!_goboringcrypto_EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 12,
+                                           0)) {
+    goto err;
+  }
+  if (!_goboringcrypto_EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IV_FIXED, -1,
+                                           iv)) {
+    goto err;
+  }
+  if (!_goboringcrypto_EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_IV_GEN, 0, iv)) {
+    goto err;
+  }
+
+  // Provide AAD data.
+  if (!_goboringcrypto_EVP_EncryptUpdate(ctx, NULL, &len, aad, aad_len)) {
+    goto err;
+  }
+
+  if (!_goboringcrypto_EVP_EncryptUpdate(ctx, out, &len, plaintext,
+                                         plaintext_len)) {
+    goto err;
+  }
+  *ciphertext_len = len;
+
+  if (!_goboringcrypto_EVP_EncryptFinal_ex(ctx, out + len, &len)) {
+    goto err;
+  }
+  *ciphertext_len += len;
+
+  if (!_goboringcrypto_EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16,
+                                           out + (*ciphertext_len))) {
+    goto err;
+  }
+  *ciphertext_len += 16;
+  ret = 1;
+
+err:
+  _goboringcrypto_EVP_CIPHER_CTX_free(ctx);
+
+  if (ret > 0) {
+    return ret;
+  } else {
+    return 0;
+  }
+}
+
+int _goboringcrypto_EVP_CIPHER_CTX_open(uint8_t *ciphertext, int ciphertext_len,
+                                        uint8_t *aad, int aad_len, uint8_t *tag,
+                                        uint8_t *key, int key_size, uint8_t *iv,
+                                        int iv_len, uint8_t *plaintext,
+                                        size_t *plaintext_len) {
+
+  EVP_CIPHER_CTX *ctx;
+  int len;
+  int ret;
+
+  if (aad_len == 0) {
+    aad = "";
+  }
+
+  // Create and initialise the context.
+  if (!(ctx = _goboringcrypto_EVP_CIPHER_CTX_new()))
+    return 0;
+
+  switch (key_size) {
+  case 128:
+    if (!_goboringcrypto_EVP_DecryptInit_ex(
+            ctx, _goboringcrypto_EVP_aes_128_gcm(), NULL, NULL, NULL)) {
+      goto err;
+    }
+    break;
+  case 256:
+    if (!_goboringcrypto_EVP_DecryptInit_ex(
+            ctx, _goboringcrypto_EVP_aes_256_gcm(), NULL, NULL, NULL)) {
+      goto err;
+    }
+    break;
+  }
+
+  // Initialize key and nonce.
+  if (!_goboringcrypto_EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv)) {
+    goto err;
+  }
+
+  // Provide any AAD data.
+  if (!_goboringcrypto_EVP_DecryptUpdate(ctx, NULL, &len, aad, aad_len)) {
+    goto err;
+  }
+
+  // Provide the message to be decrypted, and obtain the plaintext output.
+  if (!_goboringcrypto_EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext,
+                                         ciphertext_len)) {
+    goto err;
+  }
+  *plaintext_len = len;
+
+  // Set expected tag value. Works in OpenSSL 1.0.1d and later.
+  if (!_goboringcrypto_EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16,
+                                           tag)) {
+    goto err;
+  }
+
+  // Finalise the decryption. A positive return value indicates success,
+  // anything else is a failure - the plaintext is not trustworthy.
+  ret = _goboringcrypto_EVP_DecryptFinal_ex(ctx, plaintext + len, &len);
+
+err:
+  _goboringcrypto_EVP_CIPHER_CTX_free(ctx);
+
+  if (ret > 0) {
+    // Success
+    *plaintext_len += len;
+    return ret;
+  } else {
+    // Verify failed
+    return 0;
+  }
+}
diff --git a/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_port_ctr128.c b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_port_ctr128.c
new file mode 100644
index 0000000..df4ebe3
--- /dev/null
+++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_port_ctr128.c
@@ -0,0 +1,13 @@
+// +build linux
+// +build !android
+// +build !no_openssl
+// +build !cmd_go_bootstrap
+// +build !msan
+
+#include "goopenssl.h"
+
+void _goboringcrypto_EVP_AES_ctr128_enc(EVP_CIPHER_CTX *ctx, const uint8_t *in,
+                                        uint8_t *out, size_t in_len) {
+  int len;
+  _goboringcrypto_EVP_EncryptUpdate(ctx, out, &len, in, in_len);
+}
diff --git a/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_port_evp_md5_sha1.c b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_port_evp_md5_sha1.c
new file mode 100644
index 0000000..2eedd5b
--- /dev/null
+++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_port_evp_md5_sha1.c
@@ -0,0 +1,90 @@
+// This file contains a backport of the EVP_md5_sha1 method.
+// +build linux
+// +build !android
+// +build !no_openssl
+// +build !cmd_go_bootstrap
+// +build !msan
+
+// 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.
+
+#include "goopenssl.h"
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+// New in OpenSSL 1.1.
+static inline void *
+_goboringcrypto_internal_EVP_MD_CTX_md_data(EVP_MD_CTX *ctx) {
+  return ctx->md_data;
+}
+
+/*
+ * 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
+ */
+
+#if !defined(OPENSSL_NO_MD5)
+
+#include <openssl/evp.h>
+#include <openssl/md5.h>
+#include <openssl/objects.h>
+#include <openssl/rsa.h>
+#include <openssl/sha.h>
+#include <openssl/x509.h>
+
+struct md5_sha1_ctx {
+  MD5_CTX md5;
+  SHA_CTX sha1;
+};
+
+static int _goboringcrypto_internal_init(EVP_MD_CTX *ctx) {
+  struct md5_sha1_ctx *mctx = _goboringcrypto_internal_EVP_MD_CTX_md_data(ctx);
+  if (!_goboringcrypto_internal_MD5_Init(&mctx->md5))
+    return 0;
+  return _goboringcrypto_SHA1_Init(&mctx->sha1);
+}
+
+static int _goboringcrypto_internal_update(EVP_MD_CTX *ctx, const void *data,
+                                           size_t count) {
+  struct md5_sha1_ctx *mctx = _goboringcrypto_internal_EVP_MD_CTX_md_data(ctx);
+  if (!_goboringcrypto_internal_MD5_Update(&mctx->md5, data, count))
+    return 0;
+  return _goboringcrypto_SHA1_Update(&mctx->sha1, data, count);
+}
+
+static int _goboringcrypto_internal_final(EVP_MD_CTX *ctx, unsigned char *md) {
+  struct md5_sha1_ctx *mctx = _goboringcrypto_internal_EVP_MD_CTX_md_data(ctx);
+  if (!_goboringcrypto_internal_MD5_Final(md, &mctx->md5))
+    return 0;
+  return _goboringcrypto_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,
+    _goboringcrypto_internal_init,
+    _goboringcrypto_internal_update,
+    _goboringcrypto_internal_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 *_goboringcrypto_backport_EVP_md5_sha1(void) {
+  return &md5_sha1_md;
+}
+#endif
+#endif
diff --git a/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_port_hmac.c b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_port_hmac.c
new file mode 100644
index 0000000..362d9e5
--- /dev/null
+++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_port_hmac.c
@@ -0,0 +1,16 @@
+// This file contains HMAC portability wrappers.
+// +build linux
+// +build !android
+// +build !no_openssl
+// +build !cmd_go_bootstrap
+// +build !msan
+
+#include "goopenssl.h"
+
+// Not in OpenSSL 1.1.  However, HMAC_CTX_copy expects an initialized
+// target in OpenSSL 1.1.
+int _goboringcrypto_HMAC_CTX_copy_ex(GO_HMAC_CTX *dest,
+                                     const GO_HMAC_CTX *src) {
+  // HMAC_CTX_copy lacks the const qualifier for the second parameter.
+  return _goboringcrypto_HMAC_CTX_copy(dest, (GO_HMAC_CTX *)src);
+}
diff --git a/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_port_rsa.c b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_port_rsa.c
new file mode 100644
index 0000000..2824147
--- /dev/null
+++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_port_rsa.c
@@ -0,0 +1,219 @@
+// This file contains RSA portability wrappers.
+// +build linux
+// +build !android
+// +build !no_openssl
+// +build !cmd_go_bootstrap
+// +build !msan
+
+#include "goopenssl.h"
+
+// Only in BoringSSL.
+int _goboringcrypto_RSA_generate_key_fips(GO_RSA *rsa, int size,
+                                          GO_BN_GENCB *cb) {
+  // BoringSSL's RSA_generate_key_fips hard-codes e to 65537.
+  BIGNUM *e = _goboringcrypto_BN_new();
+  if (e == NULL)
+    return 0;
+  int ret = _goboringcrypto_BN_set_word(e, RSA_F4) &&
+            _goboringcrypto_RSA_generate_key_ex(rsa, size, e, cb);
+  _goboringcrypto_BN_free(e);
+  return ret;
+}
+
+int _goboringcrypto_RSA_digest_and_sign_pss_mgf1(
+    GO_RSA *rsa, unsigned int *out_len, uint8_t *out, size_t max_out,
+    const uint8_t *in, size_t in_len, EVP_MD *md, const EVP_MD *mgf1_md,
+    int salt_len) {
+  EVP_PKEY_CTX *ctx;
+  unsigned int siglen;
+
+  int ret = 0;
+  EVP_PKEY *key = _goboringcrypto_EVP_PKEY_new();
+  if (!key) {
+    goto err;
+  }
+  if (!_goboringcrypto_EVP_PKEY_set1_RSA(key, rsa))
+    goto err;
+  ctx = _goboringcrypto_EVP_PKEY_CTX_new(key, NULL /* no engine */);
+  if (!ctx)
+    goto err;
+
+  EVP_MD_CTX *mdctx = NULL;
+  if (!(mdctx = _goboringcrypto_EVP_MD_CTX_create()))
+    goto err;
+
+  if (1 != _goboringcrypto_EVP_DigestSignInit(mdctx, &ctx, md, NULL, key))
+    goto err;
+
+  if (_goboringcrypto_EVP_PKEY_sign_init(ctx) <= 0)
+    goto err;
+  if (_goboringcrypto_EVP_PKEY_CTX_set_signature_md(ctx, md) <= 0)
+    goto err;
+  if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_padding(ctx,
+                                                   RSA_PKCS1_PSS_PADDING) <= 0)
+    goto err;
+  if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, salt_len) <= 0)
+    goto err;
+  if (mgf1_md)
+    if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, mgf1_md) <= 0)
+      goto err;
+  if (1 != _goboringcrypto_EVP_DigestUpdate(mdctx, in, in_len))
+    goto err;
+
+  /* Obtain the signature length */
+  if (1 != _goboringcrypto_EVP_DigestSignFinal(mdctx, NULL, out_len))
+    goto err;
+  /* Obtain the signature */
+  if (1 != _goboringcrypto_EVP_DigestSignFinal(mdctx, out, out_len))
+    goto err;
+
+  ret = 1;
+
+err:
+  if (mdctx)
+    _goboringcrypto_EVP_MD_CTX_free(mdctx);
+  if (ctx)
+    _goboringcrypto_EVP_PKEY_CTX_free(ctx);
+  if (key)
+    _goboringcrypto_EVP_PKEY_free(key);
+
+  return ret;
+}
+
+int _goboringcrypto_RSA_sign_pss_mgf1(GO_RSA *rsa, unsigned int *out_len,
+                                      uint8_t *out, unsigned int max_out,
+                                      const uint8_t *in, unsigned int in_len,
+                                      EVP_MD *md, const EVP_MD *mgf1_md,
+                                      int salt_len) {
+  EVP_PKEY_CTX *ctx;
+  EVP_PKEY *pkey;
+  size_t siglen;
+
+  int ret = 0;
+  pkey = _goboringcrypto_EVP_PKEY_new();
+  if (!pkey)
+    goto err;
+
+  if (_goboringcrypto_EVP_PKEY_set1_RSA(pkey, rsa) <= 0)
+    goto err;
+
+  ctx = _goboringcrypto_EVP_PKEY_CTX_new(pkey, NULL /* no engine */);
+  if (!ctx)
+    goto err;
+
+  if (_goboringcrypto_EVP_PKEY_sign_init(ctx) <= 0)
+    goto err;
+  if (_goboringcrypto_EVP_PKEY_CTX_set_signature_md(ctx, md) <= 0)
+    goto err;
+  if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_padding(ctx,
+                                                   RSA_PKCS1_PSS_PADDING) <= 0)
+    goto err;
+  if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, salt_len) <= 0)
+    goto err;
+  if (mgf1_md)
+    if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, mgf1_md) <= 0)
+      goto err;
+  /* Determine buffer length */
+  if (_goboringcrypto_EVP_PKEY_sign(ctx, NULL, &siglen, in, in_len) <= 0)
+    goto err;
+
+  if (max_out < siglen)
+    goto err;
+
+  if (_goboringcrypto_EVP_PKEY_sign(ctx, out, &siglen, in, in_len) <= 0)
+    goto err;
+
+  *out_len = siglen;
+  ret = 1;
+
+err:
+  if (ctx)
+    _goboringcrypto_EVP_PKEY_CTX_free(ctx);
+  if (pkey)
+    _goboringcrypto_EVP_PKEY_free(pkey);
+
+  return ret;
+}
+
+int _goboringcrypto_RSA_verify_pss_mgf1(RSA *rsa, const uint8_t *msg,
+                                        unsigned int msg_len, EVP_MD *md,
+                                        const EVP_MD *mgf1_md, int salt_len,
+                                        const uint8_t *sig,
+                                        unsigned int sig_len) {
+  EVP_PKEY_CTX *ctx;
+  EVP_PKEY *pkey;
+
+  int ret = 0;
+
+  pkey = _goboringcrypto_EVP_PKEY_new();
+  if (!pkey)
+    goto err;
+
+  if (_goboringcrypto_EVP_PKEY_set1_RSA(pkey, rsa) <= 0)
+    goto err;
+
+  ctx = _goboringcrypto_EVP_PKEY_CTX_new(pkey, NULL /* no engine */);
+  if (!ctx)
+    goto err;
+
+  if (_goboringcrypto_EVP_PKEY_verify_init(ctx) <= 0)
+    goto err;
+  if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_padding(ctx,
+                                                   RSA_PKCS1_PSS_PADDING) <= 0)
+    goto err;
+  if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, salt_len) <= 0)
+    goto err;
+  if (_goboringcrypto_EVP_PKEY_CTX_set_signature_md(ctx, md) <= 0)
+    goto err;
+  if (mgf1_md)
+    if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, mgf1_md) <= 0)
+      goto err;
+  if (_goboringcrypto_EVP_PKEY_verify(ctx, sig, sig_len, msg, msg_len) <= 0)
+    goto err;
+
+  ret = 1;
+
+err:
+  if (ctx)
+    _goboringcrypto_EVP_PKEY_CTX_free(ctx);
+  if (pkey)
+    _goboringcrypto_EVP_PKEY_free(pkey);
+
+  return ret;
+}
+
+int _goboringcrypto_EVP_RSA_sign(EVP_MD *md, const uint8_t *msg,
+                                 unsigned int msgLen, uint8_t *sig,
+                                 unsigned int *slen, RSA *rsa) {
+  int result;
+  EVP_PKEY *key = _goboringcrypto_EVP_PKEY_new();
+  if (!key) {
+    return 0;
+  }
+  if (!_goboringcrypto_EVP_PKEY_set1_RSA(key, rsa)) {
+    result = 0;
+    goto err;
+  }
+  result = _goboringcrypto_EVP_sign(md, NULL, msg, msgLen, sig, slen, key);
+err:
+  _goboringcrypto_EVP_PKEY_free(key);
+  return result;
+}
+
+int _goboringcrypto_EVP_RSA_verify(EVP_MD *md, const uint8_t *msg,
+                                   unsigned int msgLen, const uint8_t *sig,
+                                   unsigned int slen, GO_RSA *rsa) {
+  int result;
+  EVP_PKEY *key = _goboringcrypto_EVP_PKEY_new();
+  if (!key) {
+    return 0;
+  }
+  if (!_goboringcrypto_EVP_PKEY_set1_RSA(key, rsa)) {
+    result = 0;
+    goto err;
+  }
+  result = _goboringcrypto_EVP_verify(md, NULL, msg, msgLen, sig, slen, key);
+err:
+  _goboringcrypto_EVP_PKEY_free(key);
+  return result;
+}
\ No newline at end of file
diff --git a/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_stub_rand.c b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_stub_rand.c
new file mode 100644
index 0000000..22bd865
--- /dev/null
+++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/openssl_stub_rand.c
@@ -0,0 +1,45 @@
+// +build linux
+// +build !android
+// +build !no_openssl
+// +build !cmd_go_bootstrap
+// +build !msan
+
+#include "goopenssl.h"
+#include <openssl/rand.h>
+
+static RAND_METHOD fake_rand;
+static const RAND_METHOD *old_rand;
+
+int _goboringcrypto_stub_openssl_rand(void) {
+  /* save old rand method */
+  if ((old_rand = _goboringcrypto_RAND_get_rand_method()) == NULL)
+    return 0;
+
+  fake_rand.seed = old_rand->seed;
+  fake_rand.cleanup = old_rand->cleanup;
+  fake_rand.add = old_rand->add;
+  fake_rand.status = old_rand->status;
+  /* use own random function */
+  fake_rand.bytes = fbytes;
+  fake_rand.pseudorand = old_rand->bytes;
+  /* set new RAND_METHOD */
+  if (!_goboringcrypto_RAND_set_rand_method(&fake_rand))
+    return 0;
+  return 1;
+}
+
+int _goboringcrypto_restore_openssl_rand(void) {
+  if (!_goboringcrypto_RAND_set_rand_method(old_rand))
+    return 0;
+  else
+    return 1;
+}
+
+int fbytes(unsigned char *buf, int num) {
+  // return old_rand->bytes(buf, num);
+  int i;
+  for (i = 0; i < num; i++) {
+    buf[i] = 1;
+  }
+  return 1;
+}
diff --git a/src/crypto/internal/boring/rand.go b/src/vendor/github.com/golang-fips/openssl-fips/openssl/rand.go
similarity index 70%
rename from src/crypto/internal/boring/rand.go
rename to src/vendor/github.com/golang-fips/openssl-fips/openssl/rand.go
index d2e432e..b3668b8 100644
--- a/src/crypto/internal/boring/rand.go
+++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/rand.go
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build boringcrypto && linux && amd64 && !android && !cmd_go_bootstrap && !msan
-// +build boringcrypto,linux,amd64,!android,!cmd_go_bootstrap,!msan
+//go:build linux && !android && !cmd_go_bootstrap && !msan && !no_openssl
+// +build linux,!android,!cmd_go_bootstrap,!msan,!no_openssl
 
-package boring
+package openssl
 
-// #include "goboringcrypto.h"
+// #include "goopenssl.h"
 import "C"
 import "unsafe"
 
@@ -17,7 +17,7 @@ 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._goboringcrypto_RAND_bytes((*C.uint8_t)(unsafe.Pointer(&b[0])), C.size_t(len(b))) == 0 {
-		return 0, fail("RAND_bytes")
+		return 0, NewOpenSSLError("RAND_bytes")
 	}
 	return len(b), nil
 }
diff --git a/src/crypto/internal/boring/rsa.go b/src/vendor/github.com/golang-fips/openssl-fips/openssl/rsa.go
similarity index 58%
rename from src/crypto/internal/boring/rsa.go
rename to src/vendor/github.com/golang-fips/openssl-fips/openssl/rsa.go
index 64c83c2..915c840 100644
--- a/src/crypto/internal/boring/rsa.go
+++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/rsa.go
@@ -2,16 +2,15 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build boringcrypto && linux && amd64 && !android && !cmd_go_bootstrap && !msan
-// +build boringcrypto,linux,amd64,!android,!cmd_go_bootstrap,!msan
+//go:build linux && !android && !cmd_go_bootstrap && !msan && !no_openssl
+// +build linux,!android,!cmd_go_bootstrap,!msan,!no_openssl
 
-package boring
+package openssl
 
-// #include "goboringcrypto.h"
+// #include "goopenssl.h"
 import "C"
 import (
 	"crypto"
-	"crypto/subtle"
 	"errors"
 	"hash"
 	"runtime"
@@ -26,12 +25,12 @@ func GenerateKeyRSA(bits int) (N, E, D, P, Q, Dp, Dq, Qinv BigInt, err error) {
 
 	key := C._goboringcrypto_RSA_new()
 	if key == nil {
-		return bad(fail("RSA_new"))
+		return bad(NewOpenSSLError("RSA_new failed"))
 	}
 	defer C._goboringcrypto_RSA_free(key)
 
 	if C._goboringcrypto_RSA_generate_key_fips(key, C.int(bits), nil) == 0 {
-		return bad(fail("RSA_generate_key_fips"))
+		return bad(NewOpenSSLError("RSA_generate_key_fips failed"))
 	}
 
 	var n, e, d, p, q, dp, dq, qinv *C.GO_BIGNUM
@@ -49,12 +48,12 @@ type PublicKeyRSA struct {
 func NewPublicKeyRSA(N, E BigInt) (*PublicKeyRSA, error) {
 	key := C._goboringcrypto_RSA_new()
 	if key == nil {
-		return nil, fail("RSA_new")
-	}
-	if !bigToBn(&key.n, N) ||
-		!bigToBn(&key.e, E) {
-		return nil, fail("BN_bin2bn")
+		return nil, NewOpenSSLError("RSA_new failed")
 	}
+	var n, e *C.GO_BIGNUM
+	n = bigToBN(N)
+	e = bigToBN(E)
+	C._goboringcrypto_RSA_set0_key(key, n, e, nil)
 	k := &PublicKeyRSA{_key: key}
 	runtime.SetFinalizer(k, (*PublicKeyRSA).finalize)
 	return k, nil
@@ -80,17 +79,23 @@ type PrivateKeyRSA struct {
 func NewPrivateKeyRSA(N, E, D, P, Q, Dp, Dq, Qinv BigInt) (*PrivateKeyRSA, error) {
 	key := C._goboringcrypto_RSA_new()
 	if key == nil {
-		return nil, fail("RSA_new")
-	}
-	if !bigToBn(&key.n, N) ||
-		!bigToBn(&key.e, E) ||
-		!bigToBn(&key.d, D) ||
-		!bigToBn(&key.p, P) ||
-		!bigToBn(&key.q, Q) ||
-		!bigToBn(&key.dmp1, Dp) ||
-		!bigToBn(&key.dmq1, Dq) ||
-		!bigToBn(&key.iqmp, Qinv) {
-		return nil, fail("BN_bin2bn")
+		return nil, NewOpenSSLError("RSA_new failed")
+	}
+	var n, e, d, p, q, dp, dq, qinv *C.GO_BIGNUM
+	n = bigToBN(N)
+	e = bigToBN(E)
+	d = bigToBN(D)
+	C._goboringcrypto_RSA_set0_key(key, n, e, d)
+	if P != nil && Q != nil {
+		p = bigToBN(P)
+		q = bigToBN(Q)
+		C._goboringcrypto_RSA_set0_factors(key, p, q)
+	}
+	if Dp != nil && Dq != nil && Qinv != nil {
+		dp = bigToBN(Dp)
+		dq = bigToBN(Dq)
+		qinv = bigToBN(Qinv)
+		C._goboringcrypto_RSA_set0_crt_params(key, dp, dq, qinv)
 	}
 	k := &PrivateKeyRSA{_key: key}
 	runtime.SetFinalizer(k, (*PrivateKeyRSA).finalize)
@@ -127,7 +132,7 @@ func setupRSA(withKey func(func(*C.GO_RSA) C.int) C.int,
 
 	pkey = C._goboringcrypto_EVP_PKEY_new()
 	if pkey == nil {
-		return nil, nil, fail("EVP_PKEY_new")
+		return nil, nil, NewOpenSSLError("EVP_PKEY_new failed")
 	}
 	if withKey(func(key *C.GO_RSA) C.int {
 		return C._goboringcrypto_EVP_PKEY_set1_RSA(pkey, key)
@@ -136,13 +141,13 @@ func setupRSA(withKey func(func(*C.GO_RSA) C.int) C.int,
 	}
 	ctx = C._goboringcrypto_EVP_PKEY_CTX_new(pkey, nil)
 	if ctx == nil {
-		return nil, nil, fail("EVP_PKEY_CTX_new")
+		return nil, nil, NewOpenSSLError("EVP_PKEY_CTX_new failed")
 	}
 	if init(ctx) == 0 {
-		return nil, nil, fail("EVP_PKEY_operation_init")
+		return nil, nil, NewOpenSSLError("EVP_PKEY_operation_init failed")
 	}
 	if C._goboringcrypto_EVP_PKEY_CTX_set_rsa_padding(ctx, padding) == 0 {
-		return nil, nil, fail("EVP_PKEY_CTX_set_rsa_padding")
+		return nil, nil, NewOpenSSLError("EVP_PKEY_CTX_set_rsa_padding failed")
 	}
 	if padding == C.GO_RSA_PKCS1_OAEP_PADDING {
 		md := hashToMD(h)
@@ -150,22 +155,33 @@ func setupRSA(withKey func(func(*C.GO_RSA) C.int) C.int,
 			return nil, nil, errors.New("crypto/rsa: unsupported hash function")
 		}
 		if C._goboringcrypto_EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md) == 0 {
-			return nil, nil, fail("EVP_PKEY_set_rsa_oaep_md")
+			return nil, nil, NewOpenSSLError("EVP_PKEY_set_rsa_oaep_md failed")
 		}
 		// ctx takes ownership of label, so malloc a copy for BoringCrypto to free.
-		clabel := (*C.uint8_t)(C._goboringcrypto_OPENSSL_malloc(C.size_t(len(label))))
-		if clabel == nil {
-			return nil, nil, fail("OPENSSL_malloc")
+		var clabel *C.uint8_t
+		clabel = nil
+		// OpenSSL 1.1.1 does not take ownership of the label if the length is zero.
+		// Depending on the malloc implementation, if clabel is allocated with malloc(0),
+		// metadata for the size-zero allocation is never cleaned up, which is a memory leak.
+		// As such, we must only allocate clabel if the label is of non zero length.
+		if (len(label) > 0) || (openSSLVersion() > OPENSSL_VERSION_3_0_0) {
+			clabel = (*C.uint8_t)(C.malloc(C.size_t(len(label))))
+			if clabel == nil {
+				return nil, nil, fail("OPENSSL_malloc")
+			}
+			copy((*[1 << 30]byte)(unsafe.Pointer(clabel))[:len(label)], label)
 		}
-		copy((*[1 << 30]byte)(unsafe.Pointer(clabel))[:len(label)], label)
-		if C._goboringcrypto_EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, clabel, C.size_t(len(label))) == 0 {
-			return nil, nil, fail("EVP_PKEY_CTX_set0_rsa_oaep_label")
+		if C._goboringcrypto_EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, clabel, C.int(len(label))) != 1 {
+			if clabel != nil {
+				C.free(unsafe.Pointer(clabel))
+			}
+			return nil, nil, NewOpenSSLError("EVP_PKEY_CTX_set0_rsa_oaep_label failed")
 		}
 	}
 	if padding == C.GO_RSA_PKCS1_PSS_PADDING {
 		if saltLen != 0 {
 			if C._goboringcrypto_EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, C.int(saltLen)) == 0 {
-				return nil, nil, fail("EVP_PKEY_set_rsa_pss_saltlen")
+				return nil, nil, NewOpenSSLError("EVP_PKEY_set_rsa_pss_saltlen failed")
 			}
 		}
 		md := cryptoHashToMD(ch)
@@ -173,7 +189,7 @@ func setupRSA(withKey func(func(*C.GO_RSA) C.int) C.int,
 			return nil, nil, errors.New("crypto/rsa: unsupported hash function")
 		}
 		if C._goboringcrypto_EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, md) == 0 {
-			return nil, nil, fail("EVP_PKEY_set_rsa_mgf1_md")
+			return nil, nil, NewOpenSSLError("EVP_PKEY_set_rsa_mgf1_md failed")
 		}
 	}
 
@@ -183,7 +199,7 @@ func setupRSA(withKey func(func(*C.GO_RSA) C.int) C.int,
 func cryptRSA(withKey func(func(*C.GO_RSA) C.int) C.int,
 	padding C.int, h hash.Hash, label []byte, saltLen int, ch crypto.Hash,
 	init func(*C.GO_EVP_PKEY_CTX) C.int,
-	crypt func(*C.GO_EVP_PKEY_CTX, *C.uint8_t, *C.size_t, *C.uint8_t, C.size_t) C.int,
+	crypt func(*C.GO_EVP_PKEY_CTX, *C.uint8_t, *C.uint, *C.uint8_t, C.uint) C.int,
 	in []byte) ([]byte, error) {
 
 	pkey, ctx, err := setupRSA(withKey, padding, h, label, saltLen, ch, init)
@@ -193,13 +209,13 @@ func cryptRSA(withKey func(func(*C.GO_RSA) C.int) C.int,
 	defer C._goboringcrypto_EVP_PKEY_free(pkey)
 	defer C._goboringcrypto_EVP_PKEY_CTX_free(ctx)
 
-	var outLen C.size_t
-	if crypt(ctx, nil, &outLen, base(in), C.size_t(len(in))) == 0 {
-		return nil, fail("EVP_PKEY_decrypt/encrypt")
+	var outLen C.uint
+	if crypt(ctx, nil, &outLen, base(in), C.uint(len(in))) == 0 {
+		return nil, NewOpenSSLError("EVP_PKEY_decrypt/encrypt failed")
 	}
 	out := make([]byte, outLen)
-	if crypt(ctx, base(out), &outLen, base(in), C.size_t(len(in))) == 0 {
-		return nil, fail("EVP_PKEY_decrypt/encrypt")
+	if crypt(ctx, base(out), &outLen, base(in), C.uint(len(in))) <= 0 {
+		return nil, NewOpenSSLError("EVP_PKEY_decrypt/encrypt failed")
 	}
 	return out[:outLen], nil
 }
@@ -234,7 +250,7 @@ func decryptInit(ctx *C.GO_EVP_PKEY_CTX) C.int {
 	return C._goboringcrypto_EVP_PKEY_decrypt_init(ctx)
 }
 
-func decrypt(ctx *C.GO_EVP_PKEY_CTX, out *C.uint8_t, outLen *C.size_t, in *C.uint8_t, inLen C.size_t) C.int {
+func decrypt(ctx *C.GO_EVP_PKEY_CTX, out *C.uint8_t, outLen *C.uint, in *C.uint8_t, inLen C.uint) C.int {
 	return C._goboringcrypto_EVP_PKEY_decrypt(ctx, out, outLen, in, inLen)
 }
 
@@ -242,7 +258,7 @@ func encryptInit(ctx *C.GO_EVP_PKEY_CTX) C.int {
 	return C._goboringcrypto_EVP_PKEY_encrypt_init(ctx)
 }
 
-func encrypt(ctx *C.GO_EVP_PKEY_CTX, out *C.uint8_t, outLen *C.size_t, in *C.uint8_t, inLen C.size_t) C.int {
+func encrypt(ctx *C.GO_EVP_PKEY_CTX, out *C.uint8_t, outLen *C.uint, in *C.uint8_t, inLen C.uint) C.int {
 	return C._goboringcrypto_EVP_PKEY_encrypt(ctx, out, outLen, in, inLen)
 }
 
@@ -255,11 +271,11 @@ func SignRSAPSS(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte, saltLen int)
 		saltLen = -1
 	}
 	var out []byte
-	var outLen C.size_t
+	var outLen C.uint
 	if priv.withKey(func(key *C.GO_RSA) C.int {
 		out = make([]byte, C._goboringcrypto_RSA_size(key))
-		return C._goboringcrypto_RSA_sign_pss_mgf1(key, &outLen, base(out), C.size_t(len(out)),
-			base(hashed), C.size_t(len(hashed)), md, nil, C.int(saltLen))
+		return C._goboringcrypto_RSA_sign_pss_mgf1(key, &outLen, base(out), C.uint(len(out)),
+			base(hashed), C.uint(len(hashed)), md, nil, C.int(saltLen))
 	}) == 0 {
 		return nil, fail("RSA_sign_pss_mgf1")
 	}
@@ -276,72 +292,120 @@ func VerifyRSAPSS(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte, saltLen
 		saltLen = -2 // auto-recover
 	}
 	if pub.withKey(func(key *C.GO_RSA) C.int {
-		return C._goboringcrypto_RSA_verify_pss_mgf1(key, base(hashed), C.size_t(len(hashed)),
-			md, nil, C.int(saltLen), base(sig), C.size_t(len(sig)))
+		return C._goboringcrypto_RSA_verify_pss_mgf1(key, base(hashed), C.uint(len(hashed)),
+			md, nil, C.int(saltLen), base(sig), C.uint(len(sig)))
 	}) == 0 {
 		return fail("RSA_verify_pss_mgf1")
 	}
 	return nil
 }
 
-func SignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte) ([]byte, error) {
-	if h == 0 {
-		// No hashing.
+func SignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, msg []byte, msgIsHashed bool) ([]byte, error) {
+	if h == 0 && ExecutingTest() {
+		return signRSAPKCS1v15Raw(priv, msg, C._goboringcrypto_EVP_md_null())
+	}
+
+	md := cryptoHashToMD(h)
+	if md == nil {
+		return nil, errors.New("crypto/rsa: unsupported hash function: " + strconv.Itoa(int(h)))
+	}
+
+	if msgIsHashed {
 		var out []byte
-		var outLen C.size_t
+		var outLen C.uint
+		PanicIfStrictFIPS("You must provide a raw unhashed message for PKCS1v15 signing and use HashSignPKCS1v15 instead of SignPKCS1v15")
+		nid := C._goboringcrypto_EVP_MD_type(md)
 		if priv.withKey(func(key *C.GO_RSA) C.int {
 			out = make([]byte, C._goboringcrypto_RSA_size(key))
-			return C._goboringcrypto_RSA_sign_raw(key, &outLen, base(out), C.size_t(len(out)),
-				base(hashed), C.size_t(len(hashed)), C.GO_RSA_PKCS1_PADDING)
+			return C._goboringcrypto_RSA_sign(nid, base(msg), C.uint(len(msg)), base(out), &outLen, key)
 		}) == 0 {
-			return nil, fail("RSA_sign_raw")
+			return nil, NewOpenSSLError("RSA_sign")
 		}
+		runtime.KeepAlive(priv)
 		return out[:outLen], nil
 	}
 
-	md := cryptoHashToMD(h)
-	if md == nil {
-		return nil, errors.New("crypto/rsa: unsupported hash function: " + strconv.Itoa(int(h)))
-	}
-	nid := C._goboringcrypto_EVP_MD_type(md)
 	var out []byte
 	var outLen C.uint
+
+	if priv.withKey(func(key *C.GO_RSA) C.int {
+		return C._goboringcrypto_EVP_RSA_sign(md, base(msg), C.uint(len(msg)), base(out), &outLen, key)
+	}) == 0 {
+		return nil, NewOpenSSLError("RSA_sign")
+	}
+	return out[:outLen], nil
+}
+
+func signRSAPKCS1v15Raw(priv *PrivateKeyRSA, msg []byte, md *C.GO_EVP_MD) ([]byte, error) {
+	var out []byte
+	var outLen C.size_t
+	PanicIfStrictFIPS("You must provide a raw unhashed message for PKCS1v15 signing and use HashSignPKCS1v15 instead of SignPKCS1v15")
+
 	if priv.withKey(func(key *C.GO_RSA) C.int {
 		out = make([]byte, C._goboringcrypto_RSA_size(key))
-		return C._goboringcrypto_RSA_sign(nid, base(hashed), C.uint(len(hashed)),
-			base(out), &outLen, key)
+		outLen = C.size_t(len(out))
+		return C._goboringcrypto_EVP_sign_raw(md, nil, base(msg),
+			C.size_t(len(msg)), base(out), &outLen, key)
 	}) == 0 {
-		return nil, fail("RSA_sign")
+		return nil, NewOpenSSLError("RSA_sign")
 	}
+	runtime.KeepAlive(priv)
 	return out[:outLen], nil
 }
 
-func VerifyRSAPKCS1v15(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte) error {
-	if h == 0 {
-		var out []byte
-		var outLen C.size_t
+func VerifyRSAPKCS1v15(pub *PublicKeyRSA, h crypto.Hash, msg, sig []byte, msgIsHashed bool) error {
+	if h == 0 && ExecutingTest() {
+		return verifyRSAPKCS1v15Raw(pub, msg, sig)
+	}
+
+	md := cryptoHashToMD(h)
+	if md == nil {
+		return errors.New("crypto/rsa: unsupported hash function")
+	}
+
+	if pub.withKey(func(key *C.GO_RSA) C.int {
+		size := int(C._goboringcrypto_RSA_size(key))
+		if len(sig) < size {
+			return 0
+		}
+		return 1
+	}) == 0 {
+		return errors.New("crypto/rsa: verification error")
+	}
+
+	if msgIsHashed {
+		PanicIfStrictFIPS("You must provide a raw unhashed message for PKCS1v15 verification and use HashVerifyPKCS1v15 instead of VerifyPKCS1v15")
+		nid := C._goboringcrypto_EVP_MD_type(md)
 		if pub.withKey(func(key *C.GO_RSA) C.int {
-			out = make([]byte, C._goboringcrypto_RSA_size(key))
-			return C._goboringcrypto_RSA_verify_raw(key, &outLen, base(out),
-				C.size_t(len(out)), base(sig), C.size_t(len(sig)), C.GO_RSA_PKCS1_PADDING)
+			return C._goboringcrypto_RSA_verify(nid, base(msg), C.uint(len(msg)), base(sig), C.uint(len(sig)), key)
 		}) == 0 {
-			return fail("RSA_verify")
-		}
-		if subtle.ConstantTimeCompare(hashed, out[:outLen]) != 1 {
-			return fail("RSA_verify")
+			return NewOpenSSLError("RSA_verify failed")
 		}
 		return nil
 	}
-	md := cryptoHashToMD(h)
-	if md == nil {
-		return errors.New("crypto/rsa: unsupported hash function")
+
+	if pub.withKey(func(key *C.GO_RSA) C.int {
+		return C._goboringcrypto_EVP_RSA_verify(md, base(msg), C.uint(len(msg)), base(sig), C.uint(len(sig)), key)
+	}) == 0 {
+		return NewOpenSSLError("RSA_verify failed")
+	}
+	return nil
+}
+
+func verifyRSAPKCS1v15Raw(pub *PublicKeyRSA, msg, sig []byte) error {
+	if pub.withKey(func(key *C.GO_RSA) C.int {
+		size := int(C._goboringcrypto_RSA_size(key))
+		if len(sig) < size {
+			return 0
+		}
+		return 1
+	}) == 0 {
+		return errors.New("crypto/rsa: verification error")
 	}
-	nid := C._goboringcrypto_EVP_MD_type(md)
 	if pub.withKey(func(key *C.GO_RSA) C.int {
-		return C._goboringcrypto_RSA_verify(nid, base(hashed), C.size_t(len(hashed)),
-			base(sig), C.size_t(len(sig)), key)
+		return C._goboringcrypto_EVP_verify_raw(base(msg), C.size_t(len(msg)), base(sig), C.uint(len(sig)), key)
 	}) == 0 {
-		return fail("RSA_verify")
+		return NewOpenSSLError("RSA_verify failed")
 	}
 	return nil
 }
diff --git a/src/crypto/internal/boring/sha.go b/src/vendor/github.com/golang-fips/openssl-fips/openssl/sha.go
similarity index 78%
rename from src/crypto/internal/boring/sha.go
rename to src/vendor/github.com/golang-fips/openssl-fips/openssl/sha.go
index 15b50c9..0b55ced 100644
--- a/src/crypto/internal/boring/sha.go
+++ b/src/vendor/github.com/golang-fips/openssl-fips/openssl/sha.go
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build boringcrypto && linux && amd64 && !android && !cmd_go_bootstrap && !msan
-// +build boringcrypto,linux,amd64,!android,!cmd_go_bootstrap,!msan
+//go:build linux && !android && !cmd_go_bootstrap && !msan && !no_openssl
+// +build linux,!android,!cmd_go_bootstrap,!msan,!no_openssl
 
-package boring
+package openssl
 
 /*
-#include "goboringcrypto.h"
+#include "goopenssl.h"
 
 int
 _goboringcrypto_gosha1(void *p, size_t n, void *out)
@@ -18,7 +18,6 @@ _goboringcrypto_gosha1(void *p, size_t n, void *out)
 	return _goboringcrypto_SHA1_Update(&ctx, p, n) &&
 		_goboringcrypto_SHA1_Final(out, &ctx);
 }
-
 int
 _goboringcrypto_gosha224(void *p, size_t n, void *out)
 {
@@ -27,7 +26,6 @@ _goboringcrypto_gosha224(void *p, size_t n, void *out)
 	return _goboringcrypto_SHA224_Update(&ctx, p, n) &&
 		_goboringcrypto_SHA224_Final(out, &ctx);
 }
-
 int
 _goboringcrypto_gosha256(void *p, size_t n, void *out)
 {
@@ -36,7 +34,6 @@ _goboringcrypto_gosha256(void *p, size_t n, void *out)
 	return _goboringcrypto_SHA256_Update(&ctx, p, n) &&
 		_goboringcrypto_SHA256_Final(out, &ctx);
 }
-
 int
 _goboringcrypto_gosha384(void *p, size_t n, void *out)
 {
@@ -45,7 +42,6 @@ _goboringcrypto_gosha384(void *p, size_t n, void *out)
 	return _goboringcrypto_SHA384_Update(&ctx, p, n) &&
 		_goboringcrypto_SHA384_Final(out, &ctx);
 }
-
 int
 _goboringcrypto_gosha512(void *p, size_t n, void *out)
 {
@@ -54,7 +50,6 @@ _goboringcrypto_gosha512(void *p, size_t n, void *out)
 	return _goboringcrypto_SHA512_Update(&ctx, p, n) &&
 		_goboringcrypto_SHA512_Final(out, &ctx);
 }
-
 */
 import "C"
 import (
@@ -127,31 +122,24 @@ type sha1Ctx struct {
 	nx     uint32
 }
 
-func (h *sha1Hash) noescapeCtx() *C.GO_SHA_CTX {
-	return (*C.GO_SHA_CTX)(noescape(unsafe.Pointer(&h.ctx)))
-}
-
-func (h *sha1Hash) Reset() {
-	C._goboringcrypto_SHA1_Init(h.noescapeCtx())
-}
-
-func (h *sha1Hash) Size() int             { return 20 }
-func (h *sha1Hash) BlockSize() int        { return 64 }
-func (h *sha1Hash) Sum(dst []byte) []byte { return h.sum(dst) }
+func (h *sha1Hash) Reset()               { C._goboringcrypto_SHA1_Init(&h.ctx) }
+func (h *sha1Hash) Size() int            { return 20 }
+func (h *sha1Hash) BlockSize() int       { return 64 }
+func (h *sha1Hash) Sum(in []byte) []byte { return append(in, h.sum()...) }
 
 func (h *sha1Hash) Write(p []byte) (int, error) {
-	if len(p) > 0 && C._goboringcrypto_SHA1_Update(h.noescapeCtx(), unsafe.Pointer(&*addr(p)), C.size_t(len(p))) == 0 {
+	if len(p) > 0 && C._goboringcrypto_SHA1_Update(&h.ctx, unsafe.Pointer(&p[0]), C.size_t(len(p))) == 0 {
 		panic("boringcrypto: SHA1_Update failed")
 	}
 	return len(p), nil
 }
 
-func (h0 *sha1Hash) sum(dst []byte) []byte {
+func (h0 *sha1Hash) sum() []byte {
 	h := *h0 // make copy so future Write+Sum is valid
-	if C._goboringcrypto_SHA1_Final((*C.uint8_t)(noescape(unsafe.Pointer(&h.out[0]))), h.noescapeCtx()) == 0 {
+	if C._goboringcrypto_SHA1_Final((*C.uint8_t)(unsafe.Pointer(&h.out[0])), &h.ctx) == 0 {
 		panic("boringcrypto: SHA1_Final failed")
 	}
-	return append(dst, h.out[:]...)
+	return h.out[:]
 }
 
 const (
@@ -208,30 +196,24 @@ type sha224Hash struct {
 	out [224 / 8]byte
 }
 
-func (h *sha224Hash) noescapeCtx() *C.GO_SHA256_CTX {
-	return (*C.GO_SHA256_CTX)(noescape(unsafe.Pointer(&h.ctx)))
-}
-
-func (h *sha224Hash) Reset() {
-	C._goboringcrypto_SHA224_Init(h.noescapeCtx())
-}
-func (h *sha224Hash) Size() int             { return 224 / 8 }
-func (h *sha224Hash) BlockSize() int        { return 64 }
-func (h *sha224Hash) Sum(dst []byte) []byte { return h.sum(dst) }
+func (h *sha224Hash) Reset()               { C._goboringcrypto_SHA224_Init(&h.ctx) }
+func (h *sha224Hash) Size() int            { return 224 / 8 }
+func (h *sha224Hash) BlockSize() int       { return 64 }
+func (h *sha224Hash) Sum(in []byte) []byte { return append(in, h.sum()...) }
 
 func (h *sha224Hash) Write(p []byte) (int, error) {
-	if len(p) > 0 && C._goboringcrypto_SHA224_Update(h.noescapeCtx(), unsafe.Pointer(&*addr(p)), C.size_t(len(p))) == 0 {
+	if len(p) > 0 && C._goboringcrypto_SHA224_Update(&h.ctx, unsafe.Pointer(&p[0]), C.size_t(len(p))) == 0 {
 		panic("boringcrypto: SHA224_Update failed")
 	}
 	return len(p), nil
 }
 
-func (h0 *sha224Hash) sum(dst []byte) []byte {
+func (h0 *sha224Hash) sum() []byte {
 	h := *h0 // make copy so future Write+Sum is valid
-	if C._goboringcrypto_SHA224_Final((*C.uint8_t)(noescape(unsafe.Pointer(&h.out[0]))), h.noescapeCtx()) == 0 {
+	if C._goboringcrypto_SHA224_Final((*C.uint8_t)(unsafe.Pointer(&h.out[0])), &h.ctx) == 0 {
 		panic("boringcrypto: SHA224_Final failed")
 	}
-	return append(dst, h.out[:]...)
+	return h.out[:]
 }
 
 // NewSHA256 returns a new SHA256 hash.
@@ -246,30 +228,24 @@ type sha256Hash struct {
 	out [256 / 8]byte
 }
 
-func (h *sha256Hash) noescapeCtx() *C.GO_SHA256_CTX {
-	return (*C.GO_SHA256_CTX)(noescape(unsafe.Pointer(&h.ctx)))
-}
-
-func (h *sha256Hash) Reset() {
-	C._goboringcrypto_SHA256_Init(h.noescapeCtx())
-}
-func (h *sha256Hash) Size() int             { return 256 / 8 }
-func (h *sha256Hash) BlockSize() int        { return 64 }
-func (h *sha256Hash) Sum(dst []byte) []byte { return h.sum(dst) }
+func (h *sha256Hash) Reset()               { C._goboringcrypto_SHA256_Init(&h.ctx) }
+func (h *sha256Hash) Size() int            { return 256 / 8 }
+func (h *sha256Hash) BlockSize() int       { return 64 }
+func (h *sha256Hash) Sum(in []byte) []byte { return append(in, h.sum()...) }
 
 func (h *sha256Hash) Write(p []byte) (int, error) {
-	if len(p) > 0 && C._goboringcrypto_SHA256_Update(h.noescapeCtx(), unsafe.Pointer(&*addr(p)), C.size_t(len(p))) == 0 {
+	if len(p) > 0 && C._goboringcrypto_SHA256_Update(&h.ctx, unsafe.Pointer(&p[0]), C.size_t(len(p))) == 0 {
 		panic("boringcrypto: SHA256_Update failed")
 	}
 	return len(p), nil
 }
 
-func (h0 *sha256Hash) sum(dst []byte) []byte {
+func (h0 *sha256Hash) sum() []byte {
 	h := *h0 // make copy so future Write+Sum is valid
-	if C._goboringcrypto_SHA256_Final((*C.uint8_t)(noescape(unsafe.Pointer(&h.out[0]))), h.noescapeCtx()) == 0 {
+	if C._goboringcrypto_SHA256_Final((*C.uint8_t)(unsafe.Pointer(&h.out[0])), &h.ctx) == 0 {
 		panic("boringcrypto: SHA256_Final failed")
 	}
-	return append(dst, h.out[:]...)
+	return h.out[:]
 }
 
 const (
@@ -383,30 +359,24 @@ type sha384Hash struct {
 	out [384 / 8]byte
 }
 
-func (h *sha384Hash) noescapeCtx() *C.GO_SHA512_CTX {
-	return (*C.GO_SHA512_CTX)(noescape(unsafe.Pointer(&h.ctx)))
-}
-
-func (h *sha384Hash) Reset() {
-	C._goboringcrypto_SHA384_Init(h.noescapeCtx())
-}
-func (h *sha384Hash) Size() int             { return 384 / 8 }
-func (h *sha384Hash) BlockSize() int        { return 128 }
-func (h *sha384Hash) Sum(dst []byte) []byte { return h.sum(dst) }
+func (h *sha384Hash) Reset()               { C._goboringcrypto_SHA384_Init(&h.ctx) }
+func (h *sha384Hash) Size() int            { return 384 / 8 }
+func (h *sha384Hash) BlockSize() int       { return 128 }
+func (h *sha384Hash) Sum(in []byte) []byte { return append(in, h.sum()...) }
 
 func (h *sha384Hash) Write(p []byte) (int, error) {
-	if len(p) > 0 && C._goboringcrypto_SHA384_Update(h.noescapeCtx(), unsafe.Pointer(&*addr(p)), C.size_t(len(p))) == 0 {
+	if len(p) > 0 && C._goboringcrypto_SHA384_Update(&h.ctx, unsafe.Pointer(&p[0]), C.size_t(len(p))) == 0 {
 		panic("boringcrypto: SHA384_Update failed")
 	}
 	return len(p), nil
 }
 
-func (h0 *sha384Hash) sum(dst []byte) []byte {
+func (h0 *sha384Hash) sum() []byte {
 	h := *h0 // make copy so future Write+Sum is valid
-	if C._goboringcrypto_SHA384_Final((*C.uint8_t)(noescape(unsafe.Pointer(&h.out[0]))), h.noescapeCtx()) == 0 {
+	if C._goboringcrypto_SHA384_Final((*C.uint8_t)(unsafe.Pointer(&h.out[0])), &h.ctx) == 0 {
 		panic("boringcrypto: SHA384_Final failed")
 	}
-	return append(dst, h.out[:]...)
+	return h.out[:]
 }
 
 // NewSHA512 returns a new SHA512 hash.
@@ -421,30 +391,24 @@ type sha512Hash struct {
 	out [512 / 8]byte
 }
 
-func (h *sha512Hash) noescapeCtx() *C.GO_SHA512_CTX {
-	return (*C.GO_SHA512_CTX)(noescape(unsafe.Pointer(&h.ctx)))
-}
-
-func (h *sha512Hash) Reset() {
-	C._goboringcrypto_SHA512_Init(h.noescapeCtx())
-}
-func (h *sha512Hash) Size() int             { return 512 / 8 }
-func (h *sha512Hash) BlockSize() int        { return 128 }
-func (h *sha512Hash) Sum(dst []byte) []byte { return h.sum(dst) }
+func (h *sha512Hash) Reset()               { C._goboringcrypto_SHA512_Init(&h.ctx) }
+func (h *sha512Hash) Size() int            { return 512 / 8 }
+func (h *sha512Hash) BlockSize() int       { return 128 }
+func (h *sha512Hash) Sum(in []byte) []byte { return append(in, h.sum()...) }
 
 func (h *sha512Hash) Write(p []byte) (int, error) {
-	if len(p) > 0 && C._goboringcrypto_SHA512_Update(h.noescapeCtx(), unsafe.Pointer(&*addr(p)), C.size_t(len(p))) == 0 {
+	if len(p) > 0 && C._goboringcrypto_SHA512_Update(&h.ctx, unsafe.Pointer(&p[0]), C.size_t(len(p))) == 0 {
 		panic("boringcrypto: SHA512_Update failed")
 	}
 	return len(p), nil
 }
 
-func (h0 *sha512Hash) sum(dst []byte) []byte {
+func (h0 *sha512Hash) sum() []byte {
 	h := *h0 // make copy so future Write+Sum is valid
-	if C._goboringcrypto_SHA512_Final((*C.uint8_t)(noescape(unsafe.Pointer(&h.out[0]))), h.noescapeCtx()) == 0 {
+	if C._goboringcrypto_SHA512_Final((*C.uint8_t)(unsafe.Pointer(&h.out[0])), &h.ctx) == 0 {
 		panic("boringcrypto: SHA512_Final failed")
 	}
-	return append(dst, h.out[:]...)
+	return h.out[:]
 }
 
 type sha512Ctx struct {
diff --git a/src/vendor/modules.txt b/src/vendor/modules.txt
index dfb87ab..70df081 100644
--- a/src/vendor/modules.txt
+++ b/src/vendor/modules.txt
@@ -1,3 +1,6 @@
+# github.com/golang-fips/openssl-fips v0.0.0-20220914203141-60f04d7f65e2
+## explicit; go 1.18
+github.com/golang-fips/openssl-fips/openssl
 # golang.org/x/crypto v0.0.0-20220516162934-403b01795ae8
 ## explicit; go 1.17
 golang.org/x/crypto/chacha20