ssl/test/runner: use hash.Cloner when copying hash instances

hash.Cloner is available since Go 1.25. It is a more straightforward way
to copy hash instances compared to duplicating their state.

Also, my team has a fork of Go that supports hash.Cloner, but not
encoding.BinaryMarshaler, for hash implementations in the standard
library. Using hash.Cloner allows us to reenable the bogo tests.

Change-Id: Iaef1a28e944d3d17e75cd3a3afeca46d645e2d85
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/103607
Reviewed-by: David Benjamin <davidben@google.com>
Auto-Submit: Quim Muntal <quimmuntal@gmail.com>
Presubmit-BoringSSL-Verified: boringssl-scoped@luci-project-accounts.iam.gserviceaccount.com <boringssl-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
diff --git a/ssl/test/runner/prf.go b/ssl/test/runner/prf.go
index 8193d16..a5bb3fe 100644
--- a/ssl/test/runner/prf.go
+++ b/ssl/test/runner/prf.go
@@ -20,10 +20,18 @@
 )
 
 // copyHash returns a copy of |h|, which must be an instance of |hashType|.
-func copyHash(h hash.Hash, hash crypto.Hash) hash.Hash {
+func copyHash(h hash.Hash, hashType crypto.Hash) hash.Hash {
 	// While hash.Hash is not copyable, the documentation says all standard
-	// library hash.Hash implementations implement BinaryMarshaler and
-	// BinaryUnmarshaler interfaces.
+	// library hash.Hash implementations implement hash.Cloner, except with
+	// GOFIPS140=v1.0.0, where we use BinaryMarshaler and BinaryUnmarshaler.
+	if c, ok := h.(hash.Cloner); ok {
+		ret, err := c.Clone()
+		if err != nil {
+			panic(err)
+		}
+		return ret
+	}
+
 	m, ok := h.(encoding.BinaryMarshaler)
 	if !ok {
 		panic("hash did not implement encoding.BinaryMarshaler")
@@ -32,7 +40,7 @@
 	if err != nil {
 		panic(err)
 	}
-	ret := hash.New()
+	ret := hashType.New()
 	u, ok := ret.(encoding.BinaryUnmarshaler)
 	if !ok {
 		panic("hash did not implement BinaryUnmarshaler")