From e5407501cb5c43f9ba874fe5dad215435acbf5a2 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Wed, 27 Apr 2022 09:03:35 -0400 Subject: [dev.boringcrypto] cmd: use notsha256 instead of md5, sha1, sha256 When we add GOEXPERIMENT=boringcrypto, the bootstrap process will not converge if the compiler itself depends on the boringcrypto cgo-based implementations of sha1 and sha256. Using notsha256 avoids boringcrypto and makes bootstrap converge. Removing md5 is not strictly necessary but it seemed worthwhile to be consistent. For #51940. Change-Id: Iba649507e0964d1a49a1d16e463dd23c4e348f14 Reviewed-on: https://go-review.googlesource.com/c/go/+/402595 Reviewed-by: Ian Lance Taylor Run-TryBot: Russ Cox TryBot-Result: Gopher Robot --- src/cmd/cgo/main.go | 6 +++--- src/cmd/compile/internal/liveness/plive.go | 4 ++-- src/cmd/compile/internal/ssa/func.go | 4 ++-- src/cmd/compile/internal/ssa/print.go | 9 +++++---- src/cmd/compile/internal/staticdata/data.go | 8 ++++---- src/cmd/compile/internal/typecheck/iexport.go | 4 ++-- src/cmd/compile/internal/types/fmt.go | 6 +++--- src/cmd/dist/buildtool.go | 1 + src/cmd/internal/codesign/codesign.go | 16 ++++++++++++---- src/cmd/internal/goobj/objfile.go | 4 ++-- src/cmd/internal/obj/objfile.go | 4 ++-- src/cmd/internal/obj/sym.go | 4 ++-- src/cmd/link/internal/ld/elf.go | 6 +++--- src/cmd/link/internal/ld/lib.go | 4 ++-- src/cmd/objdump/objdump_test.go | 4 ++-- 15 files changed, 47 insertions(+), 37 deletions(-) diff --git a/src/cmd/cgo/main.go b/src/cmd/cgo/main.go index 364d8b81fb..75d48c2ede 100644 --- a/src/cmd/cgo/main.go +++ b/src/cmd/cgo/main.go @@ -11,7 +11,6 @@ package main import ( - "crypto/md5" "flag" "fmt" "go/ast" @@ -28,6 +27,7 @@ import ( "strings" "cmd/internal/edit" + "cmd/internal/notsha256" "cmd/internal/objabi" ) @@ -329,8 +329,8 @@ func main() { // we use to coordinate between gcc and ourselves. // We already put _cgo_ at the beginning, so the main // concern is other cgo wrappers for the same functions. - // Use the beginning of the md5 of the input to disambiguate. - h := md5.New() + // Use the beginning of the notsha256 of the input to disambiguate. + h := notsha256.New() io.WriteString(h, *importPath) fs := make([]*File, len(goFiles)) for i, input := range goFiles { diff --git a/src/cmd/compile/internal/liveness/plive.go b/src/cmd/compile/internal/liveness/plive.go index bd0a6fa1a3..93f49fad45 100644 --- a/src/cmd/compile/internal/liveness/plive.go +++ b/src/cmd/compile/internal/liveness/plive.go @@ -15,7 +15,6 @@ package liveness import ( - "crypto/sha1" "fmt" "os" "sort" @@ -30,6 +29,7 @@ import ( "cmd/compile/internal/ssa" "cmd/compile/internal/typebits" "cmd/compile/internal/types" + "cmd/internal/notsha256" "cmd/internal/obj" "cmd/internal/objabi" "cmd/internal/src" @@ -959,7 +959,7 @@ func (lv *liveness) enableClobber() { // Clobber only functions where the hash of the function name matches a pattern. // Useful for binary searching for a miscompiled function. hstr := "" - for _, b := range sha1.Sum([]byte(lv.f.Name)) { + for _, b := range notsha256.Sum256([]byte(lv.f.Name)) { hstr += fmt.Sprintf("%08b", b) } if !strings.HasSuffix(hstr, h) { diff --git a/src/cmd/compile/internal/ssa/func.go b/src/cmd/compile/internal/ssa/func.go index 35a9382663..75f17634ec 100644 --- a/src/cmd/compile/internal/ssa/func.go +++ b/src/cmd/compile/internal/ssa/func.go @@ -8,8 +8,8 @@ import ( "cmd/compile/internal/abi" "cmd/compile/internal/base" "cmd/compile/internal/types" + "cmd/internal/notsha256" "cmd/internal/src" - "crypto/sha1" "fmt" "io" "math" @@ -854,7 +854,7 @@ func (f *Func) DebugHashMatch(evname string) bool { // We use this feature to do a binary search to // find a function that is incorrectly compiled. hstr := "" - for _, b := range sha1.Sum([]byte(name)) { + for _, b := range notsha256.Sum256([]byte(name)) { hstr += fmt.Sprintf("%08b", b) } diff --git a/src/cmd/compile/internal/ssa/print.go b/src/cmd/compile/internal/ssa/print.go index 96cd2c7c90..aea9ce9e33 100644 --- a/src/cmd/compile/internal/ssa/print.go +++ b/src/cmd/compile/internal/ssa/print.go @@ -6,10 +6,11 @@ package ssa import ( "bytes" - "cmd/internal/src" - "crypto/sha256" "fmt" "io" + + "cmd/internal/notsha256" + "cmd/internal/src" ) func printFunc(f *Func) { @@ -17,7 +18,7 @@ func printFunc(f *Func) { } func hashFunc(f *Func) []byte { - h := sha256.New() + h := notsha256.New() p := stringFuncPrinter{w: h, printDead: true} fprintFunc(p, f) return h.Sum(nil) @@ -32,7 +33,7 @@ func (f *Func) String() string { // rewriteHash returns a hash of f suitable for detecting rewrite cycles. func (f *Func) rewriteHash() string { - h := sha256.New() + h := notsha256.New() p := stringFuncPrinter{w: h, printDead: false} fprintFunc(p, f) return fmt.Sprintf("%x", h.Sum(nil)) diff --git a/src/cmd/compile/internal/staticdata/data.go b/src/cmd/compile/internal/staticdata/data.go index b114bb2df6..b8b645f246 100644 --- a/src/cmd/compile/internal/staticdata/data.go +++ b/src/cmd/compile/internal/staticdata/data.go @@ -5,7 +5,6 @@ package staticdata import ( - "crypto/sha256" "fmt" "go/constant" "io" @@ -20,6 +19,7 @@ import ( "cmd/compile/internal/objw" "cmd/compile/internal/typecheck" "cmd/compile/internal/types" + "cmd/internal/notsha256" "cmd/internal/obj" "cmd/internal/objabi" "cmd/internal/src" @@ -73,7 +73,7 @@ func StringSym(pos src.XPos, s string) (data *obj.LSym) { // Indulge in some paranoia by writing the length of s, too, // as protection against length extension attacks. // Same pattern is known to fileStringSym below. - h := sha256.New() + h := notsha256.New() io.WriteString(h, s) symname = fmt.Sprintf(stringSymPattern, len(s), h.Sum(nil)) } else { @@ -131,7 +131,7 @@ func fileStringSym(pos src.XPos, file string, readonly bool, hash []byte) (*obj. sym = slicedata(pos, string(data)).Linksym() } if len(hash) > 0 { - sum := sha256.Sum256(data) + sum := notsha256.Sum256(data) copy(hash, sum[:]) } return sym, size, nil @@ -148,7 +148,7 @@ func fileStringSym(pos src.XPos, file string, readonly bool, hash []byte) (*obj. // Compute hash if needed for read-only content hashing or if the caller wants it. var sum []byte if readonly || len(hash) > 0 { - h := sha256.New() + h := notsha256.New() n, err := io.Copy(h, f) if err != nil { return nil, 0, err diff --git a/src/cmd/compile/internal/typecheck/iexport.go b/src/cmd/compile/internal/typecheck/iexport.go index 12159b71e1..9436aa5504 100644 --- a/src/cmd/compile/internal/typecheck/iexport.go +++ b/src/cmd/compile/internal/typecheck/iexport.go @@ -236,7 +236,6 @@ package typecheck import ( "bytes" - "crypto/md5" "encoding/binary" "fmt" "go/constant" @@ -250,6 +249,7 @@ import ( "cmd/compile/internal/ir" "cmd/compile/internal/types" "cmd/internal/goobj" + "cmd/internal/notsha256" "cmd/internal/src" ) @@ -353,7 +353,7 @@ func WriteExports(out io.Writer, extensions bool) { hdr.uint64(dataLen) // Flush output. - h := md5.New() + h := notsha256.New() wr := io.MultiWriter(out, h) io.Copy(wr, &hdr) io.Copy(wr, &p.strings) diff --git a/src/cmd/compile/internal/types/fmt.go b/src/cmd/compile/internal/types/fmt.go index bdd3ca1d28..3c02cb8681 100644 --- a/src/cmd/compile/internal/types/fmt.go +++ b/src/cmd/compile/internal/types/fmt.go @@ -6,7 +6,6 @@ package types import ( "bytes" - "crypto/md5" "encoding/binary" "fmt" "go/constant" @@ -15,6 +14,7 @@ import ( "sync" "cmd/compile/internal/base" + "cmd/internal/notsha256" ) // BuiltinPkg is a fake package that declares the universe block. @@ -771,7 +771,7 @@ func FmtConst(v constant.Value, sharp bool) string { func TypeHash(t *Type) uint32 { p := tconv(t, 0, fmtTypeIDHash) - // Using MD5 is overkill, but reduces accidental collisions. - h := md5.Sum([]byte(p)) + // Using SHA256 is overkill, but reduces accidental collisions. + h := notsha256.Sum256([]byte(p)) return binary.LittleEndian.Uint32(h[:4]) } diff --git a/src/cmd/dist/buildtool.go b/src/cmd/dist/buildtool.go index 79ccf2b167..3161e3fa75 100644 --- a/src/cmd/dist/buildtool.go +++ b/src/cmd/dist/buildtool.go @@ -44,6 +44,7 @@ var bootstrapDirs = []string{ "cmd/internal/edit", "cmd/internal/gcprog", "cmd/internal/goobj", + "cmd/internal/notsha256", "cmd/internal/obj/...", "cmd/internal/objabi", "cmd/internal/pkgpath", diff --git a/src/cmd/internal/codesign/codesign.go b/src/cmd/internal/codesign/codesign.go index 0517a10640..1116393b5c 100644 --- a/src/cmd/internal/codesign/codesign.go +++ b/src/cmd/internal/codesign/codesign.go @@ -11,10 +11,11 @@ package codesign import ( - "crypto/sha256" "debug/macho" "encoding/binary" "io" + + "cmd/internal/notsha256" ) // Code signature layout. @@ -190,7 +191,7 @@ func Size(codeSize int64, id string) int64 { nhashes := (codeSize + pageSize - 1) / pageSize idOff := int64(codeDirectorySize) hashOff := idOff + int64(len(id)+1) - cdirSz := hashOff + nhashes*sha256.Size + cdirSz := hashOff + nhashes*notsha256.Size return int64(superBlobSize+blobSize) + cdirSz } @@ -226,7 +227,7 @@ func Sign(out []byte, data io.Reader, id string, codeSize, textOff, textSize int identOffset: uint32(idOff), nCodeSlots: uint32(nhashes), codeLimit: uint32(codeSize), - hashSize: sha256.Size, + hashSize: notsha256.Size, hashType: CS_HASHTYPE_SHA256, pageSize: uint8(pageSizeBits), execSegBase: uint64(textOff), @@ -245,8 +246,12 @@ func Sign(out []byte, data io.Reader, id string, codeSize, textOff, textSize int outp = puts(outp, []byte(id+"\000")) // emit hashes + // NOTE(rsc): These must be SHA256, but for cgo bootstrap reasons + // we cannot import crypto/sha256 when GOEXPERIMENT=boringcrypto + // and the host is linux/amd64. So we use NOT-SHA256 + // and then apply a NOT ourselves to get SHA256. Sigh. var buf [pageSize]byte - h := sha256.New() + h := notsha256.New() p := 0 for p < int(codeSize) { n, err := io.ReadFull(data, buf[:]) @@ -263,6 +268,9 @@ func Sign(out []byte, data io.Reader, id string, codeSize, textOff, textSize int h.Reset() h.Write(buf[:n]) b := h.Sum(nil) + for i := range b { + b[i] ^= 0xFF // convert notsha256 to sha256 + } outp = puts(outp, b[:]) } } diff --git a/src/cmd/internal/goobj/objfile.go b/src/cmd/internal/goobj/objfile.go index 3e36c461fa..e58be66e59 100644 --- a/src/cmd/internal/goobj/objfile.go +++ b/src/cmd/internal/goobj/objfile.go @@ -20,7 +20,7 @@ package goobj import ( "cmd/internal/bio" - "crypto/sha1" + "cmd/internal/notsha256" "encoding/binary" "errors" "fmt" @@ -367,7 +367,7 @@ const Hash64Size = 8 // Hash type HashType [HashSize]byte -const HashSize = sha1.Size +const HashSize = notsha256.Size // Relocation. // diff --git a/src/cmd/internal/obj/objfile.go b/src/cmd/internal/obj/objfile.go index 2f7ce061d4..2caff62702 100644 --- a/src/cmd/internal/obj/objfile.go +++ b/src/cmd/internal/obj/objfile.go @@ -10,9 +10,9 @@ import ( "bytes" "cmd/internal/bio" "cmd/internal/goobj" + "cmd/internal/notsha256" "cmd/internal/objabi" "cmd/internal/sys" - "crypto/sha1" "encoding/binary" "fmt" "io" @@ -460,7 +460,7 @@ func contentHash64(s *LSym) goobj.Hash64Type { // For now, we assume there is no circular dependencies among // hashed symbols. func (w *writer) contentHash(s *LSym) goobj.HashType { - h := sha1.New() + h := notsha256.New() var tmp [14]byte // Include the size of the symbol in the hash. diff --git a/src/cmd/internal/obj/sym.go b/src/cmd/internal/obj/sym.go index a8360527ef..95dd07d0fa 100644 --- a/src/cmd/internal/obj/sym.go +++ b/src/cmd/internal/obj/sym.go @@ -33,8 +33,8 @@ package obj import ( "cmd/internal/goobj" + "cmd/internal/notsha256" "cmd/internal/objabi" - "crypto/md5" "fmt" "internal/buildcfg" "log" @@ -175,7 +175,7 @@ func (ctxt *Link) Int64Sym(i int64) *LSym { // GCLocalsSym generates a content-addressable sym containing data. func (ctxt *Link) GCLocalsSym(data []byte) *LSym { - return ctxt.LookupInit(fmt.Sprintf("gclocals·%x", md5.Sum(data)), func(lsym *LSym) { + return ctxt.LookupInit(fmt.Sprintf("gclocals·%x", notsha256.Sum256(data)), func(lsym *LSym) { lsym.P = data lsym.Set(AttrContentAddressable, true) }) diff --git a/src/cmd/link/internal/ld/elf.go b/src/cmd/link/internal/ld/elf.go index d93f72e112..343803b47c 100644 --- a/src/cmd/link/internal/ld/elf.go +++ b/src/cmd/link/internal/ld/elf.go @@ -5,11 +5,11 @@ package ld import ( + "cmd/internal/notsha256" "cmd/internal/objabi" "cmd/internal/sys" "cmd/link/internal/loader" "cmd/link/internal/sym" - "crypto/sha1" "debug/elf" "encoding/binary" "encoding/hex" @@ -1533,10 +1533,10 @@ func (ctxt *Link) doelf() { sb.SetType(sym.SRODATA) ldr.SetAttrSpecial(s, true) sb.SetReachable(true) - sb.SetSize(sha1.Size) + sb.SetSize(notsha256.Size) sort.Sort(byPkg(ctxt.Library)) - h := sha1.New() + h := notsha256.New() for _, l := range ctxt.Library { h.Write(l.Fingerprint[:]) } diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go index 36db56950b..5103e55e00 100644 --- a/src/cmd/link/internal/ld/lib.go +++ b/src/cmd/link/internal/ld/lib.go @@ -34,6 +34,7 @@ import ( "bytes" "cmd/internal/bio" "cmd/internal/goobj" + "cmd/internal/notsha256" "cmd/internal/objabi" "cmd/internal/sys" "cmd/link/internal/loadelf" @@ -42,7 +43,6 @@ import ( "cmd/link/internal/loadpe" "cmd/link/internal/loadxcoff" "cmd/link/internal/sym" - "crypto/sha1" "debug/elf" "debug/macho" "encoding/base64" @@ -929,7 +929,7 @@ func typeSymbolMangle(name string) string { if len(name) <= 14 && !strings.Contains(name, "@") { // Issue 19529 return name } - hash := sha1.Sum([]byte(name)) + hash := notsha256.Sum256([]byte(name)) prefix := "type." if name[5] == '.' { prefix = "type.." diff --git a/src/cmd/objdump/objdump_test.go b/src/cmd/objdump/objdump_test.go index 313cc7a809..01967f3fed 100644 --- a/src/cmd/objdump/objdump_test.go +++ b/src/cmd/objdump/objdump_test.go @@ -5,7 +5,7 @@ package main import ( - "crypto/md5" + "cmd/internal/notsha256" "flag" "fmt" "go/build" @@ -142,7 +142,7 @@ func testDisasm(t *testing.T, srcfname string, printCode bool, printGnuAsm bool, goarch = f[1] } - hash := md5.Sum([]byte(fmt.Sprintf("%v-%v-%v-%v", srcfname, flags, printCode, printGnuAsm))) + hash := notsha256.Sum256([]byte(fmt.Sprintf("%v-%v-%v-%v", srcfname, flags, printCode, printGnuAsm))) hello := filepath.Join(tmp, fmt.Sprintf("hello-%x.exe", hash)) args := []string{"build", "-o", hello} args = append(args, flags...) -- cgit v1.2.3-54-g00ecf