cmd/internal/hash: stop using md5, sha1

These break if the tools are run with GODEBUG=fips140=only,
which happens if someone sets that during 'go test' (and a test
binary must be built).

The easiest fix is to make the tools compatible with this GODEBUG
by just using sha256 as the underlying hash always. Just in case,
I made the wrappers select different sections of the hash, but
none of the call sites really care.

This CL is for the Go 1.24 release, but a follow-up during the Go 1.25
dev cycle could change all the usage sites to only use Sum32/New32.

For #70514
Fixes #70878

Change-Id: Id5fea779c83df51d1680dbe561e0949c56e8d1e5
Reviewed-on: https://go-review.googlesource.com/c/go/+/641096
Reviewed-by: Keith Randall <khr@golang.org>
Auto-Submit: Russ Cox <rsc@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Keith Randall <khr@google.com>
This commit is contained in:
Russ Cox 2025-01-07 11:20:07 -05:00 committed by Gopher Robot
parent d93b549f05
commit b2aa18b96c
3 changed files with 32 additions and 15 deletions

View file

@ -5,22 +5,33 @@
// Package hash implements hash functions used in the compiler toolchain. // Package hash implements hash functions used in the compiler toolchain.
package hash package hash
// TODO(rsc): Delete the 16 and 20 forms and use 32 at all call sites.
import ( import (
"crypto/md5"
"crypto/sha1"
"crypto/sha256" "crypto/sha256"
"hash" "hash"
) )
const ( const (
// Size32 is the size of 32 bytes hash checksum. // Size32 is the size of the 32-byte hash checksum.
Size32 = sha256.Size Size32 = 32
// Size20 is the size of 20 bytes hash checksum. // Size20 is the size of the 20-byte hash checksum.
Size20 = sha1.Size Size20 = 20
// Size16 is the size of 16 bytes hash checksum. // Size16 is the size of the 16-byte hash checksum.
Size16 = md5.Size Size16 = 16
) )
type shortHash struct {
hash.Hash
n int
}
func (h *shortHash) Sum(b []byte) []byte {
old := b
sum := h.Hash.Sum(b)
return sum[:len(old)+h.n]
}
// New32 returns a new [hash.Hash] computing the 32 bytes hash checksum. // New32 returns a new [hash.Hash] computing the 32 bytes hash checksum.
func New32() hash.Hash { func New32() hash.Hash {
h := sha256.New() h := sha256.New()
@ -30,12 +41,12 @@ func New32() hash.Hash {
// New20 returns a new [hash.Hash] computing the 20 bytes hash checksum. // New20 returns a new [hash.Hash] computing the 20 bytes hash checksum.
func New20() hash.Hash { func New20() hash.Hash {
return sha1.New() return &shortHash{New32(), 20}
} }
// New16 returns a new [hash.Hash] computing the 16 bytes hash checksum. // New16 returns a new [hash.Hash] computing the 16 bytes hash checksum.
func New16() hash.Hash { func New16() hash.Hash {
return md5.New() return &shortHash{New32(), 16}
} }
// Sum32 returns the 32 bytes checksum of the data. // Sum32 returns the 32 bytes checksum of the data.
@ -47,10 +58,16 @@ func Sum32(data []byte) [Size32]byte {
// Sum20 returns the 20 bytes checksum of the data. // Sum20 returns the 20 bytes checksum of the data.
func Sum20(data []byte) [Size20]byte { func Sum20(data []byte) [Size20]byte {
return sha1.Sum(data) sum := Sum32(data)
var short [Size20]byte
copy(short[:], sum[4:])
return short
} }
// Sum16 returns the 16 bytes checksum of the data. // Sum16 returns the 16 bytes checksum of the data.
func Sum16(data []byte) [Size16]byte { func Sum16(data []byte) [Size16]byte {
return md5.Sum(data) sum := Sum32(data)
var short [Size16]byte
copy(short[:], sum[8:])
return short
} }

View file

@ -568,7 +568,7 @@ var depsRules = `
# crypto-aware packages # crypto-aware packages
DEBUG, go/build, go/types, text/scanner, crypto/md5 DEBUG, go/build, go/types, text/scanner, crypto/sha256
< internal/pkgbits, internal/exportdata < internal/pkgbits, internal/exportdata
< go/internal/gcimporter, go/internal/gccgoimporter, go/internal/srcimporter < go/internal/gcimporter, go/internal/gccgoimporter, go/internal/srcimporter
< go/importer; < go/importer;

View file

@ -6,7 +6,7 @@ package pkgbits
import ( import (
"bytes" "bytes"
"crypto/md5" "crypto/sha256"
"encoding/binary" "encoding/binary"
"go/constant" "go/constant"
"io" "io"
@ -55,7 +55,7 @@ func NewPkgEncoder(version Version, syncFrames int) PkgEncoder {
// DumpTo writes the package's encoded data to out0 and returns the // DumpTo writes the package's encoded data to out0 and returns the
// package fingerprint. // package fingerprint.
func (pw *PkgEncoder) DumpTo(out0 io.Writer) (fingerprint [8]byte) { func (pw *PkgEncoder) DumpTo(out0 io.Writer) (fingerprint [8]byte) {
h := md5.New() h := sha256.New()
out := io.MultiWriter(out0, h) out := io.MultiWriter(out0, h)
writeUint32 := func(x uint32) { writeUint32 := func(x uint32) {