diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..4f71bcf
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+SOURCES/go-go-1.17.7-1-openssl-fips.tar.gz
diff --git a/.golang.metadata b/.golang.metadata
new file mode 100644
index 0000000..fde6008
--- /dev/null
+++ b/.golang.metadata
@@ -0,0 +1 @@
+139fe29f985b3feda50c407d194f1a102352388a SOURCES/go-go-1.17.7-1-openssl-fips.tar.gz
diff --git a/SOURCES/fedora.go b/SOURCES/fedora.go
new file mode 100644
index 0000000..81b28ba
--- /dev/null
+++ b/SOURCES/fedora.go
@@ -0,0 +1,7 @@
+// +build rpm_crashtraceback
+
+package runtime
+
+func init() {
+	setTraceback("crash")
+}
diff --git a/SOURCES/fix_TestScript_list_std.patch b/SOURCES/fix_TestScript_list_std.patch
new file mode 100644
index 0000000..1387cb7
--- /dev/null
+++ b/SOURCES/fix_TestScript_list_std.patch
@@ -0,0 +1,13 @@
+diff --git a/src/cmd/go/testdata/script/list_std.txt b/src/cmd/go/testdata/script/list_std.txt
+index 6ab1bd1674..4a00e436fd 100644
+--- a/src/cmd/go/testdata/script/list_std.txt
++++ b/src/cmd/go/testdata/script/list_std.txt
+@@ -6,7 +6,7 @@ env GO111MODULE=off
+ # Listing GOROOT should only find standard packages.
+ cd $GOROOT/src
+ go list -f '{{if not .Standard}}{{.ImportPath}}{{end}}' ./...
+-! stdout .
++stdout _$GOROOT
+ 
+ # Standard packages should include cmd, but not cmd/vendor.
+ go list ./...
diff --git a/SOURCES/go1.5-zoneinfo_testing_only.patch b/SOURCES/go1.5-zoneinfo_testing_only.patch
new file mode 100644
index 0000000..581cb94
--- /dev/null
+++ b/SOURCES/go1.5-zoneinfo_testing_only.patch
@@ -0,0 +1,70 @@
+diff -up go-dd7cbf3a846c2cb125ac65173abaf6a8b9f903ff/src/time/internal_test.go.time go-dd7cbf3a846c2cb125ac65173abaf6a8b9f903ff/src/time/internal_test.go
+--- go-dd7cbf3a846c2cb125ac65173abaf6a8b9f903ff/src/time/internal_test.go.time	2017-12-05 01:10:10.000000000 +0100
++++ go-dd7cbf3a846c2cb125ac65173abaf6a8b9f903ff/src/time/internal_test.go	2017-12-05 14:55:10.574637475 +0100
+@@ -4,13 +4,15 @@
+ 
+ package time
+ 
++import "runtime"
++
+ func init() {
+ 	// force US/Pacific for time zone tests
+ 	ForceUSPacificForTesting()
+ }
+ 
+ func initTestingZone() {
+-	z, err := loadLocation("America/Los_Angeles", zoneSources[len(zoneSources)-1:])
++	z, err := loadLocation("America/Los_Angeles", zoneSources)
+ 	if err != nil {
+ 		panic("cannot load America/Los_Angeles for testing: " + err.Error())
+ 	}
+@@ -21,8 +23,9 @@ func initTestingZone() {
+ var OrigZoneSources = zoneSources
+ 
+ func forceZipFileForTesting(zipOnly bool) {
+-	zoneSources = make([]string, len(OrigZoneSources))
++	zoneSources = make([]string, len(OrigZoneSources)+1)
+ 	copy(zoneSources, OrigZoneSources)
++	zoneSources = append(zoneSources, runtime.GOROOT()+"/lib/time/zoneinfo.zip")
+ 	if zipOnly {
+ 		zoneSources = zoneSources[len(zoneSources)-1:]
+ 	}
+diff -up go-dd7cbf3a846c2cb125ac65173abaf6a8b9f903ff/src/time/zoneinfo_test.go.time go-dd7cbf3a846c2cb125ac65173abaf6a8b9f903ff/src/time/zoneinfo_test.go
+--- go-dd7cbf3a846c2cb125ac65173abaf6a8b9f903ff/src/time/zoneinfo_test.go.time	2017-12-05 01:10:10.000000000 +0100
++++ go-dd7cbf3a846c2cb125ac65173abaf6a8b9f903ff/src/time/zoneinfo_test.go	2017-12-05 14:58:09.823109248 +0100
+@@ -8,6 +8,7 @@ import (
+ 	"fmt"
+ 	"os"
+ 	"reflect"
++	"runtime"
+ 	"testing"
+ 	"time"
+ )
+@@ -128,7 +129,7 @@ func TestLoadLocationFromTZData(t *testi
+ 		t.Fatal(err)
+ 	}
+ 
+-	tzinfo, err := time.LoadTzinfo(locationName, time.OrigZoneSources[len(time.OrigZoneSources)-1])
++	tzinfo, err := time.LoadTzinfo(locationName, runtime.GOROOT()+"/lib/time/zoneinfo.zip")
+ 	if err != nil {
+ 		t.Fatal(err)
+ 	}
+diff -up go-dd7cbf3a846c2cb125ac65173abaf6a8b9f903ff/src/time/zoneinfo_unix.go.time go-dd7cbf3a846c2cb125ac65173abaf6a8b9f903ff/src/time/zoneinfo_unix.go
+--- go-dd7cbf3a846c2cb125ac65173abaf6a8b9f903ff/src/time/zoneinfo_unix.go.time	2017-12-05 01:10:10.000000000 +0100
++++ go-dd7cbf3a846c2cb125ac65173abaf6a8b9f903ff/src/time/zoneinfo_unix.go	2017-12-05 14:55:10.574637475 +0100
+@@ -12,7 +12,6 @@
+ package time
+ 
+ import (
+-	"runtime"
+ 	"syscall"
+ )
+ 
+@@ -22,7 +21,6 @@ var zoneSources = []string{
+ 	"/usr/share/zoneinfo/",
+ 	"/usr/share/lib/zoneinfo/",
+ 	"/usr/lib/locale/TZ/",
+-	runtime.GOROOT() + "/lib/time/zoneinfo.zip",
+ }
+ 
+ func initLocal() {
diff --git a/SOURCES/golang-gdbinit b/SOURCES/golang-gdbinit
new file mode 100644
index 0000000..4ef690b
--- /dev/null
+++ b/SOURCES/golang-gdbinit
@@ -0,0 +1 @@
+add-auto-load-safe-path /usr/lib/golang/src/pkg/runtime/runtime-gdb.py
diff --git a/SOURCES/golang-prelink.conf b/SOURCES/golang-prelink.conf
new file mode 100644
index 0000000..471e8e6
--- /dev/null
+++ b/SOURCES/golang-prelink.conf
@@ -0,0 +1,3 @@
+# there are ELF files in src which are testdata and shouldn't be modified
+-b /usr/lib/golang/src
+-b /usr/lib64/golang/src
diff --git a/SOURCES/remove_ed25519vectors_test.patch b/SOURCES/remove_ed25519vectors_test.patch
new file mode 100644
index 0000000..45e3182
--- /dev/null
+++ b/SOURCES/remove_ed25519vectors_test.patch
@@ -0,0 +1,128 @@
+From d7cad65ab9179804e9f089ce97bc124e9ef79494 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Alejandro=20S=C3=A1ez?= <asm@redhat.com>
+Date: Wed, 15 Dec 2021 16:02:15 +0100
+Subject: [PATCH] Remove ed25519vectors_test.go
+
+---
+ src/crypto/ed25519/ed25519vectors_test.go | 109 ----------------------
+ 1 file changed, 109 deletions(-)
+ delete mode 100644 src/crypto/ed25519/ed25519vectors_test.go
+
+diff --git a/src/crypto/ed25519/ed25519vectors_test.go b/src/crypto/ed25519/ed25519vectors_test.go
+deleted file mode 100644
+index 74fcdcdf4e..0000000000
+--- a/src/crypto/ed25519/ed25519vectors_test.go
++++ /dev/null
+@@ -1,109 +0,0 @@
+-// Copyright 2021 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 ed25519_test
+-
+-import (
+-	"crypto/ed25519"
+-	"encoding/hex"
+-	"encoding/json"
+-	"internal/testenv"
+-	"os"
+-	"os/exec"
+-	"path/filepath"
+-	"testing"
+-)
+-
+-// TestEd25519Vectors runs a very large set of test vectors that exercise all
+-// combinations of low-order points, low-order components, and non-canonical
+-// encodings. These vectors lock in unspecified and spec-divergent behaviors in
+-// edge cases that are not security relevant in most contexts, but that can
+-// cause issues in consensus applications if changed.
+-//
+-// Our behavior matches the "classic" unwritten verification rules of the
+-// "ref10" reference implementation.
+-//
+-// Note that although we test for these edge cases, they are not covered by the
+-// Go 1 Compatibility Promise. Applications that need stable verification rules
+-// should use github.com/hdevalence/ed25519consensus.
+-//
+-// See https://hdevalence.ca/blog/2020-10-04-its-25519am for more details.
+-func TestEd25519Vectors(t *testing.T) {
+-	jsonVectors := downloadEd25519Vectors(t)
+-	var vectors []struct {
+-		A, R, S, M string
+-		Flags      []string
+-	}
+-	if err := json.Unmarshal(jsonVectors, &vectors); err != nil {
+-		t.Fatal(err)
+-	}
+-	for i, v := range vectors {
+-		expectedToVerify := true
+-		for _, f := range v.Flags {
+-			switch f {
+-			// We use the simplified verification formula that doesn't multiply
+-			// by the cofactor, so any low order residue will cause the
+-			// signature not to verify.
+-			//
+-			// This is allowed, but not required, by RFC 8032.
+-			case "LowOrderResidue":
+-				expectedToVerify = false
+-			// Our point decoding allows non-canonical encodings (in violation
+-			// of RFC 8032) but R is not decoded: instead, R is recomputed and
+-			// compared bytewise against the canonical encoding.
+-			case "NonCanonicalR":
+-				expectedToVerify = false
+-			}
+-		}
+-
+-		publicKey := decodeHex(t, v.A)
+-		signature := append(decodeHex(t, v.R), decodeHex(t, v.S)...)
+-		message := []byte(v.M)
+-
+-		didVerify := ed25519.Verify(publicKey, message, signature)
+-		if didVerify && !expectedToVerify {
+-			t.Errorf("#%d: vector with flags %s unexpectedly verified", i, v.Flags)
+-		}
+-		if !didVerify && expectedToVerify {
+-			t.Errorf("#%d: vector with flags %s unexpectedly rejected", i, v.Flags)
+-		}
+-	}
+-}
+-
+-func downloadEd25519Vectors(t *testing.T) []byte {
+-	testenv.MustHaveExternalNetwork(t)
+-
+-	// Download the JSON test file from the GOPROXY with `go mod download`,
+-	// pinning the version so test and module caching works as expected.
+-	goTool := testenv.GoToolPath(t)
+-	path := "filippo.io/mostly-harmless/ed25519vectors@v0.0.0-20210322192420-30a2d7243a94"
+-	cmd := exec.Command(goTool, "mod", "download", "-json", path)
+-	// TODO: enable the sumdb once the TryBots proxy supports it.
+-	cmd.Env = append(os.Environ(), "GONOSUMDB=*")
+-	output, err := cmd.Output()
+-	if err != nil {
+-		t.Fatalf("failed to run `go mod download -json %s`, output: %s", path, output)
+-	}
+-	var dm struct {
+-		Dir string // absolute path to cached source root directory
+-	}
+-	if err := json.Unmarshal(output, &dm); err != nil {
+-		t.Fatal(err)
+-	}
+-
+-	jsonVectors, err := os.ReadFile(filepath.Join(dm.Dir, "ed25519vectors.json"))
+-	if err != nil {
+-		t.Fatalf("failed to read ed25519vectors.json: %v", err)
+-	}
+-	return jsonVectors
+-}
+-
+-func decodeHex(t *testing.T, s string) []byte {
+-	t.Helper()
+-	b, err := hex.DecodeString(s)
+-	if err != nil {
+-		t.Errorf("invalid hex: %v", err)
+-	}
+-	return b
+-}
+-- 
+2.33.1
+
diff --git a/SOURCES/remove_waitgroup_misuse_tests.patch b/SOURCES/remove_waitgroup_misuse_tests.patch
new file mode 100644
index 0000000..b643563
--- /dev/null
+++ b/SOURCES/remove_waitgroup_misuse_tests.patch
@@ -0,0 +1,151 @@
+diff --git a/src/sync/waitgroup_test.go b/src/sync/waitgroup_test.go
+index c569e0faa2eb..4ded218d2d8d 100644
+--- a/src/sync/waitgroup_test.go
++++ b/src/sync/waitgroup_test.go
+@@ -5,8 +5,6 @@
+ package sync_test
+ 
+ import (
+-	"internal/race"
+-	"runtime"
+ 	. "sync"
+ 	"sync/atomic"
+ 	"testing"
+@@ -48,12 +46,6 @@ func TestWaitGroup(t *testing.T) {
+ 	}
+ }
+ 
+-func knownRacy(t *testing.T) {
+-	if race.Enabled {
+-		t.Skip("skipping known-racy test under the race detector")
+-	}
+-}
+-
+ func TestWaitGroupMisuse(t *testing.T) {
+ 	defer func() {
+ 		err := recover()
+@@ -68,124 +60,6 @@ func TestWaitGroupMisuse(t *testing.T) {
+ 	t.Fatal("Should panic")
+ }
+ 
+-// pollUntilEqual blocks until v, loaded atomically, is
+-// equal to the target.
+-func pollUntilEqual(v *uint32, target uint32) {
+-	for {
+-		for i := 0; i < 1e3; i++ {
+-			if atomic.LoadUint32(v) == target {
+-				return
+-			}
+-		}
+-		// yield to avoid deadlock with the garbage collector
+-		// see issue #20072
+-		runtime.Gosched()
+-	}
+-}
+-
+-func TestWaitGroupMisuse2(t *testing.T) {
+-	knownRacy(t)
+-	if runtime.NumCPU() <= 4 {
+-		t.Skip("NumCPU<=4, skipping: this test requires parallelism")
+-	}
+-	defer func() {
+-		err := recover()
+-		if err != "sync: negative WaitGroup counter" &&
+-			err != "sync: WaitGroup misuse: Add called concurrently with Wait" &&
+-			err != "sync: WaitGroup is reused before previous Wait has returned" {
+-			t.Fatalf("Unexpected panic: %#v", err)
+-		}
+-	}()
+-	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
+-	done := make(chan interface{}, 2)
+-	// The detection is opportunistic, so we want it to panic
+-	// at least in one run out of a million.
+-	for i := 0; i < 1e6; i++ {
+-		var wg WaitGroup
+-		var here uint32
+-		wg.Add(1)
+-		go func() {
+-			defer func() {
+-				done <- recover()
+-			}()
+-			atomic.AddUint32(&here, 1)
+-			pollUntilEqual(&here, 3)
+-			wg.Wait()
+-		}()
+-		go func() {
+-			defer func() {
+-				done <- recover()
+-			}()
+-			atomic.AddUint32(&here, 1)
+-			pollUntilEqual(&here, 3)
+-			wg.Add(1) // This is the bad guy.
+-			wg.Done()
+-		}()
+-		atomic.AddUint32(&here, 1)
+-		pollUntilEqual(&here, 3)
+-		wg.Done()
+-		for j := 0; j < 2; j++ {
+-			if err := <-done; err != nil {
+-				panic(err)
+-			}
+-		}
+-	}
+-	t.Fatal("Should panic")
+-}
+-
+-func TestWaitGroupMisuse3(t *testing.T) {
+-	knownRacy(t)
+-	if runtime.NumCPU() <= 1 {
+-		t.Skip("NumCPU==1, skipping: this test requires parallelism")
+-	}
+-	defer func() {
+-		err := recover()
+-		if err != "sync: negative WaitGroup counter" &&
+-			err != "sync: WaitGroup misuse: Add called concurrently with Wait" &&
+-			err != "sync: WaitGroup is reused before previous Wait has returned" {
+-			t.Fatalf("Unexpected panic: %#v", err)
+-		}
+-	}()
+-	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
+-	done := make(chan interface{}, 3)
+-	// The detection is opportunistically, so we want it to panic
+-	// at least in one run out of a million.
+-	for i := 0; i < 1e6; i++ {
+-		var wg WaitGroup
+-		wg.Add(1)
+-		go func() {
+-			defer func() {
+-				done <- recover()
+-			}()
+-			wg.Done()
+-		}()
+-		go func() {
+-			defer func() {
+-				done <- recover()
+-			}()
+-			wg.Wait()
+-			// Start reusing the wg before waiting for the Wait below to return.
+-			wg.Add(1)
+-			go func() {
+-				wg.Done()
+-			}()
+-			wg.Wait()
+-		}()
+-		go func() {
+-			defer func() {
+-				done <- recover()
+-			}()
+-			wg.Wait()
+-		}()
+-		for j := 0; j < 3; j++ {
+-			if err := <-done; err != nil {
+-				panic(err)
+-			}
+-		}
+-	}
+-	t.Fatal("Should panic")
+-}
+-
+ func TestWaitGroupRace(t *testing.T) {
+ 	// Run this test for about 1ms.
+ 	for i := 0; i < 1000; i++ {
diff --git a/SOURCES/rhbz1952381.patch b/SOURCES/rhbz1952381.patch
new file mode 100644
index 0000000..6e1b7f0
--- /dev/null
+++ b/SOURCES/rhbz1952381.patch
@@ -0,0 +1,1142 @@
+diff --git a/src/crypto/ecdsa/ecdsa_test.go b/src/crypto/ecdsa/ecdsa_test.go
+index d60fdb8..b90782a 100644
+--- a/src/crypto/ecdsa/ecdsa_test.go
++++ b/src/crypto/ecdsa/ecdsa_test.go
+@@ -323,6 +323,10 @@ func TestVectors(t *testing.T) {
+ 			h.Write(msg)
+ 			hashed := h.Sum(hashed[:0])
+ 			if boring.Enabled() {
++				// SHA-1 signatures not supported in OpenSSL 3.0
++			        if ch == crypto.SHA1 {
++					expected = false
++				}
+ 				if HashVerify(pub, msg, r, s, ch) != expected {
+ 					t.Fatalf("incorrect result on line %d", lineNo)
+ 				}
+diff --git a/src/crypto/internal/boring/aes.go b/src/crypto/internal/boring/aes.go
+index 457decf..961795a 100644
+--- a/src/crypto/internal/boring/aes.go
++++ b/src/crypto/internal/boring/aes.go
+@@ -130,7 +130,11 @@ func (c *aesCipher) Decrypt(dst, src []byte) {
+ 			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)
+@@ -157,6 +161,11 @@ func (x *aesCBC) CryptBlocks(dst, src []byte) {
+ 	}
+ 	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,
+diff --git a/src/crypto/internal/boring/boring.go b/src/crypto/internal/boring/boring.go
+index e7ae80c..45c856b 100644
+--- a/src/crypto/internal/boring/boring.go
++++ b/src/crypto/internal/boring/boring.go
+@@ -20,7 +20,8 @@ import (
+ 	"math/big"
+ 	"os"
+ 	"runtime"
+-	"strings"
++	"unsafe"
++	"fmt"
+ )
+ 
+ const (
+@@ -68,8 +69,22 @@ func enableBoringFIPSMode() {
+ }
+ 
+ func fipsModeEnabled() bool {
+-	return os.Getenv("GOLANG_FIPS") == "1" ||
+-		C._goboringcrypto_FIPS_mode() == fipsOn
++	// 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 := C._goboringcrypto_internal_OPENSSL_VERSION_NUMBER()
++	if openSSLVersion >= C.ulong(0x30000000) {
++		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
+@@ -126,23 +141,31 @@ func PanicIfStrictFIPS(msg string) {
+ }
+ 
+ func NewOpenSSLError(msg string) error {
+-	var b strings.Builder
+ 	var e C.ulong
+ 
+-	b.WriteString(msg)
+-	b.WriteString("\nopenssl error(s):\n")
++	message := fmt.Sprintf("\n%v\nopenssl error(s):", msg)
+ 
+ 	for {
+-		e = C._goboringcrypto_internal_ERR_get_error()
++		var file *C.char
++		var line C.int
++		var fnc  *C.char
++		var data  *C.char
++		var flags C.int
++		e = C._goboringcrypto_internal_ERR_get_error_all(&file, &line, &fnc, &data, &flags)
+ 		if e == 0 {
+ 			break
+ 		}
+-		var buf [256]byte
+-		C._goboringcrypto_internal_ERR_error_string_n(e, base(buf[:]), 256)
+-		b.Write(buf[:])
+-		b.WriteByte('\n')
++		var buf [256]C.char
++                C._goboringcrypto_internal_ERR_error_string_n(e, (*C.uchar)(unsafe.Pointer (&buf[0])), 256)
++		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(b.String())
++	return errors.New(message)
+ }
+ 
+ type fail string
+diff --git a/src/crypto/internal/boring/goopenssl.h b/src/crypto/internal/boring/goopenssl.h
+index 355638b..2737441 100644
+--- a/src/crypto/internal/boring/goopenssl.h
++++ b/src/crypto/internal/boring/goopenssl.h
+@@ -14,6 +14,15 @@
+ 
+ #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;   \
+@@ -22,7 +31,7 @@
+ 	{                                                \
+ 		if (unlikely(!_g_##func))                    \
+ 		{                                            \
+-			_g_##func = dlsym(handle, #func);        \
++			_g_##func = OPENSSL_DLSYM_CALL(handle, #func); \
+ 		}                                            \
+ 		return _g_##func argscall;                   \
+ 	}
+@@ -34,7 +43,7 @@
+ 	{                                                \
+ 		if (unlikely(!_g_internal_##func))                    \
+ 		{                                            \
+-			_g_internal_##func = dlsym(handle, #func);        \
++			_g_internal_##func = OPENSSL_DLSYM_CALL(handle, #func); \
+ 		}                                            \
+ 		return _g_internal_##func argscall;                   \
+ 	}
+@@ -45,7 +54,6 @@
+ 		return func argscall;                     \
+ 	}
+ 
+-#include <dlfcn.h>
+ 
+ static void* handle;
+ static void*
+@@ -57,8 +65,10 @@ _goboringcrypto_DLOPEN_OPENSSL(void)
+ 	}
+ #if OPENSSL_VERSION_NUMBER < 0x10100000L
+ 	handle = dlopen("libcrypto.so.10", RTLD_NOW | RTLD_GLOBAL);
+-#else
++#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;
+ }
+@@ -68,6 +78,10 @@ _goboringcrypto_DLOPEN_OPENSSL(void)
+ 
+ DEFINEFUNCINTERNAL(int, 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();
+@@ -76,6 +90,9 @@ _goboringcrypto_OPENSSL_setup(void) {
+ #include <openssl/err.h>
+ DEFINEFUNCINTERNAL(void, ERR_print_errors_fp, (FILE* fp), (fp))
+ DEFINEFUNCINTERNAL(unsigned long, ERR_get_error, (void), ())
++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))
+ DEFINEFUNCINTERNAL(void, ERR_error_string_n, (unsigned long e, unsigned char *buf, size_t len), (e, buf, len))
+ 
+ #include <openssl/crypto.h>
+@@ -112,8 +129,15 @@ _goboringcrypto_CRYPTO_set_locking_callback(void (*locking_function)(int mode, i
+ 
+ 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>
+ 
+@@ -711,12 +735,9 @@ _goboringcrypto_EVP_PKEY_CTX_set_rsa_padding(GO_EVP_PKEY_CTX* ctx, int pad) {
+ #endif
+ }
+ 
+-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);
+-}
++DEFINEFUNC(int, EVP_PKEY_CTX_set0_rsa_oaep_label,
++		(GO_EVP_PKEY_CTX *ctx, uint8_t *l, int llen),
++		(ctx, l, llen))
+ 
+ static inline int
+ _goboringcrypto_EVP_PKEY_CTX_set_rsa_oaep_md(GO_EVP_PKEY_CTX *ctx, const GO_EVP_MD *md)
+@@ -736,6 +757,7 @@ 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,
+diff --git a/src/crypto/internal/boring/openssl_port_rsa.c b/src/crypto/internal/boring/openssl_port_rsa.c
+index 92fbb36..781975c 100644
+--- a/src/crypto/internal/boring/openssl_port_rsa.c
++++ b/src/crypto/internal/boring/openssl_port_rsa.c
+@@ -91,31 +91,40 @@ int _goboringcrypto_RSA_sign_pss_mgf1(GO_RSA *rsa, unsigned int *out_len, uint8_
+ 
+ 	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_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING) <= 0)
++	if (_goboringcrypto_EVP_PKEY_sign_init(ctx) <= 0) {
+ 		goto err;
+-	if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, salt_len) <= 0)
++	}
++	// This is moved earlier because openssl 3.0 alpha defaults
++	// to sha1 in EVP_PKEY_CTRL_RSA_PADDING if unset and produces an error
++	if (_goboringcrypto_EVP_PKEY_CTX_set_signature_md(ctx, md) <= 0) {
+ 		goto err;
+-	if (_goboringcrypto_EVP_PKEY_CTX_set_signature_md(ctx, md) <= 0)
++	}
++	if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING) <= 0) {
+ 		goto err;
+-	if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, mgf1_md) <= 0)
++	}
++	if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, salt_len) <= 0) {
+ 		goto err;
+-
++	}
++	// doesnt take null anymore
++	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)
++	if (_goboringcrypto_EVP_PKEY_sign(ctx, NULL, &siglen, in, in_len) <= 0) {
+ 		goto err;
+-
+-	if (max_out < siglen)
++	}
++	if (max_out < siglen) {
+ 		goto err;
+-
+-	if (_goboringcrypto_EVP_PKEY_sign(ctx, out, &siglen, in, in_len) <= 0)
++	}
++	if (_goboringcrypto_EVP_PKEY_sign(ctx, out, &siglen, in, in_len) <= 0) {
+ 		goto err;
++	}
+ 
+ 	*out_len = siglen;
+ 	ret = 1;
+@@ -142,23 +151,31 @@ int _goboringcrypto_RSA_verify_pss_mgf1(RSA *rsa, const uint8_t *msg, unsigned i
+ 
+ 	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)
++	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)
++	}
++	if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING) <= 0) {
+ 		goto err;
+-	if (_goboringcrypto_EVP_PKEY_CTX_set_signature_md(ctx, md) <= 0)
++	}
++	if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, salt_len) <= 0) {
+ 		goto err;
+-	if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, mgf1_md) <= 0)
++	}
++	if (_goboringcrypto_EVP_PKEY_CTX_set_signature_md(ctx, md) <= 0) {
+ 		goto err;
+-	if (_goboringcrypto_EVP_PKEY_verify(ctx, sig, sig_len, msg, msg_len) <= 0)
++	}
++	// doesnt take null anymore
++	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;
+ 
+diff --git a/src/crypto/internal/boring/rand.go b/src/crypto/internal/boring/rand.go
+index ff5c439..6047d65 100644
+--- a/src/crypto/internal/boring/rand.go
++++ b/src/crypto/internal/boring/rand.go
+@@ -20,7 +20,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/crypto/internal/boring/rsa.go
+index b3a907f..b74e7a9 100644
+--- a/src/crypto/internal/boring/rsa.go
++++ b/src/crypto/internal/boring/rsa.go
+@@ -120,7 +120,9 @@ func (k *PrivateKeyRSA) withKey(f func(*C.GO_RSA) C.int) C.int {
+ 
+ func setupRSA(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) (pkey *C.GO_EVP_PKEY, ctx *C.GO_EVP_PKEY_CTX, err error) {
++	init func(*C.GO_EVP_PKEY_CTX) C.int) (_pkey *C.GO_EVP_PKEY, _ctx *C.GO_EVP_PKEY_CTX, err error) {
++	var pkey *C.GO_EVP_PKEY
++	var ctx *C.GO_EVP_PKEY_CTX
+ 	defer func() {
+ 		if err != nil {
+ 			if pkey != nil {
+@@ -141,7 +143,7 @@ func setupRSA(withKey func(func(*C.GO_RSA) C.int) C.int,
+ 	if withKey(func(key *C.GO_RSA) C.int {
+ 		return C._goboringcrypto_EVP_PKEY_set1_RSA(pkey, key)
+ 	}) == 0 {
+-		return nil, nil, fail("EVP_PKEY_set1_RSA")
++		return nil, nil, NewOpenSSLError("EVP_PKEY_set1_RSA")
+ 	}
+ 	ctx = C._goboringcrypto_EVP_PKEY_CTX_new(pkey, nil)
+ 	if ctx == nil {
+@@ -162,23 +164,12 @@ func setupRSA(withKey func(func(*C.GO_RSA) C.int) C.int,
+ 			return nil, nil, NewOpenSSLError("EVP_PKEY_set_rsa_oaep_md failed")
+ 		}
+ 		// ctx takes ownership of label, so malloc a copy for BoringCrypto to free.
+-		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 {
+-			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)
++		clabel := (*C.uint8_t)(C.malloc(C.size_t(len(label))))
++		if clabel == nil {
++			return nil, nil, NewOpenSSLError("OPENSSL_malloc")
+ 		}
+-		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))
+-			}
++		copy((*[1 << 30]byte)(unsafe.Pointer(clabel))[:len(label)], label)
++		if C._goboringcrypto_EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, clabel, C.int(len(label))) == 0 {
+ 			return nil, nil, NewOpenSSLError("EVP_PKEY_CTX_set0_rsa_oaep_label failed")
+ 		}
+ 	}
+@@ -276,12 +267,13 @@ func SignRSAPSS(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte, saltLen int)
+ 	}
+ 	var out []byte
+ 	var outLen C.uint
+-	if priv.withKey(func(key *C.GO_RSA) C.int {
++	result := 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.uint(len(out)),
+ 			base(hashed), C.uint(len(hashed)), md, nil, C.int(saltLen))
+-	}) == 0 {
+-		return nil, fail("RSA_sign_pss_mgf1")
++	})
++	if result != 1 {
++		return nil, NewOpenSSLError("RSA_sign_pss_mgf1: returned " + strconv.Itoa(int(result)))
+ 	}
+ 
+ 	return out[:outLen], nil
+@@ -295,11 +287,12 @@ func VerifyRSAPSS(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte, saltLen
+ 	if saltLen == 0 {
+ 		saltLen = -2 // auto-recover
+ 	}
+-	if pub.withKey(func(key *C.GO_RSA) C.int {
++	result := pub.withKey(func(key *C.GO_RSA) C.int {
+ 		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")
++		})
++	if result != 1 {
++		return NewOpenSSLError("RSA_verify_pss_mgf1: returned " + strconv.Itoa(int(result)))
+ 	}
+ 	return nil
+ }
+diff --git a/src/crypto/rsa/pkcs1v15.go b/src/crypto/rsa/pkcs1v15.go
+index 2d425f9..ceb32d0 100644
+--- a/src/crypto/rsa/pkcs1v15.go
++++ b/src/crypto/rsa/pkcs1v15.go
+@@ -102,7 +102,7 @@ func DecryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) ([]byt
+ 		}
+ 		out, err := boring.DecryptRSAPKCS1(bkey, ciphertext)
+ 		if err != nil {
+-			return nil, ErrDecryption
++			return nil, err
+ 		}
+ 		return out, nil
+ 	}
+diff --git a/src/crypto/rsa/pkcs1v15_test.go b/src/crypto/rsa/pkcs1v15_test.go
+index 3dd1ec9..60c769c 100644
+--- a/src/crypto/rsa/pkcs1v15_test.go
++++ b/src/crypto/rsa/pkcs1v15_test.go
+@@ -9,7 +9,6 @@ import (
+ 	"crypto"
+ 	"crypto/internal/boring"
+ 	"crypto/rand"
+-	"crypto/sha1"
+ 	"crypto/sha256"
+ 	"encoding/base64"
+ 	"encoding/hex"
+@@ -32,22 +31,22 @@ type DecryptPKCS1v15Test struct {
+ 	in, out string
+ }
+ 
+-// These test vectors were generated with `openssl rsautl -pkcs -encrypt`
++// Test vectors for testRSA2048PrivateKey
+ var decryptPKCS1v15Tests = []DecryptPKCS1v15Test{
+ 	{
+-		"gIcUIoVkD6ATMBk/u/nlCZCCWRKdkfjCgFdo35VpRXLduiKXhNz1XupLLzTXAybEq15juc+EgY5o0DHv/nt3yg==",
++		"Ppg5lRhQZ8zLMgU8jFWURwm+Oj3t1+9x8qIDZwWMlP6O1QVO4xXxHdheVnLRa0Iq+L5HTgjk/PNNkSLIMD11ERxbMD5NtXoj64qaQDkyIBXaN0FNc5Nga/Lbb+vXVYSJ5F4KIOUYaOwzgNSCMensYNz5/7TloMy2Zoqa6vsWzcU+ujfyFaNjJXC26ZM0zv/4v9Aqqb/WIsLjEgdVvplqL1jwbI8Vv/MLEpQRay3S2RHoS9PIcvGKe3Ze0nOE8rAPiRQKfAsX+zlMkw1+LDttb5Dg/vM4lGF6jTg/nmfgCb6gjWE+QpapLKuZIN3WOwG/zslKeROErPn71xAlVeHI1Q==",
+ 		"x",
+ 	},
+ 	{
+-		"Y7TOCSqofGhkRb+jaVRLzK8xw2cSo1IVES19utzv6hwvx+M8kFsoWQm5DzBeJCZTCVDPkTpavUuEbgp8hnUGDw==",
++		"kjtn1z9R67b0t7RydEoXeK9GC9wWt1J47i+14alOLCuWr9aqnJxYJS+jr2Z3/TWf4qqTiEujIP5bzvM8vnU2cnJqOGUqoH5xH1+8gq9aD0RbVY0auvUxPUKI3foLoMlp6M1fTSJGiuD9DASp7BZfiMvsU1kKPrLlHpu4azOKbAfIojyyt64Dl3cIpha8FBakym1SRM2iJKKBVae3Reu58uGX9lHroJAWiIdDT4VDIGXQv9dvsViPn4hvWKls5xYtf3V5GPHyvrptsLYcqBOUXM1Wnu2SpZxKRuyz9tWA3w377XNByDMchLJeC4qxdA6ayo53ckXr0no0fU0JrRHkdg==",
+ 		"testing.",
+ 	},
+ 	{
+-		"arReP9DJtEVyV2Dg3dDp4c/PSk1O6lxkoJ8HcFupoRorBZG+7+1fDAwT1olNddFnQMjmkb8vxwmNMoTAT/BFjQ==",
++		"gljV2jJNON8RwzgVezwG/ddFWPSpGHgnUgEot42vU7Kow5TMvd43f9QAJsPQd0ocT9YIp/3km+2CSWWr+5E3fWW0p2cQBxUfnsJFsNKPvQt6Ct7Bn8HzkhxLJuvIShFzQlBuph4hBuN33dWhAFFDESsZnPvU6EFJlmTHrmqY+H9cdECU4hXQ1R7Z+lHlvT8RxDNBu1fdAarRXcKrw9EeN2ZwSvVx62aXnAcAQQkijmOn9dkObgqeii/wHPI28SR/Aa/hTw1XE5DoZmDBCx6EFJ4hcY7MKAX0iSQiaxinM+IxkqiCftOnvYv737cD/vKG6llhGCCDx0Et5xYu2JWakw==",
+ 		"testing.\n",
+ 	},
+ 	{
+-		"WtaBXIoGC54+vH0NH0CHHE+dRDOsMc/6BrfFu2lEqcKL9+uDuWaf+Xj9mrbQCjjZcpQuX733zyok/jsnqe/Ftw==",
++		"iJiYwVBtLhZBmYngT5u+YR5+raI33OvpShPR9arl4zSss+eK5krMANZUTrRCsw8Tho6kpyDgVohfH5V/8zX4Rtslak1peZdvnmcEkJCFk0FpnlcALRBGTCXUJEwxlSgaTz00awCjkfLzMYNCwTAlEP9QxUX2kSIABKSUw4ARwZ5jQTGCdJNl696Q/cF1JjEqsjpPbjn4UYkV3gNl0xXPiTVgfNJKZir1caEGOKfOsfbTFixvA5oANgRySxwZfoj/6dW9xIVgcq/ssmkTl8TnTKQTY0dRTNWs8+HuQxp2I4MSmAun6LYdr8pom1IazJtp1BEaSDZ+thRIQ/oMsYDJXQ==",
+ 		"01234567890123456789012345678901234567890123456789012",
+ 	},
+ }
+@@ -55,10 +54,10 @@ var decryptPKCS1v15Tests = []DecryptPKCS1v15Test{
+ func TestDecryptPKCS1v15(t *testing.T) {
+ 	decryptionFuncs := []func([]byte) ([]byte, error){
+ 		func(ciphertext []byte) (plaintext []byte, err error) {
+-			return DecryptPKCS1v15(nil, rsaPrivateKey, ciphertext)
++			return DecryptPKCS1v15(nil, testRSA2048PrivateKey, ciphertext)
+ 		},
+ 		func(ciphertext []byte) (plaintext []byte, err error) {
+-			return rsaPrivateKey.Decrypt(nil, ciphertext, nil)
++			return testRSA2048PrivateKey.Decrypt(nil, ciphertext, nil)
+ 		},
+ 	}
+ 
+@@ -78,14 +77,14 @@ func TestDecryptPKCS1v15(t *testing.T) {
+ 
+ func TestEncryptPKCS1v15(t *testing.T) {
+ 	random := rand.Reader
+-	k := (rsaPrivateKey.N.BitLen() + 7) / 8
++	k := (testRSA2048PrivateKey.N.BitLen() + 7) / 8
+ 
+ 	tryEncryptDecrypt := func(in []byte, blind bool) bool {
+ 		if len(in) > k-11 {
+ 			in = in[0 : k-11]
+ 		}
+ 
+-		ciphertext, err := EncryptPKCS1v15(random, &rsaPrivateKey.PublicKey, in)
++		ciphertext, err := EncryptPKCS1v15(random, &testRSA2048PrivateKey.PublicKey, in)
+ 		if err != nil {
+ 			t.Errorf("error encrypting: %s", err)
+ 			return false
+@@ -97,7 +96,7 @@ func TestEncryptPKCS1v15(t *testing.T) {
+ 		} else {
+ 			rand = random
+ 		}
+-		plaintext, err := DecryptPKCS1v15(rand, rsaPrivateKey, ciphertext)
++		plaintext, err := DecryptPKCS1v15(rand, testRSA2048PrivateKey, ciphertext)
+ 		if err != nil {
+ 			t.Errorf("error decrypting: %s", err)
+ 			return false
+@@ -117,22 +116,22 @@ func TestEncryptPKCS1v15(t *testing.T) {
+ 	quick.Check(tryEncryptDecrypt, config)
+ }
+ 
+-// These test vectors were generated with `openssl rsautl -pkcs -encrypt`
++// Test vectors for testRSA2048PrivateKey
+ var decryptPKCS1v15SessionKeyTests = []DecryptPKCS1v15Test{
+ 	{
+-		"e6ukkae6Gykq0fKzYwULpZehX+UPXYzMoB5mHQUDEiclRbOTqas4Y0E6nwns1BBpdvEJcilhl5zsox/6DtGsYg==",
++		"cSBy/rsocfCY2L/WDP7+oyI/uk0qf3BuJvWo1VwV/DG9XLuu7J1Gb2e7hYl3kmdf6rSnoqDuVE3viOsGeq1OsW9w0uw08syTwdOp34z90qxlrrKsGjjz9XIgErqwlWvfQ5KQQb8KA29Ub7q0sqQMMQD75bUxN3P4GhtOG6kNVY33QoCIVR65vHLcqe3SlrxAfYzlOjMNwdPsNP1GGVyAZpccxOiBJSUrssAFvRJ3g62wj2xrrtneRztmOGOy8ZSiEjGNjJ4/lmJXt2GyPXapTTKeHFbyqh5Xu8PNgMxaCgtWgMqnK6CPbJOGgski9axyaxPzjKEjUcs99dJ1mTT+qw==",
+ 		"1234",
+ 	},
+ 	{
+-		"Dtis4uk/q/LQGGqGk97P59K03hkCIVFMEFZRgVWOAAhxgYpCRG0MX2adptt92l67IqMki6iVQyyt0TtX3IdtEw==",
++		"lcsS8tzZSJSiaaOSQSO4pT3Je5vvrNfAVUy3Axojr4uRreMuLRTIOOmEYRM/JcWakpJelPd+EHG/aXxId8aCoBg1MkH5q8AHW3zUARhlOd91rpASVs03v5wuk0jtiQiqr0HLNyxifSEzj04VPklc6n00yuHbI+DNTATTVkxj3a5hgOECqKi2matXGcJ5FtMEPAi2V+36y2dQ+DA/tgQrhlZ4ycA2FJnjvOHRJbC6QwNzPkzbjTlCqNzq92nwWKDypVJ29CrIQ2HYXG63DOuT96gIa08hyeZEeIrAUjtb9DK1TSEF/9BDASffHevW3/CqfpRYnFSNOj2xli3wBn1Dvg==",
+ 		"FAIL",
+ 	},
+ 	{
+-		"LIyFyCYCptPxrvTxpol8F3M7ZivlMsf53zs0vHRAv+rDIh2YsHS69ePMoPMe3TkOMZ3NupiL3takPxIs1sK+dw==",
++		"Bsrz5yYuevhqx1Pxx4zEsegU2aVBZ2h9ebtAgQkq3N/og0t+8O92XpPBoNH/HT2jHclh01aij1niCqdBn2/6GBN4irnVjrWQkoAV2Q5Q+gVS0ZYeTzeX/15M/iq9xeLjBPXqj5PmNYh+vbL05FyPB+CcY8MPyv7HmtDsAWRVDxQVWy6y4lmC1/VwnG5jtmAbapE+Vyty0iVb9/Q6UaaV7DVKVssEDmwnychibJ4ACcTQ18kLkB1AE73dXp1B/XHh6ExbHXoaPeaRYr2gEI0No6VBTrMrG5eVz3dub/a5MVeat9n/oU2QQ3s/Pm0FlF9n2mwgvKm/4nLjwjiTFt3ToQ==",
+ 		"abcd",
+ 	},
+ 	{
+-		"bafnobel46bKy76JzqU/RIVOH0uAYvzUtauKmIidKgM0sMlvobYVAVQPeUQ/oTGjbIZ1v/6Gyi5AO4DtHruGdw==",
++		"FKynVeuuoYxonMoXWwIw3mY7KTV3yS3fe2D+h5v6FXs/0xb5PeINCEq0+Ub5LFAZcx/lIbnt4bkLZcaKDxLpBCxpvpZNdgGxP970BvE5xmOuagF47VaqCciiERTTztRjwKTu0PZ5VtcpsxiSN4axlC1NOpJnIpDsNOWUaf5G6fCCEdfZWwgxaHLbxSAy+IdUHBH+honCPPZAyGyhERdcDRGJ8a6R20MFXC18e8asHtF5VWaicaYe0fy1Mrii46WqFY8hwoSrbHOGEQkjRymM/IQvXFdxQ1vtzAFavUsr5taiVe84DvcFJ5eRZ2jpVQTdO4gBy6RyD64iNSrv8a5dqA==",
+ 		"FAIL",
+ 	},
+ }
+@@ -140,7 +139,7 @@ var decryptPKCS1v15SessionKeyTests = []DecryptPKCS1v15Test{
+ func TestEncryptPKCS1v15SessionKey(t *testing.T) {
+ 	for i, test := range decryptPKCS1v15SessionKeyTests {
+ 		key := []byte("FAIL")
+-		err := DecryptPKCS1v15SessionKey(nil, rsaPrivateKey, decodeBase64(test.in), key)
++		err := DecryptPKCS1v15SessionKey(nil, testRSA2048PrivateKey, decodeBase64(test.in), key)
+ 		if err != nil {
+ 			t.Errorf("#%d error decrypting", i)
+ 		}
+@@ -153,7 +152,7 @@ func TestEncryptPKCS1v15SessionKey(t *testing.T) {
+ 
+ func TestEncryptPKCS1v15DecrypterSessionKey(t *testing.T) {
+ 	for i, test := range decryptPKCS1v15SessionKeyTests {
+-		plaintext, err := rsaPrivateKey.Decrypt(rand.Reader, decodeBase64(test.in), &PKCS1v15DecryptOptions{SessionKeyLen: 4})
++		plaintext, err := testRSA2048PrivateKey.Decrypt(rand.Reader, decodeBase64(test.in), &PKCS1v15DecryptOptions{SessionKeyLen: 4})
+ 		if err != nil {
+ 			t.Fatalf("#%d: error decrypting: %s", i, err)
+ 		}
+@@ -187,19 +186,19 @@ type signPKCS1v15Test struct {
+ 	in, out string
+ }
+ 
+-// These vectors have been tested with
+-//   `openssl rsautl -verify -inkey pk -in signature | hexdump -C`
+-var signPKCS1v15Tests = []signPKCS1v15Test{
+-	{"Test.\n", "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e336ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"},
++// Test vector for testRSA2048PrivateKey
++// generated with `openssl pkeyutl -rawin -digest sha256 -sign -inkey <key>`
++ var signPKCS1v15Tests = []signPKCS1v15Test{
++	{"Test.\n", "467c3c8f16223ba09aecfe44488d6b34b3f91f11379949b1d8af31636ee8b3aa51eebb96ee11678323cb1f909af17c9d0fe4b6012078af8120474474efd1bb51765e1647369ddba6525c6608113857bb0e2aaed9ad01fe041b476b162f7d4db55bb31fa957046616ce463cecb2a66f38fa62c594d07afcc870582d545853b31fa705ab8565e4085804c32e73459720bf4e08f097843b0845116d4376231fa2472abc89b1e42462002bf70f9a1df31db6d2ab6dc52c8223798a4f57c40d6a9123b80739846d779044eac28d8c783e8ce73919f1d4a6efe8fb601b8d36c5c9b61654d6f8717d1fb9fcafa19669200900899dd08ce921a1745312eb06040a405903"},
+ }
+ 
+ func TestSignPKCS1v15(t *testing.T) {
+ 	for i, test := range signPKCS1v15Tests {
+-		h := sha1.New()
++		h := sha256.New()
+ 		h.Write([]byte(test.in))
+ 		digest := h.Sum(nil)
+ 
+-		s, err := SignPKCS1v15(nil, rsaPrivateKey, crypto.SHA1, digest)
++		s, err := SignPKCS1v15(nil, testRSA2048PrivateKey, crypto.SHA256, digest)
+ 		if err != nil {
+ 			t.Errorf("#%d %s", i, err)
+ 		}
+@@ -213,13 +212,13 @@ func TestSignPKCS1v15(t *testing.T) {
+ 
+ func TestVerifyPKCS1v15(t *testing.T) {
+ 	for i, test := range signPKCS1v15Tests {
+-		h := sha1.New()
++		h := sha256.New()
+ 		h.Write([]byte(test.in))
+ 		digest := h.Sum(nil)
+ 
+ 		sig, _ := hex.DecodeString(test.out)
+ 
+-		err := VerifyPKCS1v15(&rsaPrivateKey.PublicKey, crypto.SHA1, digest, sig)
++		err := VerifyPKCS1v15(&testRSA2048PrivateKey.PublicKey, crypto.SHA256, digest, sig)
+ 		if err != nil {
+ 			t.Errorf("#%d %s", i, err)
+ 		}
+@@ -230,7 +229,7 @@ func TestHashVerifyPKCS1v15(t *testing.T) {
+ 	for i, test := range signPKCS1v15Tests {
+ 		sig, _ := hex.DecodeString(test.out)
+ 
+-		err := HashVerifyPKCS1v15(&rsaPrivateKey.PublicKey, crypto.SHA1, []byte(test.in), sig)
++		err := HashVerifyPKCS1v15(&testRSA2048PrivateKey.PublicKey, crypto.SHA256, []byte(test.in), sig)
+ 		if err != nil {
+ 			t.Errorf("#%d %s", i, err)
+ 		}
+@@ -273,19 +272,47 @@ func TestUnpaddedSignature(t *testing.T) {
+ func TestShortSessionKey(t *testing.T) {
+ 	// This tests that attempting to decrypt a session key where the
+ 	// ciphertext is too small doesn't run outside the array bounds.
+-	ciphertext, err := EncryptPKCS1v15(rand.Reader, &rsaPrivateKey.PublicKey, []byte{1})
+-	if err != nil {
+-		t.Fatalf("Failed to encrypt short message: %s", err)
++	var keys []*PrivateKey
++	if boring.Enabled() {
++		keys = GenerateTestPrivateKeys()
++	} else {
++		keys = []*PrivateKey{rsaPrivateKey}
+ 	}
+ 
+-	var key [32]byte
+-	if err := DecryptPKCS1v15SessionKey(nil, rsaPrivateKey, ciphertext, key[:]); err != nil {
+-		t.Fatalf("Failed to decrypt short message: %s", err)
+-	}
++        for i, k := range keys {
++
++		if k.Size() >= 256 || !boring.Enabled() {
++			ciphertext, err := EncryptPKCS1v15(rand.Reader, &k.PublicKey, []byte{1})
++			if err != nil {
++				t.Fatalf("Failed to encrypt short message: key: %v, %s", i, err)
++				continue
++			}
++
++			var key [32]byte
++			if err := DecryptPKCS1v15SessionKey(nil, k, ciphertext, key[:]); err != nil {
++				t.Fatalf("Failed to decrypt short message: key: %v, %s", i, err)
++				continue
++			}
++
++			for _, v := range key {
++				if v != 0 {
++					t.Fatal("key was modified when ciphertext was invalid")
++				}
++			}
++		} else {
++			ciphertext, err := EncryptPKCS1v15(rand.Reader, &k.PublicKey, []byte{1})
++			if err == nil {
++				t.Errorf("EncryptPKCS1v15: Should reject key smaller than 2048 bits")
++			} else {
++				continue
++			}
++
++			var key [32]byte
++			err = DecryptPKCS1v15SessionKey(nil, k, ciphertext, key[:]);
++			if err != nil {
++				t.Errorf("DecryptPKCS1v15SessionKey: Should reject key smaller than 2048 bits")
++			}
+ 
+-	for _, v := range key {
+-		if v != 0 {
+-			t.Fatal("key was modified when ciphertext was invalid")
+ 		}
+ 	}
+ }
+@@ -313,6 +340,28 @@ var rsaPrivateKey = &PrivateKey{
+ 	},
+ }
+ 
++func generateKey(size int) *PrivateKey {
++	result, err := GenerateKey(rand.Reader, size)
++	if err != nil {
++		panic("could not generate key")
++	}
++	return result
++}
++
++func GenerateTestPrivateKeys() []*PrivateKey {
++
++	keys := []*PrivateKey{
++		generateKey(128),
++		generateKey(256),
++		generateKey(768),
++		generateKey(1024),
++		generateKey(2048),
++		generateKey(3072),
++		generateKey(4096),
++	}
++	return keys
++}
++
+ func TestShortPKCS1v15Signature(t *testing.T) {
+ 	pub := &PublicKey{
+ 		E: 65537,
+diff --git a/src/crypto/rsa/pss_test.go b/src/crypto/rsa/pss_test.go
+index 6a5a93f..2032b4b 100644
+--- a/src/crypto/rsa/pss_test.go
++++ b/src/crypto/rsa/pss_test.go
+@@ -132,7 +132,6 @@ func TestPSSGolden(t *testing.T) {
+ 	opts := &PSSOptions{
+ 		SaltLength: PSSSaltLengthEqualsHash,
+ 	}
+-
+ 	for marker := range values {
+ 		switch marker {
+ 		case newKeyMarker:
+@@ -174,18 +173,13 @@ func TestPSSOpenSSL(t *testing.T) {
+ 	h.Write(hashed)
+ 	hashed = h.Sum(nil)
+ 
++	// Test vector for testRSA2048PrivateKey
+ 	// Generated with `echo -n testing | openssl dgst -sign key.pem -sigopt rsa_padding_mode:pss -sha256 > sig`
+ 	sig := []byte{
+-		0x95, 0x59, 0x6f, 0xd3, 0x10, 0xa2, 0xe7, 0xa2, 0x92, 0x9d,
+-		0x4a, 0x07, 0x2e, 0x2b, 0x27, 0xcc, 0x06, 0xc2, 0x87, 0x2c,
+-		0x52, 0xf0, 0x4a, 0xcc, 0x05, 0x94, 0xf2, 0xc3, 0x2e, 0x20,
+-		0xd7, 0x3e, 0x66, 0x62, 0xb5, 0x95, 0x2b, 0xa3, 0x93, 0x9a,
+-		0x66, 0x64, 0x25, 0xe0, 0x74, 0x66, 0x8c, 0x3e, 0x92, 0xeb,
+-		0xc6, 0xe6, 0xc0, 0x44, 0xf3, 0xb4, 0xb4, 0x2e, 0x8c, 0x66,
+-		0x0a, 0x37, 0x9c, 0x69,
++		0x50, 0x97, 0xc1, 0xe2, 0x7c, 0x67, 0x99, 0x50, 0xdc, 0x5a, 0x43, 0xc6, 0xc6, 0xf2, 0xf1, 0xff, 0xcd, 0xe7, 0x66, 0xef, 0x61, 0x41, 0x5f, 0x49, 0x4f, 0xf0, 0x11, 0xfc, 0x3d, 0xa8, 0xf9, 0x3c, 0x3a, 0x8a, 0x71, 0x5c, 0xfa, 0xbc, 0x48, 0x73, 0x37, 0xec, 0x68, 0x6d, 0x6c, 0xca, 0xe, 0x30, 0x74, 0xe1, 0xbd, 0x88, 0xb6, 0x42, 0x92, 0x8d, 0x41, 0x5f, 0x7, 0x80, 0xc5, 0xef, 0xa3, 0x2e, 0x68, 0x47, 0x83, 0xb4, 0x96, 0x4c, 0x53, 0x61, 0x2c, 0xe8, 0xb8, 0x3, 0xae, 0x44, 0x5e, 0xb3, 0x44, 0x10, 0x58, 0xfd, 0x68, 0x9c, 0x33, 0xac, 0x63, 0xfe, 0x9d, 0x84, 0xab, 0x45, 0x70, 0x54, 0xc5, 0x90, 0x1e, 0x80, 0xd4, 0x31, 0x16, 0x15, 0x4b, 0x60, 0x13, 0x24, 0xa, 0xa8, 0xbc, 0xe5, 0xeb, 0xf8, 0x7d, 0x32, 0xd9, 0xcd, 0x8b, 0xef, 0x55, 0x60, 0x1, 0xa6, 0x99, 0xa2, 0xde, 0xb0, 0x68, 0xc1, 0x64, 0x8b, 0x6, 0xe6, 0x75, 0xcf, 0x2d, 0x7a, 0x8b, 0xd6, 0xa3, 0x99, 0xf1, 0xc9, 0xaf, 0x9a, 0x81, 0xe4, 0xac, 0x2e, 0x17, 0x8c, 0x49, 0xfc, 0x12, 0x79, 0xfb, 0x4a, 0xba, 0x68, 0xd8, 0xdb, 0x43, 0x6c, 0x15, 0xaf, 0xa4, 0x16, 0x2f, 0xc9, 0x1e, 0xbe, 0xef, 0xb3, 0x35, 0x14, 0x2f, 0x35, 0x41, 0x10, 0xf8, 0x32, 0xf8, 0x0, 0x5c, 0xbf, 0x77, 0xa, 0xbb, 0x77, 0x49, 0x47, 0x54, 0x7a, 0x58, 0xfd, 0xb3, 0x2c, 0x46, 0xa0, 0x5c, 0x3, 0x7a, 0xf7, 0xab, 0x77, 0xdb, 0xca, 0x9a, 0x38, 0x89, 0xb, 0x3e, 0xb0, 0x13, 0xe8, 0x16, 0xc0, 0xca, 0x29, 0xbb, 0x4a, 0x97, 0x46, 0x53, 0x59, 0x66, 0x81, 0x84, 0x6d, 0xe5, 0xda, 0x26, 0xc9, 0x83, 0xfc, 0x67, 0xd0, 0x96, 0x72, 0x81, 0x1c, 0xe0, 0x4, 0xb7, 0x0, 0xca, 0xe0, 0x4a, 0x51, 0x4e, 0x83, 0xc8, 0xeb, 0xf7, 0x6d,
+ 	}
+ 
+-	if err := VerifyPSS(&rsaPrivateKey.PublicKey, hash, hashed, sig, nil); err != nil {
++	if err := VerifyPSS(&testRSA2048PrivateKey.PublicKey, hash, hashed, sig, nil); err != nil {
+ 		t.Error(err)
+ 	}
+ }
+@@ -212,24 +206,47 @@ func TestPSSSigning(t *testing.T) {
+ 		{8, 8, true},
+ 	}
+ 
++	var opts PSSOptions
+ 	hash := crypto.SHA1
++	keys := []*PrivateKey{rsaPrivateKey}
++	if boring.Enabled() {
++		hash = crypto.SHA256
++		keys = GenerateTestPrivateKeys()
++	}
+ 	h := hash.New()
+ 	h.Write([]byte("testing"))
+ 	hashed := h.Sum(nil)
+-	var opts PSSOptions
+ 
+-	for i, test := range saltLengthCombinations {
+-		opts.SaltLength = test.signSaltLength
+-		sig, err := SignPSS(rand.Reader, rsaPrivateKey, hash, hashed, &opts)
+-		if err != nil {
+-			t.Errorf("#%d: error while signing: %s", i, err)
+-			continue
+-		}
++	for _, key := range keys {
++		if !boring.Enabled() || key.Size() >= 256 {
++			for i, test := range saltLengthCombinations {
++				opts.SaltLength = test.signSaltLength
++				sig, err := SignPSS(rand.Reader, key, hash, hashed, &opts)
++				if err != nil {
++					t.Errorf("#%d: ALG: %v, error while signing: %s", i, hash, err)
++					continue
++				}
++				opts.SaltLength = test.verifySaltLength
++				err = VerifyPSS(&key.PublicKey, hash, hashed, sig, &opts)
++				if (err == nil) != test.good {
++					t.Errorf("#%d: bad result, wanted: %t, got: %s", i, test.good, err)
++				}
++			}
++		} else {
++			 for _, test := range saltLengthCombinations {
++				opts.SaltLength = test.signSaltLength
++				sig, err := SignPSS(rand.Reader, key, hash, hashed, &opts)
++				if err == nil {
++					t.Errorf("SignPSS should reject key of size: %v\n%v", key.Size() * 8, err)
++					continue
++				}
++				opts.SaltLength = test.verifySaltLength
++				err = VerifyPSS(&key.PublicKey, hash, hashed, sig, &opts)
++				if (err == nil) {
++					t.Errorf("VerifyPSS should reject key of size: %v\n%v", key.Size() * 8, err)
++				}
++			}
+ 
+-		opts.SaltLength = test.verifySaltLength
+-		err = VerifyPSS(&rsaPrivateKey.PublicKey, hash, hashed, sig, &opts)
+-		if (err == nil) != test.good {
+-			t.Errorf("#%d: bad result, wanted: %t, got: %s", i, test.good, err)
+ 		}
+ 	}
+ }
+diff --git a/src/crypto/rsa/rsa.go b/src/crypto/rsa/rsa.go
+index 24e2d22..1fd5a9a 100644
+--- a/src/crypto/rsa/rsa.go
++++ b/src/crypto/rsa/rsa.go
+@@ -35,6 +35,7 @@ import (
+ 	"crypto/internal/boring"
+ 	"crypto/internal/randutil"
+ 	"unsafe"
++	"fmt"
+ )
+ 
+ var bigZero = big.NewInt(0)
+@@ -664,7 +665,7 @@ func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext
+ 		}
+ 		out, err := boring.DecryptRSAOAEP(hash, bkey, ciphertext, label)
+ 		if err != nil {
+-			return nil, ErrDecryption
++			return nil, fmt.Errorf("decryption error: %s", err)
+ 		}
+ 		return out, nil
+ 	}
+diff --git a/src/crypto/rsa/rsa_test.go b/src/crypto/rsa/rsa_test.go
+index d9693a7..cfe020e 100644
+--- a/src/crypto/rsa/rsa_test.go
++++ b/src/crypto/rsa/rsa_test.go
+@@ -13,6 +13,7 @@ import (
+ 	"fmt"
+ 	"math/big"
+ 	"testing"
++
+ )
+ 
+ import "crypto/internal/boring"
+@@ -34,34 +35,42 @@ func TestKeyGeneration(t *testing.T) {
+ }
+ 
+ func Test3PrimeKeyGeneration(t *testing.T) {
+-	size := 768
++	var sizes []int
+ 	if testing.Short() {
+-		size = 256
++		sizes = []int{256}
++	} else {
++		sizes = []int{128, 768, 1024, 2048, 3072}
+ 	}
++	for _, size := range sizes {
+ 
+-	priv, err := GenerateMultiPrimeKey(rand.Reader, 3, size)
+-	if err != nil {
+-		t.Errorf("failed to generate key")
++		priv, err := GenerateMultiPrimeKey(rand.Reader, 3, size)
++		if err != nil {
++			t.Errorf("failed to generate key")
++		}
++		testKeyBasics(t, priv)
+ 	}
+-	testKeyBasics(t, priv)
+ }
+ 
+ func Test4PrimeKeyGeneration(t *testing.T) {
+-	size := 768
++	var sizes []int
+ 	if testing.Short() {
+-		size = 256
++		sizes = []int{256}
++	} else {
++		sizes = []int{128, 768, 1024, 2048, 3072}
+ 	}
++	for _, size := range sizes {
+ 
+-	priv, err := GenerateMultiPrimeKey(rand.Reader, 4, size)
+-	if err != nil {
+-		t.Errorf("failed to generate key")
++		priv, err := GenerateMultiPrimeKey(rand.Reader, 4, size)
++		if err != nil {
++			t.Errorf("failed to generate key")
++		}
++		testKeyBasics(t, priv)
+ 	}
+-	testKeyBasics(t, priv)
+ }
+ 
+ func TestNPrimeKeyGeneration(t *testing.T) {
+ 	primeSize := 64
+-	maxN := 24
++	maxN := 32
+ 	if testing.Short() {
+ 		primeSize = 16
+ 		maxN = 16
+@@ -117,18 +126,32 @@ func testKeyBasics(t *testing.T, priv *PrivateKey) {
+ 	if boring.Enabled() {
+ 		// Cannot call encrypt/decrypt directly. Test via PKCS1v15.
+ 		msg := []byte("hi!")
+-		enc, err := EncryptPKCS1v15(rand.Reader, &priv.PublicKey, msg)
+-		if err != nil {
+-			t.Errorf("EncryptPKCS1v15: %v", err)
+-			return
+-		}
+-		dec, err := DecryptPKCS1v15(rand.Reader, priv, enc)
+-		if err != nil {
+-			t.Errorf("DecryptPKCS1v15: %v", err)
+-			return
+-		}
+-		if !bytes.Equal(dec, msg) {
+-			t.Errorf("got:%x want:%x (%+v)", dec, msg, priv)
++		// Should not accept keys smaller than 2048 bits (256 bytes)
++		if priv.Size() >= 256 {
++			enc, err := EncryptPKCS1v15(rand.Reader, &priv.PublicKey, msg)
++			if err != nil {
++				t.Errorf("EncryptPKCS1v15: %v", err)
++				return
++			}
++			dec, err := DecryptPKCS1v15(rand.Reader, priv, enc)
++			if err != nil {
++				t.Errorf("DecryptPKCS1v15: %v", err)
++				return
++			}
++			if !bytes.Equal(dec, msg) {
++				t.Errorf("got:%x want:%x (%+v)", dec, msg, priv)
++			}
++		} else {
++			enc, err := EncryptPKCS1v15(rand.Reader, &priv.PublicKey, msg)
++			if err == nil {
++				t.Errorf("EncryptPKCS1v15: Should not accept key of size %v", priv.Size() * 8)
++				return
++			}
++			_ , err = DecryptPKCS1v15(rand.Reader, priv, enc)
++			if err == nil {
++				t.Errorf("DecryptPKCS1v15: Should not accept key of size %v", priv.Size() * 8)
++				return
++			}
+ 		}
+ 		return
+ 	}
+@@ -164,6 +187,7 @@ func fromBase10(base10 string) *big.Int {
+ }
+ 
+ var test2048Key *PrivateKey
++var testRSA2048PrivateKey *PrivateKey
+ 
+ func init() {
+ 	test2048Key = &PrivateKey{
+@@ -178,6 +202,21 @@ func init() {
+ 		},
+ 	}
+ 	test2048Key.Precompute()
++	// This is the same testRSA2048PrivateKey from src/crypto/tls/boring_test.go,
++	// just formatted without using the x509 Parser
++	testRSA2048PrivateKey = &PrivateKey {
++		PublicKey: PublicKey{
++                        N: fromBase10("20191212046465051006148469115982609963794084216822290493008497548603282433337961188011759317867632936762484431807200684727542982286641865915343951546098189846608892055894575224375729344858650310374442622904229900868894242623139807621975608166515302294530216022389036816474348374698399654955992710180316983674809047409565569027596663420090767109285120403886497729233127551307356270679924351259776100107640885071765865832767303853854517356000385050677175012549806941229051812974721510192346810990827150439838227830352248569839727388943852973737249863837089274675024496841834194785931485429238306703429257731792443735979"),
++                        E: 65537,
++                },
++                D: fromBase10("17880854551669112566868255345124108779447961606053558991611260520405836487267781427740459393783689829925402008838157275130340717548134956040019107677074732476577915942750039777107871579671122369249613210066309031335411813988461299033587444447689322284662780986426216011635232478916424602504476935371549462113036228740820951710434375466081011497256196435741125837599218374223248197677547321257961509961401385322723627033844333644253777689603896264679633990939957571483400832267925506777396569554295752505112186882586887396943424085633026984063372469902814987050483471096892524886948283571883744403645335501920852525393"),
++                Primes: []*big.Int{
++                        fromBase10("135564917074042739008372452399559667250812269638554028593490636590148234941034106656615266472037321030780472224077878987192393666277731486488609490961161995141171813440923127505183021899359310251888145112092740773465142711876177808655062479870526201006500762429604105802612357839979630776094264195301632424911"),
++                        fromBase10("148941278335581696308445609123523329975323575697232717856977715718810138995490768513650108277383732380774181214791356462453504708304090734692215322335879527529217737837271384209093576836051031684425884921572908683147368296418243939771852059523598364231128661438022752350148969064661946939745752818523498309989"),
++                },
++	}
++	testRSA2048PrivateKey.Precompute()
++
+ }
+ 
+ func BenchmarkRSA2048Decrypt(b *testing.B) {
+@@ -317,6 +356,11 @@ func TestEncryptDecryptOAEP(t *testing.T) {
+ 		priv.PublicKey = PublicKey{N: n, E: test.e}
+ 		priv.D = d
+ 
++		if boring.Enabled() && priv.PublicKey.Size() < 256 {
++			t.Logf("skipping check for unsupported key less than 2048 bits")
++			continue;
++		}
++		t.Logf("running check for supported key size")
+ 		for j, message := range test.msgs {
+ 			label := []byte(fmt.Sprintf("hi#%d", j))
+ 			enc, err := EncryptOAEP(sha256, rand.Reader, &priv.PublicKey, message.in, label)
+diff --git a/src/crypto/tls/boring_test.go b/src/crypto/tls/boring_test.go
+index 94a24ff..577bc73 100644
+--- a/src/crypto/tls/boring_test.go
++++ b/src/crypto/tls/boring_test.go
+@@ -26,7 +26,7 @@ import (
+ func TestBoringServerProtocolVersion(t *testing.T) {
+ 	test := func(name string, v uint16, msg string) {
+ 		t.Run(name, func(t *testing.T) {
+-			serverConfig := testConfig.Clone()
++			serverConfig := testConfigTemplate()
+ 			serverConfig.MinVersion = VersionSSL30
+ 			clientHello := &clientHelloMsg{
+ 				vers:               v,
+@@ -108,7 +108,7 @@ func isBoringSignatureScheme(alg SignatureScheme) bool {
+ }
+ 
+ func TestBoringServerCipherSuites(t *testing.T) {
+-	serverConfig := testConfig.Clone()
++	serverConfig := testConfigTemplate()
+ 	serverConfig.CipherSuites = allCipherSuites()
+ 	serverConfig.Certificates = make([]Certificate, 1)
+ 
+@@ -148,7 +148,7 @@ func TestBoringServerCipherSuites(t *testing.T) {
+ }
+ 
+ func TestBoringServerCurves(t *testing.T) {
+-	serverConfig := testConfig.Clone()
++	serverConfig := testConfigTemplate()
+ 	serverConfig.Certificates = make([]Certificate, 1)
+ 	serverConfig.Certificates[0].Certificate = [][]byte{testECDSACertificate}
+ 	serverConfig.Certificates[0].PrivateKey = testECDSAPrivateKey
+@@ -204,7 +204,7 @@ func TestBoringServerSignatureAndHash(t *testing.T) {
+ 
+ 	for _, sigHash := range defaultSupportedSignatureAlgorithms {
+ 		t.Run(fmt.Sprintf("%#x", sigHash), func(t *testing.T) {
+-			serverConfig := testConfig.Clone()
++			serverConfig := testConfigTemplate()
+ 			serverConfig.Certificates = make([]Certificate, 1)
+ 
+ 			testingOnlyForceClientHelloSignatureAlgorithms = []SignatureScheme{sigHash}
+@@ -263,7 +263,7 @@ func TestBoringClientHello(t *testing.T) {
+ 	defer c.Close()
+ 	defer s.Close()
+ 
+-	clientConfig := testConfig.Clone()
++	clientConfig := testConfigTemplate()
+ 	// All sorts of traps for the client to avoid.
+ 	clientConfig.MinVersion = VersionSSL30
+ 	clientConfig.MaxVersion = VersionTLS13
+@@ -337,12 +337,12 @@ func TestBoringCertAlgs(t *testing.T) {
+ 
+ 	// client verifying server cert
+ 	testServerCert := func(t *testing.T, desc string, pool *x509.CertPool, key interface{}, list [][]byte, ok bool) {
+-		clientConfig := testConfig.Clone()
++		clientConfig := testConfigTemplate()
+ 		clientConfig.RootCAs = pool
+ 		clientConfig.InsecureSkipVerify = false
+ 		clientConfig.ServerName = "example.com"
+ 
+-		serverConfig := testConfig.Clone()
++		serverConfig := testConfigTemplate()
+ 		serverConfig.Certificates = []Certificate{{Certificate: list, PrivateKey: key}}
+ 		serverConfig.BuildNameToCertificate()
+ 
+@@ -365,11 +365,11 @@ func TestBoringCertAlgs(t *testing.T) {
+ 
+ 	// server verifying client cert
+ 	testClientCert := func(t *testing.T, desc string, pool *x509.CertPool, key interface{}, list [][]byte, ok bool) {
+-		clientConfig := testConfig.Clone()
++		clientConfig := testConfigTemplate()
+ 		clientConfig.ServerName = "example.com"
+ 		clientConfig.Certificates = []Certificate{{Certificate: list, PrivateKey: key}}
+ 
+-		serverConfig := testConfig.Clone()
++		serverConfig := testConfigTemplate()
+ 		serverConfig.ClientCAs = pool
+ 		serverConfig.ClientAuth = RequireAndVerifyClientCert
+ 
+@@ -394,8 +394,13 @@ func TestBoringCertAlgs(t *testing.T) {
+ 	// exhaustive test with computed answers.
+ 	r1pool := x509.NewCertPool()
+ 	r1pool.AddCert(R1.cert)
+-	testServerCert(t, "basic", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, true)
+-	testClientCert(t, "basic (client cert)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, true)
++	// openssl 3 FIPS provider fails these now without fipstls.Force()
++	shouldPass := true
++	if boring.Enabled() {
++		shouldPass = false
++	}
++	testClientCert(t, "basic (client cert)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, shouldPass)
++	testClientCert(t, "basic (client cert)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, shouldPass)
+ 	fipstls.Force()
+ 	testServerCert(t, "basic (fips)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, false)
+ 	testClientCert(t, "basic (fips, client cert)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, false)
+@@ -458,6 +463,10 @@ func TestBoringCertAlgs(t *testing.T) {
+ 				addRoot(r&1, R1)
+ 				addRoot(r&2, R2)
+ 				rootName = rootName[1:] // strip leading comma
++				// openssl 3 FIPS provider fails these now without fipstls.Force()
++				if boring.Enabled() {
++					shouldVerify = shouldVerifyFIPS
++				}
+ 				testServerCert(t, listName+"->"+rootName[1:], pool, leaf.key, list, shouldVerify)
+ 				testClientCert(t, listName+"->"+rootName[1:]+"(client cert)", pool, leaf.key, list, shouldVerify)
+ 				fipstls.Force()
+@@ -577,6 +586,16 @@ var (
+ 	testRSA2048PrivateKey  *rsa.PrivateKey
+ )
+ 
++func testConfigTemplate() *Config {
++	config := testConfig.Clone()
++	if boring.Enabled() {
++		config.Certificates[0].Certificate = [][]byte{testRSA2048Certificate}
++		config.Certificates[0].PrivateKey = testRSA2048PrivateKey
++	}
++	return config
++
++}
++
+ func init() {
+ 	block, _ := pem.Decode([]byte(`
+ -----BEGIN CERTIFICATE-----
+diff --git a/src/crypto/x509/x509_test.go b/src/crypto/x509/x509_test.go
+index 449379f..801a954 100644
+--- a/src/crypto/x509/x509_test.go
++++ b/src/crypto/x509/x509_test.go
+@@ -151,6 +151,7 @@ func TestPKIXMismatchPublicKeyFormat(t *testing.T) {
+ }
+ 
+ var testPrivateKey *rsa.PrivateKey
++var testPrivateKey2048 *rsa.PrivateKey
+ 
+ func init() {
+ 	block, _ := pem.Decode([]byte(pemPrivateKey))
+@@ -159,6 +160,9 @@ func init() {
+ 	if testPrivateKey, err = ParsePKCS1PrivateKey(block.Bytes); err != nil {
+ 		panic("Failed to parse private key: " + err.Error())
+ 	}
++	if testPrivateKey2048, err = rsa.GenerateKey(rand.Reader, 2048); err != nil {
++		panic("Failed to generate key: " + err.Error())
++	}
+ }
+ 
+ func bigFromString(s string) *big.Int {
+@@ -589,8 +593,9 @@ func TestCreateSelfSignedCertificate(t *testing.T) {
+ 		{"RSA/ECDSA", &testPrivateKey.PublicKey, ecdsaPriv, false, ECDSAWithSHA384},
+ 		{"ECDSA/RSA", &ecdsaPriv.PublicKey, testPrivateKey, false, SHA256WithRSA},
+ 		{"ECDSA/ECDSA", &ecdsaPriv.PublicKey, ecdsaPriv, true, ECDSAWithSHA1},
+-		{"RSAPSS/RSAPSS", &testPrivateKey.PublicKey, testPrivateKey, true, SHA256WithRSAPSS},
+-		{"ECDSA/RSAPSS", &ecdsaPriv.PublicKey, testPrivateKey, false, SHA256WithRSAPSS},
++		// TODO: hardcode the next two keys
++		{"RSAPSS/RSAPSS", &testPrivateKey2048.PublicKey, testPrivateKey2048, true, SHA256WithRSAPSS},
++		{"ECDSA/RSAPSS", &ecdsaPriv.PublicKey, testPrivateKey2048, false, SHA256WithRSAPSS},
+ 		{"RSAPSS/ECDSA", &testPrivateKey.PublicKey, ecdsaPriv, false, ECDSAWithSHA384},
+ 		{"Ed25519", ed25519Pub, ed25519Priv, true, PureEd25519},
+ 	}
diff --git a/SPECS/golang.spec b/SPECS/golang.spec
new file mode 100644
index 0000000..bbea5fb
--- /dev/null
+++ b/SPECS/golang.spec
@@ -0,0 +1,1236 @@
+%undefine _missing_build_ids_terminate_build
+
+%global bcond_with strict_fips
+
+# build ids are not currently generated:
+# https://code.google.com/p/go/issues/detail?id=5238
+#
+# also, debuginfo extraction currently fails with
+# "Failed to write file: invalid section alignment"
+%global debug_package %{nil}
+
+# we are shipping the full contents of src in the data subpackage, which
+# contains binary-like things (ELF data for tests, etc)
+%global _binaries_in_noarch_packages_terminate_build 0
+
+# Do not check any files in doc or src for requires
+%global __requires_exclude_from ^(%{_datadir}|/usr/lib)/%{name}/(doc|src)/.*$
+
+# Don't alter timestamps of especially the .a files (or else go will rebuild later)
+# Actually, don't strip at all since we are not even building debug packages and this corrupts the dwarf testdata
+%global __strip /bin/true
+
+# rpmbuild magic to keep from having meta dependency on libc.so.6
+%define _use_internal_dependency_generator 0
+%define __find_requires %{nil}
+%global __spec_install_post /usr/lib/rpm/check-rpaths   /usr/lib/rpm/check-buildroot  \
+  /usr/lib/rpm/brp-compress
+
+# Define GOROOT macros
+%global goroot          %{_prefix}/lib/%{name}
+%global gopath          %{_datadir}/gocode
+%global golang_arches   x86_64 aarch64 ppc64le s390x
+%global golibdir        %{_libdir}/%{name}
+
+# Golang build options.
+
+# Build golang using external/internal(close to cgo disabled) linking.
+%ifarch x86_64 ppc64le %{arm} aarch64 s390x
+%global external_linker 1
+%else
+%global external_linker 0
+%endif
+
+# Build golang with cgo enabled/disabled(later equals more or less to internal linking).
+%ifarch x86_64 ppc64le %{arm} aarch64 s390x
+%global cgo_enabled 1
+%else
+%global cgo_enabled 0
+%endif
+
+# Use golang/gcc-go as bootstrap compiler
+%ifarch %{golang_arches}
+%global golang_bootstrap 1
+%else
+%global golang_bootstrap 0
+%endif
+
+# Controls what ever we fail on failed tests
+%ifarch x86_64 %{arm} aarch64 ppc64le
+%global fail_on_tests 1
+%else
+%global fail_on_tests 0
+%endif
+
+# Build golang shared objects for stdlib
+%ifarch 0
+%global shared 1
+%else
+%global shared 0
+%endif
+
+# Pre build std lib with -race enabled
+%ifarch x86_64
+%global race 1
+%else
+%global race 0
+%endif
+
+%ifarch x86_64
+%global gohostarch  amd64
+%endif
+%ifarch %{arm}
+%global gohostarch  arm
+%endif
+%ifarch aarch64
+%global gohostarch  arm64
+%endif
+%ifarch ppc64
+%global gohostarch  ppc64
+%endif
+%ifarch ppc64le
+%global gohostarch  ppc64le
+%endif
+%ifarch s390x
+%global gohostarch  s390x
+%endif
+
+%global go_api 1.17
+%global go_version 1.17.7
+%global pkg_release 1
+
+Name:           golang
+Version:        %{go_version}
+Release:        1%{?dist}
+Summary:        The Go Programming Language
+# source tree includes several copies of Mark.Twain-Tom.Sawyer.txt under Public Domain
+License:        BSD and Public Domain
+URL:            http://golang.org/
+Source0:        https://pagure.io/go/archive/go-%{go_version}-%{pkg_release}-openssl-fips/go-go-%{go_version}-%{pkg_release}-openssl-fips.tar.gz
+# make possible to override default traceback level at build time by setting build tag rpm_crashtraceback
+Source1:        fedora.go
+
+# The compiler is written in Go. Needs go(1.4+) compiler for build.
+# Actual Go based bootstrap compiler provided by above source.
+%if !%{golang_bootstrap}
+BuildRequires:  gcc-go >= 5
+%else
+BuildRequires:  golang
+%endif
+%if 0%{?rhel} > 6 || 0%{?fedora} > 0
+BuildRequires:  hostname
+%else
+BuildRequires:  net-tools
+%endif
+# For OpenSSL FIPS
+BuildRequires:  openssl-devel
+
+# For openssl-fipsinstall
+BuildRequires:  openssl
+
+# for tests
+BuildRequires:  pcre-devel, glibc-static, perl
+
+Provides:       go = %{version}-%{release}
+Requires:       %{name}-bin = %{version}-%{release}
+Requires:       %{name}-src = %{version}-%{release}
+Requires:       openssl-devel
+Requires:       diffutils
+
+# we had been just removing the zoneinfo.zip, but that caused tests to fail for users that
+# later run `go test -a std`. This makes it only use the zoneinfo.zip where needed in tests.
+Patch215:       go1.5-zoneinfo_testing_only.patch
+
+# Proposed patch by jcajka https://golang.org/cl/86541
+Patch221:       fix_TestScript_list_std.patch
+
+# Port to openssl 3.0
+Patch1952381:   rhbz1952381.patch
+
+Patch222: remove_waitgroup_misuse_tests.patch
+Patch223: remove_ed25519vectors_test.patch
+
+# Having documentation separate was broken
+Obsoletes:      %{name}-docs < 1.1-4
+
+# RPM can't handle symlink -> dir with subpackages, so merge back
+Obsoletes:      %{name}-data < 1.1.1-4
+
+# These are the only RHEL/Fedora architectures that we compile this package for
+ExclusiveArch:  %{golang_arches}
+
+Source100:      golang-gdbinit
+Source101:      golang-prelink.conf
+
+%description
+%{summary}.
+
+%package       docs
+Summary:       Golang compiler docs
+Requires:      %{name} = %{version}-%{release}
+BuildArch:     noarch
+Obsoletes:     %{name}-docs < 1.1-4
+
+%description   docs
+%{summary}.
+
+%package       misc
+Summary:       Golang compiler miscellaneous sources
+Requires:      %{name} = %{version}-%{release}
+BuildArch:     noarch
+
+%description   misc
+%{summary}.
+
+%package       tests
+Summary:       Golang compiler tests for stdlib
+Requires:      %{name} = %{version}-%{release}
+BuildArch:     noarch
+
+%description   tests
+%{summary}.
+
+%package        src
+Summary:        Golang compiler source tree
+BuildArch:      noarch
+
+%description    src
+%{summary}
+
+%package        bin
+Summary:        Golang core compiler tools
+Requires:       %{name} = %{version}-%{release}
+
+# We strip the meta dependency, but go does require glibc.
+# This is an odd issue, still looking for a better fix.
+Requires:       glibc
+Requires:       /usr/bin/gcc
+%description    bin
+%{summary}
+
+# Workaround old RPM bug of symlink-replaced-with-dir failure
+%pretrans -p <lua>
+for _,d in pairs({"api", "doc", "include", "lib", "src"}) do
+  path = "%{goroot}/" .. d
+  if posix.stat(path, "type") == "link" then
+    os.remove(path)
+    posix.mkdir(path)
+  end
+end
+
+%if %{shared}
+%package        shared
+Summary:        Golang shared object libraries
+
+%description    shared
+%{summary}.
+%endif
+
+%if %{race}
+%package        race
+Summary:        Golang std library with -race enabled
+
+Requires:       %{name} = %{version}-%{release}
+
+%description    race
+%{summary}
+%endif
+
+%prep
+%setup -q -n go-go-%{go_version}-%{pkg_release}-openssl-fips
+
+%patch215 -p1
+
+%patch221 -p1
+
+%patch1952381 -p1
+
+%patch222 -p1
+
+%patch223 -p1
+
+cp %{SOURCE1} ./src/runtime/
+
+%build
+set -xe
+# print out system information
+uname -a
+cat /proc/cpuinfo
+cat /proc/meminfo
+
+# bootstrap compiler GOROOT
+%if !%{golang_bootstrap}
+export GOROOT_BOOTSTRAP=/
+%else
+export GOROOT_BOOTSTRAP=/opt/rh/go-toolset-1.10/root/usr/lib/go-toolset-1.10-golang
+%endif
+
+# set up final install location
+export GOROOT_FINAL=%{goroot}
+
+export GOHOSTOS=linux
+export GOHOSTARCH=%{gohostarch}
+
+pushd src
+# use our gcc options for this build, but store gcc as default for compiler
+export CFLAGS="$RPM_OPT_FLAGS"
+export LDFLAGS="$RPM_LD_FLAGS"
+export CC="gcc"
+export CC_FOR_TARGET="gcc"
+export GOOS=linux
+export GOARCH=%{gohostarch}
+
+DEFAULT_GO_LD_FLAGS=""
+%if !%{external_linker}
+export GO_LDFLAGS="-linkmode internal $DEFAULT_GO_LD_FLAGS"
+%else
+# Only pass a select subset of the external hardening flags. We do not pass along
+# the default $RPM_LD_FLAGS as on certain arches Go does not fully, correctly support
+# building in PIE mode.
+export GO_LDFLAGS="\"-extldflags=-Wl,-z,now,-z,relro\" $DEFAULT_GO_LD_FLAGS"
+%endif
+%if !%{cgo_enabled}
+export CGO_ENABLED=0
+%endif
+./make.bash --no-clean
+popd
+
+# build shared std lib
+%if %{shared}
+GOROOT=$(pwd) PATH=$(pwd)/bin:$PATH go install -buildmode=shared std
+%endif
+
+%if %{race}
+GOROOT=$(pwd) PATH=$(pwd)/bin:$PATH go install -race std
+%endif
+
+
+%install
+
+rm -rf $RPM_BUILD_ROOT
+
+# create the top level directories
+mkdir -p $RPM_BUILD_ROOT%{_bindir}
+mkdir -p $RPM_BUILD_ROOT%{goroot}
+
+# remove bootstrap binaries
+rm -rf pkg/bootstrap/bin
+
+# install everything into libdir (until symlink problems are fixed)
+# https://code.google.com/p/go/issues/detail?id=5830
+cp -apv api bin doc lib pkg src misc test VERSION \
+   $RPM_BUILD_ROOT%{goroot}
+
+# bz1099206
+find $RPM_BUILD_ROOT%{goroot}/src -exec touch -r $RPM_BUILD_ROOT%{goroot}/VERSION "{}" \;
+# and level out all the built archives
+touch $RPM_BUILD_ROOT%{goroot}/pkg
+find $RPM_BUILD_ROOT%{goroot}/pkg -exec touch -r $RPM_BUILD_ROOT%{goroot}/pkg "{}" \;
+# generate the spec file ownership of this source tree and packages
+cwd=$(pwd)
+src_list=$cwd/go-src.list
+pkg_list=$cwd/go-pkg.list
+shared_list=$cwd/go-shared.list
+race_list=$cwd/go-race.list
+misc_list=$cwd/go-misc.list
+docs_list=$cwd/go-docs.list
+tests_list=$cwd/go-tests.list
+rm -f $src_list $pkg_list $docs_list $misc_list $tests_list $shared_list $race_list
+touch $src_list $pkg_list $docs_list $misc_list $tests_list $shared_list $race_list
+pushd $RPM_BUILD_ROOT%{goroot}
+    find src/ -type d -a \( ! -name testdata -a ! -ipath '*/testdata/*' \) -printf '%%%dir %{goroot}/%p\n' >> $src_list
+    find src/ ! -type d -a \( ! -ipath '*/testdata/*' -a ! -name '*_test*.go' \) -printf '%{goroot}/%p\n' >> $src_list
+
+    find bin/ pkg/ -type d -a ! -path '*_dynlink/*' -a ! -path '*_race/*' -printf '%%%dir %{goroot}/%p\n' >> $pkg_list
+    find bin/ pkg/ ! -type d -a ! -path '*_dynlink/*' -a ! -path '*_race/*' -printf '%{goroot}/%p\n' >> $pkg_list
+
+    find doc/ -type d -printf '%%%dir %{goroot}/%p\n' >> $docs_list
+    find doc/ ! -type d -printf '%{goroot}/%p\n' >> $docs_list
+
+    find misc/ -type d -printf '%%%dir %{goroot}/%p\n' >> $misc_list
+    find misc/ ! -type d -printf '%{goroot}/%p\n' >> $misc_list
+
+%if %{shared}
+    mkdir -p %{buildroot}/%{_libdir}/
+    mkdir -p %{buildroot}/%{golibdir}/
+    for file in $(find .  -iname "*.so" ); do
+        chmod 755 $file
+        mv  $file %{buildroot}/%{golibdir}
+        pushd $(dirname $file)
+        ln -fs %{golibdir}/$(basename $file) $(basename $file)
+        popd
+        echo "%%{goroot}/$file" >> $shared_list
+        echo "%%{golibdir}/$(basename $file)" >> $shared_list
+    done
+
+    find pkg/*_dynlink/ -type d -printf '%%%dir %{goroot}/%p\n' >> $shared_list
+    find pkg/*_dynlink/ ! -type d -printf '%{goroot}/%p\n' >> $shared_list
+%endif
+
+%if %{race}
+
+    find pkg/*_race/ -type d -printf '%%%dir %{goroot}/%p\n' >> $race_list
+    find pkg/*_race/ ! -type d -printf '%{goroot}/%p\n' >> $race_list
+
+%endif
+
+    find test/ -type d -printf '%%%dir %{goroot}/%p\n' >> $tests_list
+    find test/ ! -type d -printf '%{goroot}/%p\n' >> $tests_list
+    find src/ -type d -a \( -name testdata -o -ipath '*/testdata/*' \) -printf '%%%dir %{goroot}/%p\n' >> $tests_list
+    find src/ ! -type d -a \( -ipath '*/testdata/*' -o -name '*_test*.go' \) -printf '%{goroot}/%p\n' >> $tests_list
+    # this is only the zoneinfo.zip
+    find lib/ -type d -printf '%%%dir %{goroot}/%p\n' >> $tests_list
+    find lib/ ! -type d -printf '%{goroot}/%p\n' >> $tests_list
+popd
+
+# remove the doc Makefile
+rm -rfv $RPM_BUILD_ROOT%{goroot}/doc/Makefile
+
+# put binaries to bindir, linked to the arch we're building,
+# leave the arch independent pieces in {goroot}
+mkdir -p $RPM_BUILD_ROOT%{goroot}/bin/linux_%{gohostarch}
+ln -sf %{goroot}/bin/go $RPM_BUILD_ROOT%{_bindir}/go
+ln -sf %{goroot}/bin/gofmt $RPM_BUILD_ROOT%{_bindir}/gofmt
+
+# ensure these exist and are owned
+mkdir -p $RPM_BUILD_ROOT%{gopath}/src/github.com
+mkdir -p $RPM_BUILD_ROOT%{gopath}/src/bitbucket.org
+mkdir -p $RPM_BUILD_ROOT%{gopath}/src/code.google.com/p
+mkdir -p $RPM_BUILD_ROOT%{gopath}/src/golang.org/x
+
+# gdbinit
+mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/gdbinit.d
+cp -av %{SOURCE100} $RPM_BUILD_ROOT%{_sysconfdir}/gdbinit.d/golang.gdb
+
+# prelink blacklist
+mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/prelink.conf.d
+cp -av %{SOURCE101} $RPM_BUILD_ROOT%{_sysconfdir}/prelink.conf.d/golang.conf
+sed -i 's/const defaultGO_LDSO = `.*`/const defaultGO_LDSO = ``/' $RPM_BUILD_ROOT%{goroot}/src/internal/buildcfg/zbootstrap.go
+
+%check
+export GOROOT=$(pwd -P)
+export PATH="$GOROOT"/bin:"$PATH"
+cd src
+
+# Add some sanity checks.
+echo "GO VERSION:"
+go version
+
+echo "GO ENVIRONMENT:"
+go env
+
+export CC="gcc"
+export CFLAGS="$RPM_OPT_FLAGS"
+export LDFLAGS="$RPM_LD_FLAGS"
+%if !%{external_linker}
+export GO_LDFLAGS="-linkmode internal"
+%else
+export GO_LDFLAGS="-extldflags '$RPM_LD_FLAGS'"
+%endif
+%if !%{cgo_enabled} || !%{external_linker}
+export CGO_ENABLED=0
+%endif
+
+# work around aarch64 issue
+# https://src.fedoraproject.org/rpms/golang/c/ea99ebaff6b9561243bb43039458771edb691eaf?branch=f32
+%ifarch aarch64
+export CGO_CFLAGS="-mno-outline-atomics"
+%endif
+
+# make sure to not timeout
+export GO_TEST_TIMEOUT_SCALE=2
+
+export GO_TEST_RUN=""
+%ifarch aarch64
+  export GO_TEST_RUN="-run=!testshared"
+%endif
+
+%if %{fail_on_tests}
+
+./run.bash --no-rebuild -v -v -v -k $GO_TEST_RUN
+
+export OPENSSL_FORCE_FIPS_MODE=1
+# Run tests with FIPS enabled.
+pushd crypto
+  # Run all crypto tests but skip TLS, we will run FIPS specific TLS tests later
+  GOLANG_FIPS=1 go test $(go list ./... | grep -v tls) -v
+  # Check that signature functions have parity between boring and notboring
+  CGO_ENABLED=0 go test $(go list ./... | grep -v tls) -v
+popd
+# Run all FIPS specific TLS tests
+pushd crypto/tls
+  GOLANG_FIPS=1 go test -v -run "Boring"
+popd
+%else
+./run.bash --no-rebuild -v -v -v -k || :
+%endif
+cd ..
+
+%files
+
+%doc AUTHORS CONTRIBUTORS LICENSE PATENTS
+# VERSION has to be present in the GOROOT, for `go install std` to work
+%doc %{goroot}/VERSION
+%dir %{goroot}/doc
+%doc %{goroot}/doc/*
+
+# go files
+%dir %{goroot}
+%exclude %{goroot}/bin/
+%exclude %{goroot}/pkg/
+%exclude %{goroot}/src/
+%exclude %{goroot}/doc/
+%exclude %{goroot}/misc/
+%exclude %{goroot}/test/
+%{goroot}/*
+
+# ensure directory ownership, so they are cleaned up if empty
+%dir %{gopath}
+%dir %{gopath}/src
+%dir %{gopath}/src/github.com/
+%dir %{gopath}/src/bitbucket.org/
+%dir %{gopath}/src/code.google.com/
+%dir %{gopath}/src/code.google.com/p/
+%dir %{gopath}/src/golang.org
+%dir %{gopath}/src/golang.org/x
+
+# gdbinit (for gdb debugging)
+%{_sysconfdir}/gdbinit.d
+
+# prelink blacklist
+%{_sysconfdir}/prelink.conf.d
+
+
+%files -f go-src.list src
+
+%files -f go-docs.list docs
+
+%files -f go-misc.list misc
+
+%files -f go-tests.list tests
+
+%files -f go-pkg.list bin
+%{_bindir}/go
+%{_bindir}/gofmt
+
+%if %{shared}
+%files -f go-shared.list shared
+%endif
+
+%if %{race}
+%files -f go-race.list race
+%endif
+
+%changelog
+* Thu Feb 17 2022 David Benoit <dbenoit@redhat.com> - 1.17.7-1
+- Rebase to Go 1.17.7
+- Update ecdsa tests to reject SHA1 signatures in boring mode
+- Resolves: rhbz#2025637
+- Resolves: rhbz#1975396
+
+* Mon Dec 13 2021 Alejandro Sáez <asm@redhat.com> - 1.17.5-1
+- Rebase to Go 1.17.5
+- Add remove_waitgroup_misuse_tests patch
+- Add remove_ed25519vectors_test.patch
+- Remove FIPS checks to avoid issues in the CI
+- Related: rhbz#2031116
+- Resolves: rhbz#2022829
+- Resolves: rhbz#2024687
+- Resolves: rhbz#2030851
+- Resolves: rhbz#2031253
+
+* Wed Nov 03 2021 Alejandro Sáez <asm@redhat.com> - 1.17.2-1
+- Rebase to Go 1.17.2
+- Related: rhbz#2014087
+- Remove favicon.ico and robots.txt references
+- Exclude TestEd25519Vectors test
+- Update patch rhbz1952381
+- Remove rhbz1904567 patch
+- Remove rhbz1939923 patch
+
+* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 1.16.6-4
+- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
+  Related: rhbz#1991688
+
+* Wed Aug 4 2021 Derek Parker <deparker@redhat.com> - 1.16.6-3
+- Include ppc64le VDSO segfault backport fix
+- Resolves: rhbz#1966622
+
+* Mon Aug 2 2021 Derek Parker <deparker@redhat.com> - 1.16.6-2
+- Bump release
+- Resolves: rhbz#1904567
+
+* Mon Aug 2 2021 Derek Parker <deparker@redhat.com> - 1.16.6-2
+- Backport fix allowing LTO to be enabled on cgo sources
+- Resolves: rhbz#1904567
+
+* Tue Jul 20 2021 Derek Parker <deparker@redhat.com> - 1.16.6-1
+- Rebase to 1.16.6
+- Resolves: rhbz#1984124
+- Replace symbols no longer present in OpenSSL 3.0 ABI
+- Resolves: rhbz#1984110
+- Fix TestBoringServerCurves failing when ran by itself
+- Resolves: rhbz#1977914
+
+* Tue Jun 22 2021 Mohan Boddu <mboddu@redhat.com> - 1.16.4-3
+- Rebuilt for RHEL 9 BETA for openssl 3.0
+  Related: rhbz#1971065
+
+* Fri May 28 2021 David Benoit <dbenoit@redhat.com> - 1.16.4-2
+- Port to OpenSSL 3.0
+- Resolves: rhbz#1952381
+
+* Fri May 14 2021 Alejandro Sáez <asm@redhat.com> - 1.16.4-1
+- Rebase to 1.16.4
+- Resolves: rhbz#1955035
+- Resolves: rhbz#1957961
+
+* Thu Apr 15 2021 Mohan Boddu <mboddu@redhat.com> - 1.16.1-3
+- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
+
+* Tue Mar 30 2021 Alejandro Sáez <asm@redhat.com> - 1.16.1-2
+- Rebase to go-1.16.1-2-openssl-fips
+- Resolves: rhbz#1922455
+
+* Tue Mar 30 2021 Alejandro Sáez <asm@redhat.com> - 1.16.1-1
+- Rebase to go-1.16.1-2-openssl-fips
+- Adds a workaround for rhbz#1939923
+- Removes Patch224, it's on upstream -> rhbz#1888673
+- Removes Patch225, it's on upstream -> https://go-review.googlesource.com/c/text/+/238238
+- Removes old patches for cleaning purposes
+- Related: rhbz#1942898
+
+* Fri Jan 22 2021 David Benoit <dbenoit@redhat.com> - 1.15.7-1
+- Rebase to 1.15.7
+- Resolves: rhbz#1892207
+- Resolves: rhbz#1918755
+
+* Tue Nov 24 2020 David Benoit <dbenoit@redhat.com> - 1.15.5-1
+- Rebase to 1.15.5
+- Resolves: rhbz#1899184
+- Resolves: rhbz#1899185
+- Resolves: rhbz#1899186
+
+* Thu Nov 12 2020 David Benoit <dbenoit@redhat.com> - 1.15.3-2
+- Rebase to 1.15.3
+- fix x/text infinite loop
+- Resolves: rhbz#1881539
+
+* Tue Nov 03 2020 Alejandro Sáez <asm@redhat.com> - 1.15.2-2
+- Resolves: rhbz#1850045
+
+* Mon Oct 19 2020 David Benoit <dbenoit@redhat.com> - 1.15.2-1
+- Rebase to 1.15.2
+- fix rhbz#1872622 in commit af9a1b1f6567a1c5273a134d395bfe7bb840b7f8
+- Resolves: rhbz#1872622
+- add net/http graceful shutdown patch
+- Resolves: rhbz#1888673
+- add x509warnCN patch
+- Resolves: rhbz#1889437
+
+* Wed Sep 09 2020 Alejandro Sáez <asm@redhat.com> - 1.15.0-1
+- Rebase to 1.15.0
+- Related: rhbz#1870531
+
+* Thu Aug 27 2020 Alejandro Sáez <asm@redhat.com> - 1.14.7-2
+- Improve test suite
+- Resolves: rhbz#1854693
+
+* Tue Aug 18 2020 Alejandro Sáez <asm@redhat.com> - 1.14.7-1
+- Rebase to 1.14.7
+
+* Mon Aug 03 2020 Alejandro Sáez <asm@redhat.com> - 1.14.6-1
+- Rebase to 1.14.6
+- Resolves: rhbz#1820596
+
+* Wed Jul 08 2020 Alejandro Sáez <asm@redhat.com> - 1.14.4-2
+- Include patch to fix missing deferreturn on linux/ppc64le
+- Resolves: rhbz#1854836
+
+* Thu Jun 25 2020 Alejandro Sáez <asm@redhat.com> - 1.14.4-1
+- Rebase to 1.14.4
+
+* Thu May 21 2020 Alejandro Sáez <asm@redhat.com> - 1.14.2-2
+- Remove i686 references
+- Related: rhbz#1752991
+
+* Wed May 06 2020 Alejandro Sáez <asm@redhat.com> - 1.14.2-1
+- Rebase to 1.14.2
+- Related: rhbz#1820596
+
+* Wed Nov 27 2019 Alejandro Sáez <asm@redhat.com> - 1.13.4-2
+- Remove patches
+- Related: rhbz#1747150
+
+* Mon Nov 25 2019 Alejandro Sáez <asm@redhat.com> - 1.13.4-1
+- Rebase to 1.13.4
+- Related: rhbz#1747150
+
+* Tue Sep 17 2019 Tom Stellard <tstellar@redhat.com> - 1.12.8-4
+- Reduce number of threads when testing on i686
+
+* Wed Sep 11 2019 Tom Stellard <tstellar@redhat.com> - 1.12.8-3
+- Relax FIPS requirements to unblock OpenShift testing
+
+* Wed Aug 28 2019 Tom Stellard <tstellar@redhat.com> - 1.12.8-2
+- Rebase to 1.12.8
+- Resolves: rhbz#1745706
+- Resolves: rhbz#1745712
+
+* Mon Aug 5 2019 Derek Parker <deparker@redhat.com> - 1.12.6-3
+- Add README for more documentation
+- Resolves: rhbz#1734788
+
+* Fri Aug 2 2019 Derek Parker <deparker@redhat.com> - 1.12.6-3
+- Revert some TLS FIPS changes for now
+- Resolves: rhbz#1734788
+
+* Thu Aug 1 2019 Derek Parker <deparker@redhat.com> - 1.12.6-2
+- Updates to be less strict on key size in FIPS mode
+- Resolves: rhbz#1734788
+
+* Thu Jun 13 2019 Derek Parker <deparker@redhat.com> - 1.12.6-1
+- Rebase to 1.12.6
+- Resolves: rhbz#1677819
+
+* Thu Jun 13 2019 Derek Parker <deparker@redhat.com> - 1.12.5-2
+- Remove macros present in go-compiler
+- Resolves: rhbz#1700109
+
+* Wed Jun 12 2019 Derek Parker <deparker@redhat.com> - 1.12.5-1
+- Rebase to 1.12.5
+- Resolves: rhbz#1677819
+
+* Wed May 29 2019 Derek Parker <deparker@redhat.com> - 1.12.1-2
+- Lock OpenSSL to specific built version and include more initialization.
+- Resolves: rhbz#1709603
+
+* Fri May 10 2019 Derek Parker <deparker@redhat.com> - 1.12.1-1
+- Rebase to 1.12.1
+- Include FIPS compliance updates
+- Resolves: rhbz#1709603
+
+* Thu Apr 4 2019 Derek Parker <deparker@redhat.com> - 1.11.5-2
+- Include patch to fix CVE-2019-9741
+- Resolves: rhbz#1690443
+
+* Mon Feb 18 2019 Derek Parker <deparker@redhat.com> - 1.11.5-2
+- Switch to pagure fork for Go FIPS
+
+* Thu Feb 7 2019 Derek Parker <deparker@redhat.com> - 1.11.5-1
+- Rebase to Go 1.11.5
+- Resolves: rhbz#1671277
+- Fixes CVE-2019-6486
+
+* Thu Jan 3 2019 Derek Parker <deparker@redhat.com> - 1.11.4-1
+- Rebase to Go 1.11.4
+- Fixes CVE-2018-16873, CVE-2018-16874, CVE-2018-16875
+
+* Thu Dec 6 2018 Derek Parker <deparker@redhat.com> - 1.11.2-1
+- Rebase to Go 1.11.2
+
+* Fri Nov 16 2018 Derek Parker <deparker@redhat.com> - 1.10.3-18
+- Remove SCL from macros
+
+* Wed Nov 7 2018 Derek Parker <deparker@redhat.com> - 1.10.3-17
+- Prefer go-toolset over go-toolset-1.10
+- Resolves: rhbz#1630786
+
+* Mon Nov 5 2018 Derek Parker <deparker@redhat.com> - 1.10.3-16
+- Fix implicit syscall declaration warning
+
+* Mon Nov 5 2018 Derek Parker <deparker@redhat.com> - 1.10.3-15
+- Remove usage of redhat hardening flag file, just pass a select few manually
+- Resolves: rhbz#1642798
+
+* Wed Oct 31 2018 Derek Parker <deparker@redhat.com> - 1.10.3-14
+- Do not build toolchain in PIE mode
+- Resolves: rhbz#1642798
+
+* Fri Oct 26 2018 Derek Parker <deparker@redhat.com> - 1.10.3-13
+- Fix setting of internal FIPS enabled flag
+- Resolves: rhbz#1643653
+
+* Wed Oct 10 2018 Derek Parker <deparker@redhat.com> - 1.10.3-12
+- Pass external linker flags to fix annocheck errors
+- Resolves: rhbz#1624421
+
+* Wed Oct 10 2018 Derek Parker <deparker@redhat.com> - 1.10.3-11
+- Fix UnreachableExceptTests false panic
+- Resolves: rhbz#1634748
+
+* Fri Oct 5 2018 Derek Parker <deparker@redhat.com> - 1.10.3-10
+- Remove SCL, fix bug in boringcrypto with ecdsa
+- Related: rhbz#1635066
+- Resolves: rhbz#1636221
+
+* Wed Sep 26 2018 Derek Parker <deparker@redhat.com> - 1.10.3-9
+- Add runtime FIPS detection patches
+- Resolves: rhbz#1633351
+
+* Fri Sep 21 2018 Derek Parker <deparker@redhat.com> - 1.10.3-8
+- Add `gobuild` and `gotest` macros from go-compilers
+- Resolves: rhbz#1631846
+
+* Thu Sep 20 2018 Derek Parker <deparker@redhat.com> - 1.10.3-7
+- Bootstrap package using old build of same package
+- Resolves: rhbz#1630786
+
+* Mon Aug 13 2018 Derek Parker <deparker@redhat.com> - 1.10.3-6
+- Update stack allocation of OpenSSL type patch
+- Resolves: rhbz#1615032
+
+* Sat Aug 11 2018 Troy Dawson <tdawson@redhat.com> - 1.10.3-5
+- Build on i686
+- Related: bug#1614611
+
+* Tue Aug 7 2018 Derek Parker <deparker@redhat.com> - 1.10.3-4
+- Add patch fixing stack allocation of opaque OpenSSL type bug.
+- Resolves: rhbz#1613538
+
+* Thu Aug 2 2018 Derek Parker <deparker@redhat.com> - 1.10.3-3
+- Add patch with tag to opt out of OpenSSL during build
+
+* Wed Jul 25 2018 Derek Parker <deparker@redhat.com> - 1.10.3-2
+- Add runtime requirement for openssl-devel and misc updates
+
+* Tue Jul 24 2018 Derek Parker <deparker@redhat.com> - 1.10.3-1
+- Bump to 1.10.3
+
+* Tue Jul 24 2018 Derek Parker <deparker@redhat.com> - 1.10.2-3
+- Prepare for module build
+
+* Wed Jun 27 2018 Derek Parker <deparker@redhat.com> - 1.10.2-2
+- Include FIPS patches
+
+* Wed May 23 2018 Derek Parker <deparker@redhat.com> - 1.10.2-1
+- Bump to Go 1.10.2
+
+* Thu Mar 15 2018 Derek Parker <deparker@redhat.com> - 1.10-1
+- Bump to Go 1.10
+
+* Wed Oct 18 2017 Jakub Čajka <jcajka@redhat.com> - 1.8.5-1
+- Fix CVE-2017-15041 and CVE-2017-15042
+- Resolves: BZ#1499160, BZ#1498073, BZ#1512063
+
+* Thu Aug 31 2017 Tom Stellard <tstellar@redhat.com> - 1.8.3-4
+- Explicitly require /usr/bin/gcc
+- Resolves: #1487345
+
+* Thu Jun 22 2017 Jakub Čajka <jcajka@redhat.com> - 1.8.3-3
+- apply asn1 patch
+- add ppc64le trampolines patch
+
+* Wed Jun 14 2017 Jakub Čajka <jcajka@redhat.com> - 1.8.3-2
+- regular GTS build
+
+* Tue Jun 06 2017 Jakub Čajka <jcajka@redhat.com> - 1.8.3-1
+- initial GTS build
+
+* Fri Feb 10 2017 Fedora Release Engineering <releng@fedoraproject.org> - 1.8-0.rc3.2.1
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
+
+* Fri Jan 27 2017 Jakub Čajka <jcajka@redhat.com> - 1.8-0.rc3.2
+- make possible to override default traceback level at build time
+- add sub-package race containing std lib built with -race enabled
+- Related: BZ#1411242
+
+* Fri Jan 27 2017 Jakub Čajka <jcajka@redhat.com> - 1.8-0.rc3.1
+- rebase to go1.8rc3
+- Resolves: BZ#1411242
+
+* Fri Jan 20 2017 Jakub Čajka <jcajka@redhat.com> - 1.7.4-2
+- Resolves: BZ#1404679
+- expose IfInfomsg.X__ifi_pad on s390x
+
+* Fri Dec 02 2016 Jakub Čajka <jcajka@redhat.com> - 1.7.4-1
+- Bump to 1.7.4
+- Resolves: BZ#1400732
+
+* Thu Nov 17 2016 Tom Callaway <spot@fedoraproject.org> - 1.7.3-2
+- re-enable the NIST P-224 curve
+
+* Thu Oct 20 2016 Jakub Čajka <jcajka@redhat.com> - 1.7.3-1
+- Resolves: BZ#1387067 - golang-1.7.3 is available
+- added fix for tests failing with latest tzdata
+
+* Fri Sep 23 2016 Jakub Čajka <jcajka@redhat.com> - 1.7.1-2
+- fix link failure due to relocation overflows on PPC64X
+
+* Thu Sep 08 2016 Jakub Čajka <jcajka@redhat.com> - 1.7.1-1
+- rebase to 1.7.1
+- Resolves: BZ#1374103
+
+* Tue Aug 23 2016 Jakub Čajka <jcajka@redhat.com> - 1.7-1
+- update to released version
+- related: BZ#1342090, BZ#1357394
+
+* Mon Aug 08 2016 Jakub Čajka <jcajka@redhat.com> - 1.7-0.3.rc5
+- Obsolete golang-vet and golang-cover from golang-googlecode-tools package
+  vet/cover binaries are provided by golang-bin rpm (thanks to jchaloup)
+- clean up exclusive arch after s390x boostrap
+- resolves: #1268206
+
+* Wed Aug 03 2016 Jakub Čajka <jcajka@redhat.com> - 1.7-0.2.rc5
+- rebase to go1.7rc5
+- Resolves: BZ#1342090
+
+* Thu Jul 21 2016 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.7-0.1.rc2
+- https://fedoraproject.org/wiki/Changes/golang1.7
+
+* Tue Jul 19 2016 Jakub Čajka <jcajka@redhat.com> - 1.7-0.0.rc2
+- rebase to 1.7rc2
+- added s390x build
+- improved shared lib packaging
+- Resolves: bz1357602 - CVE-2016-5386
+- Resolves: bz1342090, bz1342090
+
+* Tue Apr 26 2016 Jakub Čajka <jcajka@redhat.com> - 1.6.2-1
+- rebase to 1.6.2
+- Resolves: bz1329206 - golang-1.6.2.src is available
+
+* Wed Apr 13 2016 Jakub Čajka <jcajka@redhat.com> - 1.6.1-1
+- rebase to 1.6.1
+- Resolves: bz1324344 - CVE-2016-3959
+- Resolves: bz1324951 - prelink is gone, /etc/prelink.conf.d/* is no longer used
+- Resolves: bz1326366 - wrong epoll_event struct for ppc64le/ppc64
+
+* Mon Feb 22 2016 Jakub Čajka <jcajka@redhat.com> - 1.6-1
+- Resolves: bz1304701 - rebase to go1.6 release
+- Resolves: bz1304591 - fix possible stack miss-alignment in callCgoMmap
+
+* Wed Feb 03 2016 Fedora Release Engineering <releng@fedoraproject.org> - 1.6-0.3.rc1
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
+
+* Fri Jan 29 2016 Jakub Čajka <jcajka@redhat.com> - 1.6-0.2.rc1
+- disabled cgo and external linking on ppc64
+
+* Thu Jan 28 2016 Jakub Čajka <jcajka@redhat.com> - 1.6-0.1.rc1
+- Resolves bz1292640, rebase to pre-release 1.6
+- bootstrap for PowerPC
+- fix rpmlint errors/warning
+
+* Thu Jan 14 2016 Jakub Čajka <jcajka@redhat.com> - 1.5.3-1
+- rebase to 1.5.3
+- resolves bz1293451, CVE-2015-8618
+- apply timezone patch, avoid using bundled data
+- print out rpm build system info
+
+* Fri Dec 11 2015 Jakub Čajka <jcajka@redhat.com> - 1.5.2-2
+- bz1290543 Accept x509 certs with negative serial
+
+* Tue Dec 08 2015 Jakub Čajka <jcajka@redhat.com> - 1.5.2-1
+- bz1288263 rebase to 1.5.2
+- spec file clean up
+- added build options
+- scrubbed "Project Gutenberg License"
+
+* Mon Oct 19 2015 Vincent Batts <vbatts@fedoraproject.org> - 1.5.1-1
+- bz1271709 include patch from upstream fix
+
+* Wed Sep 09 2015 Vincent Batts <vbatts@fedoraproject.org> - 1.5.1-0
+- update to go1.5.1
+
+* Fri Sep 04 2015 Vincent Batts <vbatts@fedoraproject.org> - 1.5-8
+- bz1258166 remove srpm macros, for go-srpm-macros
+
+* Thu Sep 03 2015 Vincent Batts <vbatts@fedoraproject.org> - 1.5-7
+- bz1258166 remove srpm macros, for go-srpm-macros
+
+* Thu Aug 27 2015 Vincent Batts <vbatts@fedoraproject.org> - 1.5-6
+- starting a shared object subpackage. This will be x86_64 only until upstream supports more arches shared objects.
+
+* Thu Aug 27 2015 Vincent Batts <vbatts@fedoraproject.org> - 1.5-5
+- bz991759 gdb path fix
+
+* Wed Aug 26 2015 Vincent Batts <vbatts@fedoraproject.org> - 1.5-4
+- disable shared object until linux/386 is ironned out
+- including the test/ directory for tests
+
+* Tue Aug 25 2015 Vincent Batts <vbatts@fedoraproject.org> - 1.5-3
+- bz1256910 only allow the golang zoneinfo.zip to be used in tests
+- bz1166611 add golang.org/x directory
+- bz1256525 include stdlib shared object. This will let other libraries and binaries
+  build with `go build -buildmode=shared -linkshared ...` or similar.
+
+* Sun Aug 23 2015 Peter Robinson <pbrobinson@fedoraproject.org> 1.5-2
+- Enable aarch64
+- Minor cleanups
+
+* Thu Aug 20 2015 Vincent Batts <vbatts@fedoraproject.org> - 1.5-1
+- updating to go1.5
+
+* Thu Aug 06 2015 Vincent Batts <vbatts@fedoraproject.org> - 1.5-0.11.rc1
+- fixing the sources reference
+
+* Thu Aug 06 2015 Vincent Batts <vbatts@fedoraproject.org> - 1.5-0.10.rc1
+- updating to go1.5rc1
+- checks are back in place
+
+* Tue Aug 04 2015 Vincent Batts <vbatts@fedoraproject.org> - 1.5-0.9.beta3
+- pull in upstream archive/tar fix
+
+* Thu Jul 30 2015 Vincent Batts <vbatts@fedoraproject.org> - 1.5-0.8.beta3
+- updating to go1.5beta3
+
+* Thu Jul 30 2015 Vincent Batts <vbatts@fedoraproject.org> - 1.5-0.7.beta2
+- add the patch ..
+
+* Thu Jul 30 2015 Vincent Batts <vbatts@fedoraproject.org> - 1.5-0.6.beta2
+- increase ELFRESERVE (bz1248071)
+
+* Tue Jul 28 2015 Lokesh Mandvekar <lsm5@fedoraproject.org> - 1.5-0.5.beta2
+- correct package version and release tags as per naming guidelines
+
+* Fri Jul 17 2015 Vincent Batts <vbatts@fedoraproject.org> - 1.4.99-4.1.5beta2
+- adding test output, for visibility
+
+* Fri Jul 10 2015 Vincent Batts <vbatts@fedoraproject.org> - 1.4.99-3.1.5beta2
+- updating to go1.5beta2
+
+* Fri Jul 10 2015 Vincent Batts <vbatts@fedoraproject.org> - 1.4.99-2.1.5beta1
+- add checksum to sources and fixed one patch
+
+* Fri Jul 10 2015 Vincent Batts <vbatts@fedoraproject.org> - 1.4.99-1.1.5beta1
+- updating to go1.5beta1
+
+* Wed Jun 17 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.4.2-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
+
+* Wed Mar 18 2015 Vincent Batts <vbatts@fedoraproject.org> - 1.4.2-2
+- obsoleting deprecated packages
+
+* Wed Feb 18 2015 Vincent Batts <vbatts@fedoraproject.org> - 1.4.2-1
+- updating to go1.4.2
+
+* Fri Jan 16 2015 Vincent Batts <vbatts@fedoraproject.org> - 1.4.1-1
+- updating to go1.4.1
+
+* Fri Jan 02 2015 Vincent Batts <vbatts@fedoraproject.org> - 1.4-2
+- doc organizing
+
+* Thu Dec 11 2014 Vincent Batts <vbatts@fedoraproject.org> - 1.4-1
+- update to go1.4 release
+
+* Wed Dec 03 2014 Vincent Batts <vbatts@fedoraproject.org> - 1.3.99-3.1.4rc2
+- update to go1.4rc2
+
+* Mon Nov 17 2014 Vincent Batts <vbatts@fedoraproject.org> - 1.3.99-2.1.4rc1
+- update to go1.4rc1
+
+* Thu Oct 30 2014 Vincent Batts <vbatts@fedoraproject.org> - 1.3.99-1.1.4beta1
+- update to go1.4beta1
+
+* Thu Oct 30 2014 Vincent Batts <vbatts@fedoraproject.org> - 1.3.3-3
+- macros will need to be in their own rpm
+
+* Fri Oct 24 2014 Vincent Batts <vbatts@fedoraproject.org> - 1.3.3-2
+- split out rpm macros (bz1156129)
+- progress on gccgo accomodation
+
+* Wed Oct 01 2014 Vincent Batts <vbatts@fedoraproject.org> - 1.3.3-1
+- update to go1.3.3 (bz1146882)
+
+* Mon Sep 29 2014 Vincent Batts <vbatts@fedoraproject.org> - 1.3.2-1
+- update to go1.3.2 (bz1147324)
+
+* Thu Sep 11 2014 Vincent Batts <vbatts@fedoraproject.org> - 1.3.1-3
+- patching the tzinfo failure
+
+* Sat Aug 16 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.3.1-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
+
+* Wed Aug 13 2014 Vincent Batts <vbatts@fedoraproject.org> - 1.3.1-1
+- update to go1.3.1
+
+* Wed Aug 13 2014 Vincent Batts <vbatts@fedoraproject.org> - 1.3-11
+- merged a line wrong
+
+* Wed Aug 13 2014 Vincent Batts <vbatts@fedoraproject.org> - 1.3-10
+- more work to get cgo.a timestamps to line up, due to build-env
+- explicitly list all the files and directories for the source and packages trees
+- touch all the built archives to be the same
+
+* Mon Aug 11 2014 Vincent Batts <vbatts@fedoraproject.org> - 1.3-9
+- make golang-src 'noarch' again, since that was not a fix, and takes up more space
+
+* Mon Aug 11 2014 Vincent Batts <vbatts@fedoraproject.org> - 1.3-8
+- update timestamps of source files during %%install bz1099206
+
+* Fri Aug 08 2014 Vincent Batts <vbatts@fedoraproject.org> - 1.3-7
+- update timestamps of source during %%install bz1099206
+
+* Wed Aug 06 2014 Vincent Batts <vbatts@fedoraproject.org> - 1.3-6
+- make the source subpackage arch'ed, instead of noarch
+
+* Mon Jul 21 2014 Vincent Batts <vbatts@fedoraproject.org> - 1.3-5
+- fix the writing of pax headers
+
+* Tue Jul 15 2014 Vincent Batts <vbatts@fedoraproject.org> - 1.3-4
+- fix the loading of gdb safe-path. bz981356
+
+* Tue Jul 08 2014 Vincent Batts <vbatts@fedoraproject.org> - 1.3-3
+- `go install std` requires gcc, to build cgo. bz1105901, bz1101508
+
+* Mon Jul 07 2014 Vincent Batts <vbatts@fedoraproject.org> - 1.3-2
+- archive/tar memory allocation improvements
+
+* Thu Jun 19 2014 Vincent Batts <vbatts@fedoraproject.org> - 1.3-1
+- update to go1.3
+
+* Fri Jun 13 2014 Vincent Batts <vbatts@fedoraproject.org> - 1.3rc2-1
+- update to go1.3rc2
+
+* Sat Jun 07 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.3rc1-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
+
+* Tue Jun 03 2014 Vincent Batts <vbatts@redhat.com> 1.3rc1-1
+- update to go1.3rc1
+- new arch file shuffling
+
+* Wed May 21 2014 Vincent Batts <vbatts@redhat.com> 1.3beta2-1
+- update to go1.3beta2
+- no longer provides go-mode for xemacs (emacs only)
+
+* Wed May 21 2014 Vincent Batts <vbatts@redhat.com> 1.2.2-7
+- bz1099206 ghost files are not what is needed
+
+* Tue May 20 2014 Vincent Batts <vbatts@redhat.com> 1.2.2-6
+- bz1099206 more fixing. The packages %%post need golang-bin present first
+
+* Tue May 20 2014 Vincent Batts <vbatts@redhat.com> 1.2.2-5
+- bz1099206 more fixing. Let go fix its own timestamps and freshness
+
+* Tue May 20 2014 Vincent Batts <vbatts@redhat.com> 1.2.2-4
+- fix the existence and alternatives of `go` and `gofmt`
+
+* Mon May 19 2014 Vincent Batts <vbatts@redhat.com> 1.2.2-3
+- bz1099206 fix timestamp issue caused by koji builders
+
+* Fri May 09 2014 Vincent Batts <vbatts@redhat.com> 1.2.2-2
+- more arch file shuffling
+
+* Fri May 09 2014 Vincent Batts <vbatts@redhat.com> 1.2.2-1
+- update to go1.2.2
+
+* Thu May 08 2014 Vincent Batts <vbatts@redhat.com> 1.2.1-8
+- RHEL6 rpm macros can't %%exlude missing files
+
+* Wed May 07 2014 Vincent Batts <vbatts@redhat.com> 1.2.1-7
+- missed two arch-dependent src files
+
+* Wed May 07 2014 Vincent Batts <vbatts@redhat.com> 1.2.1-6
+- put generated arch-dependent src in their respective RPMs
+
+* Fri Apr 11 2014 Vincent Batts <vbatts@redhat.com> 1.2.1-5
+- skip test that is causing a SIGABRT on fc21 bz1086900
+
+* Thu Apr 10 2014 Vincent Batts <vbatts@fedoraproject.org> 1.2.1-4
+- fixing file and directory ownership bz1010713
+
+* Wed Apr 09 2014 Vincent Batts <vbatts@fedoraproject.org> 1.2.1-3
+- including more to macros (%%go_arches)
+- set a standard goroot as /usr/lib/golang, regardless of arch
+- include sub-packages for compiler toolchains, for all golang supported architectures
+
+* Wed Mar 26 2014 Vincent Batts <vbatts@fedoraproject.org> 1.2.1-2
+- provide a system rpm macros. Starting with gopath
+
+* Tue Mar 04 2014 Adam Miller <maxamillion@fedoraproject.org> 1.2.1-1
+- Update to latest upstream
+
+* Thu Feb 20 2014 Adam Miller <maxamillion@fedoraproject.org> 1.2-7
+- Remove  _BSD_SOURCE and _SVID_SOURCE, they are deprecated in recent
+  versions of glibc and aren't needed
+
+* Wed Feb 19 2014 Adam Miller <maxamillion@fedoraproject.org> 1.2-6
+- pull in upstream archive/tar implementation that supports xattr for
+  docker 0.8.1
+
+* Tue Feb 18 2014 Vincent Batts <vbatts@redhat.com> 1.2-5
+- provide 'go', so users can yum install 'go'
+
+* Fri Jan 24 2014 Vincent Batts <vbatts@redhat.com> 1.2-4
+- skip a flaky test that is sporadically failing on the build server
+
+* Thu Jan 16 2014 Vincent Batts <vbatts@redhat.com> 1.2-3
+- remove golang-godoc dependency. cyclic dependency on compiling godoc
+
+* Wed Dec 18 2013 Vincent Batts <vbatts@redhat.com> - 1.2-2
+- removing P224 ECC curve
+
+* Mon Dec 2 2013 Vincent Batts <vbatts@fedoraproject.org> - 1.2-1
+- Update to upstream 1.2 release
+- remove the pax tar patches
+
+* Tue Nov 26 2013 Vincent Batts <vbatts@redhat.com> - 1.1.2-8
+- fix the rpmspec conditional for rhel and fedora
+
+* Thu Nov 21 2013 Vincent Batts <vbatts@redhat.com> - 1.1.2-7
+- patch tests for testing on rawhide
+- let the same spec work for rhel and fedora
+
+* Wed Nov 20 2013 Vincent Batts <vbatts@redhat.com> - 1.1.2-6
+- don't symlink /usr/bin out to ../lib..., move the file
+- seperate out godoc, to accomodate the go.tools godoc
+
+* Fri Sep 20 2013 Adam Miller <maxamillion@fedoraproject.org> - 1.1.2-5
+- Pull upstream patches for BZ#1010271
+- Add glibc requirement that got dropped because of meta dep fix
+
+* Fri Aug 30 2013 Adam Miller <maxamillion@fedoraproject.org> - 1.1.2-4
+- fix the libc meta dependency (thanks to vbatts [at] redhat.com for the fix)
+
+* Tue Aug 27 2013 Adam Miller <maxamillion@fedoraproject.org> - 1.1.2-3
+- Revert incorrect merged changelog
+
+* Tue Aug 27 2013 Adam Miller <maxamillion@fedoraproject.org> - 1.1.2-2
+- This was reverted, just a placeholder changelog entry for bad merge
+
+* Tue Aug 20 2013 Adam Miller <maxamillion@fedoraproject.org> - 1.1.2-1
+- Update to latest upstream
+
+* Sat Aug 03 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.1.1-7
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
+
+* Wed Jul 17 2013 Petr Pisar <ppisar@redhat.com> - 1.1.1-6
+- Perl 5.18 rebuild
+
+* Wed Jul 10 2013 Adam Goode <adam@spicenitz.org> - 1.1.1-5
+- Blacklist testdata files from prelink
+- Again try to fix #973842
+
+* Fri Jul  5 2013 Adam Goode <adam@spicenitz.org> - 1.1.1-4
+- Move src to libdir for now (#973842) (upstream issue https://code.google.com/p/go/issues/detail?id=5830)
+- Eliminate noarch data package to work around RPM bug (#975909)
+- Try to add runtime-gdb.py to the gdb safe-path (#981356)
+
+* Wed Jun 19 2013 Adam Goode <adam@spicenitz.org> - 1.1.1-3
+- Use lua for pretrans (http://fedoraproject.org/wiki/Packaging:Guidelines#The_.25pretrans_scriptlet)
+
+* Mon Jun 17 2013 Adam Goode <adam@spicenitz.org> - 1.1.1-2
+- Hopefully really fix #973842
+- Fix update from pre-1.1.1 (#974840)
+
+* Thu Jun 13 2013 Adam Goode <adam@spicenitz.org> - 1.1.1-1
+- Update to 1.1.1
+- Fix basically useless package (#973842)
+
+* Sat May 25 2013 Dan Horák <dan[at]danny.cz> - 1.1-3
+- set ExclusiveArch
+
+* Fri May 24 2013 Adam Goode <adam@spicenitz.org> - 1.1-2
+- Fix noarch package discrepancies
+
+* Fri May 24 2013 Adam Goode <adam@spicenitz.org> - 1.1-1
+- Initial Fedora release.
+- Update to 1.1
+
+* Thu May  9 2013 Adam Goode <adam@spicenitz.org> - 1.1-0.3.rc3
+- Update to rc3
+
+* Thu Apr 11 2013 Adam Goode <adam@spicenitz.org> - 1.1-0.2.beta2
+- Update to beta2
+
+* Tue Apr  9 2013 Adam Goode <adam@spicenitz.org> - 1.1-0.1.beta1
+- Initial packaging.