[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 <iant@google.com>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
diff --git a/src/cmd/cgo/main.go b/src/cmd/cgo/main.go
index 364d8b8..75d48c2 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 @@
 	"strings"
 
 	"cmd/internal/edit"
+	"cmd/internal/notsha256"
 	"cmd/internal/objabi"
 )
 
@@ -329,8 +329,8 @@
 	// 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 bd0a6fa..93f49fa 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 @@
 	"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 @@
 		// 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 35a9382..75f1763 100644
--- a/src/cmd/compile/internal/ssa/func.go
+++ b/src/cmd/compile/internal/ssa/func.go
@@ -8,8 +8,8 @@
 	"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 @@
 	// 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 96cd2c7..aea9ce9 100644
--- a/src/cmd/compile/internal/ssa/print.go
+++ b/src/cmd/compile/internal/ssa/print.go
@@ -6,10 +6,11 @@
 
 import (
 	"bytes"
-	"cmd/internal/src"
-	"crypto/sha256"
 	"fmt"
 	"io"
+
+	"cmd/internal/notsha256"
+	"cmd/internal/src"
 )
 
 func printFunc(f *Func) {
@@ -17,7 +18,7 @@
 }
 
 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 @@
 
 // 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 b114bb2..b8b645f 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 @@
 	"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 @@
 		// 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 @@
 			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 @@
 	// 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 12159b7..9436aa5 100644
--- a/src/cmd/compile/internal/typecheck/iexport.go
+++ b/src/cmd/compile/internal/typecheck/iexport.go
@@ -236,7 +236,6 @@
 
 import (
 	"bytes"
-	"crypto/md5"
 	"encoding/binary"
 	"fmt"
 	"go/constant"
@@ -250,6 +249,7 @@
 	"cmd/compile/internal/ir"
 	"cmd/compile/internal/types"
 	"cmd/internal/goobj"
+	"cmd/internal/notsha256"
 	"cmd/internal/src"
 )
 
@@ -353,7 +353,7 @@
 	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 bdd3ca1..3c02cb8 100644
--- a/src/cmd/compile/internal/types/fmt.go
+++ b/src/cmd/compile/internal/types/fmt.go
@@ -6,7 +6,6 @@
 
 import (
 	"bytes"
-	"crypto/md5"
 	"encoding/binary"
 	"fmt"
 	"go/constant"
@@ -15,6 +14,7 @@
 	"sync"
 
 	"cmd/compile/internal/base"
+	"cmd/internal/notsha256"
 )
 
 // BuiltinPkg is a fake package that declares the universe block.
@@ -771,7 +771,7 @@
 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 79ccf2b..3161e3f 100644
--- a/src/cmd/dist/buildtool.go
+++ b/src/cmd/dist/buildtool.go
@@ -44,6 +44,7 @@
 	"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 0517a10..1116393 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 @@
 	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 @@
 		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 @@
 	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 @@
 		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 3e36c46..e58be66 100644
--- a/src/cmd/internal/goobj/objfile.go
+++ b/src/cmd/internal/goobj/objfile.go
@@ -20,7 +20,7 @@
 
 import (
 	"cmd/internal/bio"
-	"crypto/sha1"
+	"cmd/internal/notsha256"
 	"encoding/binary"
 	"errors"
 	"fmt"
@@ -367,7 +367,7 @@
 // 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 2f7ce06..2caff62 100644
--- a/src/cmd/internal/obj/objfile.go
+++ b/src/cmd/internal/obj/objfile.go
@@ -10,9 +10,9 @@
 	"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 @@
 // 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 a836052..95dd07d 100644
--- a/src/cmd/internal/obj/sym.go
+++ b/src/cmd/internal/obj/sym.go
@@ -33,8 +33,8 @@
 
 import (
 	"cmd/internal/goobj"
+	"cmd/internal/notsha256"
 	"cmd/internal/objabi"
-	"crypto/md5"
 	"fmt"
 	"internal/buildcfg"
 	"log"
@@ -175,7 +175,7 @@
 
 // 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 d93f72e..343803b 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 @@
 		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 36db569..5103e55 100644
--- a/src/cmd/link/internal/ld/lib.go
+++ b/src/cmd/link/internal/ld/lib.go
@@ -34,6 +34,7 @@
 	"bytes"
 	"cmd/internal/bio"
 	"cmd/internal/goobj"
+	"cmd/internal/notsha256"
 	"cmd/internal/objabi"
 	"cmd/internal/sys"
 	"cmd/link/internal/loadelf"
@@ -42,7 +43,6 @@
 	"cmd/link/internal/loadpe"
 	"cmd/link/internal/loadxcoff"
 	"cmd/link/internal/sym"
-	"crypto/sha1"
 	"debug/elf"
 	"debug/macho"
 	"encoding/base64"
@@ -929,7 +929,7 @@
 	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 313cc7a..01967f3 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 @@
 		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...)