]> Cypherpunks.ru repositories - gostls13.git/commitdiff
[dev.boringcrypto] all: merge master (2f0da6d) into dev.boringcrypto
authorRuss Cox <rsc@golang.org>
Wed, 17 Feb 2021 21:30:12 +0000 (16:30 -0500)
committerRuss Cox <rsc@golang.org>
Wed, 17 Feb 2021 21:43:48 +0000 (16:43 -0500)
Manual edits in src/cmd/compile/internal/reflectdata/reflect.go
to keep build working.

Merge List:

+ 2021-02-17 2f0da6d9e2 go/types: revert "no 'declared but not used' errors for invalid var decls"
+ 2021-02-17 70c37ee7d0 cmd/compile/internal/test: gofmt abiutils_test.go
+ 2021-02-16 84825599dc all: merge branch dev.regabi (d3cd4830ad) into master
+ 2021-02-16 d3cd4830ad [dev.regabi] test: run abi/regabipragma test with -c=1
+ 2021-02-16 03cea563d1 [dev.regabi] all: merge master (5faf941) into dev.regabi
+ 2021-02-16 b8fb049c7a [dev.regabi] cmd/go: copy internal/abi in TestNewReleaseRebuildsStalePackagesInGOPATH
+ 2021-02-16 5faf941df0 internal/goversion: update Version to 1.17
+ 2021-02-16 ed55da46ab [dev.regabi] go/types: overlapping embedded interfaces requires go1.14
+ 2021-02-16 7696c94334 [dev.regabi] go/types: type alias decl requires go1.9
+ 2021-02-16 c2358a1ae7 [dev.regabi] runtime: stub out spillArgs and unspillArgs
+ 2021-02-16 8cfbf34dd9 internal/abi: set register count constants to zero for regabi experiment
+ 2021-02-16 6f3da9d2f6 README: pull gopher image from website
+ 2021-02-16 d28aae26b0 [dev.regabi] cmd/link: recognize internal/abi as runtime package
+ 2021-02-16 098504c73f cmd/link: generate trampoline for inter-dependent packages
+ 2021-02-16 1004a7cb31 runtime/metrics: update documentation to current interface
+ 2021-02-16 6530f2617f doc/go1.16: remove draft notice
+ 2021-02-16 353e111455 doc/go1.16: fix mismatched id attribute
+ 2021-02-16 e0215315f5 [dev.regabi] reflect: support for register ABI on amd64 for reflect.(Value).Call
+ 2021-02-16 f0d23c9dbb internal/poll: netpollcheckerr before sendfile
+ 2021-02-16 0cb3415154 doc: remove all docs not tied to distribution
+ 2021-02-16 626ef08127 doc: remove install.html and install-source.html
+ 2021-02-16 30641e36aa internal/poll: if copy_file_range returns 0, assume it failed
+ 2021-02-15 33d72fd412 doc/faq: update generics entry to reflect accepted proposal
+ 2021-02-15 852ce7c212 cmd/go: provide a more helpful suggestion for "go vet -?"
+ 2021-02-13 66c27093d0 cmd/link: fix typo in link_test.go
+ 2021-02-13 b81efb7ec4 [dev.regabi] go/types: add support for language version checking
+ 2021-02-13 a7e9b4b948 [dev.regabi] go/types: untyped shift counts must fit into uint
+ 2021-02-13 060fa49bd2 [dev.regabi] go/types: refuse excessively long constants
+ 2021-02-12 baa6c75dce [dev.regabi] internal/abi: add new internal/abi package for ABI constants
+ 2021-02-12 d1fd9a8863 [dev.regabi] all: merge master (ff0e93e) into dev.regabi
+ 2021-02-12 ff0e93ea31 doc/go1.16: note that package path elements beginning with '.' are disallowed
+ 2021-02-11 249da7ec02 CONTRIBUTORS: update for the Go 1.16 release
+ 2021-02-11 864d4f1c6b cmd/go: multiple small 'go help' fixes
+ 2021-02-11 26ceae85a8 spec: More precise wording in section on function calls.
+ 2021-02-11 930c2c9a68 cmd/go: reject embedded files that can't be packed into modules
+ 2021-02-11 e5b08e6d5c io/fs: allow backslash in ValidPath, reject in os.DirFS.Open
+ 2021-02-10 ed8079096f cmd/compile: mark concrete call of reflect.(*rtype).Method as REFLECTMETHOD
+ 2021-02-10 59703d53e2 [dev.regabi] cmd/link: stop using ABI aliases if wrapper is enabled
+ 2021-02-09 e9c9683597 cmd/go: suppress errors from 'go get -d' for packages that only conditionally exist
+ 2021-02-09 168d6a49a5 [dev.regabi] go/types: use 512 bits as max. integer precision
+ 2021-02-09 0a62067708 [dev.regabi] go/types: adjust importer to match compiler importer
+ 2021-02-09 1c58fcf7ed [dev.regabi] go/types: handle untyped constant arithmetic overflow
+ 2021-02-09 493363ccff [dev.regabi] go/types: must not import a package called "init"
+ 2021-02-09 e0ac989cf3 archive/tar: detect out of bounds accesses in PAX records resulting from padded lengths
+ 2021-02-09 c48d1503ba [dev.regabi] go/types: report unused packages in source order
+ 2021-02-09 813958f13c [dev.regabi] go/types: factor out sorting of methods
+ 2021-02-09 11d15c171b [dev.regabi] go/types: convert untyped arguments to delete
+ 2021-02-09 c9d6f45fec runtime/metrics: fix a couple of documentation typpos
+ 2021-02-09 cea4e21b52 io/fs: backslash is always a glob meta character
+ 2021-02-08 dc725bfb3c doc/go1.16: mention new vet check for asn1.Unmarshal
+ 2021-02-08 618e3c15bd [dev.regabi] go/types: consistently report nil type as "untyped nil"
+ 2021-02-08 50449de66a [dev.regabi] all: merge master (1901853) into dev.regabi
+ 2021-02-08 7b0dfb177f [dev.regabi] runtime: use g register in some assembly functions on AMD64
+ 2021-02-08 2e60c00f56 [dev.regabi] cmd/internal/obj/x86: use g register in stack bounds check
+ 2021-02-08 22f9e1ccbc [dev.regabi] runtime: initialize special registers before sigpanic
+ 2021-02-08 5d7dc53888 [dev.regabi] cmd/compile, runtime: reserve R14 as g registers on AMD64
+ 2021-02-08 1901853098 runtime/metrics: fix panic in readingAllMetric example
+ 2021-02-08 ed3e4afa12 syscall/plan9: remove spooky fd action at a distance
+ 2021-02-08 a21de9ec73 [dev.regabi] cmd/link: resolve symbol ABI in shared linkage
+ 2021-02-05 724d0720b3 doc/go1.16: add missed heading tag in vet section
+ 2021-02-05 b54cd94d47 embed, io/fs: clarify that leading and trailing slashes are disallowed
+ 2021-02-05 4516afebed testing/fstest: avoid symlink-induced failures in tester
+ 2021-02-05 8fa84772ba [dev.regabi] runtime: delete gosave function
+ 2021-02-05 946351d5a2 [dev.regabi] runtime: zero X15 in racecall
+ 2021-02-05 397a46a10a [dev.regabi] cmd/asm: define g register on AMD64
+ 2021-02-05 e79c2fd428 [dev.regabi] runtime: mark racecallbackthunk as ABIInternal
+ 2021-02-05 7cc6de59f2 [dev.regabi] runtime: don't mark rt0_go ABIInternal
+ 2021-02-05 63de211014 [dev.regabi] runtime/cgo: call setg_gcc in crosscall_amd64
+ 2021-02-04 120b819f45 [dev.regabi] go/types: report error for invalid main function signature
+ 2021-02-04 52d5cb2822 [dev.regabi] cmd/internal/obj: access Attribute atomically
+ 2021-02-04 bc451b5770 [dev.regabi] go/types: port check_test.go ergonomics from dev.typeparams
+ 2021-02-04 afd67f3334 [dev.regabi] go/types: no "declared but not used" errors for invalid var decls
+ 2021-02-04 8869086d8f runtime: fix typo in histogram.go
+ 2021-02-03 401d7e5a24 [dev.regabi] cmd/compile: reserve X15 as zero register on AMD64
+ 2021-02-03 bfc7418e6d [dev.regabi] runtime, syscall, etc.: mark Darwin syscall wrappers as ABIInternal
+ 2021-02-03 e491c6eea9 math/big: fix comment in divRecursiveStep
+ 2021-02-02 23b0c1f76e [dev.regabi] all: merge master (fca94ab) into dev.regabi
+ 2021-02-02 fca94ab3ab spec: improve the example in Type assertions section
+ 2021-02-02 98f8454a73 cmd/link: don't decode type symbol in shared library in deadcode
+ 2021-02-02 1426a571b7 cmd/link: fix off-by-1 error in findShlibSection
+ 2021-02-01 32e789f4fb test: fix incorrectly laid out instructions in issue11656.go
+ 2021-02-01 ca6999e27c [dev.regabi] test: add a test for inlining closures
+ 2021-02-01 0b6cfea634 doc/go1.16: document that on OpenBSD syscalls are now made through libc
+ 2021-02-01 26e29aa15a cmd/link: disable TestPIESize if CGO isn't enabled
+ 2021-02-01 6ac91e460c doc/go1.16: minor markup fixes
+ 2021-01-29 44361140c0 embed: update docs for proposal tweaks
+ 2021-01-29 68058edc39 runtime: document pointer write atomicity for memclrNoHeapPointers
+ 2021-01-28 c8bd8010ff syscall: generate readlen/writelen for openbsd libc
+ 2021-01-28 41bb49b878 cmd/go: revert TestScript/build_trimpath to use ioutil.ReadFile
+ 2021-01-28 725a642c2d runtime: correct syscall10/syscall10X on openbsd/amd64
+ 2021-01-28 4b068cafb5 doc/go1.16: document go/build/constraint package
+ 2021-01-28 376518d77f runtime,syscall: convert syscall on openbsd/arm64 to libc
+ 2021-01-27 aca22bddf2 [dev.regabi] cmd/compile: remove nested functions from expands_calls.go
+ 2021-01-27 667e08ba8c [dev.regabi] cmd/go: Use GOMAXPROCS to limit default build, compile parallelism
+ 2021-01-27 00f2ff5c94 api/go1.16: add go/build/constraint APIs
+ 2021-01-27 35334caf18 crypto/x509: remove leftover CertificateRequest field
+ 2021-01-27 a5a5e2c968 runtime: make sure to remove open-coded defer entries in all cases after a recover
+ 2021-01-27 8cfa01943a runtime: block console ctrlhandler when the signal is handled
+ 2021-01-27 ff9e8364c6 cmd/go: skip issue33139 when the 'cc' script command is unavailable
+ 2021-01-27 cd176b3615 runtime: switch runtime to libc for openbsd/arm64
+ 2021-01-27 6c8fbfbdcf runtime: convert openbsd/arm64 locking to libc
+ 2021-01-27 5cdf0da1bf syscall: clean up mkasm related changes
+ 2021-01-27 210f70e298 doc/go1.16: fix closing brace in .Export format
+ 2021-01-27 0f797f168d math: fix typo in sqrt.go code comment
+ 2021-01-26 9b636feafe [dev.regabi] cmd/compile: missing last patch set for cl286013
+ 2021-01-26 f7dad5eae4 [dev.regabi] cmd/compile: remove leftover code form late call lowering work
+ 2021-01-26 8634a234df runtime,syscall: convert syscall on openbsd/amd64 to libc
+ 2021-01-26 1d5e14632e os: further document limitations around naked file descriptors
+ 2021-01-25 5e4a0cdde3 [dev.regabi] all: merge master (bf0f7c9) into dev.regabi
+ 2021-01-26 cf263e9f77 os: correct names in CreateTemp and MkdirTemp doc comments
+ 2021-01-26 ce8b318624 net/http/fcgi: remove locking added to prevent a test-only race
+ 2021-01-25 bf0f7c9d78 doc/go1.16: mention os.DirFS in os section
+ 2021-01-25 deaf29a8a8 cmd/compile: fix order-of-assignment issue w/ defers
+ 2021-01-25 ad2ca26a52 doc/go1.16: mention os.DirEntry and types moved from os to io/fs
+ 2021-01-25 a51921fa5b doc/go1.16: mention new testing/iotest functions
+ 2021-01-25 e6b6d107f7 doc/go1.16: mention deprecation of io/ioutil
+ 2021-01-25 7eaaf28cae [dev.regabi] cmd/compile: disallow taking address of SSA'd values
+ 2021-01-25 96a276363b doc/go1.16: mention go/build changes
+ 2021-01-25 3d85c69a0b html/template: revert "avoid race when escaping updates template"
+ 2021-01-25 54514c6b28 cmd/go: fix TestScript/cgo_path, cgo_path_space when CC set
+ 2021-01-25 6f5e79f470 [dev.regabi] cmd/compile/internal: specify memory layout
+ 2021-01-25 cabffc199d [dev.regabi] cmd/compile/internal: add internal ABI specification
+ 2021-01-25 6de8443f3b doc/asm: add a section on go_asm.h, clean up go_tls.h section
+ 2021-01-25 6a4739ccc5 [dev.regabi] cmd/compile: enable rational constant arithmetic
+ 2021-01-25 be9612a832 [dev.regabi] os: disable TestDirFS until #42637 is fixed
+ 2021-01-25 8ee3d39838 [dev.regabi] cmd/go: workaround -race issue on ppc64le
+ 2021-01-25 54b251f542 lib/time, time/tzdata: update tzdata to 2021a
+ 2021-01-25 5a76c3d548 [dev.regabi] cmd/compile: modify abiutils for recently updated ABI
+ 2021-01-25 ff82cc971a os: force consistent mtime before running fstest on directory on Windows
+ 2021-01-25 044f937a73 doc/go1.16: fix WalkDir and Walk links
+ 2021-01-25 063c72f06d [dev.regabi] cmd/compile: backport changes from dev.typeparams (9456804)
+ 2021-01-23 b634f5d97a doc/go1.16: add crypto/x509 memory optimization
+ 2021-01-23 9897655c61 doc/go1.16: reword ambiguously parsable sentence
+ 2021-01-23 cd99385ff4 cmd/internal/obj/arm64: fix VMOVQ instruction encoding error
+ 2021-01-23 d05d6fab32 [dev.regabi] cmd/compile: replace ir.Name map with ir.NameSet for SSA 2
+ 2021-01-23 66ee8b158f runtime: restore cgo_import_dynamic for libc.so on openbsd
+ 2021-01-23 48badc5fa8 [dev.regabi] cmd/compile: fix escape analysis problem with closures
+ 2021-01-23 51e1819a8d [dev.regabi] cmd/compile: scan body of closure in tooHairy to check for disallowed nodes
+ 2021-01-22 25c39e4fb5 io/ioutil: fix example test for WriteFile to allow it to run in the playground
+ 2021-01-22 eb21b31e48 runtime: define dummy msanmove
+ 2021-01-22 3a778ff50f runtime: check for g0 stack last in signal handler
+ 2021-01-22 a2cef9b544 cmd/go: don't lookup the path for CC when invoking cgo
+ 2021-01-22 7e0a81d280 [dev.regabi] all: merge master (dab3e5a) into dev.regabi
+ 2021-01-22 dab3e5affe runtime: switch runtime to libc for openbsd/amd64
+ 2021-01-22 a1b53d85da cmd/go: add documentation for test and xtest fields output by go list
+ 2021-01-22 b268b60774 runtime: remove pthread_kill/pthread_self for openbsd
+ 2021-01-22 ec4051763d runtime: fix typo in mgcscavenge.go
+ 2021-01-22 7ece3a7b17 net/http: fix flaky TestDisableKeepAliveUpgrade
+ 2021-01-22 50cba0506f time: clarify Timer.Reset behavior on AfterFunc Timers
+ 2021-01-22 cf10e69f17 doc/go1.16: mention net/http.Transport.GetProxyConnectHeader
+ 2021-01-22 ec1b945265 doc/go1.16: mention path/filepath.WalkDir
+ 2021-01-22 11def3d40b doc/go1.16: mention syscall.AllThreadsSyscall
+ 2021-01-21 07b0235609 doc/go1.16: add notes about package-specific fs.FS changes
+ 2021-01-21 e2b4f1fea5 doc/go1.16: minor formatting fix
+ 2021-01-21 9f43a9e07b doc/go1.16: mention new debug/elf constants
+ 2021-01-21 3c2f11ba5b cmd/go: overwrite program name with full path
+ 2021-01-21 953d1feca9 all: introduce and use internal/execabs
+ 2021-01-21 b186e4d70d cmd/go: add test case for cgo CC setting
+ 2021-01-21 5a8a2265fb cmd/cgo: report exec errors a bit more clearly
+ 2021-01-21 46e2e2e9d9 cmd/go: pass resolved CC, GCCGO to cgo
+ 2021-01-21 3d40895e36 runtime: switch openbsd/arm64 to pthreads
+ 2021-01-21 d95ca91380 crypto/elliptic: fix P-224 field reduction
+ 2021-01-21 d7e71c01ad [dev.regabi] cmd/compile: replace ir.Name map with ir.NameSet for dwarf
+ 2021-01-21 5248f59a22 [dev.regabi] cmd/compile: replace ir.Name map with ir.NameSet for SSA
+ 2021-01-21 970d8b6cb2 [dev.regabi] cmd/compile: replace ir.Name map with ir.NameSet in inlining
+ 2021-01-21 68a4664475 [dev.regabi] cmd/compile: remove tempAssigns in walkCall1
+ 2021-01-21 fd9a391cdd [dev.regabi] cmd/compile: remove CallExpr.Rargs
+ 2021-01-21 19a6db6b63 [dev.regabi] cmd/compile: make sure mkcall* passed non-nil init
+ 2021-01-21 9f036844db [dev.regabi] cmd/compile: use ir.DoChildren directly in inlining
+ 2021-01-21 213c3905e9 [dev.regabi] cmd/compile: use node walked flag to prevent double walk for walkSelect
+ 2021-01-20 1760d736f6 [dev.regabi] cmd/compile: exporting, importing, and inlining functions with OCLOSURE
+ 2021-01-20 ecf4ebf100 cmd/internal/moddeps: check content of all modules in GOROOT
+ 2021-01-20 92cb157cf3 [dev.regabi] cmd/compile: late expansion of return values
+ 2021-01-20 d2d155d1ae runtime: don't adjust timer pp field in timerWaiting status
+ 2021-01-20 803d18fc6c cmd/go: set Incomplete field on go list output if no files match embed
+ 2021-01-20 6e243ce71d cmd/go: have go mod vendor copy embedded files in subdirs
+ 2021-01-20 be28e5abc5 cmd/go: fix mod_get_fallback test
+ 2021-01-20 928bda4f4a runtime: convert openbsd/amd64 locking to libc
+ 2021-01-19 824f2d635c cmd/go: allow go fmt to complete when embedded file is missing
+ 2021-01-19 0575e35e50 cmd/compile: require 'go 1.16' go.mod line for //go:embed
+ 2021-01-19 9423d50d53 [dev.regabi] cmd/compile: use '%q' for printing rune values less than 128
+ 2021-01-19 ccb2e90688 cmd/link: exit before Asmb2 if error
+ 2021-01-19 ca5774a5a5 embed: treat uninitialized FS as empty
+ 2021-01-19 d047c91a6c cmd/link,runtime: switch openbsd/amd64 to pthreads
+ 2021-01-19 61debffd97 runtime: factor out usesLibcall
+ 2021-01-19 9fed39d281 runtime: factor out mStackIsSystemAllocated
+ 2021-01-19 a2f825c542 [dev.regabi] cmd/compile: directly create go.map and go.track symbols
+ 2021-01-19 4a4212c0e5 [dev.regabi] cmd/compile: refactor Linksym creation
+ 2021-01-19 4f5c603c0f [dev.regabi] cmd/compile: cleanup callTargetLSym
+ 2021-01-18 dbab079835 runtime: free Windows event handles after last lock is dropped
+ 2021-01-18 5a8fbb0d2d os: do not close syscall.Stdin in TestReadStdin
+ 2021-01-18 422f38fb6c [dev.regabi] cmd/compile: move stack objects to liveness
+ 2021-01-18 6113db0bb4 [dev.regabi] cmd/compile: convert OPANIC argument to interface{} during typecheck
+ 2021-01-18 4c835f9169 [dev.regabi] cmd/compile: use LinksymOffsetExpr in TypePtr/ItabAddr
+ 2021-01-18 0ffa1ead6e [dev.regabi] cmd/compile: use *obj.LSym instead of *ir.Name for staticdata functions
+ 2021-01-17 7e0fa38aad [dev.regabi] cmd/compile: remove unneeded packages from ir.Pkgs
+ 2021-01-17 99a5db11ac [dev.regabi] cmd/compile: use LinksymOffsetExpr in walkConvInterface
+ 2021-01-17 87845d14f9 [dev.regabi] cmd/compile: add ir.TailCallStmt
+ 2021-01-17 e3027c6828 [dev.regabi] cmd/compile: fix linux-amd64-noopt builder
+ 2021-01-17 59ff93fe64 [dev.regabi] cmd/compile: rename NameOffsetExpr to LinksymOffsetExpr
+ 2021-01-17 82b9cae700 [dev.regabi] cmd/compile: change ir.NameOffsetExpr to use *obj.LSym instead of *Name
+ 2021-01-17 88956fc4b1 [dev.regabi] cmd/compile: stop analyze NameOffsetExpr.Name_ in escape analysis
+ 2021-01-17 7ce2a8383d [dev.regabi] cmd/compile: simplify stack temp initialization
+ 2021-01-17 ba0e8a92fa [dev.regabi] cmd/compile: refactor temp construction in walk
+ 2021-01-17 78e5aabcdb [dev.regabi] cmd/compile: replace Node.HasCall with walk.mayCall
+ 2021-01-16 6de9423445 [dev.regabi] cmd/compile: cleanup OAS2FUNC ordering
+ 2021-01-16 a956a0e909 [dev.regabi] cmd/compile, runtime: fix up comments/error messages from recent renames
+ 2021-01-16 ab3b67abfd [dev.regabi] cmd/compile: remove ONEWOBJ
+ 2021-01-16 c9b1445ac8 [dev.regabi] cmd/compile: remove TypeAssertExpr {Src,Dst}Type fields
+ 2021-01-15 682a1d2176 runtime: detect errors in DuplicateHandle
+ 2021-01-15 9f83418b83 cmd/link: remove GOROOT write in TestBuildForTvOS
+ 2021-01-15 ec9470162f cmd/compile: allow embed into any string or byte slice type
+ 2021-01-15 54198b04db cmd/compile: disallow embed of var inside func
+ 2021-01-15 b386c735e7 cmd/go: fix go generate docs
+ 2021-01-15 bb5075a525 syscall: remove RtlGenRandom and move it into internal/syscall
+ 2021-01-15 1deae0b597 os: invoke processKiller synchronously in testKillProcess
+ 2021-01-15 03a875137f [dev.regabi] cmd/compile: unexport reflectdata.WriteType
+ 2021-01-15 14537e6e54 [dev.regabi] cmd/compile: move stkobj symbol generation to SSA
+ 2021-01-15 ab523fc510 [dev.regabi] cmd/compile: don't promote Byval CaptureVars if Addrtaken
+ 2021-01-15 ff196c3e84 crypto/x509: update iOS bundled roots to version 55188.40.9
+ 2021-01-15 b7a698c73f [dev.regabi] test: disable test on windows because expected contains path separators.
+ 2021-01-15 4be7af23f9 [dev.regabi] cmd/compile: fix ICE during ir.Dump
+ 2021-01-14 e125ccd10e cmd/go: in 'go mod edit', validate versions given to -retract and -exclude
+ 2021-01-14 eb330020dc cmd/dist, cmd/go: pass -arch for C compilation on Darwin
+ 2021-01-14 84e8a06f62 cmd/cgo: remove unnecessary space in cgo export header
+ 2021-01-14 0c86b999c3 cmd/test2json: document passing -test.paniconexit0
+ 2021-01-14 9135795891 cmd/go/internal/load: report positions for embed errors
+ 2021-01-14 35b9c66601 [dev.regabi] cmd/compile,cmd/link: additional code review suggestions for CL 270863
+ 2021-01-14 d9b79e53bb cmd/compile: fix wrong complement for arm64 floating-point comparisons
+ 2021-01-14 c73232d08f cmd/go/internal/load: refactor setErrorPos to PackageError.setPos
+ 2021-01-14 6aa28d3e06 go/build: report positions for go:embed directives
+ 2021-01-14 9734fd482d [dev.regabi] cmd/compile: use node walked flag to prevent double walk for walkSwitch
+ 2021-01-14 f97983249a [dev.regabi] cmd/compile: move more PAUTOHEAP to SSA construction
+ 2021-01-14 4476300425 [dev.regabi] cmd/compile: use byte for CallExpr.Use
+ 2021-01-14 5a5ab24689 [dev.regabi] cmd/compile: do not rely on CallExpr.Rargs for detect already walked calls
+ 2021-01-14 983ac4b086 [dev.regabi] cmd/compile: fix ICE when initializing blank vars
+ 2021-01-13 7eb31d999c cmd/go: add hints to more missing sum error messages
+ 2021-01-13 d6d4673728 [dev.regabi] cmd/compile: fix GOEXPERIMENT=regabi builder
+ 2021-01-13 c41b999ad4 [dev.regabi] cmd/compile: refactor abiutils from "gc" into new "abi"
+ 2021-01-13 861707a8c8 [dev.regabi] cmd/compile: added limited //go:registerparams pragma for new ABI dev
+ 2021-01-13 c1370e918f [dev.regabi] cmd/compile: add code to support register ABI spills around morestack calls
+ 2021-01-13 2abd24f3b7 [dev.regabi] test: make run.go error messages slightly more informative
+ 2021-01-13 9a19481acb [dev.regabi] cmd/compile: make ordering for InvertFlags more stable
+ 2021-01-12 d9acf6f3a3 [dev.regabi] cmd/compile: remove Func.ClosureType
+ 2021-01-12 41352fd401 [dev.regabi] cmd/compile: transform closures during walk
+ 2021-01-12 d6ad88b4db [dev.regabi] cmd/compile: compile functions before closures
+ 2021-01-12 432f9ffb11 [dev.regabi] cmd/compile: unindent compileFunctions
+ 2021-01-12 cc90e7a51e [dev.regabi] cmd/compile: always use the compile queue
+ 2021-01-12 cd5b74d2df [dev.regabi] cmd/compile: call NeedFuncSym in InitLSym
+ 2021-01-12 ba76567bc2 cmd/go/internal/modload: delete unused *mvsReqs.next method
+ 2021-01-12 665def2c11 encoding/asn1: document unmarshaling behavior for IMPLICIT string fields
+ 2021-01-12 95acd8121b [dev.regabi] cmd/compile: remove Name.Typegen
+ 2021-01-12 12ee55ba7b [dev.regabi] cmd/compile: stop using Vargen for import/export
+ 2021-01-12 b4d2a0445b [dev.regabi] cmd/compile: refactor closure var setup/teardown
+ 2021-01-12 f57f484053 [dev.regabi] cmd/compile: decouple escape analysis from Name.Vargen
+ 2021-01-11 81ea89adf3 cmd/go: fix non-script staleness checks interacting badly with GOFLAGS
+ 2021-01-11 759309029f doc: update editors.html for Go 1.16
+ 2021-01-11 c3b4c7093a cmd/internal/objfile: don't require runtime.symtab symbol for XCOFF
+ 2021-01-10 7fd84c6e46 [dev.regabi] cmd/compile: remove OCLOSUREREAD
+ 2021-01-10 c9c26d7ffb [dev.regabi] cmd/compile: use ClosureVars for method value wrappers
+ 2021-01-10 950cf4d46c [dev.regabi] cmd/compile: bind closure vars during SSA constructions
+ 2021-01-10 8b2efa990b [dev.regabi] cmd/compile: deref PAUTOHEAPs during SSA construction
+ 2021-01-08 59bfc18e34 cmd/go: add hint to read 'go help vcs' to GOVCS errors
+ 2021-01-08 6ee9b118a2 [dev.regabi] cmd/compile: remove fmt_test code; it has outlived its usefulness
+ 2021-01-08 cd6f3a54e4 cmd/go: revise 'go help' documentation for modules
+ 2021-01-08 6192b98751 cmd/go: make hints in error messages more consistent
+ 2021-01-08 25886cf4bd cmd/go: preserve sums for indirect deps fetched by 'go mod download'
+ 2021-01-08 6250833911 runtime/metrics: mark histogram metrics as cumulative
+ 2021-01-08 8f6a9acbb3 runtime/metrics: remove unused StopTheWorld Description field
+ 2021-01-08 6598c65646 cmd/compile: fix exponential-time init-cycle reporting
+ 2021-01-08 fefad1dc85 test: fix timeout code for invoking compiler
+ 2021-01-08 6728118e0a cmd/go: pass signals forward during "go tool"
+ 2021-01-08 e65c543f3c go/build/constraint: add parser for build tag constraint expressions
+ 2021-01-08 0c5afc4fb7 testing/fstest,os: clarify racy behavior of TestFS
+ 2021-01-08 32afcc9436 runtime/metrics: change unit on *-by-size metrics to match bucket unit
+ 2021-01-08 c6513bca5a io/fs: minor corrections to Glob doc
+ 2021-01-08 b241938e04 [dev.regabi] cmd/compile: fix some methods error text
+ 2021-01-08 304f769ffc cmd/compile: don't short-circuit copies whose source is volatile
+ 2021-01-08 ae97717133 runtime,runtime/metrics: use explicit histogram boundaries
+ 2021-01-08 a9ccd2d795 go/build: skip string literal while findEmbed
+ 2021-01-08 d92f8add32 archive/tar: fix typo in comment
+ 2021-01-08 cab1202183 cmd/link: accept extra blocks in TestFallocate
+ 2021-01-08 ee4d32249b io/fs: minor corrections to Glob release date
+ 2021-01-08 54bd1ccce2 cmd: update to latest golang.org/x/tools
+ 2021-01-07 9ec21a8f34 Revert "reflect: support multiple keys in struct tags"
+ 2021-01-07 091414b5b7 io/fs: correct WalkDirFunc documentation
+ 2021-01-07 9b55088d6b doc/go1.16: add release note for disallowing non-ASCII import paths
+ 2021-01-07 fa90aaca7d cmd/compile: fix late expand_calls leaf type for OpStructSelect/OpArraySelect
+ 2021-01-07 7cee66d4cb cmd/go: add documentation for Embed fields in go list output
+ 2021-01-07 e60cffa4ca html/template: attach functions to namespace
+ 2021-01-07 6da2d3b7d7 cmd/link: fix typo in asm.go
+ 2021-01-07 df81a15819 runtime: check mips64 VDSO clock_gettime return code
+ 2021-01-06 4787e906cf crypto/x509: rollback new CertificateRequest fields
+ 2021-01-06 c9658bee93 cmd/go: make module suggestion more friendly
+ 2021-01-06 4c668b25c6 runtime/metrics: fix panic message for Float64Histogram
+ 2021-01-06 d2131704a6 net/http/httputil: fix deadlock in DumpRequestOut
+ 2021-01-05 3e1e13ce6d cmd/go: set cfg.BuildMod to "readonly" by default with no module root
+ 2021-01-05 0b0d004983 cmd/go: pass embedcfg to gccgo if supported
+ 2021-01-05 cb05a0aa6a [dev.regabi] cmd/compile: remove toolstash scaffolding
+ 2021-01-05 9821838832 [dev.regabi] cmd/compile: remove CaptureVars
+ 2021-01-05 fd43831f44 [dev.regabi] cmd/compile: reimplement capture analysis
+ 2021-01-05 fb69c67cad [dev.regabi] test: enable finalizer tests on !amd64
+ 2021-01-05 1b85e7c057 cmd/go: don't scan gccgo standard library packages for imports
+ 2021-01-05 81f4f0e912 [dev.regabi] cmd/compile: remove race-y check in Name.Canonical
+ 2021-01-05 6b37b15d95 runtime: don't take allglock in tracebackothers
+ 2021-01-05 4a9d9adea4 [dev.regabi] cmd/compile: remove initname function
+ 2021-01-05 77365c5ed7 [dev.regabi] cmd/compile: add Name.Canonical and move Byval
+ 2021-01-05 e09783cbc0 [dev.regabi] cmd/compile: make ir.StaticValue safer
+ 2021-01-05 9aa950c407 [dev.regabi] cmd/compile: make ir.OuterValue safer
+ 2021-01-05 eb626409d1 [dev.regabi] cmd/compile: simplify CaptureVars
+ 2021-01-05 c28ca67a96 [dev.regabi] cmd/compile: fix ir.Dump for []*CaseClause, etc
+ 2021-01-04 9eef49cfa6 math/rand: fix typo in comment
+ 2021-01-04 b01fb2af9e testing/fstest: fix typo in error message
+ 2021-01-04 f24e40c14a [dev.regabi] cmd/compile: remove Name.Class_ accessors
+ 2021-01-04 d89705e087 [dev.regabi] cmd/compile: fix re-export of parameters
+ 2021-01-04 290b4154b7 [dev.regabi] cmd/compile: fix ICE due to large uint64 constants
+ 2021-01-04 a30fd52884 [dev.regabi] cmd/compile: use ir.NewNameAt in SubstArgTypes
+ 2021-01-03 8fc44cf0fa [dev.regabi] cmd/compile: remove a couple CloneName calls
+ 2021-01-03 907a4bfdc7 [dev.regabi] cmd/compile: fix map assignment order
+ 2021-01-03 f2e6dab048 [dev.regabi] cmd/compile: remove walkReturn "common case" path
+ 2021-01-03 d36a6bf44d [dev.regabi] cmd/compile: improve walkReturn common case
+ 2021-01-03 a317067d65 [dev.regabi] cmd/compile: improve ascompatee
+ 2021-01-03 5d80a590a2 [dev.regabi] cmd/compile: simplify walkReturn
+ 2021-01-03 bb1b6c95c2 [dev.regabi] cmd/compile: remove Node.{,Set}Walkdef
+ 2021-01-03 57c426c9a5 [dev.regabi] cmd/compile: tighten typecheckdef to *ir.Name
+ 2021-01-03 b1747756e3 [dev.regabi] cmd/compile: reorganize escape analysis somewhat
+ 2021-01-02 f2538033c0 [dev.regabi] cmd/compile: remove Nodes.Set [generated]
+ 2021-01-02 2f2d4b4e68 [dev.regabi] cmd/compile: remove {Ptr,Set}Init from Node interface
+ 2021-01-01 3dd5867605 doc: 2021 is the Year of the Gopher
+ 2021-01-01 1544a03198 [dev.regabi] cmd/compile: refactor redundant type conversion [generated]
+ 2021-01-01 7958a23ea3 [dev.regabi] cmd/compile: use *ir.Name where possible in inl.go
+ 2021-01-01 bfa97ba48f [dev.regabi] test: add another closure test case
+ 2021-01-01 67ad695416 [dev.regabi] cmd/compile: split escape analysis state
+ 2021-01-01 fad9a8b528 [dev.regabi] cmd/compile: simplify inlining of closures
+ 2021-01-01 7d55669847 [dev.regabi] cmd/compile: simplify dwarfgen.declPos
+ 2021-01-01 9ed1577779 [dev.regabi] cmd/compile: remove Func.ClosureEnter
+ 2021-01-01 ece345aa69 [dev.regabi] cmd/compile: expand documentation for Func.Closure{Vars,Enter}
+ 2021-01-01 6ddbc75efd [dev.regabi] cmd/compile: earlier deadcode removal
+ 2021-01-01 68e6fa4f68 [dev.regabi] cmd/compile: fix package-initialization order
+ 2021-01-01 3a4474cdfd [dev.regabi] cmd/compile: some more manual shuffling
+ 2021-01-01 0f1d2129c4 [dev.regabi] cmd/compile: reshuffle type-checking code [generated]
+ 2021-01-01 b8fd3440cd [dev.regabi] cmd/compile: report unused variables during typecheck
+ 2021-01-01 fd22df9905 [dev.regabi] cmd/compile: remove idempotent Name() calls [generated]
+ 2020-12-31 dfbcff80c6 [dev.regabi] cmd/compile: make copyExpr return *ir.Name directly
+ 2020-12-31 77fd81a3e6 [dev.regabi] cmd/compile: use names for keep alive variables in function call
+ 2020-12-31 8fe1197654 [dev.regabi] cmd/compile: remove Name.orig
+ 2020-12-31 477b049060 [dev.regabi] cmd/compile: fix printing of method expressions
+ 2020-12-31 95ce805d14 io/fs: remove darwin/arm64 special condition
+ 2020-12-30 20d0991b86 lib/time, time/tzdata: update tzdata to 2020f
+ 2020-12-30 ed301733bb misc/cgo/testcarchive: remove special flags for Darwin/ARM
+ 2020-12-30 0ae2e032f2 misc/cgo/test: enable TestCrossPackageTests on darwin/arm64
+ 2020-12-30 178c667db2 [dev.regabi] cmd/compile: fix OSLICEARR comments
+ 2020-12-30 f0d99def5b [dev.regabi] cmd/compile: add newline to ir.Dump
+ 2020-12-30 451693af71 [dev.regabi] cmd/compile: simplify typecheckdef
+ 2020-12-30 0c1a899a6c [dev.regabi] cmd/compile: fix defined-pointer method call check
+ 2020-12-30 f9b67f76a5 [dev.regabi] cmd/compile: change ir.DoChildren to use bool result type
+ 2020-12-30 499851bac8 [dev.regabi] cmd/compile: generalize ir/mknode.go
+ 2020-12-30 82ab3d1448 [dev.regabi] cmd/compile: use *ir.Name for Decl.X
+ 2020-12-30 9958b7ed3e [dev.regabi] cmd/compile: unexport ir.FmtNode
+ 2020-12-29 780b4de16b misc/ios: fix wording for command line instructions
+ 2020-12-29 b4a71c95d2 doc/go1.16: reference misc/ios/README for how to build iOS programs
+ 2020-12-29 f83e0f6616 misc/ios: add to README how to build ios executables
+ 2020-12-29 f5816624cd [dev.regabi] cmd/compile: change AddrExpr.Alloc to AddrExpr.Prealloc
+ 2020-12-29 850aa7c60c [dev.regabi] cmd/compile: use *ir.Name instead of ir.Node for CaseClause.Var
+ 2020-12-29 37babc97bb [dev.regabi] cmd/compile: allow visitor visits *ir.Name
+ 2020-12-29 5cf3c87fa6 [dev.regabi] cmd/compile: generate case/comm clause functions in mknode.go
+ 2020-12-29 b3e1ec97fd [dev.regabi] cmd/compile: move new addrtaken bit back to the old name
+ 2020-12-29 0620c674dd [dev.regabi] cmd/compile: remove original addrtaken bit
+ 2020-12-29 0523d525ae [dev.regabi] cmd/compile: separate out address taken computation from typechecker
+ 2020-12-29 9ea272e5ec [dev.regabi] cmd/compile: simplify ir.Func somewhat
+ 2020-12-29 e40cb4d4ae [dev.regabi] cmd/compile: remove more unused code
+ 2020-12-29 6f30c95048 [dev.regabi] cmd/compile: remove unneeded indirection
+ 2020-12-29 171fc6f223 [dev.regabi] cmd/compile: remove workarounds for go/constant issues
+ 2020-12-29 33801cdc62 [dev.regabi] cmd/compile: use Ntype where possible
+ 2020-12-29 82ad3083f8 [dev.regabi] cmd/compile: remove typ from AssignOpStmt
+ 2020-12-29 e34c44a7c4 [dev.regabi] cmd/compile: refactoring typecheck arith
+ 2020-12-29 a5ec920160 [dev.regabi] cmd/compile: more Linksym cleanup
+ 2020-12-29 ec59b197d5 [dev.regabi] cmd/compile: rewrite to use linksym helpers [generated]
+ 2020-12-29 25c613c02d [dev.regabi] cmd/compile: add Linksym helpers
+ 2020-12-29 289da2b33e [dev.regabi] cmd/compile: move Node.Opt to Name
+ 2020-12-29 6acbae4fcc [dev.regabi] cmd/compile: address some ir TODOs
+ 2020-12-29 4629f6a51d [dev.regabi] cmd/compile: merge {Selector,CallPart,Method}Expr
+ 2020-12-29 e563715b30 [dev.regabi] cmd/compile: remove Sym.Importdef
+ 2020-12-29 3f370b75fb [dev.regabi] cmd/compile: cleanup //go:generate directives
+ 2020-12-28 4fd9455882 io/fs: fix typo in comment
+ 2020-12-28 07569dac4e [dev.regabi] all: merge master (1d78139) into dev.regabi
+ 2020-12-28 76136be027 [dev.regabi] cmd/compile: check for recursive import in ImportBody
+ 2020-12-28 fda7ec3a3f [dev.regabi] cmd/compile: remove Name.IsDDD, etc
+ 2020-12-28 098a6490b9 [dev.regabi] cmd/compile: remove Declare in makepartialcall
+ 2020-12-28 137f0d2e06 [dev.regabi] cmd/compile: remove unnecessary Name.Sym call
+ 2020-12-28 3383b5c74a [dev.regabi] cmd/compile: flatten dependency graph [generated]
+ 2020-12-28 f8afb8216a [dev.regabi] cmd/compile: rename CommStmt and CaseStmt [generated]
+ 2020-12-28 5f3bd59a0d [dev.regabi] cmd/compile: remove some unneeded code in package ir
+ 2020-12-28 3bdafb0d82 [dev.regabi] cmd/compile: remove CommStmt.List
+ 2020-12-28 2ecf52b841 [dev.regabi] cmd/compile: separate CommStmt from CaseStmt
+ 2020-12-28 ed9772e130 [dev.regabi] cmd/compile: add explicit file name in types generation
+ 2020-12-28 a59d26603f [dev.regabi] cmd/compile: use []*CaseStmt in {Select,Switch}Stmt
+ 2020-12-28 fbc4458c06 [dev.regabi] cmd/compile: simplify some tree traversal code
+ 2020-12-28 6c67677541 [dev.regabi] cmd/compile: simplify FuncName and PkgFuncName
+ 2020-12-28 676d794b81 [dev.regabi] cmd/compile: remove refersToCommonName
+ 2020-12-28 c98548e110 [dev.regabi] cmd/compile: merge ascompatee, ascompatee1, and reorder3
+ 2020-12-28 4c215c4fa9 [dev.regabi] cmd/compile: simplify and optimize reorder3
+ 2020-12-28 e6c973198d [dev.regabi] cmd/compile: stop mangling SelectorExpr.Sel for ODOTMETH
+ 2020-12-28 135ce1c485 [dev.regabi] cmd/compile: desugar OMETHEXPR into ONAME during walk
+ 2020-12-28 0f732f8c91 [dev.regabi] cmd/compile: minor walkExpr cleanups
+ 2020-12-28 0de8eafd98 [dev.regabi] cmd/compile: remove SelectorExpr.Offset field
+ 2020-12-28 a4f335f420 [dev.regabi] cmd/compile: always use a Field for ODOTPTR expressions
+ 2020-12-26 1d78139128 runtime/cgo: fix Android build with NDK 22
+ 2020-12-25 2018b68a65 net/mail: don't use MDT in test
+ 2020-12-25 e4f293d853 [dev.regabi] cmd/compile: fix OCALLMETH desugaring
+ 2020-12-25 1d9a1f67d5 [dev.regabi] cmd/compile: don't emit reflect data for method types
+ 2020-12-25 396b6c2e7c [dev.regabi] cmd/compile: cleanup assignment typechecking
+ 2020-12-25 e24d2f3d05 [dev.regabi] cmd/compile: remove typ from RangeStmt
+ 2020-12-25 2785c691c2 [dev.regabi] cmd/compile: cleanup devirtualization docs
+ 2020-12-25 4b1d0fe66f [dev.regabi] cmd/compile: new devirtualization pkg [generated]
+ 2020-12-24 082cc8b7d9 [dev.regabi] cmd/compile: change ir.IsAssignable -> ir.IsAddressable
+ 2020-12-24 27b248b307 [dev.regabi] cmd/compile: separate range stmt Vars to Key, Value nodes
+ 2020-12-23 40818038bf [dev.regabi] cmd/compile: change CaseStmt.Vars to Var
+ 2020-12-23 b116404444 runtime: shift timeHistogram buckets and allow negative durations
+ 2020-12-23 8db7e2fecd runtime: fix allocs-by-size and frees-by-size buckets
+ 2020-12-23 fb96f07e1a runtime: fix nStackRoots comment about stack roots
+ 2020-12-23 d1502b3c72 lib/time, time/tzdata: update tzdata to 2020e
+ 2020-12-23 30c99cbb7a cmd/go: add the Retract field to 'go help mod edit' definition of the GoMod struct
+ 2020-12-23 49d0b239cb doc: fix a typo in contribute.html
+ 2020-12-23 9eeed291bc [dev.regabi] cmd/compile: eliminate usage of ir.Node in liveness
+ 2020-12-23 d1d64e4cea [dev.regabi] cmd/compile: split SliceExpr.List into separate fields
+ 2020-12-23 98a73030b0 cmd/go: in 'go get', promote named implicit dependencies to explicit
+ 2020-12-23 d19018e8f1 [dev.regabi] cmd/compile: split SliceHeaderExpr.LenCap into separate fields
+ 2020-12-23 53f082b0ee [dev.regabi] cmd/compile: cleanup export code further
+ 2020-12-23 31267f82e1 [dev.regabi] cmd/compile: simplify function/interface/struct typechecking
+ 2020-12-23 addade2cce [dev.regabi] cmd/compile: prefer types constructors over typecheck
+ 2020-12-23 18ebfb49e9 [dev.regabi] cmd/compile: cleanup noder
+ 2020-12-23 87a592b356 [dev.regabi] cmd/compile: cleanup import/export code
+ 2020-12-23 5898025026 [dev.regabi] cmd/compile: update mkbuiltin.go to use new type constructors
+ 2020-12-23 63c96c2ee7 [dev.regabi] cmd/compile: update mkbuiltin.go and re-enable TestBuiltin
+ 2020-12-23 37f138df6b [dev.regabi] cmd/compile: split out package test [generated]
+ 2020-12-23 3d8a3cb06b [dev.regabi] cmd/compile: split out package pkginit [generated]
+ 2020-12-23 3f04d964ab [dev.regabi] cmd/compile: split up walkexpr1, walkstmt [generated]
+ 2020-12-23 e4895ab4c0 [dev.regabi] cmd/compile: split out package walk [generated]
+ 2020-12-23 01fd2d05c8 [dev.regabi] cmd/compile: split out package dwarfgen [generated]
+ 2020-12-23 6c34d2f420 [dev.regabi] cmd/compile: split out package ssagen [generated]
+ 2020-12-23 de65151e50 [dev.regabi] cmd/compile: split out package reflectdata [generated]
+ 2020-12-23 4dfb5d91a8 [dev.regabi] cmd/compile: split out package staticdata [generated]
+ 2020-12-23 fbc82f03b1 [dev.regabi] cmd/compile: split out package noder [generated]
+ 2020-12-23 de454eef5f [dev.regabi] cmd/compile: split out package escape [generated]
+ 2020-12-23 071ab0a14c [dev.regabi] cmd/compile: split out package liveness [generated]
+ 2020-12-23 0ced54062e [dev.regabi] cmd/compile: split out package objw [generated]
+ 2020-12-23 575fd6ff0a [dev.regabi] cmd/compile: split out package inline [generated]
+ 2020-12-23 0256ba99a8 [dev.regabi] cmd/compile: split up typecheck1 [generated]
+ 2020-12-23 b9693d7627 [dev.regabi] cmd/compile: split out package typecheck [generated]
+ 2020-12-23 dac0de3748 [dev.regabi] cmd/compile: move type size calculations into package types [generated]
+ 2020-12-23 527a1895d6 [dev.regabi] cmd/compile: move helpers into package ir [generated]
+ 2020-12-23 65c4c6dfb2 [dev.regabi] cmd/compile: group known symbols, packages, names [generated]
+ 2020-12-23 9ee309255a [dev.regabi] cmd/compile: move helpers into package types [generated]
+ 2020-12-23 ead4957892 [dev.regabi] cmd/compile: move helpers into package base [generated]
+ 2020-12-23 440308ffd7 [dev.regabi] cmd/compile: simplify Nodes usage [generated]
+ 2020-12-23 f9d373720e [dev.regabi] cmd/compile: remove Left, Right etc methods [generated]
+ 2020-12-23 14d667341f [dev.regabi] cmd/compile: remove Node.Left etc [generated]
+ 2020-12-23 6f27d29be0 [dev.regabi] cmd/compile: remove ir.Nod [generated]
+ 2020-12-23 fd6ba1c8a2 os/signal: fix a deadlock with syscall.AllThreadsSyscall() use
+ 2020-12-23 69cf39089f [dev.regabi] cmd/compile: do not die in early base.FlushErrors
+ 2020-12-23 6d03cde88a [dev.regabi] cmd/dist: automatically bootstrap cmd subdirs
+ 2020-12-23 b0b0d98283 runtime: linux iscgo support for not blocking nptl signals
+ 2020-12-23 d1d1099c91 [dev.regabi] cmd/compile: fixes for big rewrite
+ 2020-12-22 223331fc0c cmd/go/internal/modload: add hint for missing implicit dependency
+ 2020-12-22 ec741b0447 [dev.regabi] all: merge master (c9fb4eb) into dev.regabi
+ 2020-12-22 acc32ea124 [dev.regabi] codereview.cfg: add config for dev.regabi
+ 2020-12-22 c9fb4eb0a2 cmd/link: handle grouped resource sections
+ 2020-12-22 c40934b33d [dev.regabi] cmd/compile: adjust one case in walkexpr
+ 2020-12-22 280e7fd1ee [dev.regabi] cmd/compile: only access Func method on concrete types
+ 2020-12-22 51ba53f5c2 [dev.regabi] cmd/compile: separate misc for gc split
+ 2020-12-22 572f168ed2 [dev.regabi] cmd/compile: separate various from Main
+ 2020-12-22 3b12c6dc08 [dev.regabi] cmd/compile: separate typecheck more cleanly
+ 2020-12-22 7c8f5356ab [dev.regabi] cmd/compile: separate dowidth better
+ 2020-12-22 c06a354bcc test: trigger SIGSEGV instead of SIGTRAP in issue11656.go
+ 2020-12-22 0aa9b4709a cmd/pack: r command create output file if not exist
+ 2020-12-22 cb28c96be8 [dev.regabi] cmd/compile,cmd/link: initial support for ABI wrappers
+ 2020-12-22 c8610e4700 [dev.regabi] cmd/compile: add ir.BasicLit to represent literals
+ 2020-12-22 3512cde10a [dev.regabi] cmd/compile: stop reusing Ntype for OSLICELIT length
+ 2020-12-22 2755361e6a [dev.regabi] cmd/compile: change noder.declNames to returns ir.Names
+ 2020-12-22 301af2cb71 [dev.regabi] runtime/race: adjust test pattern match for ABI wrapper
+ 2020-12-22 4d27c4c223 runtime: correct error handling in several FreeBSD syscall wrappers
+ 2020-12-22 9b6147120a cmd/pack: treat compiler's -linkobj output as "compiler object"
+ 2020-12-22 306b2451c8 [dev.regabi] runtime: fix ABI targets in runtime.panic{Index,Slice} shims
+ 2020-12-21 bc7e4d9257 syscall: don't generate ptrace on iOS
+ 2020-12-21 94cfeca0a5 [dev.regabi] cmd/compile: stop using ONONAME with Name
+ 2020-12-21 cb4898a77d [dev.regabi] cmd/compile: simplify declaration importing
+ 2020-12-21 06915ac14d [dev.regabi] cmd/compile: move itabname call out of implements
+ 2020-12-21 6cff874c47 runtime/metrics: add Read examples
+ 2020-12-21 4e8f681eff Merge "[dev.regabi] all: merge master into dev.regabi" into dev.regabi
+ 2020-12-21 1a523c8ab0 [dev.regabi] cmd/compile: separate nowritebarrierrec from main
+ 2020-12-21 e999c17022 [dev.regabi] cmd/compile: separate ssa from other phases
+ 2020-12-21 4836e28ac0 [dev.regabi] cmd/compile: separate noder more cleanly
+ 2020-12-21 85ce6ecfe3 [dev.regabi] cmd/compile: separate exportsym more cleanly
+ 2020-12-21 1a3b036b83 [dev.regabi] cmd/compile: collect global compilation state
+ 2020-12-21 2153a99914 [dev.regabi] cmd/compile: setup to move Addrconst, Patch into cmd/internal/obj
+ 2020-12-21 0bb0baf683 [dev.regabi] cmd/compile: cleanup for concrete types - more
+ 2020-12-21 ca8e17164e [dev.regabi] all: merge master into dev.regabi
+ 2020-12-21 8438a5779b runtime: use _exit on darwin
+ 2020-12-21 cb95819cf6 runtime: detect netbsd netpoll overrun in sysmon
+ 2020-12-21 53c984d976 runtime: skip wakep call in wakeNetPoller on Plan 9
+ 2020-12-21 9abbe27710 test: skip issue11656.go on mips/mips64/ppc64
+ 2020-12-20 89b44b4e2b cmd/compile: recognize reassignments involving receives
+ 2020-12-19 55b58018f4 test: for issue11656 try to execute trap, not call it
+ 2020-12-18 626cc7c02d test: permit "exponent too large" error
+ 2020-12-18 139cd0e12f go/build: make TestDependencies work again
+ 2020-12-18 2de7866470 os: remove dependency on strings package
+ 2020-12-18 c45313bf45 [dev.regabi] cmd/compile: remove prealloc map
+ 2020-12-18 ffb0cb7044 [dev.regabi] cmd/compile: remove uses of Name.Offset, Name.copy
+ 2020-12-18 c76be2a24e [dev.regabi] cmd/compile: add ONAMEOFFSET, delete to-be-deleted fields
+ 2020-12-18 4e8f1e139f [dev.regabi] cmd/compile: cleanup for concrete types - sinit
+ 2020-12-18 27aba22651 [dev.regabi] cmd/compile: cleanup for concrete types - walk
+ 2020-12-18 0b9cb63b8d [dev.regabi] cmd/compile: rename ir.Find to ir.Any and update uses
+ 2020-12-18 ae652a4ac9 os/signal: fix flaky tests for NotifyContext.
+ 2020-12-18 740851baca cmd/link: avoid use of -T when linking with lld
+ 2020-12-18 f1778c28a9 test: recognize and use gc build tag
+ 2020-12-17 8fcf318123 api/go1.16: remove crypto/tls APIs that are moved to Go 1.17
+ 2020-12-17 520f3b72db crypto/tls: revert "add HandshakeContext method to Conn"
+ 2020-12-17 2ff33f5e44 api: promote next to go1.16
+ 2020-12-17 aeedc9f804 [dev.regabi] cmd/compile: remove OSELRECV
+ 2020-12-17 0328c3b660 [dev.regabi] cmd/compile: use OSELRECV2 for all <-c variants
+ 2020-12-17 88e1415d08 [dev.regabi] cmd/compile: add type assertion in regabi test
+ 2020-12-17 9c384e881e [dev.regabi] cmd/compile: cleanup for concrete types - mop-up
+ 2020-12-17 be64c8bece [dev.regabi] cmd/compile: cleanup for concrete types - noder
+ 2020-12-17 5024396563 [dev.regabi] cmd/compile: cleanup for concrete types - subr
+ 2020-12-17 dd67b13d07 [dev.regabi] cmd/compile: cleanup for concrete types - range, select, swt
+ 2020-12-17 42fec2ded4 [dev.regabi] cmd/compile: cleanup for concrete types - const
+ 2020-12-17 389ae3d5ba [dev.regabi] cmd/compile: cleanup for concrete types - inl
+ 2020-12-17 5fe64298a4 [dev.regabi] cmd/compile: cleanup for concrete types - import/export
+ 2020-12-17 aa55d4e54b [dev.regabi] cmd/compile: cleanup for concrete types - escape
+ 2020-12-17 846740c17f [dev.regabi] cmd/compile: cleanup for concrete types - ssa
+ 2020-12-17 bf9bbbd6ed [dev.regabi] cmd/compile: cleanup for concrete types - order
+ 2020-12-17 4ac6a6317b [dev.regabi] cmd/compile: cleanup for concrete types - typecheck
+ 2020-12-17 f6efa3d4a4 [dev.regabi] cmd/compile: simplify ir.Find, replace ir.Inspect with ir.Visit
+ 2020-12-17 f6d2834f8f [dev.regabi] cmd/compile: limit Implicit method to nodes where it is defined
+ 2020-12-17 7fde0d2b50 [dev.regabi] cmd/compile: remove use of Initorder, Offset Node fields for initorder
+ 2020-12-17 114af2a044 [dev.regabi] cmd/compile: change Nodes to be a slice
+ 2020-12-17 4dfc7333f4 [dev.regabi] cmd/compile: update ir/fmt for concrete types
+ 2020-12-17 a997543292 [dev.regabi] cmd/compile: fix potential closure waste in Order
+ 2020-12-17 578fbbe3aa [dev.regabi] cmd/compile: rewrite some generic ir.Nod calls
+ 2020-12-17 5ae70b85c6 [dev.regabi] cmd/compile: cleanup preparing for concrete types, 2
+ 2020-12-17 fa06894b36 [dev.regabi] cmd/compile: cleanup preparing for concrete types
+ 2020-12-17 5a4db102b2 html/template: avoid race when escaping updates template
+ 2020-12-16 b0f01e17f8 go/types: report error for invalid (but empty) expr switch
+ 2020-12-16 5abda2618b cmd/link: handle large relocation addend on darwin/arm64
+ 2020-12-16 a318d56c1e cmd/link: pass arch-specific flags to external linker when testing supported flag
+ 2020-12-16 f4e7a6b905 cmd/internal/goobj: fix buglet in object file reader
+ 2020-12-16 75e16f5127 doc/go1.16: add link to reflect.StructTag
+ 2020-12-16 08b5091d03 net: close connection in localServer teardown
+ 2020-12-16 8981092d71 cmd/link: ignore SEH marking on PE objects
+ 2020-12-15 731bb54038 test: update for gofrontend error message changes
+ 2020-12-15 129bb1917b doc/go1.15: mention 1.15.3 cgo restriction on empty structs
+ 2020-12-15 685a322fe4 test: match gofrontend error messages
+ 2020-12-15 3d6467824c test: only require issue11674 errors with gc compiler
+ 2020-12-15 7cdc84a15b test: remove bug429 (duplicates runtime.TestSimpleDeadlock)
+ 2020-12-15 412dc2f4d3 test: adjust issue11371 to fit in required precision
+ 2020-12-15 8e2d74b705 test: only check for issue11362 error with gc
+ 2020-12-15 f8ac237032 test: import file name for issue19028
+ 2020-12-15 a508840c67 doc/go1.16: fix path, path/filepath release notes
+ 2020-12-15 5046cb8a6e doc/go1.16: fix formatting in net, net/http and net/http/httputil sections
+ 2020-12-15 3298300ddf text/template: error on range over send channel
+ 2020-12-15 4c2d66f642 [dev.regabi] cmd/compile: use ir.Ident for imported identifiers
+ 2020-12-15 305d93ef84 [dev.regabi] cmd/compile: type check externdcl earlier
+ 2020-12-15 9f16620f46 [dev.regabi] cmd/compile: fix latent Sym.SetPkgDef issue
+ 2020-12-15 5a25a3fd1d test: recognize gofrontend error messages
+ 2020-12-14 fea898a4b0 [dev.regabi] cmd/compile: intercept the making of OADDR nodes
+ 2020-12-14 663cd862ed cmd/link: do not mark resource section as writable
+ 2020-12-14 48dfa2b2dc cmd/link: deal with ADDR32NB relocations the same way as ADDR32 on arm
+ 2020-12-14 033390d9ad cmd/link: recognize arm header of PE objects
+ 2020-12-14 48906a6d57 net/http/pprof: don't treat os.Args as format string in Cmdline handler
+ 2020-12-14 6e3cc5c56f go/types: report invalid ... in conversions
+ 2020-12-14 278b9a8a4a io/fs: fix package reference in FS godoc
+ 2020-12-14 617383377f [dev.regabi] cmd/compile: reorg generated array hash loop
+ 2020-12-14 d06794da4a doc/go1.16: add missing <code> tag
+ 2020-12-14 dea6d94a44 math/big: add test for recursive division panic
+ 2020-12-14 2f5b1a3974 test: make a race detector test robust to timing variations
+ 2020-12-14 c81343ce3a net/http: attempt deadlock fix in TestDisableKeepAliveUpgrade
+ 2020-12-14 828746ec57 debug/dwarf: don't try to parse addr/rnglists header
+ 2020-12-14 be10af7c4e test: match gofrontend error messages
+ 2020-12-14 89f38323fa [dev.regabi] cmd/compile: add register ABI analysis utilities
+ 2020-12-14 ce61ccca8f test: match gofrontend error messages
+ 2020-12-14 a58be734ea cmd/compile: fix incorrect shift count type with s390x rules
+ 2020-12-14 8ce37e4110 [dev.regabi] cmd/compile: fix noopt builder
+ 2020-12-14 7e17b46c58 [dev.regabi] cmd/compile/internal/types: add IsScalar query method
+ 2020-12-14 2b76429eb0 [dev.regabi] cmd/compile: refactor type initialization code into helper
+ 2020-12-14 9c5241e520 [dev.regabi] cmd/compile: remove unnecessary String methods
+ 2020-12-14 267975dc47 Merge branch 'master' into dev.regabi
+ 2020-12-14 64d8846aae cmd/go: print hint when 'go install' run without version outside module
+ 2020-12-14 451b6b38fd cmd/go: refactor error reporting in internal/load
+ 2020-12-14 0a02371b05 cmd/compile: set correct type for OpIData
+ 2020-12-11 41d8e61a6b doc: make clear that Go 1.4 is not required for bootstrap
+ 2020-12-11 14305527f6 cmd/compile: fix select statement evaluation order corner case
+ 2020-12-11 1341a3decd cmd/go: add documentation for the -overlay flag
+ 2020-12-11 e508c1c67b cmd/link/internal/loadelf: support additional ELF relocations on mips64
+ 2020-12-11 58e381b0b2 cmd/vet: vendor in x/tools, update structtag vet check
+ 2020-12-10 e012d0dc34 syscall: drop references to Unix epoch in Timeval/Timespec docs
+ 2020-12-10 1fe891a937 doc/go1.16: add vet release note for CL 235677
+ 2020-12-10 6d3d3fb37f doc/go1.16: address some remaining high-level TODOs
+ 2020-12-10 6a64f6dc31 cmd/go: encode backslash and newline in response files
+ 2020-12-10 985d91666c runtime/metrics: add a note about floating-point values to package docs
+ 2020-12-10 e0d20e52ee runtime/metrics: expand Read documention with caveats
+ 2020-12-10 d0f40d2922 runtime/metrics: add ordering line to supported metrics docs
+ 2020-12-10 6d2b3351f6 test: match gofrontend error messages
+ 2020-12-10 e5522c882d std: update golang.org/x/net to 20201209123823-ac852fbbde11
+ 2020-12-10 422dc83baa database/sql: fix typo in comment
+ 2020-12-10 56b783ad94 cmd/go, cmd/asm: pass -linkshared to assembler for shared linkage builds
+ 2020-12-10 b110733327 cmd/link: reject too-large relocation addend on darwin/arm64
+ 2020-12-10 0aba8f24cb cmd/link: truncate file after code signature
+ 2020-12-10 6c64b6db68 cmd/compile: don't constant fold divide by zero
+ 2020-12-09 89f465c2b5 go/types: avoid endless recursion in the Comparable predicate
+ 2020-12-09 f1980efb92 all: update to use os.ReadDir where appropriate
+ 2020-12-09 4f1b0a44cb all: update to use os.ReadFile, os.WriteFile, os.CreateTemp, os.MkdirTemp
+ 2020-12-09 63bc23b545 [dev.regabi] cmd/compile: first start towards using Ident
+ 2020-12-09 eae8fd519b [dev.regabi] cmd/compile: iexport debug crumbs for toolstash
+ 2020-12-09 837b35cc55 [dev.regabi] cmd/compile: adjust IR representations
+ 2020-12-09 0c49440664 [dev.regabi] cmd/compile: arrange for walkstmt, walkexpr, to return from switch cases
+ 2020-12-09 4090af83c5 [dev.regabi] cmd/compile: use reflection in ir.Dump
+ 2020-12-09 e2d278bfeb [dev.regabi] cmd/compile: two small fixes
+ 2020-12-09 5627a4dc30 runtime/metrics: simplify test to support more environments
+ 2020-12-09 db6032dd0c cmd/compile: fix message typo
+ 2020-12-09 854a2f8e01 net/http: add connections back that haven't been canceled
+ 2020-12-09 6fa06d960b runtime: prevent stack growth after fork in runtime.sigfillset
+ 2020-12-09 ae9b442df2 doc: add description of new framepointer vet check
+ 2020-12-08 31496cfde5 cmd/vet: vendor in x/tools, enable framepointer vet check
+ 2020-12-08 01b76d5fbc go/types: correct error position for inherited const init expressions
+ 2020-12-08 48d6275952 doc/go1.16: improve channel race detector changes description
+ 2020-12-08 dbf2fc8cff [dev.regabi] cmd/compile: replace many uses of ir.Node with *ir.Name
+ 2020-12-08 bb31c75343 [dev.regabi] cmd/compile: ir.Node is no longer an ssa.Aux
+ 2020-12-08 6db970e20a [dev.regabi] cmd/compile: rewrite Aux uses of ir.Node to *ir.Name [generated]
+ 2020-12-08 1c8943a6ad [dev.regabi] cmd/compile: introduce FwdRefAux for wrapping ir.Node as ssa.Aux
+ 2020-12-08 9c91cab0da runtime: correct sigfwd on openbsd/mips64
+ 2020-12-08 dcec658f6c [dev.regabi] cmd/compile: change LocalSlot.N to *ir.Name
+ 2020-12-08 1a98ab0e2d [dev.regabi] cmd/compile: add ssa.Aux tag interface for Value.Aux
+ 2020-12-07 6362d01c15 doc/go1.16: update linker stats
+ 2020-12-07 9b8c272558 reflect: document multiple keys in struct tags
+ 2020-12-07 63722da46b [dev.regabi] cmd/compile: fix comment
+ 2020-12-07 7ad6596c47 io/fs: fix Sub method error text
+ 2020-12-07 6d783e7440 [dev.regabi] cmd/compile: export all Node fields [generated]
+ 2020-12-07 2de0af3b1b [dev.regabi] cmd/compile: prepare mknode for rename of Func.body
+ 2020-12-07 724374f859 [dev.regabi] cmd/compile: rewrite stale format strings
+ 2020-12-07 61889ba680 [dev.regabi] cmd/compile: simplify fmtmap
+ 2020-12-07 6ea2b8c54c [dev.regabi] cmd/compile: clean up and document formatting
+ 2020-12-07 bb4a37bd93 [dev.regabi] cmd/compile: move Type, Sym printing to package types [generated]
+ 2020-12-07 70155cca81 [dev.regabi] cmd/compile: untangle FmtFlag, FmtMode
+ 2020-12-07 3904a62829 [dev.regabi] cmd/compile: remove mode.Sprintf etc in printer
+ 2020-12-07 fb17dfa43d [dev.regabi] cmd/compile: narrow interface between ir and types
+ 2020-12-07 3b25f3c150 [dev.regabi] cmd/compile: simplify Op, Node, Nodes printing
+ 2020-12-07 8ce2605c5b [dev.regabi] cmd/compile: untangle ir.Dump printing
+ 2020-12-07 158c9dd131 [dev.regabi] cmd/compile: reorganize ir/fmt.go
+ 2020-12-07 a79742f39a [dev.regabi] cmd/compile: remove "short" node header mode
+ 2020-12-07 ef5964dd6b [dev.regabi] cmd/compile: arrange for typecheck1 to end in switch
+ 2020-12-07 dcc640e839 [dev.regabi] test: add exhaustive test of evaluated but not used
+ 2020-12-07 2cec6c4a8c [dev.regabi] cmd/compile: generate Node methods using program
+ 2020-12-07 50cdb2d8e9 runtime/cgo: fix building on musl
+ 2020-12-07 8d34585171 doc/go1.16: announce openbsd/mips64 port
+ 2020-12-07 9c0e2db051 test: add new test that gofrontend failed to handle
+ 2020-12-07 7f9a2bc2bc doc/go1.16: fix typo
+ 2020-12-07 ac0ba6707c doc/go1.16: add missing </a> tag
+ 2020-12-07 c155931974 internal/cpu: add darwin/arm64 CPU feature detection support
+ 2020-12-07 d90b199e9c [dev.regabi] cmd/compile: silence errors about missing blank methods
+ 2020-12-07 e10c94af26 doc/go1.16: document riscv64 port changes
+ 2020-12-06 e885df2731 [dev.regabi] cmd/compile: change iexport to avoid map[ir.Node]
+ 2020-12-06 2d4c95565a [dev.regabi] cmd/compile: change nowritebarrierrec to use map[*ir.Func]
+ 2020-12-06 1b5eed8982 [dev.regabi] cmd/compile: replace NodeQueue with NameQueue
+ 2020-12-06 6c5967e528 [dev.regabi] cmd/compile: change NodeSet to NameSet
+ 2020-12-05 3b2a578166 internal/cpu: fix typo in cpu_arm64.go
+ 2020-12-05 be9379f8a8 syscall: correct CertOpenStore to expect a 0 return value on failure
+ 2020-12-04 4de4480dc3 doc/go1.16: cleanup crypto release notes
+ 2020-12-04 0b99ea3b16 cmd/vendor: sync pprof@v0.0.0-20201203190320-1bf35d6f28c2
+ 2020-12-04 46b6e70e3b [dev.regabi] cmd/compile: replace ir.Node with *ir.Name in Order
+ 2020-12-04 b75f51c645 [dev.regabi] cmd/compile: replace ir.Node with *ir.Name in Liveness
+ 2020-12-04 133b03e1c3 [dev.regabi] cmd/compile: rewrite code to use DeclaredBy
+ 2020-12-04 d9cb84c84b [dev.regabi] cmd/compile: add SameSource, Uses, and DeclaredBy helpers
+ 2020-12-04 edf60be151 doc/go1.16: document no language changes
+ 2020-12-04 5dbd2e8e44 [dev.regabi] cmd/compile: remove DeepCopyNode interface
+ 2020-12-04 9ab3d854ad [dev.regabi] cmd/compile: avoid general traversal in deadcode
+ 2020-12-04 bb5aa2b664 [dev.regabi] cmd/compile: implement editChildren for nodes
+ 2020-12-04 4725c3ffd1 [dev.regabi] cmd/compile: implement doChildren for nodes
+ 2020-12-04 18f2df7e81 [dev.regabi] cmd/compile: implement copy for nodes
+ 2020-12-04 d855b30fe4 [dev.regabi] cmd/compile: use ir.EditChildren for inline rewriting
+ 2020-12-04 b9df26d7a8 [dev.regabi] cmd/compile: use ir.Find for "search" traversals
+ 2020-12-04 0d1b44c645 [dev.regabi] cmd/compile: introduce IR visitors
+ 2020-12-04 7fcf5b994c [dev.regabi] cmd/compile: replace inlcopy with ir.DeepCopy
+ 2020-12-04 989a3f5041 [dev.regabi] cmd/compile: adjustments to Copy and DeepCopy
+ 2020-12-04 99ecfcae31 [dev.regabi] cmd/compile: swap inlining order of if then vs else blocks
+ 2020-12-04 478bde3a43 io/fs: add Sub
+ 2020-12-04 5d4569197e cmd/go/internal/modload: fix minor errors in comments
+ 2020-12-04 21cfadf0dc runtime: avoid receiving preemotion signal while exec'ing
+ 2020-12-04 7358064508 doc/go1.16: preannounce dropping macOS 10.12 support
+ 2020-12-04 37588ffcb2 cmd/go, embed: exclude .* and _* from embedded directory trees
+ 2020-12-04 b67b7ddabc doc/go1.16: add reflect changes to release notes
+ 2020-12-04 cc386bd05a doc/go1.16: fix broken <code> tag
+ 2020-12-04 84cb51d7d7 [dev.regabi] cmd/compile: eliminate more SetOrig
+ 2020-12-04 2c2980aa0c doc/go1.16: pre-announce GODEBUG=x509ignoreCN=0 removal in Go 1.17
+ 2020-12-03 37a32a1833 cmd/compile: make sure address of offset(SP) is rematerializeable
+ 2020-12-03 b78b427be5 runtime, time: strictly enforce when, period constraints
+ 2020-12-03 b635e4b808 time, runtime: don't set timer when = 0
+ 2020-12-03 4eb7ceba06 doc/go1.16: update runtime and compiler sections
+ 2020-12-03 bacb307b80 test: match gofrontend error messages
+ 2020-12-03 7f5a3196c9 cmd/go/internal/modload: rename constants to reflect that lazy loading is not yet implemented
+ 2020-12-03 351bc2f38c [dev.regabi] cmd/compile: store types.Field on {Selector,CallPart}Expr
+ 2020-12-03 bdc9a837e9 doc/go1.16: add path, path/filepath changes to release notes
+ 2020-12-03 9b0e8a2c95 doc/go1.16: tidy darwin/arm64 port section
+ 2020-12-03 b1369d5862 math/big: remove the s390x assembly for shlVU and shrVU
+ 2020-12-03 a2058bac21 [dev.regabi] cmd/compile: add ConstExpr
+ 2020-12-03 beb5e05404 [dev.regabi] cmd/compile: refactoring prep for ConstExpr
+ 2020-12-03 7e81135be7 [dev.regabi] cmd/compile: rename addinit(n, init) to initExpr(init, n)
+ 2020-12-03 6e30fc10fc [dev.regabi] all: merge master (d0c0dc682c1f) into dev.regabi
+ 2020-12-03 dda2991c2e internal/cpu: disable FMA when OSXSAVE is not enabled on x86
+ 2020-12-03 58768ae15b test: match gccgo error messages
+ 2020-12-03 59b8916d48 [dev.regabi] cmd/compile: handle OCONVNOP better in ssa
+ 2020-12-03 932733d421 doc/go1.16: document embed, io/fs, runtime/metrics
+ 2020-12-03 c519b156fc doc/go1.16: more release notes
+ 2020-12-03 5246fa5e75 mime/multipart: handle ReadForm(math.MaxInt64) better
+ 2020-12-03 07cba70d57 cmd/compile, runtime: use __msan_memmove for moving data, split msanread to fields
+ 2020-12-03 d0c0dc682c doc/go1.16: document os package changes
+ 2020-12-03 00e5727790 [dev.regabi] cmd/compile: remove okAs
+ 2020-12-03 5a3b6796cd [dev.regabi] cmd/compile: remove extra typ field in Name struct
+ 2020-12-03 da54dfb6a1 doc/go1.16: document new behavior of asn1.Unmarshal on invalid argument
+ 2020-12-03 78e442ea79 doc/go1.16: add encoding/json note for tag change
+ 2020-12-02 f26f227f66 doc/go1.16: add crypto/tls Config.Clone note
+ 2020-12-02 64bc656aed [dev.regabi] cmd/compile: use explicit block statements for init
+ 2020-12-02 48838c35dc go/parser: ignore subdirectories in ParseDir
+ 2020-12-02 2d0258d495 crypto/ed25519/internal/edwards25519: fix typo in comments
+ 2020-12-02 ecc8d15bc5 [dev.regabi] cmd/compile: delete OEMPTY
+ 2020-12-02 ec5f349b22 [dev.regabi] cmd/compile: merge OBLOCK and OEMPTY
+ 2020-12-02 05ddb879c7 cmd/go: fix TestNewReleaseRebuildsStalePackagesInGOPATH
+ 2020-12-02 ac38af2f3d cmd/go: stop tests from using network during -short
+ 2020-12-02 3d913a9266 os: add ReadFile, WriteFile, CreateTemp (was TempFile), MkdirTemp (was TempDir) from io/ioutil
+ 2020-12-02 5984ea7197 doc: update signal.Notify example to use buffered channel
+ 2020-12-02 10240b9d6b cmd/go: fix unbuffered channel passed to signal.Notify
+ 2020-12-02 c32140fa94 all: update to use filepath.WalkDir instead of filepath.Walk
+ 2020-12-02 0433845ad1 cmd/asm, cmd/internal/obj/riscv: fix branch pseudo-instructions
+ 2020-12-02 c769d393de [dev.regabi] cmd/compile: add ir.NewDeclNameAt
+ 2020-12-02 c10b0ad628 [dev.regabi] cmd/compile: add Pkg parameter to type constructors
+ 2020-12-02 42e46f4ae0 [dev.regabi] cmd/compile: comment out //go:linkname warning
+ 2020-12-02 77a71e0057 [dev.regabi] cmd/compile: add Interface, Signature, and Struct constructors
+ 2020-12-02 15085f8974 [dev.regabi] cmd/compile: tweak hash bucket type descriptor
+ 2020-12-02 73e796cb00 test: match gofrontend error messages
+ 2020-12-01 cf7aa585ac cmd/link: invalidate kernel cache on darwin
+ 2020-12-01 8cd35e00bd cmd/internal/buildid: update Mach-O code signature when rewriting buildid
+ 2020-12-01 6f84993e90 cmd/link: code-sign on darwin/arm64
+ 2020-12-01 4826abb6c2 cmd/compile: do not assume TST and TEQ set V on arm
+ 2020-12-01 283d65413d encoding/json: revert "add "json: " prefix to SyntaxError messages"
+ 2020-12-01 1408d26ccc [dev.regabi] cmd/compile: cleanup some leftover cruft
+ 2020-12-01 7fca39aa05 cmd/internal/buildid: exclude Mach-O code signature in hash calculation
+ 2020-12-01 7430266af4 cmd/internal/codesign: new package
+ 2020-12-01 20e251864b cmd: update golang.org/x/mod to v0.4.0
+ 2020-12-01 933ce97bba cmd/go: don't print deprecation notice for 'go get exe'
+ 2020-12-01 50b16f9de5 net/http: allow upgrading non keepalive connections
+ 2020-12-01 212d385a2f net/http: ignore connection closes once done with the connection
+ 2020-12-01 4ef78b09c9 doc/go1.16: add runtime/debug changes to release notes
+ 2020-12-01 ae3bfba626 doc/go1.16: add text/template changes to release notes
+ 2020-12-01 5ffa275f3c [dev.regabi] cmd/compile: first pass at abstracting Type
+ 2020-12-01 dd4a52c2a5 doc/go1.16: add multiple release notes for the go command
+ 2020-12-01 6ca23a45fe [dev.regabi] cmd/compile: only save ONAMEs on Curfn.Dcl
+ 2020-12-01 a17c5e2fce [dev.regabi] cmd/compile: add NewBasic and cleanup universe
+ 2020-12-01 f37aa5e4e2 [dev.regabi] cmd/compile: add NewNamed
+ 2020-12-01 63a6f08b39 [dev.regabi] cmd/compile: move setUnderlying to package types
+ 2020-12-01 f2311462ab [dev.regabi] cmd/compile: cleanup type-checking of defined types
+ 2020-12-01 2d6ff998ed [dev.regabi] cmd/compile: process //go:linknames after declarations
+ 2020-12-01 ecff7628ea [dev.regabi] cmd/compile: unexport Node.RawCopy
+ 2020-12-01 4da41fb3f8 [dev.regabi] cmd/compile: use ir.Copy instead of direct use of RawCopy
+ 2020-12-01 dadfc80bc1 [dev.regabi] cmd/compile: improve findTypeLoop
+ 2020-12-01 f5978a0958 cmd/internal/obj/riscv: add tests for BGE/BGEU/BLT/BLTU
+ 2020-12-01 a36ba090fd cmd/link/internal/amd64: always generate R_X86_64_PLT32 for SDYNIMPORT calls
+ 2020-12-01 f3741bdf7c doc/go1.16: add crypto/x509 note about Verify on Windows
+ 2020-12-01 45f3b646d4 [dev.regabi] cmd/compile: add OSTMTEXPR Op
+ 2020-12-01 9a5a11adfa [dev.regabi] cmd/compile: add custom expression Node implementations
+ 2020-12-01 0ecf769633 cmd/compile: do not mark OpSP, OpSB pos for debugging
+ 2020-12-01 0f9f27287b [dev.regabi] cmd/compile: remove types.InitSyms
+ 2020-11-30 41ad4dec99 [dev.regabi] cmd/compile: fix -h
+ 2020-11-30 ffa68716a0 [dev.regabi] cmd/compile: add custom statement Node implementations
+ 2020-11-30 2bc814cd18 [dev.regabi] cmd/compile: clean up ONEW node
+ 2020-11-30 b7f67b75d2 [dev.regabi] cmd/compile: clean up in preparation for expression Nodes
+ 2020-11-30 5fc192af56 [dev.regabi] cmd/compile: clean up Order.copyExpr TODO
+ 2020-11-30 7c9b6b1ca2 [dev.regabi] cmd/compile: clean up in preparation for statement Nodes
+ 2020-11-30 7f688d18c0 runtime: mlock signal stack on macOS/ARM64
+ 2020-11-30 c6de5d8d1f [dev.regabi] cmd/compile: simplify export data representation of nil
+ 2020-11-30 d2b436d95d cmd/go: fix infinite loop in modload.keepSums
+ 2020-11-30 4f42a9b76b net: add note about disabling loopback in ListenMulticastUDP()
+ 2020-11-30 7b192f33cf cmd/go: remove trailing whitespace from test script
+ 2020-11-30 848dff6dda test: update gofrontend expected errors
+ 2020-11-30 a45e12fd4b test: recognize gofrontend error messages
+ 2020-11-30 d6abf298cf test: recognize new gofrontend error message
+ 2020-11-30 ae1a337809 [dev.regabi] cmd/compile: remove ODCLFIELD and ODDD ops
+ 2020-11-30 4e7685ef1a [dev.regabi] cmd/compile: add custom type syntax Node implementations
+ 2020-11-30 d40869fced [dev.regabi] cmd/compile: move gc.treecopy to ir.DeepCopy
+ 2020-11-30 f0001e8867 [dev.regabi] cmd/compile: add OTSLICE Op
+ 2020-11-30 1b84aabb01 [dev.regabi] cmd/compile: move typenod, typenodl to ir.TypeNode, ir.TypeNodeAt [generated]
+ 2020-11-30 e5c6463e20 [dev.regabi] cmd/compile: add ir.CallPartExpr
+ 2020-11-30 4eaef981b5 [dev.regabi] cmd/compile: add ir.Closure, ir.ClosureRead
+ 2020-11-30 e84b27bec5 [dev.regabi] cmd/compile: clean up Name and Func uses
+ 2020-11-30 c4bd0b7474 [dev.regabi] cmd/compile: make ir.Func the ODCLFUNC Node implementation
+ 2020-11-30 65ae15ac5d [dev.regabi] cmd/compile: move func code from node.go to func.go
+ 2020-11-30 862f638a89 [dev.regabi] cmd/compile: make ir.Name the ONAME Node implementation
+ 2020-11-30 f6106d195d [dev.regabi] cmd/compile: add ir.PkgName
+ 2020-11-30 420809ab08 [dev.regabi] cmd/compile: move name code from node.go to name.go
+ 2020-11-30 be3d8b40b5 [dev.regabi] cmd/compile: ir.BranchStmt, add ir.EmptyStmt, ir.LabelStmt
+ 2020-11-30 b09dbc6913 [dev.regabi] cmd/compile: remove SetOp(OEMPTY) calls
+ 2020-11-30 171787efcd [dev.regabi] cmd/compile: remove Orig, SetOrig from Node interface
+ 2020-11-30 79a3d5ce15 [dev.regabi] cmd/compile: setup for new Node implementations
+ 2020-11-30 0c65a2f317 [dev.regabi] cmd/compile: drop Node.HasOpt method
+ 2020-11-30 65f4ec2fae [dev.regabi] cmd/compile: cleanup label handling
+ 2020-11-30 c193279e2c os: return proper user directories on iOS
+ 2020-11-30 294c214cca runtime: gofmt
+ 2020-11-30 e5da18df52 os/exec: constrain thread usage in leaked descriptor test on illumos
+ 2020-11-28 4ce0a7cea6 runtime/pprof: ignore test failures on windows/arm
+ 2020-11-28 358d35455d bufio: make string(int) conversion safer
+ 2020-11-28 b94346e69b test: match gofrontend error messages
+ 2020-11-27 cb84d831c9 cmd/link: mark windows/arm as all PIE
+ 2020-11-27 0252cfd84d runtime: adjust address calculation in identifying abort on windows/arm
+ 2020-11-27 91f77ca2f8 runtime: return 0 from C function in test
+ 2020-11-26 926994fd7c log: make Default doc comment consistent with package doc
+ 2020-11-26 f0ff6d4a67 reflect: fix Value.Convert for int-to-string conversions (regression)
+ 2020-11-25 88e33f6ecb [dev.regabi] cmd/compile: fix latent import/export issue with break/continue
+ 2020-11-25 40f5bc4d55 [dev.regabi] merge master 4481ad6eb6 into dev.regabi
+ 2020-11-25 4481ad6eb6 doc/go1.16: consolidate stdlib changes in "Minor changes" section
+ 2020-11-25 ef603bead5 cmd/dist: restore GOARM=7 default for android/arm
+ 2020-11-25 41f3af9d04 [dev.regabi] cmd/compile: replace *Node type with an interface Node [generated]
+ 2020-11-25 4d0d9c2c5c [dev.regabi] cmd/compile: introduce ir.INode interface for *ir.Node
+ 2020-11-25 c26aead50c [dev.regabi] cmd/compile: convert types.Node (a pointer) to types.IRNode (an interface)
+ 2020-11-25 acb4d1cef1 [dev.regabi] cmd/compile: use Node getters and setters [generated]
+ 2020-11-25 41ab6689ed [dev.regabi] cmd/compile: rewrite a few ++/--/+=/-= to prep for getters/setters [generated]
+ 2020-11-25 048debb224 [dev.regabi] cmd/compile: remove gc ↔ ssa cycle hacks
+ 2020-11-25 84e2bd611f [dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
+ 2020-11-25 331b8b4797 [dev.regabi] cmd/compile: move okforconst into its own declaration
+ 2020-11-25 26b66fd60b [dev.regabi] cmd/compile: introduce cmd/compile/internal/base [generated]
+ 2020-11-25 eb3086e5a8 [dev.regabi] cmd/compile: finish cleanup of Debug parsing
+ 2020-11-25 3c240f5d17 [dev.regabi] cmd/compile: clean up debug flag (-d) handling [generated]
+ 2020-11-25 9dc2350d8c doc/go1.16: add time/tzdata release note for CL 261877
+ 2020-11-25 756661c82a [dev.regabi] cmd/compile: finish cleanup of Flag initialization
+ 2020-11-25 b9365488f0 cmd/internal/objabi: assume GOARM=7 on Android
+ 2020-11-25 df68e01b68 runtime: check channel's elemsize before calling race detector
+ 2020-11-25 259fd8adbb [dev.regabi] cmd/compile: fix reporting of overflow
+ 2020-11-25 1d3baf20dc regexp/syntax: add note about Unicode character classes
+ 2020-11-25 18573aea3c [dev.regabi] cmd/compile: clean up flag handling [generated]
+ 2020-11-25 6e583d65ab [dev.regabi] cmd/compile: simplify fmt handling of Nodes
+ 2020-11-25 d166ef6876 [dev.regabi] cmd/compile: add Node field getters and setters
+ 2020-11-25 750b3729dc go/constant: MakeFloat64(0) must return a value of Float kind
+ 2020-11-25 9262909764 [dev.regabi] cmd/compile: rewrite problematic use of Node fields
+ 2020-11-25 9e0e43d84d [dev.regabi] cmd/compile: remove uses of dummy
+ 2020-11-25 4a6b4fd139 [dev.regabi] add FatalfAt and fix Fatalf docs
+ 2020-11-25 484449c641 [dev.regabi] cmd/compile: remove file mistakenly added by CL 272248
+ 2020-11-25 1308f11897 cmd/link: add relocation type R_AARCH64_LDST16_ABS_LO12_NC for arm64
+ 2020-11-25 f6dcc975f7 go/constant: make constant.Make produce "smallest" const representation
+ 2020-11-25 7d72951229 [dev.regabi] cmd/compile: replace Val with go/constant.Value
+ 2020-11-24 e8de596f04 runtime: use inlined function name for traceback elision
+ 2020-11-24 ba2adc21e8 runtime/testdata/testprogcgo: refactor CrashTraceback
+ 2020-11-24 6826287c6b [dev.regabi] cmd/compile: replace evconst with non-mutating version
+ 2020-11-24 c22bc745c3 [dev.regabi] cmd/compile: delete n.List after collapsing OADDSTR to OLITERAL
+ 2020-11-24 ee6132a698 [dev.regabi] cmd/compile: introduce OMETHEXPR instead of overloading ONAME
+ 2020-11-24 4f9d54e41d [dev.regabi] cmd/compile: add OMETHEXPR
+ 2020-11-24 fd11a32c92 [dev.regabi] cmd/compile: clean up Node.Func
+ 2020-11-24 8e2106327c [dev.regabi] cmd/compile: clean up tests to know less about Node
+ 2020-11-24 65dcd15c72 doc/go1.16: fill in Go 1.16 release note TODOs using relnote
+ 2020-11-24 742c05e3bc [dev.regabi] cmd/compile: prep refactoring for switching to go/constant
+ 2020-11-24 015423a15b [dev.regabi] strconv: add to bootstrap packages
+ 2020-11-24 c767d73227 [dev.regabi] cmd/compile: remove CTRUNE
+ 2020-11-24 6dae48fb0b [dev.regabi] cmd/compile: refactor type/value assertions
+ 2020-11-24 88a9e2f9ad [dev.regabi] cmd/compile: replace CTNIL with ONIL
+ 2020-11-24 4af2decf30 [dev.regabi] cmd/compile: add (unused) ONIL constant
+ 2020-11-24 668e3a598f [dev.regabi] cmd/compile: cleanup type switch typechecking
+ 2020-11-24 96f3fb7244 [dev.regabi] go/constant: avoid heap allocations in match
+ 2020-11-24 1abb12fc97 [dev.regabi] go/constant: optimize BitLen
+ 2020-11-24 228b732ad9 [dev.regabi] cmd/compile: prepare for package ir
+ 2020-11-24 e37597f7f0 [dev.regabi] cmd/compile: rename a few 'base' identifiers
+ 2020-11-24 357c576878 [dev.regabi] cmd/compile: clean up error API
+ 2020-11-24 5fd949e4bd [dev.regabi] cmd/compile: initialize importMap lazily
+ 2020-11-24 7b144ed4f7 [dev.regabi] cmd/compile: rewrite concurrentFlagOk to be clearer
+ 2020-11-24 6965b01ea2 runtime: allow for usleep2HighRes to run without TLS setup
+ 2020-11-24 7dc5d909fb cmd/compile: set OpLoad argument type interface{} correctly
+ 2020-11-24 c754f25241 [dev.regabi] cmd/compile/internal/types: remove Func.Nname
+ 2020-11-24 c50c7a8c06 [dev.regabi] cmd/compile/internal/gc: refactor to use stop using Func.Nname
+ 2020-11-24 d5928847de [dev.regabi] cmd/compile/internal/gc: prep for Func.Nname removal refactoring
+ 2020-11-24 b30c7a8044 [dev.regabi] cmd/compile/internal/gc: add MethodName for getting referenced method
+ 2020-11-24 e1047302bd [dev.regabi] cmd/compile/internal/types: add pos/sym/typ params to NewField
+ 2020-11-24 762eda346a go/types: fix incorrect string(int) conversion (regression)
+ 2020-11-23 48a1a51898 runtime/metrics: tweak wording of stack and unused memory metrics
+ 2020-11-23 d902791b50 sync: use 386 instead of x86-32 to refer to the 32 bit x86 architecture
+ 2020-11-21 9ea6364a5e cmd/compile: add test for 42753
+ 2020-11-21 f7342596da syscall: add DLLError.Unwrap function
+ 2020-11-21 f93ef07b11 cmd/go/internal/modload: remove the Reqs function
+ 2020-11-21 3f5a97514b cmd/go/internal/modload: remove a stale comment for EditBuildList
+ 2020-11-20 78e59bb1f7 cmd/go: support the -overlay flag for go mod commands
+ 2020-11-20 c47eac7db0 cmd/cgo, cmd/internal/pkgpath: support gofrontend mangler v3
+ 2020-11-20 3fd4917472 doc: fix misspelling of “initialization” in diagnostics.html
+ 2020-11-20 676f0a45ed cmd/go: support overlaying go.mod files
+ 2020-11-20 a19c925eda cmd/go: recommend 'go get' command to switch from retracted versions
+ 2020-11-20 c306fd6d0b cmd/compile: allow loading single field of typed-interface{} OpIData
+ 2020-11-20 5e58ae43be cmd/go: report changes and resolved versions in 'go get'
+ 2020-11-20 012efc67f2 cmd/go/internal/modload: ignore selected version in checkRetractions
+ 2020-11-20 9264067a41 cmd/go: remove ListModules call in runGet
+ 2020-11-20 cb3f84ad25 cmd/go/internal/modload: eliminate LoadedModules
+ 2020-11-20 8bbd8294d0 cmd/go/internal/work: remove a redundant call to modload.LoadedModules
+ 2020-11-20 66c0264506 net, internal/poll: reset value before adding in minor kernel version
+ 2020-11-20 0dcc7d6ea8 go/types: use correct error position
+ 2020-11-20 c72a448881 go/types: fix error message for consistency
+ 2020-11-20 7eed73f36f go/types, go/constant: handle infinities as unknown values
+ 2020-11-19 f3ce010b33 io/fs: make WalkDirFunc parameter name consistent with doc comment
+ 2020-11-19 59f5fdac5d runtime/metrics: clarify Read's documentation
+ 2020-11-19 add45938b5 runtime/metrics: clarify memory and GC metrics documentation
+ 2020-11-19 498d8d5371 cmd/go/internal/work: avoid modload.Selected in 'go install pkg@version'
+ 2020-11-19 e73697b710 cmd/go: fix failing gccgo cases in TestScript/build_overlay
+ 2020-11-19 cb674b5c13 cmd/compile,cmd/asm: fix function pointer call perf regression on ppc64
+ 2020-11-19 c31540364c cmd/compile:  flag "-d=dumpptrs" to print Node ptrs in Dump output
+ 2020-11-19 4d048194cd runtime: support new callbackasm1 calling convention on windows/arm
+ 2020-11-19 5ba1c3f290 cmd/go/internal/modload: remove SetBuildList
+ 2020-11-19 ff2824d4b3 cmd/go/internal/modcmd: eliminate a call to modload.LoadedModules
+ 2020-11-19 0bb6115dd6 internal/fmtsort: sort the unsafe pointers in map
+ 2020-11-19 96b943a483 go/types: report an error for invalid constant values
+ 2020-11-18 35693d037f cmd/compile: fix miscompilation during inlining
+ 2020-11-18 5b0ec1a6ac cmd/compile: fix panic in field tracking logic
+ 2020-11-18 b4f3d52f6a sync: document RWMutex race semantics
+ 2020-11-18 b63db7f724 runtime: give test child time to block
+ 2020-11-18 ae76f6e962 runtime: use clock_gettime instead of gettimeofday on darwin
+ 2020-11-18 ee1b51294a runtime: use pipe2 syscall for Pipe in tests
+ 2020-11-18 d3072b8383 cmd/go: in 'go get', only load retractions for resolved versions
+ 2020-11-18 b194b5151f cmd/link: recompute heapPos after copyHeap
+ 2020-11-18 64ef84881f cmd/go: fix retract interval syntax in 'go help mod edit'
+ 2020-11-18 399b5d14d4 cmd/compile: stop MOVW-ing -1 as SRA shift amount in mips
+ 2020-11-18 a14e7bf6d4 go/ast: document invalid comment end positions with CRLF line endings
+ 2020-11-18 bcfaeca58c time: in NewTicker, document that the 1st tick comes after d
+ 2020-11-17 041a4e4c34 go/types: add test case for incorrect map index expression
+ 2020-11-17 05082c90d5 cmd/compile: clean up buggy DWARF inlined info PC ranges
+ 2020-11-17 01df2febf5 cmd/go: allow querying other versions of the main module
+ 2020-11-17 0968d2d599 cmd/go/internal/modget: clarify error for 'go get' without arguments
+ 2020-11-17 3e56bad13b cmd/go: revert "in 'go get', only load retractions for resolved versions"
+ 2020-11-17 0ae3b7cb74 cmd/compile: fix rules regression with shifts on PPC64
+ 2020-11-16 869e2957b9 cmd/go: update 'go help mod init'
+ 2020-11-16 97700baf8b cmd/go: in 'go get', only load retractions for resolved versions
+ 2020-11-16 38367d098e cmd/link/internal/ld: dedup shared libraries on openbsd
+ 2020-11-16 d834ecec86 runtime/race: reject runtime fatal error in tests
+ 2020-11-16 0932dc2118 runtime: declare arg size/map for race version of sync/atomic functions
+ 2020-11-16 d70a33a40b cmd/go/internal/work: add missing newline to go version note
+ 2020-11-16 c7233dd063 cmd/go: permit wrongly rejected -Wl,-O... linker flags
+ 2020-11-16 f2eea4c1dc cmd/compile: mask SLL,SRL,SRAconst shift amount
+ 2020-11-14 92c732e901 cmd/compile: fix load of interface{}-typed OpIData in expand_calls
+ 2020-11-14 782cf560db cmd/go: permit CGO_LDFLAGS to appear in //go:ldflag
+ 2020-11-13 4f63e0a1f8 cmd/compile:  update comments only for Node types and some functions
+ 2020-11-13 86954d5246 cmd/compile: mark plugin-exported types as used in interface
+ 2020-11-13 f423d616b1 cmd/cgo: fix initialization of empty argument types
+ 2020-11-13 35455fff0e runtime: swap the order of raceacquire() and racerelease()
+ 2020-11-13 31f71506d7 syscall: use correct type for TIOCSPGRP/TIOCGPGRP
+ 2020-11-12 30ba798093 cmd/go: use overlaid path contents in build cache
+ 2020-11-12 f016172dbe cmd/go: pass in overlaid paths for .s files
+ 2020-11-12 60b1253293 cmd/go: pass in overlaid file paths to C compiler
+ 2020-11-12 062e0e5ce6 cmd/go, cmd/cgo: don't let bogus symbol set cgo_ldflag
+ 2020-11-12 1e1fa5903b math/big: fix shift for recursive division
+ 2020-11-12 b34b0aaf69 cmd/go: skip TestScript/build_plugin_non_main on platforms that do not support -buildmode=plugin
+ 2020-11-12 c167635a6e cmd/compile: gofmt
+ 2020-11-12 e75aef80ca cmd/go: migrate away from semver.Max
+ 2020-11-12 9ef65ff137 cmd/compile: do not emit an extra debug_line entry for the end of seq addr
+ 2020-11-12 4bc5f6f45f cmd/link: put DYLD_INFO at beginning of LINKEDIT segment on darwin
+ 2020-11-12 d7974c31d0 os: gofmt
+ 2020-11-11 141fa337ad bytes: add example for (*Buffer).Bytes
+ 2020-11-11 f2e58c6d42 syscall: improve TestSetuidEtc() /proc/ parsing against races
+ 2020-11-11 4c174a7ba6 testing: reduce memory allocation in Helper
+ 2020-11-11 b641f0dcf4 os: clarify that IsExist and friends do not use errors.Is
+ 2020-11-11 26a860706a doc/go1.16: add crypto/x509 CSR release note
+ 2020-11-11 28437546f4 cmd/go: don't copy cgo files to objdir when overlay is present
+ 2020-11-11 c906608406 io/fs: fix reference to WalkFunc
+ 2020-11-11 f2e186b877 all: update vendored dependencies for Go 1.16 release
+ 2020-11-10 8f2db14cd3 cmd/go: release note for -mod=readonly by default
+ 2020-11-10 b2ef159db2 cmd/go: introduce the GOVERSION env variable
+ 2020-11-10 1948c00b6e doc/go1.16: add release notes for darwin ports
+ 2020-11-10 da3957ad0d Revert "cmd/go: don't copy cgo files to objdir when overlay is present"
+ 2020-11-10 0e0a872a76 runtime: add lock rank partial order edge pollDesc -> spanSetSpine
+ 2020-11-10 c68745b130 runtime: add lock rank partial order edge sweep -> mspanSpecial
+ 2020-11-10 e3de852f3e cmd/go: don't copy cgo files to objdir when overlay is present
+ 2020-11-10 189931296f cmd/internal/obj/s390x: fix SYNC instruction encoding
+ 2020-11-10 81322b9191 runtime/race: remove race from TestNoRaceAfterFunc2
+ 2020-11-10 1c7650aa93 internal/poll: use copy_file_range only on Linux kernel >= 5.3
+ 2020-11-10 1642cd78b5 cmd/go: update test_race_install expected output for CL 266368

Change-Id: I7ce5350ac9d0647236f1061a540c6751fb9faae9

84 files changed:
README.boringcrypto.md [new file with mode: 0644]
api/go1.9.txt
codereview.cfg [new file with mode: 0644]
misc/boring/README.md [new file with mode: 0644]
misc/boring/RELEASES [new file with mode: 0644]
misc/boring/VERSION [new file with mode: 0644]
misc/boring/build.docker [new file with mode: 0755]
misc/boring/build.release [new file with mode: 0755]
misc/boring/dockerfile.in [new file with mode: 0644]
misc/boring/merge.sh [new file with mode: 0755]
misc/boring/release.sh [new file with mode: 0755]
src/cmd/compile/internal/reflectdata/reflect.go
src/cmd/go/go_boring_test.go [new file with mode: 0644]
src/cmd/go/go_test.go
src/cmd/go/internal/load/pkg.go
src/cmd/link/internal/ld/lib.go
src/crypto/aes/cipher.go
src/crypto/aes/cipher_asm.go
src/crypto/boring/boring.go [new file with mode: 0644]
src/crypto/boring/boring_test.go [new file with mode: 0644]
src/crypto/boring/notboring_test.go [new file with mode: 0644]
src/crypto/ecdsa/boring.go [new file with mode: 0644]
src/crypto/ecdsa/ecdsa.go
src/crypto/hmac/hmac.go
src/crypto/hmac/hmac_test.go
src/crypto/internal/boring/Dockerfile [new file with mode: 0644]
src/crypto/internal/boring/LICENSE [new file with mode: 0644]
src/crypto/internal/boring/aes.go [new file with mode: 0644]
src/crypto/internal/boring/boring.go [new file with mode: 0644]
src/crypto/internal/boring/boring_test.go [new file with mode: 0644]
src/crypto/internal/boring/build.sh [new file with mode: 0755]
src/crypto/internal/boring/doc.go [new file with mode: 0644]
src/crypto/internal/boring/ecdsa.go [new file with mode: 0644]
src/crypto/internal/boring/fipstls/dummy.s [new file with mode: 0644]
src/crypto/internal/boring/fipstls/tls.go [new file with mode: 0644]
src/crypto/internal/boring/goboringcrypto.h [new file with mode: 0644]
src/crypto/internal/boring/goboringcrypto_linux_amd64.syso [new file with mode: 0644]
src/crypto/internal/boring/hmac.go [new file with mode: 0644]
src/crypto/internal/boring/notboring.go [new file with mode: 0644]
src/crypto/internal/boring/rand.go [new file with mode: 0644]
src/crypto/internal/boring/rsa.go [new file with mode: 0644]
src/crypto/internal/boring/sha.go [new file with mode: 0644]
src/crypto/internal/boring/sig/sig.go [new file with mode: 0644]
src/crypto/internal/boring/sig/sig_amd64.s [new file with mode: 0644]
src/crypto/internal/boring/sig/sig_other.s [new file with mode: 0644]
src/crypto/issue21104_test.go
src/crypto/rand/rand_unix.go
src/crypto/rsa/boring.go [new file with mode: 0644]
src/crypto/rsa/boring_test.go [new file with mode: 0644]
src/crypto/rsa/pkcs1v15.go
src/crypto/rsa/pkcs1v15_test.go
src/crypto/rsa/pss.go
src/crypto/rsa/pss_test.go
src/crypto/rsa/rsa.go
src/crypto/rsa/rsa_test.go
src/crypto/sha1/boring.go [new file with mode: 0644]
src/crypto/sha1/notboring.go [new file with mode: 0644]
src/crypto/sha1/sha1.go
src/crypto/sha1/sha1_test.go
src/crypto/sha256/sha256.go
src/crypto/sha256/sha256_test.go
src/crypto/sha512/sha512.go
src/crypto/sha512/sha512_test.go
src/crypto/tls/auth.go
src/crypto/tls/auth_test.go
src/crypto/tls/boring.go [new file with mode: 0644]
src/crypto/tls/boring_test.go [new file with mode: 0644]
src/crypto/tls/cipher_suites.go
src/crypto/tls/common.go
src/crypto/tls/fipsonly/fipsonly.go [new file with mode: 0644]
src/crypto/tls/fipsonly/fipsonly_test.go [new file with mode: 0644]
src/crypto/tls/handshake_client.go
src/crypto/tls/handshake_client_tls13.go
src/crypto/tls/handshake_messages_test.go
src/crypto/tls/handshake_server.go
src/crypto/tls/handshake_server_test.go
src/crypto/tls/handshake_server_tls13.go
src/crypto/x509/verify.go
src/go/build/build.go
src/go/build/deps_test.go
src/internal/boringtest/boring.go [new file with mode: 0644]
src/internal/boringtest/boring_test.go [new file with mode: 0644]
src/runtime/race/testdata/mop_test.go
src/runtime/runtime_boring.go [new file with mode: 0644]

diff --git a/README.boringcrypto.md b/README.boringcrypto.md
new file mode 100644 (file)
index 0000000..54adda6
--- /dev/null
@@ -0,0 +1,20 @@
+# dev.boringcrypto branch
+
+We have been working inside Google on a fork of Go that uses
+BoringCrypto (the core of [BoringSSL][]) for various crypto
+primitives, in furtherance of some [work related to FIPS 140-2][sp].
+We have heard that some external users of Go would be interested in
+this code as well, so this branch holds the patches to make Go use
+BoringCrypto.
+
+[BoringSSL]: https://boringssl.googlesource.com/boringssl/
+[sp]: https://csrc.nist.gov/CSRC/media/projects/cryptographic-module-validation-program/documents/security-policies/140sp3678.pdf
+
+Unlike typical dev branches, we do not intend any eventual merge of
+this code into the master branch. Instead we intend to maintain in
+this branch the latest release plus BoringCrypto patches.
+
+To be clear, we are not making any statements or representations about
+the suitability of this code in relation to the FIPS 140-2 standard.
+Interested users will have to evaluate for themselves whether the code
+is useful for their own purposes.
index c23a17ea1a39491822283aa30de439301b5ffc0f..c7a4968aaf701db13a4ed7809a3dde22c8e741fd 100644 (file)
@@ -7,6 +7,7 @@ pkg crypto, const BLAKE2b_512 Hash
 pkg crypto, const BLAKE2s_256 = 16
 pkg crypto, const BLAKE2s_256 Hash
 pkg crypto/x509, type Certificate struct, ExcludedDNSDomains []string
+pkg crypto/x509, type VerifyOptions struct, IsBoring func(*Certificate) bool
 pkg database/sql, method (*Conn) BeginTx(context.Context, *TxOptions) (*Tx, error)
 pkg database/sql, method (*Conn) Close() error
 pkg database/sql, method (*Conn) ExecContext(context.Context, string, ...interface{}) (Result, error)
diff --git a/codereview.cfg b/codereview.cfg
new file mode 100644 (file)
index 0000000..4157a72
--- /dev/null
@@ -0,0 +1,2 @@
+branch: dev.boringcrypto
+parent-branch: master
diff --git a/misc/boring/README.md b/misc/boring/README.md
new file mode 100644 (file)
index 0000000..bd8deff
--- /dev/null
@@ -0,0 +1,108 @@
+# README.md
+
+This directory holds build scripts for unofficial, unsupported
+distributions of Go+BoringCrypto.
+
+## Version strings
+
+The distribution name for a Go+BoringCrypto release has the form `<GoVersion>b<BoringCryptoVersion>`,
+where `<GoVersion>` is the Go version the release is based on, and `<BoringCryptoVersion>` is
+an integer that increments each time there is a new release with different BoringCrypto bits.
+The `<BoringCryptoVersion>` is stored in the `VERSION` file in this directory.
+
+For example, the first release is based on Go 1.8.3 is `go1.8.3b1`.
+If the BoringCrypto bits are updated, the next would be `go1.8.3b2`.
+If, after that, Go 1.9 is released and the same BoringCrypto code added to it,
+that would result in `go1.9b2`. There would likely not be a `go1.9b1`,
+since that would indicate Go 1.9 with the older BoringCrypto code.
+
+## Releases
+
+The `build.release` script prepares a binary release and publishes it in Google Cloud Storage
+at `gs://go-boringcrypto/`, making it available for download at
+`https://go-boringcrypto.storage.googleapis.com/<FILE>`.
+The script records each published release in the `RELEASES` file in this directory.
+
+The `build.docker` script, which must be run after `build.release`, prepares a Docker image
+and publishes it on hub.docker.com in the goboring organization.
+`go1.8.3b1` is published as `goboring/golang:1.8.3b1`.
+
+## Release process
+
+Development is done on the dev.boringcrypto branch, which tracks
+master. Releases are cut from dev.boringcrypto.go1.X branches,
+which are BoringCrypto backported to the Go 1.X release branches.
+To issue new BoringCrypto releases based on Go 1.X:
+
+1. If the BoringCrypto bits have been updated, increment the
+   number in `VERSION`, send that change out as a CL for review,
+   get it committed to dev.boringcrypto, and run `git sync`.
+
+2. Change to the dev.boringcrypto.go1.X branch and cherry-pick
+   all BoringCrypto updates, including the update of the
+   `VERSION` file. If desired, merge release-branch.go1.X into
+   dev.boringcrypto.go1.X. Mail them out and get them committed.
+
+3. **Back on the dev.boringcrypto branch**, run `git fetch`,
+   `make.bash` and then `build.release dev.boringcrypto.go1.X`.
+   The script will determine the base Go version and the
+   BoringCrypto version, build a release, and upload it.
+
+4. Run `build.docker`, which will build and upload a Docker image
+   from the latest release.
+
+5. Send out a CL with the updated `RELEASES` file and get it
+   committed to dev.boringcrypto.
+
+## Building from Docker
+
+A Dockerfile that starts with `FROM golang:1.8.3` can switch
+to `FROM goboring/golang:1.8.3b2` (see [goboring/golang on Docker Hub](https://hub.docker.com/r/goboring/golang/))
+and should need no other modifications.
+
+## Building from Bazel
+
+Starting from [bazelbuild/rules_go](https://github.com/bazelbuild/rules_go)
+tag 0.7.1, simply download the BoringCrypto-enabled Go SDK using
+`go_download_sdk()` before calling `go_register_toolchains()`.
+
+For example, to use Go 1.9.3 with BoringCrypto on Linux, use the following lines
+in `WORKSPACE`:
+```python
+load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_download_sdk", "go_register_toolchains")
+
+go_rules_dependencies()
+
+go_download_sdk(
+    name = "go_sdk",
+    sdks = {
+       "linux_amd64": ("go1.9.3b4.linux-amd64.tar.gz", "db1997b2454a2f27669b849d2d2cafb247a55128d53da678f06cb409310d6660"),
+    },
+    urls = ["https://storage.googleapis.com/go-boringcrypto/{}"],
+)
+
+go_register_toolchains()
+```
+
+**Note**: you must *not* enable `pure` mode, since cgo must be enabled. To
+ensure that binaries are linked with BoringCrypto, you can set `pure = "off"` on
+all relevant `go_binary` rules.
+
+## Caveat
+
+BoringCrypto is used for a given build only in limited circumstances:
+
+  - The build must be GOOS=linux, GOARCH=amd64.
+  - The build must have cgo enabled.
+  - The android build tag must not be specified.
+  - The cmd_go_bootstrap build tag must not be specified.
+
+The version string reported by `runtime.Version` does not indicate that BoringCrypto
+was actually used for the build. For example, linux/386 and non-cgo linux/amd64 binaries
+will report a version of `go1.8.3b2` but not be using BoringCrypto.
+
+To check whether a given binary is using BoringCrypto, run `go tool nm` on it and check
+that it has symbols named `*_Cfunc__goboringcrypto_*`.
+
+The program [rsc.io/goversion](https://godoc.org/rsc.io/goversion) will report the
+crypto implementation used by a given binary when invoked with the `-crypto` flag.
diff --git a/misc/boring/RELEASES b/misc/boring/RELEASES
new file mode 100644 (file)
index 0000000..2aa3af3
--- /dev/null
@@ -0,0 +1,123 @@
+# This file lists published Go+BoringCrypto releases.
+# Each line describes a single release: <version> <git commit> <target> <URL> <sha256sum>
+go1.9rc2b2 91753387bdf7 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.9rc2b2.linux-amd64.tar.gz 59355a45e6970e8013060851ddb3f079afe8db52e90db520a0826a13f1b5ae5b
+go1.8.3b3 f6ff81bac156 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.8.3b3.linux-amd64.tar.gz 6287ad971cd268bb2684fb8b1275dea928ad527823062bc057e73036c419e7af
+go1.9rc2b4 c339bc4e07a6 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.9rc2b4.linux-amd64.tar.gz a8f677d48dc93920065fca4dca1a55bf7110aba132489c47e25d26d55c67eb32
+go1.9b4 e6ad24cde71e linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.9b4.linux-amd64.tar.gz 6592e36a05df8e7c59812328a3a4bfa6c4eed72132fc31245951c3ade3ef2a8a
+go1.9b4 e6ad24cde71e src https://go-boringcrypto.storage.googleapis.com/go1.9b4.src.tar.gz c85f31dc743fee0e8ce0c6ffc286e27c1f51b66c9b923afafb43cdc378a41091
+go1.8.3b4 42cb4dcdb59a linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.8.3b4.linux-amd64.tar.gz 4011c86e6175925e1c63dc7c19a51f825be53bbe7b08260918e5107b0fbd4f85
+go1.8.3b4 42cb4dcdb59a src https://go-boringcrypto.storage.googleapis.com/go1.8.3b4.src.tar.gz 2531ca8918aa024aed8f4a6c9e5c3b25bc8777623f1efa66aec7214601d474e4
+go1.9.2b4 cda3c6f91d7c linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.9.2b4.linux-amd64.tar.gz 7c5e9a033ddc3ab36646e3bac7fd16962742710c70c18122e44a9ab56cdd3cf7
+go1.9.2b4 cda3c6f91d7c src https://go-boringcrypto.storage.googleapis.com/go1.9.2b4.src.tar.gz 38a2260b64a6a5ab20f8972d08b4765bad116721356433f39aebd29c7598218c
+go1.9.3b4 f4e5ebdf35c8 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.9.3b4.linux-amd64.tar.gz db1997b2454a2f27669b849d2d2cafb247a55128d53da678f06cb409310d6660
+go1.9.3b4 f4e5ebdf35c8 src https://go-boringcrypto.storage.googleapis.com/go1.9.3b4.src.tar.gz 7485e1fc53a9fab9cf34f71de74d69f4c50f9d11a449647de40ee04b59bf8a5b
+go1.9.7b4 0bad1bef406e linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.9.7b4.linux-amd64.tar.gz 9e33a0deb8fed3bd7fa3d122bb5143be9e0a974a422ab4ddac5e765fa1310a6f
+go1.9.7b4 0bad1bef406e src https://go-boringcrypto.storage.googleapis.com/go1.9.7b4.src.tar.gz ad9fb6e22a27382c468467ecade4937f725b33818852f1c1da0d09b471e7486c
+go1.10.3b4 35ba5284935c linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.10.3b4.linux-amd64.tar.gz 6754729d78a375bd1debd980b1e3e7fd49198a980d0bbd8f39e89569aa001942
+go1.10.3b4 35ba5284935c src https://go-boringcrypto.storage.googleapis.com/go1.10.3b4.src.tar.gz f3e75c60a835c11b97e30429b63917ceb31f799b2ba7e2001d99db908fb8e28f
+go1.10.4b4 2e2a04a605b6 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.10.4b4.linux-amd64.tar.gz 17c275ff448686fe1908ecbea5d11ad6f4f7caa288d1786b756439703b12b8b2
+go1.10.4b4 2e2a04a605b6 src https://go-boringcrypto.storage.googleapis.com/go1.10.4b4.src.tar.gz f9cc38e194edabebf338fb74c22f597dc847560618d5d7d4d6cdc28139efa772
+go1.11b4 685dc1638240 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.11b4.linux-amd64.tar.gz d53417b2071af0104fbc15a957000bccdcb5bbc094df0401f67d51968f7f2e4e
+go1.11b4 685dc1638240 src https://go-boringcrypto.storage.googleapis.com/go1.11b4.src.tar.gz 39896f0decd6721e81324cb2bb19540706ca97152c6800a6c8ad15a4e4162184
+go1.11.2b4 35cf0d9f6bbd linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.11.2b4.linux-amd64.tar.gz a9ceb6d0b4413d81ccc94c6460f60ca0c4f36b5dcbf659e1be582cd40c0edfbd
+go1.11.2b4 35cf0d9f6bbd src https://go-boringcrypto.storage.googleapis.com/go1.11.2b4.src.tar.gz 8e12a8df1428f00239dc67dd438a81f72c9925982e90b6899f66270971bddc1c
+go1.10.7b4 8b246fe0f595 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.10.7b4.linux-amd64.tar.gz 31917ab96004b9b482399b46928f5c10cdadefed5fda6f4de262efe2c3c7533e
+go1.10.7b4 8b246fe0f595 src https://go-boringcrypto.storage.googleapis.com/go1.10.7b4.src.tar.gz 323a184c77e3a377f5ed993b04946ee7b1a8e3350aba2894c0944f1e313636f1
+go1.11.4b4 572c4bce6792 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.11.4b4.linux-amd64.tar.gz e708ef7ecaf17a3e8e6deceadfa167cc1162f710f97ea4bc124d3837d6e2eaa1
+go1.11.4b4 572c4bce6792 src https://go-boringcrypto.storage.googleapis.com/go1.11.4b4.src.tar.gz ea963b80e218a34470e14e6e997fe06b8c5bf3f9c9bb0c801f7d8ef63b9bcb73
+go1.10.8b4 4b76b996cb0a linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.10.8b4.linux-amd64.tar.gz 6d7d3323030851b595ba7ed66931c352b63de6dfe1ab3e6d6243987765d09819
+go1.10.8b4 4b76b996cb0a src https://go-boringcrypto.storage.googleapis.com/go1.10.8b4.src.tar.gz c1f5df50a4be3d0cb3aed7b80728f2b23c18deff0383636274742a38c145f939
+go1.11.5b4 3fb9dafacc45 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.11.5b4.linux-amd64.tar.gz 9b5b2972b452da9ba6bba65bab18fb9e8fbda31b5c489275710e5429d76f568c
+go1.11.5b4 3fb9dafacc45 src https://go-boringcrypto.storage.googleapis.com/go1.11.5b4.src.tar.gz 1c5801e2af25c9299d9fd94c64f9ec11fd35777c45d5d0f398c0a9884b1cfbbf
+go1.12.1b4 88e20e81a61f linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.12.1b4.linux-amd64.tar.gz b71886e0d65e5efea2e0a3cbd0c3cd0daf84c437078e755ecde25f4ac0bbed2f
+go1.12.1b4 88e20e81a61f src https://go-boringcrypto.storage.googleapis.com/go1.12.1b4.src.tar.gz d44be1396eb2854b5d9c4d8e8ed0cf9fea1e9dc5a02d8f53b41ba571951a329f
+go1.11.6b4 7be8a5843a9b linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.11.6b4.linux-amd64.tar.gz b704f61b8979e64a46da8884c90cd2b0e2d54e802d55e5f56d7c93752334c197
+go1.11.6b4 7be8a5843a9b src https://go-boringcrypto.storage.googleapis.com/go1.11.6b4.src.tar.gz a56b45e24b61ad7b3c90dfd906cd22426a4de9e2e697b4c9ef07a2af047bcb0d
+go1.12.5b4 ad495d31d908 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.12.5b4.linux-amd64.tar.gz df0e64958cf90f27a65b2175eb80bc34a601136eed8e5559bed2a9e349e33707
+go1.12.5b4 ad495d31d908 src https://go-boringcrypto.storage.googleapis.com/go1.12.5b4.src.tar.gz 054d482896a77ae2d7d24c7adf08da5a4401b938871e61a5cdabc735c54cea9f
+go1.11.11b4 346babe6a67f linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.11.11b4.linux-amd64.tar.gz c4dd44fa00f491b3d2ea808af8a6c234f915adb27c014512d725bafc4784d75f
+go1.11.11b4 346babe6a67f src https://go-boringcrypto.storage.googleapis.com/go1.11.11b4.src.tar.gz 57a724a72f0ba8620cbb48288f39c86ed513c241509ddf73231f4c8cd2a983ac
+go1.12.6b4 6b86b09ad4d3 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.12.6b4.linux-amd64.tar.gz eebc2e7f37555760adb361985b861d0cd34f9401cf7456d8d2f2f3082a60eee1
+go1.12.6b4 6b86b09ad4d3 src https://go-boringcrypto.storage.googleapis.com/go1.12.6b4.src.tar.gz 0e6e9aaf2c72a7e61280ce1e77b2ea24f01a59f4c1e6f0aa72b753206724fd3a
+go1.11.12b4 845e947ae34f linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.11.12b4.linux-amd64.tar.gz 91808261fc357855fba920df01a933d6104e907793014317de00b92802d494d9
+go1.11.12b4 845e947ae34f src https://go-boringcrypto.storage.googleapis.com/go1.11.12b4.src.tar.gz 7b64d9e56ea627138d87c7533df8f9932a79ff900f150a8d8e6a3edc2d0066ec
+go1.12.7b4 bd126d0ad256 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.12.7b4.linux-amd64.tar.gz 7f0c73cd397bccad48ab4df4188d3651c25bf33102275848c6e67b882e11f680
+go1.12.7b4 bd126d0ad256 src https://go-boringcrypto.storage.googleapis.com/go1.12.7b4.src.tar.gz 0c48d7b81ef2b948980011fad1d176d6b10636a4016e3aed7438d86e046d816b
+go1.11.13b4 4f8e7223f936 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.11.13b4.linux-amd64.tar.gz eeb232577065732f5d57a4c77b7d73aa60231ee6fd6496daf7558993e92e403f
+go1.11.13b4 4f8e7223f936 src https://go-boringcrypto.storage.googleapis.com/go1.11.13b4.src.tar.gz 107da8846803a0a735766ca0947de6cd15cd23d8c584002f06e7ac5f81ecb114
+go1.12.8b4 55186ba70c1a linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.12.8b4.linux-amd64.tar.gz 63f278abfc1e98546bc0ffc87f000d9aae2b06c0700212cb55ffd17d059fb8e1
+go1.12.8b4 55186ba70c1a src https://go-boringcrypto.storage.googleapis.com/go1.12.8b4.src.tar.gz c12b1d56ba4e0572f85a08681e05c66293ad53f04b11ce74c688d78fcb882061
+go1.12.9b4 ee88e5b118b5 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.12.9b4.linux-amd64.tar.gz d90989cba1db647b795400a9520eab2fa30f8dea50f4189b18d53f757a4bac44
+go1.12.9b4 ee88e5b118b5 src https://go-boringcrypto.storage.googleapis.com/go1.12.9b4.src.tar.gz 9d4efed8e13fa5ebdadd4fc22f9e35e67bfb34322570c83a15a0879472412e13
+go1.13b4 28e8a0c21e00 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.13b4.linux-amd64.tar.gz 4a909f34bc487badb5ec11646c471ae690393d3f7835b8fbef8466d04ee23cba
+go1.13b4 28e8a0c21e00 src https://go-boringcrypto.storage.googleapis.com/go1.13b4.src.tar.gz 3c2dbe1bfcd7299b5be4b75529425c0a67b8d6b76f81f993b84ae0d173934257
+go1.12.10b4 5827153a1db7 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.12.10b4.linux-amd64.tar.gz 20963fde89fd20eebee9d89003e52702f0379fdb04a68754f9fadf2c302166e3
+go1.12.10b4 5827153a1db7 src https://go-boringcrypto.storage.googleapis.com/go1.12.10b4.src.tar.gz f5cfe73cfeaaa67619ff4a4bbc587e622d63a6aaa7145253e6583bd59072b323
+go1.13.1b4 2da1832ad494 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.13.1b4.linux-amd64.tar.gz 70be1bae05feb67d0560f39767e80707343d96554c5a611fbb93b04ce5913693
+go1.13.1b4 2da1832ad494 src https://go-boringcrypto.storage.googleapis.com/go1.13.1b4.src.tar.gz cf94520325f376ecaf420b7d25756cdecbed52510a1a079eca67c2c86c3cf39b
+go1.12.11b4 c5a4ae8c8c1b linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.12.11b4.linux-amd64.tar.gz a2d90aa130d45b36dd94a7e70accc94e2585eb45823fb7b07ae182ac8bc4a8ca
+go1.12.11b4 c5a4ae8c8c1b src https://go-boringcrypto.storage.googleapis.com/go1.12.11b4.src.tar.gz c334b70c9af0380fb9d397e89af1e2e2ac03380b5cc7c3327f56536c2f68bf8d
+go1.13.2b4 6a1c22797f9c linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.13.2b4.linux-amd64.tar.gz 888c1f6331862af388e730fab4926aa1cb2d4ffc5417e32f9e6d2af7953f0e29
+go1.13.2b4 6a1c22797f9c src https://go-boringcrypto.storage.googleapis.com/go1.13.2b4.src.tar.gz fc44c7713fcd84fe0587594ae5ee1a1d318a0da18b1156e1f9645c6ffa0335bc
+go1.12.12b4 cab2e4707a42 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.12.12b4.linux-amd64.tar.gz 983e996e8f60c78a400fed0edfd16c1718d704e15389c48b4a8b2d835c0d00f2
+go1.12.12b4 cab2e4707a42 src https://go-boringcrypto.storage.googleapis.com/go1.12.12b4.src.tar.gz 2d653a74c14cde1e414ac558e0bdd182ccbe1198bbff8cd22c8e423552d5e24d
+go1.13.3b4 cba6efa89376 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.13.3b4.linux-amd64.tar.gz 9ba0b7696f14dc7ecc912aae6587491853637fab30c4c005339fe36751bfd185
+go1.13.3b4 cba6efa89376 src https://go-boringcrypto.storage.googleapis.com/go1.13.3b4.src.tar.gz ba83d7e18fa49dc6e4319806e7b5cdee5eb046eb8e9fb38f3034378c4f80944a
+go1.12.13b4 5d9d84d037da linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.12.13b4.linux-amd64.tar.gz af3e0d2b9996c632b010da6700b7b8ec52bd3065b3facc478709209a854664eb
+go1.12.13b4 5d9d84d037da src https://go-boringcrypto.storage.googleapis.com/go1.12.13b4.src.tar.gz d1bae336ea076a0b2bfc984477f4a216a475e134068227e6d9b44faf239bcfb8
+go1.13.4b4 fa3f24e5c294 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.13.4b4.linux-amd64.tar.gz 23579d1bea65b2510e507bb0698ec66777bd34674c91dfe617ed130728791dc7
+go1.13.4b4 fa3f24e5c294 src https://go-boringcrypto.storage.googleapis.com/go1.13.4b4.src.tar.gz 8d82df5b4332acd5a274ac029ee5b5ff073b2a4247e2325610986221858b819d
+go1.12.16b4 f74e68136cf1 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.12.16b4.linux-amd64.tar.gz fd70cee8ca9438f99cc71b3586b11a03a36239a5bccbf1c4d06e7206b88bd77d
+go1.12.16b4 f74e68136cf1 src https://go-boringcrypto.storage.googleapis.com/go1.12.16b4.src.tar.gz 2ae0823cefc34f280d4f4ba0d665ff247ba1429cb43198d10e3bc316d3f29a8d
+go1.13.7b4 71468339f763 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.13.7b4.linux-amd64.tar.gz 85945502ad43f506902927f69b514b34a85a20e2bd1020cce87c551645194aa3
+go1.13.7b4 71468339f763 src https://go-boringcrypto.storage.googleapis.com/go1.13.7b4.src.tar.gz d30fa252de75763adb5886125e19e8bab68dbe8dbad33b0faf09a6be98b12d96
+go1.12.17b4 9e5b1367cb45 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.12.17b4.linux-amd64.tar.gz ee3a72dc1cfd8a34f32aaa5ddb05076fcb39434fd1bd25aa318234f72b462e31
+go1.12.17b4 9e5b1367cb45 src https://go-boringcrypto.storage.googleapis.com/go1.12.17b4.src.tar.gz ffb653ec8f4cc33e1e7c308d89c695f322a76f3107e0fc8c639affc6148261bf
+go1.13.8b4 fdf5e5b5905f linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.13.8b4.linux-amd64.tar.gz eac505df92aa6d6b76041f4b485d230f839159b8567c96d7980a06ef476ab3df
+go1.13.8b4 fdf5e5b5905f src https://go-boringcrypto.storage.googleapis.com/go1.13.8b4.src.tar.gz 1aa28fe37a704e94bb34e23578fd07ebbc6a025e9be9b45a898967b84405c41b
+go1.14b4 99da8fa53467 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.14b4.linux-amd64.tar.gz a617e03a6c8813c53b813b865a2e185e12dbfaa76c703c1c48e57ad89651556b
+go1.14b4 99da8fa53467 src https://go-boringcrypto.storage.googleapis.com/go1.14b4.src.tar.gz ee292639b24923f519f1f0fe1ceaeca8d46feb8c15cf88e228346398c5848380
+go1.13.9b4 bb8a1014a32c linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.13.9b4.linux-amd64.tar.gz 565e1a3c62dfc2586471b6ae189ada053a86fc51d88d2eac883a03731071bf77
+go1.13.9b4 bb8a1014a32c src https://go-boringcrypto.storage.googleapis.com/go1.13.9b4.src.tar.gz 536f0549e7bbdad32270a17d8a282667560b6da2d27a5e3580714338e70185ad
+go1.14.1b4 e784c3f4d925 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.14.1b4.linux-amd64.tar.gz 6570991396d531fb628e4c01d697eeee395104147d406aec5a8ba00a213ef63f
+go1.14.1b4 e784c3f4d925 src https://go-boringcrypto.storage.googleapis.com/go1.14.1b4.src.tar.gz 2c267c3114fa4683f51c281d216d3754b38d5d08144c3acc318cf37165b1b2da
+go1.13.10b4 b129f40bb33f linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.13.10b4.linux-amd64.tar.gz a511b2e6ee7b71ca1411d6e4bb07ec33bb5b6974fd1dded77e00520d24d9d000
+go1.13.10b4 b129f40bb33f src https://go-boringcrypto.storage.googleapis.com/go1.13.10b4.src.tar.gz 5dfa44eea19b0be0c9c394fbbf89b2a14f84380a9d7b87e21eacba3ba030c44b
+go1.14.2b4 2b0d842f4b24 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.14.2b4.linux-amd64.tar.gz 82449a7ce57733c0cd3fa7feac89214706ff2b04e387b62619b8e2b8b388ffd9
+go1.14.2b4 2b0d842f4b24 src https://go-boringcrypto.storage.googleapis.com/go1.14.2b4.src.tar.gz bfcb44fa329d6a2eb5c4ef58bfa114d65b078bf69a361bb77e3ea52ec8975d14
+go1.13.12b4 488ca930b24a linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.13.12b4.linux-amd64.tar.gz 63193aa2290af5d65d2d6bbddcd11d835d437a4e835954d605863f5b27a7661d
+go1.13.12b4 488ca930b24a src https://go-boringcrypto.storage.googleapis.com/go1.13.12b4.src.tar.gz 5b0aefb44ba2a08fedb5be0144810bc47559d7d8a6e61638c09dd261706d650e
+go1.14.4b4 fcdb6aa6ee5d linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.14.4b4.linux-amd64.tar.gz 682f2167b3d619690b1385196776822b1d2c497607f67e2d19d92faf2bea0b4a
+go1.14.4b4 fcdb6aa6ee5d src https://go-boringcrypto.storage.googleapis.com/go1.14.4b4.src.tar.gz 2fb759023360f0d42ba434f0409da2460ff4386cab062557f97fe15122b4b4cd
+go1.13.14b4 852ccd9de7d1 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.13.14b4.linux-amd64.tar.gz 49c67d3a67fac60e18a264555392aa5925126a75ef0ba152ec315cc874eccb43
+go1.13.14b4 852ccd9de7d1 src https://go-boringcrypto.storage.googleapis.com/go1.13.14b4.src.tar.gz 7b7dfc62286a07d438370b09f38845acae99c592c6e147722b8f3c098ab8756a
+go1.14.6b4 8f53ffb15fd5 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.14.6b4.linux-amd64.tar.gz 953322287806a42d4a73e096aea45511a51a0a323086e98119edcb0dae866c9d
+go1.14.6b4 8f53ffb15fd5 src https://go-boringcrypto.storage.googleapis.com/go1.14.6b4.src.tar.gz 75fea7a60da4ca225473b500b2d5ce7c302ca7d22eedfdbd3444cd01e6b9f392
+go1.15b5 a15df605fc4a linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.15b5.linux-amd64.tar.gz ebcb2212bdb645a16ffc05a1d9b77c94553ed19a6ccbbc73e4868c64777eb70a
+go1.15b5 a15df605fc4a src https://go-boringcrypto.storage.googleapis.com/go1.15b5.src.tar.gz 7107665853228b2c18f56fec73e217fa3494ccf52c609be839cf6945d501c0f0
+go1.13.15b4 5622128a77b4 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.13.15b4.linux-amd64.tar.gz 8b45ec0e578dc0a0bc483c2d12c08fee5adbfb39f0854fbe9d45f7d628ed1697
+go1.13.15b4 5622128a77b4 src https://go-boringcrypto.storage.googleapis.com/go1.13.15b4.src.tar.gz 21eab29a61a43078cd8bcdbbbb4c82ca049a7e2e211aca0c95f6a306e288db4f
+go1.14.9b4 62cd3338eed7 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.14.9b4.linux-amd64.tar.gz c81946294cbefa7a3abdf47733c720c3454418d6881c137a2e28f18ea40977aa
+go1.14.9b4 62cd3338eed7 src https://go-boringcrypto.storage.googleapis.com/go1.14.9b4.src.tar.gz e9c13c4daa10f6aac80b703f61f7e931af92e92146c8b140ae79e20e4af6bccd
+go1.15.2b5 dbc5602d1839 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.15.2b5.linux-amd64.tar.gz 30c04d854fc8990017ee8c180c1407a4f26c016e3a4134161bbf41c9d16452e3
+go1.15.2b5 dbc5602d1839 src https://go-boringcrypto.storage.googleapis.com/go1.15.2b5.src.tar.gz 67432c0b0a02aa6cc0c49ab285f1c6935a16dadfebd77dfabca7e31907240bc9
+go1.14.10b4 b5fc12785be4 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.14.10b4.linux-amd64.tar.gz d3aa38fb5108b43b155c21529190e73789df6ca0b37feafd43438aefe42f936e
+go1.14.10b4 b5fc12785be4 src https://go-boringcrypto.storage.googleapis.com/go1.14.10b4.src.tar.gz daf7603babc49935efdea5befb2ecad823771523a84d1ba6c0e8c10fac982d59
+go1.15.3b5 ed9dc25d693c linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.15.3b5.linux-amd64.tar.gz 34ec7ec094f5e9349f1612b5f6d8f014b3a7b37b6986aeedcd0fe7cf2dc76a62
+go1.15.3b5 ed9dc25d693c src https://go-boringcrypto.storage.googleapis.com/go1.15.3b5.src.tar.gz bc37727287366aabb47594717cebd0a759147d8b2eb4cd3a45a19317af199fe9
+go1.14.12b4 21ba30ad409a linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.14.12b4.linux-amd64.tar.gz 7f9fb67a3c59fff24e3c51fa2a7435f4195cfb33844c9c2def27c162cc23604b
+go1.14.12b4 21ba30ad409a src https://go-boringcrypto.storage.googleapis.com/go1.14.12b4.src.tar.gz 948d7a77a4a890a7258102bcc7b63890f238061dfb6a4c06033660e727e87fcf
+go1.15.5b5 11087322f85d linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.15.5b5.linux-amd64.tar.gz 9c97488137f1f560b3fff0d8a2a9c45d2de8790fb8952a42b46cc4633528fc48
+go1.15.5b5 11087322f85d src https://go-boringcrypto.storage.googleapis.com/go1.15.5b5.src.tar.gz ee933cb1a4b591794dbcce99740032506af25ee202765dcc6979feb5abc114fc
+go1.14.13b4 2bb8e5a94e8a linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.14.13b4.linux-amd64.tar.gz 8fb6e1cefe5535ab704e1b4e26725095dcca0060490842a54dd93e7cd8b206cd
+go1.14.13b4 2bb8e5a94e8a src https://go-boringcrypto.storage.googleapis.com/go1.14.13b4.src.tar.gz 02e0c4871d12813aee1019bf189b77ccec99dab3a1d5b95ce6abdf85b1810703
+go1.15.6b5 f78276931172 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.15.6b5.linux-amd64.tar.gz 245c500f7da70fb2abd1a6021436ed48e2b97dbbdb394a759b0601dc69cf4e77
+go1.15.6b5 f78276931172 src https://go-boringcrypto.storage.googleapis.com/go1.15.6b5.src.tar.gz 6576a29d019405b14fdc98883fed33c766de2028fbbd3a743a241275275cc7e5
+go1.14.14b4 9cf003256bc3 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.14.14b4.linux-amd64.tar.gz 7df65366d26a13c5be16f87f64e832e86db3b8b9ca1b5c6385e0e20bf79dc82f
+go1.14.14b4 9cf003256bc3 src https://go-boringcrypto.storage.googleapis.com/go1.14.14b4.src.tar.gz aaeda57e2b68ac72783c7aacded814ec660a91c1010c3139156c8e7def86f145
+go1.15.7b5 79ea7a16d7e3 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.15.7b5.linux-amd64.tar.gz cb08962897e3802cda96f4ee915ed20fbde7d5d85e688759ef523d2e6ae44851
+go1.15.7b5 79ea7a16d7e3 src https://go-boringcrypto.storage.googleapis.com/go1.15.7b5.src.tar.gz aa7cb4beff82881cbff4a66e9e07a4004e49384a8fcc95204db9b2f48c12a235
+go1.15.8b5 2a0dd053ecfa linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.15.8b5.linux-amd64.tar.gz 9d897bf42a962b064cfc9bed182c18ade0a3f5857d6a075d93b73ca8fe3b1f3a
+go1.15.8b5 2a0dd053ecfa src https://go-boringcrypto.storage.googleapis.com/go1.15.8b5.src.tar.gz 57964e7762ab03f0ad17bc787585b1709decccf095b7f7d2e9fca61a71e09010
+go1.14.15b4 47419f9cac61 linux-amd64 https://go-boringcrypto.storage.googleapis.com/go1.14.15b4.linux-amd64.tar.gz 82ba7297d26afcdade439de5621bdcb16e5261877f204aa60d03b5e07223a5c8
+go1.14.15b4 47419f9cac61 src https://go-boringcrypto.storage.googleapis.com/go1.14.15b4.src.tar.gz bf77b15f1d905753648db2d91e39c3a740b67b03dfff511aa25a360a78f9742a
diff --git a/misc/boring/VERSION b/misc/boring/VERSION
new file mode 100644 (file)
index 0000000..7f8f011
--- /dev/null
@@ -0,0 +1 @@
+7
diff --git a/misc/boring/build.docker b/misc/boring/build.docker
new file mode 100755 (executable)
index 0000000..6bdf29f
--- /dev/null
@@ -0,0 +1,56 @@
+#!/bin/bash
+# Copyright 2017 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.
+
+# build.docker builds and publishes a Docker image for
+# a given Go+BoringCrypto release.
+
+set -e
+
+# With no arguments, use the most recent linux-amd64 release in the RELEASES file.
+case "$#" in
+0)
+       version=$(grep linux-amd64 RELEASES | tail -1 | awk '{print $1}');;
+1)
+       version="$1";;
+*)
+       echo 'usage: build.docker [version]' >&2
+       exit 2
+esac
+
+url="$(grep "^$version .* linux-amd64 " RELEASES | awk '{print $4}')"
+sha256="$(grep "^$version .* linux-amd64 " RELEASES | awk '{print $5}')"
+if [ "$sha256" = "" ]; then
+       echo "cannot find $version in RELEASES file" >&2
+       exit 2
+fi
+
+# Build a temporary directory with a Dockerfile.
+dir=$(mktemp -d)
+trap "rm -rf $dir" EXIT
+
+if echo "$url" | grep '!' >/dev/null; then
+       # ! is sed delimiter below. Should never happen.
+       echo "URL contains an exclamation mark!" >&2
+       exit 2
+fi
+
+dversion=$(echo "$version" | sed 's/^go//')
+sed "s!UUU!$url!; s/SSS/$sha256/; s/VVV/$dversion/" dockerfile.in >$dir/Dockerfile
+
+docker build --pull -t goboring/golang:$dversion $dir
+docker run goboring/golang:$dversion go version
+docker run goboring/golang:$dversion go tool nm /usr/local/go/bin/go >$dir/nm
+if ! grep crypto/internal/boring/sig.BoringCrypto $dir/nm >/dev/null; then
+       echo 'built docker image but did NOT find sig.BoringCrypto in go command!' >&2
+       exit 2
+fi
+if egrep 'crypto/sha256\.\(\*digest\)' $dir/nm >/dev/null; then
+       echo 'built docker image but DID find sha256.(*digest) in go command unexpectedly!' >&2
+       exit 2
+fi
+docker push goboring/golang:$dversion
+
+echo
+echo published as goboring/golang:$dversion
diff --git a/misc/boring/build.release b/misc/boring/build.release
new file mode 100755 (executable)
index 0000000..46922c9
--- /dev/null
@@ -0,0 +1,104 @@
+#!/bin/bash
+# Copyright 2017 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.
+
+# build.release builds and publishes a new Go+BoringCrypto release.
+# After running this script, the change to the RELEASES file should be
+# sent out for review and committed to the repository (but the release
+# is already done, so there's not much to review).
+
+set -e
+
+case "$#" in
+0)
+       rev=HEAD;;
+1)
+       rev="$1";;
+*)
+       echo 'usage: build.release [git-rev]' >&2
+       exit 2
+esac
+
+# Determine commit to use.
+commit=$(git rev-parse "$rev" | awk '{print substr($1, 1, 12)}')
+if [ "$commit" = "" ]; then
+       echo 'cannot find commit in git history' >&2
+       exit 2
+fi
+
+# Determine base Go release from tags.
+base=$(git log --decorate=short --oneline "$rev" | grep 'tag: go' | sed 1q | sed 's/[),].*//; s/.*tag: //')
+if [ "$base" = "" ]; then
+       echo "cannot find go release tag in git history for $rev" >&2
+       exit 2
+fi
+
+# Determine boring crypto version from file.
+boring=$(git show "$commit:misc/boring/VERSION")
+if [ "$boring" = "" ]; then
+       echo "missing BORINGVERSION file in $commit" >&2
+       exit 2
+fi
+
+# Make sure we're not redefining a published release.
+version="${base}b${boring}"
+if grep "^$version " RELEASES >/dev/null; then
+       echo "found $version in RELEASES - not rereleasing" >&2
+       exit 2
+fi
+
+# Show what's going on, while the release builds.
+# Good time for user to type ^C if something is wrong.
+echo >&2
+echo "building $version from $commit" >&2
+echo >&2
+git log -n1 "$commit" >&2
+echo >&2
+
+# Build the release tool in a temporary directory.
+dir=$(mktemp -d)
+trap "rm -rf $dir" EXIT
+export GO111MODULE=on
+export GOBIN="$dir"
+(cd "$dir"; go get golang.org/x/build/cmd/release)
+
+# Build the release.
+sha() {
+    if hash sha256sum 2>/dev/null; then
+        sha256sum "$@"
+    else
+        shasum -a 256 "$@"
+    fi
+}
+shortgo=$(echo "$base" | perl -pe 's/(go\d+\.\d+)(\.\d+|rc\d+)/$1/')
+$dir/release -target linux-amd64 -rev "$commit" -version "$version"
+$dir/release -target src -rev "$commit" -version "$version"
+output="$version.linux-amd64.tar.gz"
+ls -l "$output"
+sha256=$(sha "$output" | awk '{print $1}')
+outputsrc="$version.src.tar.gz"
+ls -l "$outputsrc"
+sha256src=$(sha "$outputsrc" | awk '{print $1}')
+
+trap "rm -f /tmp/go.release.$$ /tmp/go.nm.$$" EXIT
+tar -xzf "$output" -O go/bin/go >/tmp/go.release.$$
+go tool nm /tmp/go.release.$$ >/tmp/go.nm.$$
+if ! grep crypto/internal/boring/sig.BoringCrypto /tmp/go.nm.$$ >/dev/null; then
+       echo 'built release but did NOT find sig.BoringCrypto in go command!' >&2
+       exit 2
+fi
+if egrep 'crypto/sha256\.\(\*digest\)' /tmp/go.nm.$$ >/dev/null; then
+       echo 'built release but DID find sha256.(*digest) in go command unexpectedly!' >&2
+       exit 2
+fi
+
+# Publish the release.
+gsutil cp "$output" gs://go-boringcrypto/
+url="https://go-boringcrypto.storage.googleapis.com/$output"
+gsutil cp "$outputsrc" gs://go-boringcrypto/
+urlsrc="https://go-boringcrypto.storage.googleapis.com/$outputsrc"
+
+# Record that it was published.
+echo "$version $commit linux-amd64 $url $sha256" >>RELEASES
+echo "$version $commit src $urlsrc $sha256src" >>RELEASES
diff --git a/misc/boring/dockerfile.in b/misc/boring/dockerfile.in
new file mode 100644 (file)
index 0000000..b439089
--- /dev/null
@@ -0,0 +1,31 @@
+# Template for Dockerfile, used in build.docker script.
+# Based on https://github.com/docker-library/golang/blob/7e3d99a803/1.13/buster/Dockerfile
+FROM buildpack-deps:buster-scm
+
+# gcc for cgo
+RUN apt-get update && apt-get install -y --no-install-recommends \
+               g++ \
+               gcc \
+               libc6-dev \
+               make \
+               pkg-config \
+       && rm -rf /var/lib/apt/lists/*
+
+ENV GOLANG_VERSION VVV
+
+RUN set -eux; \
+       \
+       url="UUU"; \
+       wget -O go.tgz "$url"; \
+       echo "SSS go.tgz" | sha256sum -c -; \
+       tar -C /usr/local -xzf go.tgz; \
+       rm go.tgz; \
+       \
+       export PATH="/usr/local/go/bin:$PATH"; \
+       go version
+
+ENV GOPATH /go
+ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH
+
+RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" && chmod -R 777 "$GOPATH"
+WORKDIR $GOPATH
diff --git a/misc/boring/merge.sh b/misc/boring/merge.sh
new file mode 100755 (executable)
index 0000000..b897a5b
--- /dev/null
@@ -0,0 +1,34 @@
+#! /bin/bash
+set -euo pipefail
+
+if [ "$#" -ne 2 ]; then
+    echo "usage: merge.sh <target branch> <source revision>"
+    echo ""
+    echo "example: merge.sh dev.boringcrypto master"
+    echo "         merge.sh dev.boringcrypto.go1.10 go1.10.7"
+    exit 1
+fi
+
+TARGET="$1"
+SOURCE="$2"
+WORKTREE="$(mktemp -d)"
+BRANCH="boring/merge-$TARGET-$(date +%Y%m%d%H%M%S)"
+
+git fetch
+git worktree add --track -b "$BRANCH" "$WORKTREE" "origin/$TARGET"
+
+cd "$WORKTREE"
+export GIT_GOFMT_HOOK=off
+git merge --no-commit --no-stat "$SOURCE" || echo "Ignoring conflict..."
+[[ -f VERSION ]] && git rm -f VERSION
+git checkout --ours codereview.cfg && git add codereview.cfg
+git commit -m "all: merge $SOURCE into $TARGET"
+
+if ! git log --format=%B -n 1 | grep "\[$TARGET\] "; then
+    echo "The commit does not seem to be targeting the BoringCrypto branch."
+    echo "(Or you are missing the git-codereview hooks.)"
+    exit 1
+fi
+
+git codereview mail -r katie@golang.org,roland@golang.org,filippo@golang.org -trybot -trust HEAD
+cd - && git worktree remove "$WORKTREE"
diff --git a/misc/boring/release.sh b/misc/boring/release.sh
new file mode 100755 (executable)
index 0000000..457ab39
--- /dev/null
@@ -0,0 +1,34 @@
+#! /bin/bash
+set -euo pipefail
+
+if [ "$#" -eq 0 ]; then
+    echo "usage: <target branch> [<target branch> ...]"
+    echo ""
+    echo "example: release.sh dev.boringcrypto.go1.11 dev.boringcrypto.go1.12"
+    exit 1
+fi
+
+# Check that the Docker daemon is available.
+docker ps > /dev/null
+
+WORKTREE="$(mktemp -d)"
+BRANCH="boring/release-$(date +%Y%m%d%H%M%S)"
+
+git fetch
+git worktree add --track -b "$BRANCH" "$WORKTREE" origin/dev.boringcrypto
+
+cd "$WORKTREE/src"
+./make.bash
+
+cd ../misc/boring
+for branch in "$@"; do
+    ./build.release "origin/$branch"
+    ./build.docker
+done
+
+git add RELEASES
+git commit -m "misc/boring: add new releases to RELEASES file"
+git codereview mail -r katie@golang.org,roland@golang.org,filippo@golang.org -trust
+
+rm *.tar.gz
+cd - && git worktree remove "$WORKTREE"
index 3ff14c87f4fc7b0603435b511771cc9cf1dcfbdc..df92a9f3498fdce1b20289f356545606697dabfe 100644 (file)
@@ -1125,6 +1125,33 @@ func writeType(t *types.Type) *obj.LSym {
        // for security, only the exported fields.
        case types.TSTRUCT:
                fields := t.Fields().Slice()
+
+               // omitFieldForAwfulBoringCryptoKludge reports whether
+               // the field t should be omitted from the reflect data.
+               // In the crypto/... packages we omit an unexported field
+               // named "boring", to keep from breaking client code that
+               // expects rsa.PublicKey etc to have only public fields.
+               // As the name suggests, this is an awful kludge, but it is
+               // limited to the dev.boringcrypto branch and avoids
+               // much more invasive effects elsewhere.
+               omitFieldForAwfulBoringCryptoKludge := func(t *types.Field) bool {
+                       if t.Sym == nil || t.Sym.Name != "boring" || t.Sym.Pkg == nil {
+                               return false
+                       }
+                       path := t.Sym.Pkg.Path
+                       if t.Sym.Pkg == types.LocalPkg {
+                               path = base.Ctxt.Pkgpath
+                       }
+                       return strings.HasPrefix(path, "crypto/")
+               }
+               newFields := fields[:0:0]
+               for _, t1 := range fields {
+                       if !omitFieldForAwfulBoringCryptoKludge(t1) {
+                               newFields = append(newFields, t1)
+                       }
+               }
+               fields = newFields
+
                for _, t1 := range fields {
                        writeType(t1.Type)
                }
diff --git a/src/cmd/go/go_boring_test.go b/src/cmd/go/go_boring_test.go
new file mode 100644 (file)
index 0000000..0000497
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2015 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 main_test
+
+import "testing"
+
+func TestBoringInternalLink(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.parallel()
+       tg.tempFile("main.go", `package main
+               import "crypto/sha1"
+               func main() {
+                       sha1.New()
+               }`)
+       tg.run("build", "-ldflags=-w -extld=false", tg.path("main.go"))
+       tg.run("build", "-ldflags=-extld=false", tg.path("main.go"))
+}
index d14b2328bfaa05ac950799eb39bec547e81e883a..e3fd1cd53fb9c0ff441a5d7d141a93b797f182e8 100644 (file)
@@ -1842,8 +1842,12 @@ func TestBinaryOnlyPackages(t *testing.T) {
        tg.grepStdout("p2: false", "p2 listed as BinaryOnly")
 }
 
-// Issue 16050.
-func TestAlwaysLinkSysoFiles(t *testing.T) {
+// Issue 16050 and 21884.
+func TestLinkSysoFiles(t *testing.T) {
+       if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" {
+               t.Skip("not linux/amd64")
+       }
+
        tg := testgo(t)
        defer tg.cleanup()
        tg.parallel()
@@ -1862,6 +1866,10 @@ func TestAlwaysLinkSysoFiles(t *testing.T) {
        tg.setenv("CGO_ENABLED", "0")
        tg.run("list", "-f", "{{.SysoFiles}}", "syso")
        tg.grepStdout("a.syso", "missing syso file with CGO_ENABLED=0")
+
+       tg.setenv("CGO_ENABLED", "1")
+       tg.run("list", "-msan", "-f", "{{.SysoFiles}}", "syso")
+       tg.grepStdoutNot("a.syso", "unexpected syso file with -msan")
 }
 
 // Issue 16120.
index 8b12faf4cd2e51d8665a838c68275dce87cba018..3f7922ab9cb304727bbd825b20dc5fcc35e37d24 100644 (file)
@@ -378,6 +378,12 @@ func (p *Package) copyBuild(pp *build.Package) {
        p.SwigFiles = pp.SwigFiles
        p.SwigCXXFiles = pp.SwigCXXFiles
        p.SysoFiles = pp.SysoFiles
+       if cfg.BuildMSan {
+               // There's no way for .syso files to be built both with and without
+               // support for memory sanitizer. Assume they are built without,
+               // and drop them.
+               p.SysoFiles = nil
+       }
        p.CgoCFLAGS = pp.CgoCFLAGS
        p.CgoCPPFLAGS = pp.CgoCPPFLAGS
        p.CgoCXXFLAGS = pp.CgoCXXFLAGS
index 314896824a03fcb8d3dcb58146759d10adbeb615..3f039aa67f9a183134cc7a7592f755622015e4dc 100644 (file)
@@ -1022,6 +1022,7 @@ var hostobj []Hostobj
 // These packages can use internal linking mode.
 // Others trigger external mode.
 var internalpkg = []string{
+       "crypto/internal/boring",
        "crypto/x509",
        "net",
        "os/user",
index bb93fbb36e289abfff7bf9b6341acf7769e719d3..29d01796eb398fe5842e5696f933b0f91b8a35c9 100644 (file)
@@ -10,6 +10,8 @@ import (
        "strconv"
 )
 
+import "crypto/internal/boring"
+
 // The AES block size in bytes.
 const BlockSize = 16
 
@@ -37,6 +39,9 @@ func NewCipher(key []byte) (cipher.Block, error) {
        case 16, 24, 32:
                break
        }
+       if boring.Enabled {
+               return boring.NewAESCipher(key)
+       }
        return newCipher(key)
 }
 
index 646bdfa5c0e6ce8867d90cd7fa3d28a660481836..4936699481f9ebbefb542b8b17a9ee774f9db557 100644 (file)
@@ -12,6 +12,8 @@ import (
        "internal/cpu"
 )
 
+import "crypto/internal/boring"
+
 // defined in asm_*.s
 
 //go:noescape
@@ -56,6 +58,7 @@ func newCipher(key []byte) (cipher.Block, error) {
 func (c *aesCipherAsm) BlockSize() int { return BlockSize }
 
 func (c *aesCipherAsm) Encrypt(dst, src []byte) {
+       boring.Unreachable()
        if len(src) < BlockSize {
                panic("crypto/aes: input not full block")
        }
@@ -69,6 +72,7 @@ func (c *aesCipherAsm) Encrypt(dst, src []byte) {
 }
 
 func (c *aesCipherAsm) Decrypt(dst, src []byte) {
+       boring.Unreachable()
        if len(src) < BlockSize {
                panic("crypto/aes: input not full block")
        }
diff --git a/src/crypto/boring/boring.go b/src/crypto/boring/boring.go
new file mode 100644 (file)
index 0000000..19e2a08
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2020 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 boring exposes functions that are only available when building with
+// Go+BoringCrypto. This package is available on all targets as long as the
+// Go+BoringCrypto toolchain is used. Use the Enabled function to determine
+// whether the BoringCrypto core is actually in use.
+//
+// Any time the Go+BoringCrypto toolchain is used, the "boringcrypto" build tag
+// is satisfied, so that applications can tag files that use this package.
+package boring
+
+import "crypto/internal/boring"
+
+// Enabled reports whether BoringCrypto handles supported crypto operations.
+func Enabled() bool {
+       return boring.Enabled
+}
diff --git a/src/crypto/boring/boring_test.go b/src/crypto/boring/boring_test.go
new file mode 100644 (file)
index 0000000..ace50de
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2020 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 boring_test
+
+import (
+       "crypto/boring"
+       "runtime"
+       "testing"
+)
+
+func TestEnabled(t *testing.T) {
+       supportedPlatform := runtime.GOOS == "linux" && runtime.GOARCH == "amd64"
+       if supportedPlatform && !boring.Enabled() {
+               t.Error("Enabled returned false on a supported platform")
+       } else if !supportedPlatform && boring.Enabled() {
+               t.Error("Enabled returned true on an unsupported platform")
+       }
+}
diff --git a/src/crypto/boring/notboring_test.go b/src/crypto/boring/notboring_test.go
new file mode 100644 (file)
index 0000000..385a384
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2020 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.
+
+// +build !boringcrypto
+
+package boring_test
+
+import "testing"
+
+func TestNotBoring(t *testing.T) {
+       t.Error("a file tagged !boringcrypto should not build under Go+BoringCrypto")
+}
diff --git a/src/crypto/ecdsa/boring.go b/src/crypto/ecdsa/boring.go
new file mode 100644 (file)
index 0000000..fa15ecb
--- /dev/null
@@ -0,0 +1,100 @@
+// Copyright 2017 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 ecdsa
+
+import (
+       "crypto/internal/boring"
+       "math/big"
+       "sync/atomic"
+       "unsafe"
+)
+
+// Cached conversions from Go PublicKey/PrivateKey to BoringCrypto.
+//
+// A new 'boring atomic.Value' field in both PublicKey and PrivateKey
+// serves as a cache for the most recent conversion. The cache is an
+// atomic.Value because code might reasonably set up a key and then
+// (thinking it immutable) use it from multiple goroutines simultaneously.
+// The first operation initializes the cache; if there are multiple simultaneous
+// first operations, they will do redundant work but not step on each other.
+//
+// We could just assume that once used in a Sign or Verify operation,
+// a particular key is never again modified, but that has not been a
+// stated assumption before. Just in case there is any existing code that
+// does modify the key between operations, we save the original values
+// alongside the cached BoringCrypto key and check that the real key
+// still matches before using the cached key. The theory is that the real
+// operations are significantly more expensive than the comparison.
+
+type boringPub struct {
+       key  *boring.PublicKeyECDSA
+       orig PublicKey
+}
+
+func boringPublicKey(pub *PublicKey) (*boring.PublicKeyECDSA, error) {
+       b := (*boringPub)(atomic.LoadPointer(&pub.boring))
+       if b != nil && publicKeyEqual(&b.orig, pub) {
+               return b.key, nil
+       }
+
+       b = new(boringPub)
+       b.orig = copyPublicKey(pub)
+       key, err := boring.NewPublicKeyECDSA(b.orig.Curve.Params().Name, b.orig.X, b.orig.Y)
+       if err != nil {
+               return nil, err
+       }
+       b.key = key
+       atomic.StorePointer(&pub.boring, unsafe.Pointer(b))
+       return key, nil
+}
+
+type boringPriv struct {
+       key  *boring.PrivateKeyECDSA
+       orig PrivateKey
+}
+
+func boringPrivateKey(priv *PrivateKey) (*boring.PrivateKeyECDSA, error) {
+       b := (*boringPriv)(atomic.LoadPointer(&priv.boring))
+       if b != nil && privateKeyEqual(&b.orig, priv) {
+               return b.key, nil
+       }
+
+       b = new(boringPriv)
+       b.orig = copyPrivateKey(priv)
+       key, err := boring.NewPrivateKeyECDSA(b.orig.Curve.Params().Name, b.orig.X, b.orig.Y, b.orig.D)
+       if err != nil {
+               return nil, err
+       }
+       b.key = key
+       atomic.StorePointer(&priv.boring, unsafe.Pointer(b))
+       return key, nil
+}
+
+func publicKeyEqual(k1, k2 *PublicKey) bool {
+       return k1.X != nil &&
+               k1.Curve.Params() == k2.Curve.Params() &&
+               k1.X.Cmp(k2.X) == 0 &&
+               k1.Y.Cmp(k2.Y) == 0
+}
+
+func privateKeyEqual(k1, k2 *PrivateKey) bool {
+       return publicKeyEqual(&k1.PublicKey, &k2.PublicKey) &&
+               k1.D.Cmp(k2.D) == 0
+}
+
+func copyPublicKey(k *PublicKey) PublicKey {
+       return PublicKey{
+               Curve: k.Curve,
+               X:     new(big.Int).Set(k.X),
+               Y:     new(big.Int).Set(k.Y),
+       }
+}
+
+func copyPrivateKey(k *PrivateKey) PrivateKey {
+       return PrivateKey{
+               PublicKey: copyPublicKey(&k.PublicKey),
+               D:         new(big.Int).Set(k.D),
+       }
+}
index ccce87385947f06dd30d813ee0998a35e3a8cd34..04738cdbd7b248ff7e2cf1e570d9b47eba74b8f7 100644 (file)
@@ -41,6 +41,11 @@ import (
        "golang.org/x/crypto/cryptobyte/asn1"
 )
 
+import (
+       "crypto/internal/boring"
+       "unsafe"
+)
+
 // A invertible implements fast inverse mod Curve.Params().N
 type invertible interface {
        // Inverse returns the inverse of k in GF(P)
@@ -60,6 +65,8 @@ const (
 type PublicKey struct {
        elliptic.Curve
        X, Y *big.Int
+
+       boring unsafe.Pointer
 }
 
 // Any methods implemented on PublicKey might need to also be implemented on
@@ -87,6 +94,8 @@ func (pub *PublicKey) Equal(x crypto.PublicKey) bool {
 type PrivateKey struct {
        PublicKey
        D *big.Int
+
+       boring unsafe.Pointer
 }
 
 // Public returns the public key corresponding to priv.
@@ -113,6 +122,15 @@ func (priv *PrivateKey) Equal(x crypto.PrivateKey) bool {
 // where the private part is kept in, for example, a hardware module. Common
 // uses should use the Sign function in this package directly.
 func (priv *PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
+       if boring.Enabled && rand == boring.RandReader {
+               b, err := boringPrivateKey(priv)
+               if err != nil {
+                       return nil, err
+               }
+               return boring.SignMarshalECDSA(b, digest)
+       }
+       boring.UnreachableExceptTests()
+
        r, s, err := Sign(rand, priv, digest)
        if err != nil {
                return nil, err
@@ -147,6 +165,15 @@ func randFieldElement(c elliptic.Curve, rand io.Reader) (k *big.Int, err error)
 
 // GenerateKey generates a public and private key pair.
 func GenerateKey(c elliptic.Curve, rand io.Reader) (*PrivateKey, error) {
+       if boring.Enabled && rand == boring.RandReader {
+               x, y, d, err := boring.GenerateKeyECDSA(c.Params().Name)
+               if err != nil {
+                       return nil, err
+               }
+               return &PrivateKey{PublicKey: PublicKey{Curve: c, X: x, Y: y}, D: d}, nil
+       }
+       boring.UnreachableExceptTests()
+
        k, err := randFieldElement(c, rand)
        if err != nil {
                return nil, err
@@ -200,6 +227,15 @@ var errZeroParam = errors.New("zero parameter")
 func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error) {
        randutil.MaybeReadByte(rand)
 
+       if boring.Enabled && rand == boring.RandReader {
+               b, err := boringPrivateKey(priv)
+               if err != nil {
+                       return nil, nil, err
+               }
+               return boring.SignECDSA(b, hash)
+       }
+       boring.UnreachableExceptTests()
+
        // Get min(log2(q) / 2, 256) bits of entropy from rand.
        entropylen := (priv.Curve.Params().BitSize + 7) / 16
        if entropylen > 32 {
@@ -289,6 +325,15 @@ func SignASN1(rand io.Reader, priv *PrivateKey, hash []byte) ([]byte, error) {
 // Verify verifies the signature in r, s of hash using the public key, pub. Its
 // return value records whether the signature is valid.
 func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool {
+       if boring.Enabled {
+               b, err := boringPublicKey(pub)
+               if err != nil {
+                       return false
+               }
+               return boring.VerifyECDSA(b, hash, r, s)
+       }
+       boring.UnreachableExceptTests()
+
        // See [NSA] 3.4.2
        c := pub.Curve
        N := c.Params().N
index cdda33c2cbac2dc55c63e71858e01bffda5a8a82..34805765d550c17234bafc0fc7e8215bbb70b81b 100644 (file)
@@ -26,6 +26,8 @@ import (
        "hash"
 )
 
+import "crypto/internal/boring"
+
 // FIPS 198-1:
 // https://csrc.nist.gov/publications/fips/fips198-1/FIPS-198-1_final.pdf
 
@@ -126,6 +128,13 @@ func (h *hmac) Reset() {
 // the returned Hash does not implement encoding.BinaryMarshaler
 // or encoding.BinaryUnmarshaler.
 func New(h func() hash.Hash, key []byte) hash.Hash {
+       if boring.Enabled {
+               hm := boring.NewHMAC(h, key)
+               if hm != nil {
+                       return hm
+               }
+               // BoringCrypto did not recognize h, so fall through to standard Go code.
+       }
        hm := new(hmac)
        hm.outer = h()
        hm.inner = h()
index 25e67d7fe5325f72f90a60df452cd6e7d5e25fbe..55415abf020799c4120705d061aac7d6b7e4f3b7 100644 (file)
@@ -5,6 +5,8 @@
 package hmac
 
 import (
+       "bytes"
+       "crypto/internal/boring"
        "crypto/md5"
        "crypto/sha1"
        "crypto/sha256"
@@ -518,6 +520,31 @@ var hmacTests = []hmacTest{
                sha512.Size,
                sha512.BlockSize,
        },
+       // HMAC without key is dumb but should probably not fail.
+       {
+               sha1.New,
+               []byte{},
+               []byte("message"),
+               "d5d1ed05121417247616cfc8378f360a39da7cfa",
+               sha1.Size,
+               sha1.BlockSize,
+       },
+       {
+               sha256.New,
+               []byte{},
+               []byte("message"),
+               "eb08c1f56d5ddee07f7bdf80468083da06b64cf4fac64fe3a90883df5feacae4",
+               sha256.Size,
+               sha256.BlockSize,
+       },
+       {
+               sha512.New,
+               []byte{},
+               []byte("message"),
+               "08fce52f6395d59c2a3fb8abb281d74ad6f112b9a9c787bcea290d94dadbc82b2ca3e5e12bf2277c7fedbb0154d5493e41bb7459f63c8e39554ea3651b812492",
+               sha512.Size,
+               sha512.BlockSize,
+       },
 }
 
 func TestHMAC(t *testing.T) {
@@ -557,6 +584,9 @@ func TestHMAC(t *testing.T) {
 }
 
 func TestNonUniqueHash(t *testing.T) {
+       if boring.Enabled {
+               t.Skip("hash.Hash provided by boringcrypto are not comparable")
+       }
        sha := sha256.New()
        defer func() {
                err := recover()
@@ -591,6 +621,42 @@ func TestEqual(t *testing.T) {
        }
 }
 
+func TestWriteAfterSum(t *testing.T) {
+       h := New(sha1.New, nil)
+       h.Write([]byte("hello"))
+       sumHello := h.Sum(nil)
+
+       h = New(sha1.New, nil)
+       h.Write([]byte("hello world"))
+       sumHelloWorld := h.Sum(nil)
+
+       // Test that Sum has no effect on future Sum or Write operations.
+       // This is a bit unusual as far as usage, but it's allowed
+       // by the definition of Go hash.Hash, and some clients expect it to work.
+       h = New(sha1.New, nil)
+       h.Write([]byte("hello"))
+       if sum := h.Sum(nil); !bytes.Equal(sum, sumHello) {
+               t.Fatalf("1st Sum after hello = %x, want %x", sum, sumHello)
+       }
+       if sum := h.Sum(nil); !bytes.Equal(sum, sumHello) {
+               t.Fatalf("2nd Sum after hello = %x, want %x", sum, sumHello)
+       }
+
+       h.Write([]byte(" world"))
+       if sum := h.Sum(nil); !bytes.Equal(sum, sumHelloWorld) {
+               t.Fatalf("1st Sum after hello world = %x, want %x", sum, sumHelloWorld)
+       }
+       if sum := h.Sum(nil); !bytes.Equal(sum, sumHelloWorld) {
+               t.Fatalf("2nd Sum after hello world = %x, want %x", sum, sumHelloWorld)
+       }
+
+       h.Reset()
+       h.Write([]byte("hello"))
+       if sum := h.Sum(nil); !bytes.Equal(sum, sumHello) {
+               t.Fatalf("Sum after Reset + hello = %x, want %x", sum, sumHello)
+       }
+}
+
 func BenchmarkHMACSHA256_1K(b *testing.B) {
        key := make([]byte, 32)
        buf := make([]byte, 1024)
diff --git a/src/crypto/internal/boring/Dockerfile b/src/crypto/internal/boring/Dockerfile
new file mode 100644 (file)
index 0000000..811a6dc
--- /dev/null
@@ -0,0 +1,42 @@
+# Copyright 2020 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.
+
+# This Docker image builds goboringcrypto_linux_amd64.syso according to the
+# Security Policy. To use it, build the image, run it, and then extract
+# /boring/godriver/goboringcrypto_linux_amd64.syso.
+#
+#   $ docker build -t goboring:140sp3678 .
+#   $ docker run -it --name goboring-140sp3678 goboring:140sp3678
+#   $ docker cp goboring-140sp3678:/boring/godriver/goboringcrypto_linux_amd64.syso .
+#   $ sha256sum goboringcrypto_linux_amd64.syso # compare to docker output
+
+FROM ubuntu:focal
+
+RUN mkdir /boring
+WORKDIR /boring
+
+# Following 140sp3678.pdf [0] page 19, install clang 7.0.1, Go 1.12.7, and
+# Ninja 1.9.0, then download and verify BoringSSL.
+#
+# [0]: https://csrc.nist.gov/CSRC/media/projects/cryptographic-module-validation-program/documents/security-policies/140sp3678.pdf
+
+RUN apt-get update && \
+        apt-get install --no-install-recommends -y cmake xz-utils wget unzip ca-certificates clang-7
+RUN wget https://github.com/ninja-build/ninja/releases/download/v1.9.0/ninja-linux.zip && \
+        unzip ninja-linux.zip && \
+        rm ninja-linux.zip && \
+        mv ninja /usr/local/bin/
+RUN wget https://golang.org/dl/go1.12.7.linux-amd64.tar.gz && \
+        tar -C /usr/local -xzf go1.12.7.linux-amd64.tar.gz && \
+        rm go1.12.7.linux-amd64.tar.gz && \
+        ln -s /usr/local/go/bin/go /usr/local/bin/
+
+RUN wget https://commondatastorage.googleapis.com/chromium-boringssl-fips/boringssl-ae223d6138807a13006342edfeef32e813246b39.tar.xz
+RUN [ "$(sha256sum boringssl-ae223d6138807a13006342edfeef32e813246b39.tar.xz | awk '{print $1}')" = \
+        3b5fdf23274d4179c2077b5e8fa625d9debd7a390aac1d165b7e47234f648bb8 ]
+
+ADD goboringcrypto.h /boring/godriver/goboringcrypto.h
+ADD build.sh /boring/build.sh
+
+ENTRYPOINT ["/boring/build.sh"]
diff --git a/src/crypto/internal/boring/LICENSE b/src/crypto/internal/boring/LICENSE
new file mode 100644 (file)
index 0000000..fc103a7
--- /dev/null
@@ -0,0 +1,200 @@
+The Go source code and supporting files in this directory
+are covered by the usual Go license (see ../../../../LICENSE).
+
+The goboringcrypto_linux_amd64.syso object file is built
+from BoringSSL source code by build/build.sh and is covered
+by the BoringSSL license reproduced below and also at
+https://boringssl.googlesource.com/boringssl/+/fips-20190808/LICENSE.
+
+BoringSSL is a fork of OpenSSL. As such, large parts of it fall under OpenSSL
+licensing. Files that are completely new have a Google copyright and an ISC
+license. This license is reproduced at the bottom of this file.
+
+Contributors to BoringSSL are required to follow the CLA rules for Chromium:
+https://cla.developers.google.com/clas
+
+Some files from Intel are under yet another license, which is also included
+underneath.
+
+The OpenSSL toolkit stays under a dual license, i.e. both the conditions of the
+OpenSSL License and the original SSLeay license apply to the toolkit. See below
+for the actual license texts. Actually both licenses are BSD-style Open Source
+licenses. In case of any license issues related to OpenSSL please contact
+openssl-core@openssl.org.
+
+The following are Google-internal bug numbers where explicit permission from
+some authors is recorded for use of their work. (This is purely for our own
+record keeping.)
+  27287199
+  27287880
+  27287883
+
+  OpenSSL License
+  ---------------
+
+/* ====================================================================
+ * Copyright (c) 1998-2011 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+ Original SSLeay License
+ -----------------------
+
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+
+ISC license used for completely new code in BoringSSL:
+
+/* Copyright (c) 2015, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+
+Some files from Intel carry the following license:
+
+# Copyright (c) 2012, Intel Corporation
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# *  Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+#
+# *  Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the
+#    distribution.
+#
+# *  Neither the name of the Intel Corporation nor the names of its
+#    contributors may be used to endorse or promote products derived from
+#    this software without specific prior written permission.
+#
+#
+# THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION ""AS IS"" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/src/crypto/internal/boring/aes.go b/src/crypto/internal/boring/aes.go
new file mode 100644 (file)
index 0000000..504a841
--- /dev/null
@@ -0,0 +1,391 @@
+// Copyright 2017 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.
+
+// +build linux,amd64
+// +build !android
+// +build !cmd_go_bootstrap
+// +build !msan
+
+package boring
+
+/*
+
+#include "goboringcrypto.h"
+
+// These wrappers allocate out_len on the C stack, and check that it matches the expected
+// value, to avoid having to pass a pointer from Go, which would escape to the heap.
+
+int EVP_AEAD_CTX_seal_wrapper(const GO_EVP_AEAD_CTX *ctx, uint8_t *out,
+                                                         size_t exp_out_len,
+                                                         const uint8_t *nonce, size_t nonce_len,
+                                                         const uint8_t *in, size_t in_len,
+                                                         const uint8_t *ad, size_t ad_len) {
+       size_t out_len;
+       int ok = _goboringcrypto_EVP_AEAD_CTX_seal(ctx, out, &out_len, exp_out_len,
+               nonce, nonce_len, in, in_len, ad, ad_len);
+       if (out_len != exp_out_len) {
+               return 0;
+       }
+       return ok;
+};
+
+int EVP_AEAD_CTX_open_wrapper(const GO_EVP_AEAD_CTX *ctx, uint8_t *out,
+                                                         size_t exp_out_len,
+                                                         const uint8_t *nonce, size_t nonce_len,
+                                                         const uint8_t *in, size_t in_len,
+                                                         const uint8_t *ad, size_t ad_len) {
+       size_t out_len;
+       int ok = _goboringcrypto_EVP_AEAD_CTX_open(ctx, out, &out_len, exp_out_len,
+               nonce, nonce_len, in, in_len, ad, ad_len);
+       if (out_len != exp_out_len) {
+               return 0;
+       }
+       return ok;
+};
+
+*/
+import "C"
+import (
+       "crypto/cipher"
+       "errors"
+       "runtime"
+       "strconv"
+       "unsafe"
+)
+
+type aesKeySizeError int
+
+func (k aesKeySizeError) Error() string {
+       return "crypto/aes: invalid key size " + strconv.Itoa(int(k))
+}
+
+const aesBlockSize = 16
+
+type aesCipher struct {
+       key []byte
+       enc C.GO_AES_KEY
+       dec C.GO_AES_KEY
+}
+
+type extraModes interface {
+       // Copied out of crypto/aes/modes.go.
+       NewCBCEncrypter(iv []byte) cipher.BlockMode
+       NewCBCDecrypter(iv []byte) cipher.BlockMode
+       NewCTR(iv []byte) cipher.Stream
+       NewGCM(nonceSize, tagSize int) (cipher.AEAD, error)
+
+       // Invented for BoringCrypto.
+       NewGCMTLS() (cipher.AEAD, error)
+}
+
+var _ extraModes = (*aesCipher)(nil)
+
+func NewAESCipher(key []byte) (cipher.Block, error) {
+       c := &aesCipher{key: make([]byte, len(key))}
+       copy(c.key, key)
+       // Note: 0 is success, contradicting the usual BoringCrypto convention.
+       if C._goboringcrypto_AES_set_decrypt_key((*C.uint8_t)(unsafe.Pointer(&c.key[0])), C.uint(8*len(c.key)), &c.dec) != 0 ||
+               C._goboringcrypto_AES_set_encrypt_key((*C.uint8_t)(unsafe.Pointer(&c.key[0])), C.uint(8*len(c.key)), &c.enc) != 0 {
+               return nil, aesKeySizeError(len(key))
+       }
+       return c, nil
+}
+
+func (c *aesCipher) BlockSize() int { return aesBlockSize }
+
+func (c *aesCipher) Encrypt(dst, src []byte) {
+       if inexactOverlap(dst, src) {
+               panic("crypto/cipher: invalid buffer overlap")
+       }
+       if len(src) < aesBlockSize {
+               panic("crypto/aes: input not full block")
+       }
+       if len(dst) < aesBlockSize {
+               panic("crypto/aes: output not full block")
+       }
+       C._goboringcrypto_AES_encrypt(
+               (*C.uint8_t)(unsafe.Pointer(&src[0])),
+               (*C.uint8_t)(unsafe.Pointer(&dst[0])),
+               &c.enc)
+}
+
+func (c *aesCipher) Decrypt(dst, src []byte) {
+       if inexactOverlap(dst, src) {
+               panic("crypto/cipher: invalid buffer overlap")
+       }
+       if len(src) < aesBlockSize {
+               panic("crypto/aes: input not full block")
+       }
+       if len(dst) < aesBlockSize {
+               panic("crypto/aes: output not full block")
+       }
+       C._goboringcrypto_AES_decrypt(
+               (*C.uint8_t)(unsafe.Pointer(&src[0])),
+               (*C.uint8_t)(unsafe.Pointer(&dst[0])),
+               &c.dec)
+}
+
+type aesCBC struct {
+       key  *C.GO_AES_KEY
+       mode C.int
+       iv   [aesBlockSize]byte
+}
+
+func (x *aesCBC) BlockSize() int { return aesBlockSize }
+
+func (x *aesCBC) CryptBlocks(dst, src []byte) {
+       if inexactOverlap(dst, src) {
+               panic("crypto/cipher: invalid buffer overlap")
+       }
+       if len(src)%aesBlockSize != 0 {
+               panic("crypto/cipher: input not full blocks")
+       }
+       if len(dst) < len(src) {
+               panic("crypto/cipher: output smaller than input")
+       }
+       if len(src) > 0 {
+               C._goboringcrypto_AES_cbc_encrypt(
+                       (*C.uint8_t)(unsafe.Pointer(&src[0])),
+                       (*C.uint8_t)(unsafe.Pointer(&dst[0])),
+                       C.size_t(len(src)), x.key,
+                       (*C.uint8_t)(unsafe.Pointer(&x.iv[0])), x.mode)
+       }
+}
+
+func (x *aesCBC) SetIV(iv []byte) {
+       if len(iv) != aesBlockSize {
+               panic("cipher: incorrect length IV")
+       }
+       copy(x.iv[:], iv)
+}
+
+func (c *aesCipher) NewCBCEncrypter(iv []byte) cipher.BlockMode {
+       x := &aesCBC{key: &c.enc, mode: C.GO_AES_ENCRYPT}
+       copy(x.iv[:], iv)
+       return x
+}
+
+func (c *aesCipher) NewCBCDecrypter(iv []byte) cipher.BlockMode {
+       x := &aesCBC{key: &c.dec, mode: C.GO_AES_DECRYPT}
+       copy(x.iv[:], iv)
+       return x
+}
+
+type aesCTR struct {
+       key        *C.GO_AES_KEY
+       iv         [aesBlockSize]byte
+       num        C.uint
+       ecount_buf [16]C.uint8_t
+}
+
+func (x *aesCTR) XORKeyStream(dst, src []byte) {
+       if inexactOverlap(dst, src) {
+               panic("crypto/cipher: invalid buffer overlap")
+       }
+       if len(dst) < len(src) {
+               panic("crypto/cipher: output smaller than input")
+       }
+       if len(src) == 0 {
+               return
+       }
+       C._goboringcrypto_AES_ctr128_encrypt(
+               (*C.uint8_t)(unsafe.Pointer(&src[0])),
+               (*C.uint8_t)(unsafe.Pointer(&dst[0])),
+               C.size_t(len(src)), x.key, (*C.uint8_t)(unsafe.Pointer(&x.iv[0])),
+               &x.ecount_buf[0], &x.num)
+}
+
+func (c *aesCipher) NewCTR(iv []byte) cipher.Stream {
+       x := &aesCTR{key: &c.enc}
+       copy(x.iv[:], iv)
+       return x
+}
+
+type aesGCM struct {
+       ctx  C.GO_EVP_AEAD_CTX
+       aead *C.GO_EVP_AEAD
+}
+
+const (
+       gcmBlockSize         = 16
+       gcmTagSize           = 16
+       gcmStandardNonceSize = 12
+)
+
+type aesNonceSizeError int
+
+func (n aesNonceSizeError) Error() string {
+       return "crypto/aes: invalid GCM nonce size " + strconv.Itoa(int(n))
+}
+
+type noGCM struct {
+       cipher.Block
+}
+
+func (c *aesCipher) NewGCM(nonceSize, tagSize int) (cipher.AEAD, error) {
+       if nonceSize != gcmStandardNonceSize && tagSize != gcmTagSize {
+               return nil, errors.New("crypto/aes: GCM tag and nonce sizes can't be non-standard at the same time")
+       }
+       // Fall back to standard library for GCM with non-standard nonce or tag size.
+       if nonceSize != gcmStandardNonceSize {
+               return cipher.NewGCMWithNonceSize(&noGCM{c}, nonceSize)
+       }
+       if tagSize != gcmTagSize {
+               return cipher.NewGCMWithTagSize(&noGCM{c}, tagSize)
+       }
+       return c.newGCM(false)
+}
+
+func (c *aesCipher) NewGCMTLS() (cipher.AEAD, error) {
+       return c.newGCM(true)
+}
+
+func (c *aesCipher) newGCM(tls bool) (cipher.AEAD, error) {
+       var aead *C.GO_EVP_AEAD
+       switch len(c.key) * 8 {
+       case 128:
+               if tls {
+                       aead = C._goboringcrypto_EVP_aead_aes_128_gcm_tls12()
+               } else {
+                       aead = C._goboringcrypto_EVP_aead_aes_128_gcm()
+               }
+       case 256:
+               if tls {
+                       aead = C._goboringcrypto_EVP_aead_aes_256_gcm_tls12()
+               } else {
+                       aead = C._goboringcrypto_EVP_aead_aes_256_gcm()
+               }
+       default:
+               // Fall back to standard library for GCM with non-standard key size.
+               return cipher.NewGCMWithNonceSize(&noGCM{c}, gcmStandardNonceSize)
+       }
+
+       g := &aesGCM{aead: aead}
+       if C._goboringcrypto_EVP_AEAD_CTX_init(&g.ctx, aead, (*C.uint8_t)(unsafe.Pointer(&c.key[0])), C.size_t(len(c.key)), C.GO_EVP_AEAD_DEFAULT_TAG_LENGTH, nil) == 0 {
+               return nil, fail("EVP_AEAD_CTX_init")
+       }
+       // Note: Because of the finalizer, any time g.ctx is passed to cgo,
+       // that call must be followed by a call to runtime.KeepAlive(g),
+       // to make sure g is not collected (and finalized) before the cgo
+       // call returns.
+       runtime.SetFinalizer(g, (*aesGCM).finalize)
+       if g.NonceSize() != gcmStandardNonceSize {
+               panic("boringcrypto: internal confusion about nonce size")
+       }
+       if g.Overhead() != gcmTagSize {
+               panic("boringcrypto: internal confusion about tag size")
+       }
+
+       return g, nil
+}
+
+func (g *aesGCM) finalize() {
+       C._goboringcrypto_EVP_AEAD_CTX_cleanup(&g.ctx)
+}
+
+func (g *aesGCM) NonceSize() int {
+       return int(C._goboringcrypto_EVP_AEAD_nonce_length(g.aead))
+}
+
+func (g *aesGCM) Overhead() int {
+       return int(C._goboringcrypto_EVP_AEAD_max_overhead(g.aead))
+}
+
+// base returns the address of the underlying array in b,
+// being careful not to panic when b has zero length.
+func base(b []byte) *C.uint8_t {
+       if len(b) == 0 {
+               return nil
+       }
+       return (*C.uint8_t)(unsafe.Pointer(&b[0]))
+}
+
+func (g *aesGCM) Seal(dst, nonce, plaintext, additionalData []byte) []byte {
+       if len(nonce) != gcmStandardNonceSize {
+               panic("cipher: incorrect nonce length given to GCM")
+       }
+       if uint64(len(plaintext)) > ((1<<32)-2)*aesBlockSize || len(plaintext)+gcmTagSize < len(plaintext) {
+               panic("cipher: message too large for GCM")
+       }
+       if len(dst)+len(plaintext)+gcmTagSize < len(dst) {
+               panic("cipher: message too large for buffer")
+       }
+
+       // Make room in dst to append plaintext+overhead.
+       n := len(dst)
+       for cap(dst) < n+len(plaintext)+gcmTagSize {
+               dst = append(dst[:cap(dst)], 0)
+       }
+       dst = dst[:n+len(plaintext)+gcmTagSize]
+
+       // Check delayed until now to make sure len(dst) is accurate.
+       if inexactOverlap(dst[n:], plaintext) {
+               panic("cipher: invalid buffer overlap")
+       }
+
+       outLen := C.size_t(len(plaintext) + gcmTagSize)
+       ok := C.EVP_AEAD_CTX_seal_wrapper(
+               &g.ctx,
+               (*C.uint8_t)(unsafe.Pointer(&dst[n])), outLen,
+               base(nonce), C.size_t(len(nonce)),
+               base(plaintext), C.size_t(len(plaintext)),
+               base(additionalData), C.size_t(len(additionalData)))
+       runtime.KeepAlive(g)
+       if ok == 0 {
+               panic(fail("EVP_AEAD_CTX_seal"))
+       }
+       return dst[:n+int(outLen)]
+}
+
+var errOpen = errors.New("cipher: message authentication failed")
+
+func (g *aesGCM) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
+       if len(nonce) != gcmStandardNonceSize {
+               panic("cipher: incorrect nonce length given to GCM")
+       }
+       if len(ciphertext) < gcmTagSize {
+               return nil, errOpen
+       }
+       if uint64(len(ciphertext)) > ((1<<32)-2)*aesBlockSize+gcmTagSize {
+               return nil, errOpen
+       }
+
+       // Make room in dst to append ciphertext without tag.
+       n := len(dst)
+       for cap(dst) < n+len(ciphertext)-gcmTagSize {
+               dst = append(dst[:cap(dst)], 0)
+       }
+       dst = dst[:n+len(ciphertext)-gcmTagSize]
+
+       // Check delayed until now to make sure len(dst) is accurate.
+       if inexactOverlap(dst[n:], ciphertext) {
+               panic("cipher: invalid buffer overlap")
+       }
+
+       outLen := C.size_t(len(ciphertext) - gcmTagSize)
+       ok := C.EVP_AEAD_CTX_open_wrapper(
+               &g.ctx,
+               base(dst[n:]), outLen,
+               base(nonce), C.size_t(len(nonce)),
+               base(ciphertext), C.size_t(len(ciphertext)),
+               base(additionalData), C.size_t(len(additionalData)))
+       runtime.KeepAlive(g)
+       if ok == 0 {
+               return nil, errOpen
+       }
+       return dst[:n+int(outLen)], nil
+}
+
+func anyOverlap(x, y []byte) bool {
+       return len(x) > 0 && len(y) > 0 &&
+               uintptr(unsafe.Pointer(&x[0])) <= uintptr(unsafe.Pointer(&y[len(y)-1])) &&
+               uintptr(unsafe.Pointer(&y[0])) <= uintptr(unsafe.Pointer(&x[len(x)-1]))
+}
+
+func inexactOverlap(x, y []byte) bool {
+       if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] {
+               return false
+       }
+       return anyOverlap(x, y)
+}
diff --git a/src/crypto/internal/boring/boring.go b/src/crypto/internal/boring/boring.go
new file mode 100644 (file)
index 0000000..9ccad7e
--- /dev/null
@@ -0,0 +1,83 @@
+// Copyright 2017 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.
+
+// +build linux,amd64
+// +build !android
+// +build !cmd_go_bootstrap
+// +build !msan
+
+package boring
+
+// #include "goboringcrypto.h"
+import "C"
+import (
+       "crypto/internal/boring/sig"
+       "math/big"
+)
+
+const available = true
+
+func init() {
+       C._goboringcrypto_BORINGSSL_bcm_power_on_self_test()
+       if C._goboringcrypto_FIPS_mode() != 1 {
+               panic("boringcrypto: not in FIPS mode")
+       }
+       sig.BoringCrypto()
+}
+
+// Unreachable marks code that should be unreachable
+// when BoringCrypto is in use. It panics.
+func Unreachable() {
+       panic("boringcrypto: invalid code execution")
+}
+
+// provided by runtime to avoid os import
+func runtime_arg0() string
+
+func hasSuffix(s, t string) bool {
+       return len(s) > len(t) && s[len(s)-len(t):] == t
+}
+
+// UnreachableExceptTests marks code that should be unreachable
+// when BoringCrypto is in use. It panics.
+func UnreachableExceptTests() {
+       name := runtime_arg0()
+       // If BoringCrypto ran on Windows we'd need to allow _test.exe and .test.exe as well.
+       if !hasSuffix(name, "_test") && !hasSuffix(name, ".test") {
+               println("boringcrypto: unexpected code execution in", name)
+               panic("boringcrypto: invalid code execution")
+       }
+}
+
+type fail string
+
+func (e fail) Error() string { return "boringcrypto: " + string(e) + " failed" }
+
+func bigToBN(x *big.Int) *C.GO_BIGNUM {
+       raw := x.Bytes()
+       return C._goboringcrypto_BN_bin2bn(base(raw), C.size_t(len(raw)), nil)
+}
+
+func bnToBig(bn *C.GO_BIGNUM) *big.Int {
+       raw := make([]byte, C._goboringcrypto_BN_num_bytes(bn))
+       n := C._goboringcrypto_BN_bn2bin(bn, base(raw))
+       return new(big.Int).SetBytes(raw[:n])
+}
+
+func bigToBn(bnp **C.GO_BIGNUM, b *big.Int) bool {
+       if *bnp != nil {
+               C._goboringcrypto_BN_free(*bnp)
+               *bnp = nil
+       }
+       if b == nil {
+               return true
+       }
+       raw := b.Bytes()
+       bn := C._goboringcrypto_BN_bin2bn(base(raw), C.size_t(len(raw)), nil)
+       if bn == nil {
+               return false
+       }
+       *bnp = bn
+       return true
+}
diff --git a/src/crypto/internal/boring/boring_test.go b/src/crypto/internal/boring/boring_test.go
new file mode 100644 (file)
index 0000000..83bbbd3
--- /dev/null
@@ -0,0 +1,34 @@
+// Copyright 2017 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.
+
+// Most functionality in this package is tested by replacing existing code
+// and inheriting that code's tests.
+
+package boring
+
+import "testing"
+
+// Test that func init does not panic.
+func TestInit(t *testing.T) {}
+
+// Test that Unreachable panics.
+func TestUnreachable(t *testing.T) {
+       defer func() {
+               if Enabled {
+                       if err := recover(); err == nil {
+                               t.Fatal("expected Unreachable to panic")
+                       }
+               } else {
+                       if err := recover(); err != nil {
+                               t.Fatalf("expected Unreachable to be a no-op")
+                       }
+               }
+       }()
+       Unreachable()
+}
+
+// Test that UnreachableExceptTests does not panic (this is a test).
+func TestUnreachableExceptTests(t *testing.T) {
+       UnreachableExceptTests()
+}
diff --git a/src/crypto/internal/boring/build.sh b/src/crypto/internal/boring/build.sh
new file mode 100755 (executable)
index 0000000..31e98cb
--- /dev/null
@@ -0,0 +1,196 @@
+#!/bin/bash
+# Copyright 2020 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.
+
+set -e
+id
+date
+export LANG=C
+unset LANGUAGE
+
+# Build BoringCrypto libcrypto.a.
+# Following https://csrc.nist.gov/CSRC/media/projects/cryptographic-module-validation-program/documents/security-policies/140sp3678.pdf page 19.
+
+tar xJf boringssl-*z
+
+# Go requires -fPIC for linux/amd64 cgo builds.
+# Setting -fPIC only affects the compilation of the non-module code in libcrypto.a,
+# because the FIPS module itself is already built with -fPIC.
+echo '#!/bin/bash
+exec clang-7 -fPIC "$@"
+' >/usr/local/bin/clang
+echo '#!/bin/bash
+exec clang++-7 -fPIC "$@"
+' >/usr/local/bin/clang++
+chmod +x /usr/local/bin/clang /usr/local/bin/clang++
+
+# The BoringSSL tests use Go, and cgo would look for gcc.
+export CGO_ENABLED=0
+
+# Verbatim instructions from BoringCrypto build docs.
+printf "set(CMAKE_C_COMPILER \"clang\")\nset(CMAKE_CXX_COMPILER \"clang++\")\n" >${HOME}/toolchain
+cd boringssl
+mkdir build && cd build && cmake -GNinja -DCMAKE_TOOLCHAIN_FILE=${HOME}/toolchain -DFIPS=1 -DCMAKE_BUILD_TYPE=Release ..
+ninja
+ninja run_tests
+
+cd ../..
+
+if [ "$(./boringssl/build/tool/bssl isfips)" != 1 ]; then
+       echo "NOT FIPS"
+       exit 2
+fi
+
+# Build and run test C++ program to make sure goboringcrypto.h matches openssl/*.h.
+# Also collect list of checked symbols in syms.txt
+set -x
+set -e
+cd godriver
+cat >goboringcrypto.cc <<'EOF'
+#include <cassert>
+#include "goboringcrypto0.h"
+#include "goboringcrypto1.h"
+#define check_size(t) if(sizeof(t) != sizeof(GO_ ## t)) {printf("sizeof(" #t ")=%d, but sizeof(GO_" #t ")=%d\n", (int)sizeof(t), (int)sizeof(GO_ ## t)); ret=1;}
+#define check_func(f) { auto x = f; x = _goboringcrypto_ ## f ; }
+#define check_value(n, v) if(n != v) {printf(#n "=%d, but goboringcrypto.h defines it as %d\n", (int)n, (int)v); ret=1;}
+int main() {
+int ret = 0;
+#include "goboringcrypto.x"
+return ret;
+}
+EOF
+
+awk '
+BEGIN {
+       exitcode = 0
+}
+
+# Ignore comments, #includes, blank lines.
+/^\/\// || /^#/ || NF == 0 { next }
+
+# Ignore unchecked declarations.
+/\/\*unchecked/ { next }
+
+# Check enum values.
+!enum && $1 == "enum" && $NF == "{" {
+       enum = 1
+       next
+}
+enum && $1 == "};" {
+       enum = 0
+       next
+}
+enum && NF == 3 && $2 == "=" {
+       name = $1
+       sub(/^GO_/, "", name)
+       val = $3
+       sub(/,$/, "", val)
+       print "check_value(" name ", " val ")" > "goboringcrypto.x"
+       next
+}
+enum {
+       print FILENAME ":" NR ": unexpected line in enum: " $0 > "/dev/stderr"
+       exitcode = 1
+       next
+}
+
+# Check struct sizes.
+/^typedef struct / && $NF ~ /^GO_/ {
+       name = $NF
+       sub(/^GO_/, "", name)
+       sub(/;$/, "", name)
+       print "check_size(" name ")" > "goboringcrypto.x"
+       next
+}
+
+# Check function prototypes.
+/^(const )?[^ ]+ \**_goboringcrypto_.*\(/ {
+       name = $2
+       if($1 == "const")
+               name = $3
+       sub(/^\**_goboringcrypto_/, "", name)
+       sub(/\(.*/, "", name)
+       print "check_func(" name ")" > "goboringcrypto.x"
+       print name > "syms.txt"
+       next
+}
+
+{
+       print FILENAME ":" NR ": unexpected line: " $0 > "/dev/stderr"
+       exitcode = 1
+}
+
+END {
+       exit exitcode
+}
+' goboringcrypto.h
+
+cat goboringcrypto.h | awk '
+       /^\/\/ #include/ {sub(/\/\//, ""); print > "goboringcrypto0.h"; next}
+       /typedef struct|enum ([a-z_]+ )?{|^[ \t]/ {print;next}
+       {gsub(/GO_/, ""); gsub(/enum go_/, "enum "); print}
+' >goboringcrypto1.h
+clang++ -std=c++11 -fPIC -I../boringssl/include -O2 -o a.out  goboringcrypto.cc
+./a.out || exit 2
+
+# Prepare copy of libcrypto.a with only the checked functions renamed and exported.
+# All other symbols are left alone and hidden.
+echo BORINGSSL_bcm_power_on_self_test >>syms.txt
+awk '{print "_goboringcrypto_" $0 }' syms.txt >globals.txt
+awk '{print $0 " _goboringcrypto_" $0 }' syms.txt >renames.txt
+objcopy --globalize-symbol=BORINGSSL_bcm_power_on_self_test ../boringssl/build/crypto/libcrypto.a libcrypto.a
+
+# clang implements u128 % u128 -> u128 by calling __umodti3,
+# which is in libgcc. To make the result self-contained even if linking
+# against a different compiler version, link our own __umodti3 into the syso.
+# This one is specialized so it only expects divisors below 2^64,
+# which is all BoringCrypto uses. (Otherwise it will seg fault.)
+cat >umod.s <<'EOF'
+# tu_int __umodti3(tu_int x, tu_int y)
+# x is rsi:rdi, y is rcx:rdx, return result is rdx:rax.
+.globl __umodti3
+__umodti3:
+       # specialized to u128 % u64, so verify that
+       test %rcx,%rcx
+       jne 1f
+
+       # save divisor
+       movq %rdx, %r8
+
+       # reduce top 64 bits mod divisor
+       movq %rsi, %rax
+       xorl %edx, %edx
+       divq %r8
+
+       # reduce full 128-bit mod divisor
+       # quotient fits in 64 bits because top 64 bits have been reduced < divisor.
+       # (even though we only care about the remainder, divq also computes
+       # the quotient, and it will trap if the quotient is too large.)
+       movq %rdi, %rax
+       divq %r8
+
+       # expand remainder to 128 for return
+       movq %rdx, %rax
+       xorl %edx, %edx
+       ret
+
+1:
+       # crash - only want 64-bit divisor
+       xorl %ecx, %ecx
+       movl %ecx, 0(%ecx)
+       jmp 1b
+
+.section .note.GNU-stack,"",@progbits
+EOF
+clang -c -o umod.o umod.s
+
+ld -r -nostdlib --whole-archive -o goboringcrypto.o libcrypto.a umod.o
+echo __umodti3 _goboringcrypto___umodti3 >>renames.txt
+objcopy --remove-section=.llvm_addrsig goboringcrypto.o goboringcrypto1.o # b/179161016
+objcopy --redefine-syms=renames.txt goboringcrypto1.o goboringcrypto2.o
+objcopy --keep-global-symbols=globals.txt goboringcrypto2.o goboringcrypto_linux_amd64.syso
+
+# Done!
+ls -l goboringcrypto_linux_amd64.syso
+sha256sum goboringcrypto_linux_amd64.syso
diff --git a/src/crypto/internal/boring/doc.go b/src/crypto/internal/boring/doc.go
new file mode 100644 (file)
index 0000000..64f41e3
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2017 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 boring provides access to BoringCrypto implementation functions.
+// Check the constant Enabled to find out whether BoringCrypto is available.
+// If BoringCrypto is not available, the functions in this package all panic.
+package boring
+
+// Enabled reports whether BoringCrypto is available.
+// When enabled is false, all functions in this package panic.
+//
+// BoringCrypto is only available on linux/amd64 systems.
+const Enabled = available
diff --git a/src/crypto/internal/boring/ecdsa.go b/src/crypto/internal/boring/ecdsa.go
new file mode 100644 (file)
index 0000000..4fcba4b
--- /dev/null
@@ -0,0 +1,201 @@
+// Copyright 2017 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.
+
+// +build linux,amd64
+// +build !android
+// +build !cmd_go_bootstrap
+// +build !msan
+
+package boring
+
+// #include "goboringcrypto.h"
+import "C"
+import (
+       "encoding/asn1"
+       "errors"
+       "math/big"
+       "runtime"
+       "unsafe"
+)
+
+type ecdsaSignature struct {
+       R, S *big.Int
+}
+
+type PrivateKeyECDSA struct {
+       key *C.GO_EC_KEY
+}
+
+func (k *PrivateKeyECDSA) finalize() {
+       C._goboringcrypto_EC_KEY_free(k.key)
+}
+
+type PublicKeyECDSA struct {
+       key *C.GO_EC_KEY
+}
+
+func (k *PublicKeyECDSA) finalize() {
+       C._goboringcrypto_EC_KEY_free(k.key)
+}
+
+var errUnknownCurve = errors.New("boringcrypto: unknown elliptic curve")
+
+func curveNID(curve string) (C.int, error) {
+       switch curve {
+       case "P-224":
+               return C.GO_NID_secp224r1, nil
+       case "P-256":
+               return C.GO_NID_X9_62_prime256v1, nil
+       case "P-384":
+               return C.GO_NID_secp384r1, nil
+       case "P-521":
+               return C.GO_NID_secp521r1, nil
+       }
+       return 0, errUnknownCurve
+}
+
+func NewPublicKeyECDSA(curve string, X, Y *big.Int) (*PublicKeyECDSA, error) {
+       key, err := newECKey(curve, X, Y)
+       if err != nil {
+               return nil, err
+       }
+       k := &PublicKeyECDSA{key}
+       // Note: Because of the finalizer, any time k.key is passed to cgo,
+       // that call must be followed by a call to runtime.KeepAlive(k),
+       // to make sure k is not collected (and finalized) before the cgo
+       // call returns.
+       runtime.SetFinalizer(k, (*PublicKeyECDSA).finalize)
+       return k, nil
+}
+
+func newECKey(curve string, X, Y *big.Int) (*C.GO_EC_KEY, error) {
+       nid, err := curveNID(curve)
+       if err != nil {
+               return nil, err
+       }
+       key := C._goboringcrypto_EC_KEY_new_by_curve_name(nid)
+       if key == nil {
+               return nil, fail("EC_KEY_new_by_curve_name")
+       }
+       group := C._goboringcrypto_EC_KEY_get0_group(key)
+       pt := C._goboringcrypto_EC_POINT_new(group)
+       if pt == nil {
+               C._goboringcrypto_EC_KEY_free(key)
+               return nil, fail("EC_POINT_new")
+       }
+       bx := bigToBN(X)
+       by := bigToBN(Y)
+       ok := bx != nil && by != nil && C._goboringcrypto_EC_POINT_set_affine_coordinates_GFp(group, pt, bx, by, nil) != 0 &&
+               C._goboringcrypto_EC_KEY_set_public_key(key, pt) != 0
+       if bx != nil {
+               C._goboringcrypto_BN_free(bx)
+       }
+       if by != nil {
+               C._goboringcrypto_BN_free(by)
+       }
+       C._goboringcrypto_EC_POINT_free(pt)
+       if !ok {
+               C._goboringcrypto_EC_KEY_free(key)
+               return nil, fail("EC_POINT_set_affine_coordinates_GFp")
+       }
+       return key, nil
+}
+
+func NewPrivateKeyECDSA(curve string, X, Y *big.Int, D *big.Int) (*PrivateKeyECDSA, error) {
+       key, err := newECKey(curve, X, Y)
+       if err != nil {
+               return nil, err
+       }
+       bd := bigToBN(D)
+       ok := bd != nil && C._goboringcrypto_EC_KEY_set_private_key(key, bd) != 0
+       if bd != nil {
+               C._goboringcrypto_BN_free(bd)
+       }
+       if !ok {
+               C._goboringcrypto_EC_KEY_free(key)
+               return nil, fail("EC_KEY_set_private_key")
+       }
+       k := &PrivateKeyECDSA{key}
+       // Note: Because of the finalizer, any time k.key is passed to cgo,
+       // that call must be followed by a call to runtime.KeepAlive(k),
+       // to make sure k is not collected (and finalized) before the cgo
+       // call returns.
+       runtime.SetFinalizer(k, (*PrivateKeyECDSA).finalize)
+       return k, nil
+}
+
+func SignECDSA(priv *PrivateKeyECDSA, hash []byte) (r, s *big.Int, err error) {
+       // We could use ECDSA_do_sign instead but would need to convert
+       // the resulting BIGNUMs to *big.Int form. If we're going to do a
+       // conversion, converting the ASN.1 form is more convenient and
+       // likely not much more expensive.
+       sig, err := SignMarshalECDSA(priv, hash)
+       if err != nil {
+               return nil, nil, err
+       }
+       var esig ecdsaSignature
+       if _, err := asn1.Unmarshal(sig, &esig); err != nil {
+               return nil, nil, err
+       }
+       return esig.R, esig.S, nil
+}
+
+func SignMarshalECDSA(priv *PrivateKeyECDSA, hash []byte) ([]byte, error) {
+       size := C._goboringcrypto_ECDSA_size(priv.key)
+       sig := make([]byte, size)
+       var sigLen C.uint
+       if C._goboringcrypto_ECDSA_sign(0, base(hash), C.size_t(len(hash)), (*C.uint8_t)(unsafe.Pointer(&sig[0])), &sigLen, priv.key) == 0 {
+               return nil, fail("ECDSA_sign")
+       }
+       runtime.KeepAlive(priv)
+       return sig[:sigLen], nil
+}
+
+func VerifyECDSA(pub *PublicKeyECDSA, hash []byte, r, s *big.Int) bool {
+       // We could use ECDSA_do_verify instead but would need to convert
+       // r and s to BIGNUM form. If we're going to do a conversion, marshaling
+       // to ASN.1 is more convenient and likely not much more expensive.
+       sig, err := asn1.Marshal(ecdsaSignature{r, s})
+       if err != nil {
+               return false
+       }
+       ok := C._goboringcrypto_ECDSA_verify(0, base(hash), C.size_t(len(hash)), (*C.uint8_t)(unsafe.Pointer(&sig[0])), C.size_t(len(sig)), pub.key) != 0
+       runtime.KeepAlive(pub)
+       return ok
+}
+
+func GenerateKeyECDSA(curve string) (X, Y, D *big.Int, err error) {
+       nid, err := curveNID(curve)
+       if err != nil {
+               return nil, nil, nil, err
+       }
+       key := C._goboringcrypto_EC_KEY_new_by_curve_name(nid)
+       if key == nil {
+               return nil, nil, nil, fail("EC_KEY_new_by_curve_name")
+       }
+       defer C._goboringcrypto_EC_KEY_free(key)
+       if C._goboringcrypto_EC_KEY_generate_key_fips(key) == 0 {
+               return nil, nil, nil, fail("EC_KEY_generate_key_fips")
+       }
+       group := C._goboringcrypto_EC_KEY_get0_group(key)
+       pt := C._goboringcrypto_EC_KEY_get0_public_key(key)
+       bd := C._goboringcrypto_EC_KEY_get0_private_key(key)
+       if pt == nil || bd == nil {
+               return nil, nil, nil, fail("EC_KEY_get0_private_key")
+       }
+       bx := C._goboringcrypto_BN_new()
+       if bx == nil {
+               return nil, nil, nil, fail("BN_new")
+       }
+       defer C._goboringcrypto_BN_free(bx)
+       by := C._goboringcrypto_BN_new()
+       if by == nil {
+               return nil, nil, nil, fail("BN_new")
+       }
+       defer C._goboringcrypto_BN_free(by)
+       if C._goboringcrypto_EC_POINT_get_affine_coordinates_GFp(group, pt, bx, by, nil) == 0 {
+               return nil, nil, nil, fail("EC_POINT_get_affine_coordinates_GFp")
+       }
+       return bnToBig(bx), bnToBig(by), bnToBig(bd), nil
+}
diff --git a/src/crypto/internal/boring/fipstls/dummy.s b/src/crypto/internal/boring/fipstls/dummy.s
new file mode 100644 (file)
index 0000000..53bb7d9
--- /dev/null
@@ -0,0 +1,10 @@
+// Copyright 2017 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.
+
+// runtime_arg0 is declared in tls.go without a body.
+// It's provided by package runtime,
+// but the go command doesn't know that.
+// Having this assembly file keeps the go command
+// from complaining about the missing body
+// (because the implementation might be here).
diff --git a/src/crypto/internal/boring/fipstls/tls.go b/src/crypto/internal/boring/fipstls/tls.go
new file mode 100644 (file)
index 0000000..4127533
--- /dev/null
@@ -0,0 +1,49 @@
+// Copyright 2017 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 fipstls allows control over whether crypto/tls requires FIPS-approved settings.
+// This package's effects are independent of the use of the BoringCrypto implementation.
+package fipstls
+
+import "sync/atomic"
+
+var required uint32
+
+// Force forces crypto/tls to restrict TLS configurations to FIPS-approved settings.
+// By design, this call is impossible to undo (except in tests).
+//
+// Note that this call has an effect even in programs using
+// standard crypto (that is, even when Enabled = false).
+func Force() {
+       atomic.StoreUint32(&required, 1)
+}
+
+// Abandon allows non-FIPS-approved settings.
+// If called from a non-test binary, it panics.
+func Abandon() {
+       // Note: Not using boring.UnreachableExceptTests because we want
+       // this test to happen even when boring.Enabled = false.
+       name := runtime_arg0()
+       // Allow _test for Go command, .test for Bazel,
+       // NaClMain for NaCl (where all binaries run as NaClMain),
+       // and empty string for Windows (where runtime_arg0 can't easily find the name).
+       // Since this is an internal package, testing that this isn't used on the
+       // other operating systems should suffice to catch any mistakes.
+       if !hasSuffix(name, "_test") && !hasSuffix(name, ".test") && name != "NaClMain" && name != "" {
+               panic("fipstls: invalid use of Abandon in " + name)
+       }
+       atomic.StoreUint32(&required, 0)
+}
+
+// provided by runtime
+func runtime_arg0() string
+
+func hasSuffix(s, t string) bool {
+       return len(s) > len(t) && s[len(s)-len(t):] == t
+}
+
+// Required reports whether FIPS-approved settings are required.
+func Required() bool {
+       return atomic.LoadUint32(&required) != 0
+}
diff --git a/src/crypto/internal/boring/goboringcrypto.h b/src/crypto/internal/boring/goboringcrypto.h
new file mode 100644 (file)
index 0000000..37b7917
--- /dev/null
@@ -0,0 +1,237 @@
+// Copyright 2017 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.
+
+// This header file describes the BoringCrypto ABI as built for use in Go.
+// The BoringCrypto build for Go (which generates goboringcrypto_*.syso)
+// takes the standard libcrypto.a from BoringCrypto and adds the prefix
+// _goboringcrypto_ to every symbol, to avoid possible conflicts with
+// code wrapping a different BoringCrypto or OpenSSL.
+//
+// To make this header standalone (so that building Go does not require
+// having a full set of BoringCrypto headers), the struct details are not here.
+// Instead, while building the syso, we compile and run a C++ program
+// that checks that the sizes match. The program also checks (during compilation)
+// that all the function prototypes match the BoringCrypto equivalents.
+// The generation of the checking program depends on the declaration
+// forms used below (one line for most, multiline for enums).
+
+#include <stdlib.h> // size_t
+#include <stdint.h> // uint8_t
+
+// This symbol is hidden in BoringCrypto and marked as a constructor,
+// but cmd/link's internal linking mode doesn't handle constructors.
+// Until it does, we've exported the symbol and can call it explicitly.
+// (If using external linking mode, it will therefore be called twice,
+// once explicitly and once as a constructor, but that's OK.)
+/*unchecked*/ void _goboringcrypto_BORINGSSL_bcm_power_on_self_test(void);
+
+// #include <openssl/crypto.h>
+int _goboringcrypto_FIPS_mode(void);
+void* _goboringcrypto_OPENSSL_malloc(size_t);
+
+// #include <openssl/rand.h>
+int _goboringcrypto_RAND_bytes(uint8_t*, size_t);
+
+// #include <openssl/nid.h>
+enum {
+       GO_NID_md5_sha1 = 114,
+
+       GO_NID_secp224r1 = 713,
+       GO_NID_X9_62_prime256v1 = 415,
+       GO_NID_secp384r1 = 715,
+       GO_NID_secp521r1 = 716,
+
+       GO_NID_sha224 = 675,
+       GO_NID_sha256 = 672,
+       GO_NID_sha384 = 673,
+       GO_NID_sha512 = 674,
+};
+
+// #include <openssl/sha.h>
+typedef struct GO_SHA_CTX { char data[96]; } GO_SHA_CTX;
+int _goboringcrypto_SHA1_Init(GO_SHA_CTX*);
+int _goboringcrypto_SHA1_Update(GO_SHA_CTX*, const void*, size_t);
+int _goboringcrypto_SHA1_Final(uint8_t*, GO_SHA_CTX*);
+
+typedef struct GO_SHA256_CTX { char data[48+64]; } GO_SHA256_CTX;
+int _goboringcrypto_SHA224_Init(GO_SHA256_CTX*);
+int _goboringcrypto_SHA224_Update(GO_SHA256_CTX*, const void*, size_t);
+int _goboringcrypto_SHA224_Final(uint8_t*, GO_SHA256_CTX*);
+int _goboringcrypto_SHA256_Init(GO_SHA256_CTX*);
+int _goboringcrypto_SHA256_Update(GO_SHA256_CTX*, const void*, size_t);
+int _goboringcrypto_SHA256_Final(uint8_t*, GO_SHA256_CTX*);
+
+typedef struct GO_SHA512_CTX { char data[88+128]; } GO_SHA512_CTX;
+int _goboringcrypto_SHA384_Init(GO_SHA512_CTX*);
+int _goboringcrypto_SHA384_Update(GO_SHA512_CTX*, const void*, size_t);
+int _goboringcrypto_SHA384_Final(uint8_t*, GO_SHA512_CTX*);
+int _goboringcrypto_SHA512_Init(GO_SHA512_CTX*);
+int _goboringcrypto_SHA512_Update(GO_SHA512_CTX*, const void*, size_t);
+int _goboringcrypto_SHA512_Final(uint8_t*, GO_SHA512_CTX*);
+
+// #include <openssl/digest.h>
+/*unchecked (opaque)*/ typedef struct GO_EVP_MD { char data[1]; } GO_EVP_MD;
+const GO_EVP_MD* _goboringcrypto_EVP_md4(void);
+const GO_EVP_MD* _goboringcrypto_EVP_md5(void);
+const GO_EVP_MD* _goboringcrypto_EVP_md5_sha1(void);
+const GO_EVP_MD* _goboringcrypto_EVP_sha1(void);
+const GO_EVP_MD* _goboringcrypto_EVP_sha224(void);
+const GO_EVP_MD* _goboringcrypto_EVP_sha256(void);
+const GO_EVP_MD* _goboringcrypto_EVP_sha384(void);
+const GO_EVP_MD* _goboringcrypto_EVP_sha512(void);
+int _goboringcrypto_EVP_MD_type(const GO_EVP_MD*);
+size_t _goboringcrypto_EVP_MD_size(const GO_EVP_MD*);
+
+// #include <openssl/hmac.h>
+typedef struct GO_HMAC_CTX { char data[104]; } GO_HMAC_CTX;
+void _goboringcrypto_HMAC_CTX_init(GO_HMAC_CTX*);
+void _goboringcrypto_HMAC_CTX_cleanup(GO_HMAC_CTX*);
+int _goboringcrypto_HMAC_Init(GO_HMAC_CTX*, const void*, int, const GO_EVP_MD*);
+int _goboringcrypto_HMAC_Update(GO_HMAC_CTX*, const uint8_t*, size_t);
+int _goboringcrypto_HMAC_Final(GO_HMAC_CTX*, uint8_t*, unsigned int*);
+size_t _goboringcrypto_HMAC_size(const GO_HMAC_CTX*);
+int _goboringcrypto_HMAC_CTX_copy_ex(GO_HMAC_CTX *dest, const GO_HMAC_CTX *src);
+
+// #include <openssl/aes.h>
+typedef struct GO_AES_KEY { char data[244]; } GO_AES_KEY;
+int _goboringcrypto_AES_set_encrypt_key(const uint8_t*, unsigned int, GO_AES_KEY*);
+int _goboringcrypto_AES_set_decrypt_key(const uint8_t*, unsigned int, GO_AES_KEY*);
+void _goboringcrypto_AES_encrypt(const uint8_t*, uint8_t*, const GO_AES_KEY*);
+void _goboringcrypto_AES_decrypt(const uint8_t*, uint8_t*, const GO_AES_KEY*);
+void _goboringcrypto_AES_ctr128_encrypt(const uint8_t*, uint8_t*, size_t, const GO_AES_KEY*, uint8_t*, uint8_t*, unsigned int*);
+enum {
+       GO_AES_ENCRYPT = 1,
+       GO_AES_DECRYPT = 0
+};
+void _goboringcrypto_AES_cbc_encrypt(const uint8_t*, uint8_t*, size_t, const GO_AES_KEY*, uint8_t*, const int);
+
+// #include <openssl/aead.h>
+/*unchecked (opaque)*/ typedef struct GO_EVP_AEAD { char data[1]; } GO_EVP_AEAD;
+/*unchecked (opaque)*/ typedef struct GO_ENGINE { char data[1]; } GO_ENGINE;
+const GO_EVP_AEAD* _goboringcrypto_EVP_aead_aes_128_gcm(void);
+const GO_EVP_AEAD* _goboringcrypto_EVP_aead_aes_256_gcm(void);
+enum {
+       GO_EVP_AEAD_DEFAULT_TAG_LENGTH = 0
+};
+size_t _goboringcrypto_EVP_AEAD_key_length(const GO_EVP_AEAD*);
+size_t _goboringcrypto_EVP_AEAD_nonce_length(const GO_EVP_AEAD*);
+size_t _goboringcrypto_EVP_AEAD_max_overhead(const GO_EVP_AEAD*);
+size_t _goboringcrypto_EVP_AEAD_max_tag_len(const GO_EVP_AEAD*);
+typedef struct GO_EVP_AEAD_CTX { char data[600]; } GO_EVP_AEAD_CTX;
+void _goboringcrypto_EVP_AEAD_CTX_zero(GO_EVP_AEAD_CTX*);
+int _goboringcrypto_EVP_AEAD_CTX_init(GO_EVP_AEAD_CTX*, const GO_EVP_AEAD*, const uint8_t*, size_t, size_t, GO_ENGINE*);
+void _goboringcrypto_EVP_AEAD_CTX_cleanup(GO_EVP_AEAD_CTX*);
+int _goboringcrypto_EVP_AEAD_CTX_seal(const GO_EVP_AEAD_CTX*, uint8_t*, size_t*, size_t, const uint8_t*, size_t, const uint8_t*, size_t, const uint8_t*, size_t);
+int _goboringcrypto_EVP_AEAD_CTX_open(const GO_EVP_AEAD_CTX*, uint8_t*, size_t*, size_t, const uint8_t*, size_t, const uint8_t*, size_t, const uint8_t*, size_t);
+const GO_EVP_AEAD* _goboringcrypto_EVP_aead_aes_128_gcm_tls12(void);
+const GO_EVP_AEAD* _goboringcrypto_EVP_aead_aes_256_gcm_tls12(void);
+enum go_evp_aead_direction_t {
+       go_evp_aead_open = 0,
+       go_evp_aead_seal = 1
+};
+int _goboringcrypto_EVP_AEAD_CTX_init_with_direction(GO_EVP_AEAD_CTX*, const GO_EVP_AEAD*, const uint8_t*, size_t, size_t, enum go_evp_aead_direction_t);
+
+// #include <openssl/bn.h>
+/*unchecked (opaque)*/ typedef struct GO_BN_CTX { char data[1]; } GO_BN_CTX;
+typedef struct GO_BIGNUM { char data[24]; } GO_BIGNUM;
+GO_BIGNUM* _goboringcrypto_BN_new(void);
+void _goboringcrypto_BN_free(GO_BIGNUM*);
+unsigned _goboringcrypto_BN_num_bits(const GO_BIGNUM*);
+unsigned _goboringcrypto_BN_num_bytes(const GO_BIGNUM*);
+int _goboringcrypto_BN_is_negative(const GO_BIGNUM*);
+GO_BIGNUM* _goboringcrypto_BN_bin2bn(const uint8_t*, size_t, GO_BIGNUM*);
+size_t _goboringcrypto_BN_bn2bin(const GO_BIGNUM*, uint8_t*);
+
+// #include <openssl/ec.h>
+/*unchecked (opaque)*/ typedef struct GO_EC_GROUP { char data[1]; } GO_EC_GROUP;
+GO_EC_GROUP* _goboringcrypto_EC_GROUP_new_by_curve_name(int);
+void _goboringcrypto_EC_GROUP_free(GO_EC_GROUP*);
+
+/*unchecked (opaque)*/ typedef struct GO_EC_POINT { char data[1]; } GO_EC_POINT;
+GO_EC_POINT* _goboringcrypto_EC_POINT_new(const GO_EC_GROUP*);
+void _goboringcrypto_EC_POINT_free(GO_EC_POINT*);
+int _goboringcrypto_EC_POINT_get_affine_coordinates_GFp(const GO_EC_GROUP*, const GO_EC_POINT*, GO_BIGNUM*, GO_BIGNUM*, GO_BN_CTX*);
+int _goboringcrypto_EC_POINT_set_affine_coordinates_GFp(const GO_EC_GROUP*, GO_EC_POINT*, const GO_BIGNUM*, const GO_BIGNUM*, GO_BN_CTX*);
+
+// #include <openssl/ec_key.h>
+/*unchecked (opaque)*/ typedef struct GO_EC_KEY { char data[1]; } GO_EC_KEY;
+GO_EC_KEY* _goboringcrypto_EC_KEY_new(void);
+GO_EC_KEY* _goboringcrypto_EC_KEY_new_by_curve_name(int);
+void _goboringcrypto_EC_KEY_free(GO_EC_KEY*);
+const GO_EC_GROUP* _goboringcrypto_EC_KEY_get0_group(const GO_EC_KEY*);
+int _goboringcrypto_EC_KEY_generate_key_fips(GO_EC_KEY*);
+int _goboringcrypto_EC_KEY_set_private_key(GO_EC_KEY*, const GO_BIGNUM*);
+int _goboringcrypto_EC_KEY_set_public_key(GO_EC_KEY*, const GO_EC_POINT*);
+int _goboringcrypto_EC_KEY_is_opaque(const GO_EC_KEY*);
+const GO_BIGNUM* _goboringcrypto_EC_KEY_get0_private_key(const GO_EC_KEY*);
+const GO_EC_POINT* _goboringcrypto_EC_KEY_get0_public_key(const GO_EC_KEY*);
+// TODO: EC_KEY_check_fips?
+
+// #include <openssl/ecdsa.h>
+typedef struct GO_ECDSA_SIG { char data[16]; } GO_ECDSA_SIG;
+GO_ECDSA_SIG* _goboringcrypto_ECDSA_SIG_new(void);
+void _goboringcrypto_ECDSA_SIG_free(GO_ECDSA_SIG*);
+GO_ECDSA_SIG* _goboringcrypto_ECDSA_do_sign(const uint8_t*, size_t, const GO_EC_KEY*);
+int _goboringcrypto_ECDSA_do_verify(const uint8_t*, size_t, const GO_ECDSA_SIG*, const GO_EC_KEY*);
+int _goboringcrypto_ECDSA_sign(int, const uint8_t*, size_t, uint8_t*, unsigned int*, const GO_EC_KEY*);
+size_t _goboringcrypto_ECDSA_size(const GO_EC_KEY*);
+int _goboringcrypto_ECDSA_verify(int, const uint8_t*, size_t, const uint8_t*, size_t, const GO_EC_KEY*);
+
+// #include <openssl/rsa.h>
+
+// Note: order of struct fields here is unchecked.
+typedef struct GO_RSA { void *meth; GO_BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp; char data[160]; } GO_RSA;
+/*unchecked (opaque)*/ typedef struct GO_BN_GENCB { char data[1]; } GO_BN_GENCB;
+GO_RSA* _goboringcrypto_RSA_new(void);
+void _goboringcrypto_RSA_free(GO_RSA*);
+void _goboringcrypto_RSA_get0_key(const GO_RSA*, const GO_BIGNUM **n, const GO_BIGNUM **e, const GO_BIGNUM **d);
+void _goboringcrypto_RSA_get0_factors(const GO_RSA*, const GO_BIGNUM **p, const GO_BIGNUM **q);
+void _goboringcrypto_RSA_get0_crt_params(const GO_RSA*, const GO_BIGNUM **dmp1, const GO_BIGNUM **dmp2, const GO_BIGNUM **iqmp);
+int _goboringcrypto_RSA_generate_key_ex(GO_RSA*, int, const GO_BIGNUM*, GO_BN_GENCB*);
+int _goboringcrypto_RSA_generate_key_fips(GO_RSA*, int, GO_BN_GENCB*);
+enum {
+       GO_RSA_PKCS1_PADDING = 1,
+       GO_RSA_NO_PADDING = 3,
+       GO_RSA_PKCS1_OAEP_PADDING = 4,
+       GO_RSA_PKCS1_PSS_PADDING = 6,
+};
+int _goboringcrypto_RSA_encrypt(GO_RSA*, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding);
+int _goboringcrypto_RSA_decrypt(GO_RSA*, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding);
+int _goboringcrypto_RSA_sign(int hash_nid, const uint8_t* in, unsigned int in_len, uint8_t *out, unsigned int *out_len, GO_RSA*);
+int _goboringcrypto_RSA_sign_pss_mgf1(GO_RSA*, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, const GO_EVP_MD *md, const GO_EVP_MD *mgf1_md, int salt_len);
+int _goboringcrypto_RSA_sign_raw(GO_RSA*, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding);
+int _goboringcrypto_RSA_verify(int hash_nid, const uint8_t *msg, size_t msg_len, const uint8_t *sig, size_t sig_len, GO_RSA*);
+int _goboringcrypto_RSA_verify_pss_mgf1(GO_RSA*, const uint8_t *msg, size_t msg_len, const GO_EVP_MD *md, const GO_EVP_MD *mgf1_md, int salt_len, const uint8_t *sig, size_t sig_len);
+int _goboringcrypto_RSA_verify_raw(GO_RSA*, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding);
+unsigned _goboringcrypto_RSA_size(const GO_RSA*);
+int _goboringcrypto_RSA_is_opaque(const GO_RSA*);
+int _goboringcrypto_RSA_check_key(const GO_RSA*);
+int _goboringcrypto_RSA_check_fips(GO_RSA*);
+GO_RSA* _goboringcrypto_RSA_public_key_from_bytes(const uint8_t*, size_t);
+GO_RSA* _goboringcrypto_RSA_private_key_from_bytes(const uint8_t*, size_t);
+int _goboringcrypto_RSA_public_key_to_bytes(uint8_t**, size_t*, const GO_RSA*);
+int _goboringcrypto_RSA_private_key_to_bytes(uint8_t**, size_t*, const GO_RSA*);
+
+// #include <openssl/evp.h>
+/*unchecked (opaque)*/ typedef struct GO_EVP_PKEY { char data[1]; } GO_EVP_PKEY;
+GO_EVP_PKEY* _goboringcrypto_EVP_PKEY_new(void);
+void _goboringcrypto_EVP_PKEY_free(GO_EVP_PKEY*);
+int _goboringcrypto_EVP_PKEY_set1_RSA(GO_EVP_PKEY*, GO_RSA*);
+
+/*unchecked (opaque)*/ typedef struct GO_EVP_PKEY_CTX { char data[1]; } GO_EVP_PKEY_CTX;
+
+GO_EVP_PKEY_CTX* _goboringcrypto_EVP_PKEY_CTX_new(GO_EVP_PKEY*, GO_ENGINE*);
+void _goboringcrypto_EVP_PKEY_CTX_free(GO_EVP_PKEY_CTX*);
+int _goboringcrypto_EVP_PKEY_CTX_set0_rsa_oaep_label(GO_EVP_PKEY_CTX*, uint8_t*, size_t);
+int _goboringcrypto_EVP_PKEY_CTX_set_rsa_oaep_md(GO_EVP_PKEY_CTX*, const GO_EVP_MD*);
+int _goboringcrypto_EVP_PKEY_CTX_set_rsa_padding(GO_EVP_PKEY_CTX*, int padding);
+int _goboringcrypto_EVP_PKEY_decrypt(GO_EVP_PKEY_CTX*, uint8_t*, size_t*, const uint8_t*, size_t);
+int _goboringcrypto_EVP_PKEY_encrypt(GO_EVP_PKEY_CTX*, uint8_t*, size_t*, const uint8_t*, size_t);
+int _goboringcrypto_EVP_PKEY_decrypt_init(GO_EVP_PKEY_CTX*);
+int _goboringcrypto_EVP_PKEY_encrypt_init(GO_EVP_PKEY_CTX*);
+int _goboringcrypto_EVP_PKEY_CTX_set_rsa_mgf1_md(GO_EVP_PKEY_CTX*, const GO_EVP_MD*);
+int _goboringcrypto_EVP_PKEY_CTX_set_rsa_pss_saltlen(GO_EVP_PKEY_CTX*, int);
+int _goboringcrypto_EVP_PKEY_sign_init(GO_EVP_PKEY_CTX*);
+int _goboringcrypto_EVP_PKEY_verify_init(GO_EVP_PKEY_CTX*);
+int _goboringcrypto_EVP_PKEY_sign(GO_EVP_PKEY_CTX*, uint8_t*, size_t*, const uint8_t*, size_t);
diff --git a/src/crypto/internal/boring/goboringcrypto_linux_amd64.syso b/src/crypto/internal/boring/goboringcrypto_linux_amd64.syso
new file mode 100644 (file)
index 0000000..2459dd7
Binary files /dev/null and b/src/crypto/internal/boring/goboringcrypto_linux_amd64.syso differ
diff --git a/src/crypto/internal/boring/hmac.go b/src/crypto/internal/boring/hmac.go
new file mode 100644 (file)
index 0000000..01b5844
--- /dev/null
@@ -0,0 +1,156 @@
+// Copyright 2017 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.
+
+// +build linux,amd64
+// +build !android
+// +build !cmd_go_bootstrap
+// +build !msan
+
+package boring
+
+// #include "goboringcrypto.h"
+import "C"
+import (
+       "crypto"
+       "hash"
+       "runtime"
+       "unsafe"
+)
+
+// hashToMD converts a hash.Hash implementation from this package
+// to a BoringCrypto *C.GO_EVP_MD.
+func hashToMD(h hash.Hash) *C.GO_EVP_MD {
+       switch h.(type) {
+       case *sha1Hash:
+               return C._goboringcrypto_EVP_sha1()
+       case *sha224Hash:
+               return C._goboringcrypto_EVP_sha224()
+       case *sha256Hash:
+               return C._goboringcrypto_EVP_sha256()
+       case *sha384Hash:
+               return C._goboringcrypto_EVP_sha384()
+       case *sha512Hash:
+               return C._goboringcrypto_EVP_sha512()
+       }
+       return nil
+}
+
+// cryptoHashToMD converts a crypto.Hash
+// to a BoringCrypto *C.GO_EVP_MD.
+func cryptoHashToMD(ch crypto.Hash) *C.GO_EVP_MD {
+       switch ch {
+       case crypto.MD5:
+               return C._goboringcrypto_EVP_md5()
+       case crypto.MD5SHA1:
+               return C._goboringcrypto_EVP_md5_sha1()
+       case crypto.SHA1:
+               return C._goboringcrypto_EVP_sha1()
+       case crypto.SHA224:
+               return C._goboringcrypto_EVP_sha224()
+       case crypto.SHA256:
+               return C._goboringcrypto_EVP_sha256()
+       case crypto.SHA384:
+               return C._goboringcrypto_EVP_sha384()
+       case crypto.SHA512:
+               return C._goboringcrypto_EVP_sha512()
+       }
+       return nil
+}
+
+// NewHMAC returns a new HMAC using BoringCrypto.
+// The function h must return a hash implemented by
+// BoringCrypto (for example, h could be boring.NewSHA256).
+// If h is not recognized, NewHMAC returns nil.
+func NewHMAC(h func() hash.Hash, key []byte) hash.Hash {
+       ch := h()
+       md := hashToMD(ch)
+       if md == nil {
+               return nil
+       }
+
+       // Note: Could hash down long keys here using EVP_Digest.
+       hkey := make([]byte, len(key))
+       copy(hkey, key)
+       hmac := &boringHMAC{
+               md:        md,
+               size:      ch.Size(),
+               blockSize: ch.BlockSize(),
+               key:       hkey,
+       }
+       hmac.Reset()
+       return hmac
+}
+
+type boringHMAC struct {
+       md          *C.GO_EVP_MD
+       ctx         C.GO_HMAC_CTX
+       ctx2        C.GO_HMAC_CTX
+       size        int
+       blockSize   int
+       key         []byte
+       sum         []byte
+       needCleanup bool
+}
+
+func (h *boringHMAC) Reset() {
+       if h.needCleanup {
+               C._goboringcrypto_HMAC_CTX_cleanup(&h.ctx)
+       } else {
+               h.needCleanup = true
+               // Note: Because of the finalizer, any time h.ctx is passed to cgo,
+               // that call must be followed by a call to runtime.KeepAlive(h),
+               // to make sure h is not collected (and finalized) before the cgo
+               // call returns.
+               runtime.SetFinalizer(h, (*boringHMAC).finalize)
+       }
+       C._goboringcrypto_HMAC_CTX_init(&h.ctx)
+
+       if C._goboringcrypto_HMAC_Init(&h.ctx, unsafe.Pointer(base(h.key)), C.int(len(h.key)), h.md) == 0 {
+               panic("boringcrypto: HMAC_Init failed")
+       }
+       if int(C._goboringcrypto_HMAC_size(&h.ctx)) != h.size {
+               println("boringcrypto: HMAC size:", C._goboringcrypto_HMAC_size(&h.ctx), "!=", h.size)
+               panic("boringcrypto: HMAC size mismatch")
+       }
+       runtime.KeepAlive(h) // Next line will keep h alive too; just making doubly sure.
+       h.sum = nil
+}
+
+func (h *boringHMAC) finalize() {
+       C._goboringcrypto_HMAC_CTX_cleanup(&h.ctx)
+}
+
+func (h *boringHMAC) Write(p []byte) (int, error) {
+       if len(p) > 0 {
+               C._goboringcrypto_HMAC_Update(&h.ctx, (*C.uint8_t)(unsafe.Pointer(&p[0])), C.size_t(len(p)))
+       }
+       runtime.KeepAlive(h)
+       return len(p), nil
+}
+
+func (h *boringHMAC) Size() int {
+       return h.size
+}
+
+func (h *boringHMAC) BlockSize() int {
+       return h.blockSize
+}
+
+func (h *boringHMAC) Sum(in []byte) []byte {
+       if h.sum == nil {
+               size := h.Size()
+               h.sum = make([]byte, size)
+       }
+       // Make copy of context because Go hash.Hash mandates
+       // that Sum has no effect on the underlying stream.
+       // In particular it is OK to Sum, then Write more, then Sum again,
+       // and the second Sum acts as if the first didn't happen.
+       C._goboringcrypto_HMAC_CTX_init(&h.ctx2)
+       if C._goboringcrypto_HMAC_CTX_copy_ex(&h.ctx2, &h.ctx) == 0 {
+               panic("boringcrypto: HMAC_CTX_copy_ex failed")
+       }
+       C._goboringcrypto_HMAC_Final(&h.ctx2, (*C.uint8_t)(unsafe.Pointer(&h.sum[0])), nil)
+       C._goboringcrypto_HMAC_CTX_cleanup(&h.ctx2)
+       return append(in, h.sum...)
+}
diff --git a/src/crypto/internal/boring/notboring.go b/src/crypto/internal/boring/notboring.go
new file mode 100644 (file)
index 0000000..c21cb3c
--- /dev/null
@@ -0,0 +1,109 @@
+// Copyright 2017 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.
+
+// +build !linux !amd64 !cgo android cmd_go_bootstrap msan
+
+package boring
+
+import (
+       "crypto"
+       "crypto/cipher"
+       "crypto/internal/boring/sig"
+       "hash"
+       "math/big"
+)
+
+const available = false
+
+// Unreachable marks code that should be unreachable
+// when BoringCrypto is in use. It is a no-op without BoringCrypto.
+func Unreachable() {
+       // Code that's unreachable when using BoringCrypto
+       // is exactly the code we want to detect for reporting
+       // standard Go crypto.
+       sig.StandardCrypto()
+}
+
+// UnreachableExceptTests marks code that should be unreachable
+// when BoringCrypto is in use. It is a no-op without BoringCrypto.
+func UnreachableExceptTests() {}
+
+type randReader int
+
+func (randReader) Read(b []byte) (int, error) { panic("boringcrypto: not available") }
+
+const RandReader = randReader(0)
+
+func NewSHA1() hash.Hash   { panic("boringcrypto: not available") }
+func NewSHA224() hash.Hash { panic("boringcrypto: not available") }
+func NewSHA256() hash.Hash { panic("boringcrypto: not available") }
+func NewSHA384() hash.Hash { panic("boringcrypto: not available") }
+func NewSHA512() hash.Hash { panic("boringcrypto: not available") }
+
+func NewHMAC(h func() hash.Hash, key []byte) hash.Hash { panic("boringcrypto: not available") }
+
+func NewAESCipher(key []byte) (cipher.Block, error) { panic("boringcrypto: not available") }
+
+type PublicKeyECDSA struct{ _ int }
+type PrivateKeyECDSA struct{ _ int }
+
+func GenerateKeyECDSA(curve string) (X, Y, D *big.Int, err error) {
+       panic("boringcrypto: not available")
+}
+func NewPrivateKeyECDSA(curve string, X, Y, D *big.Int) (*PrivateKeyECDSA, error) {
+       panic("boringcrypto: not available")
+}
+func NewPublicKeyECDSA(curve string, X, Y *big.Int) (*PublicKeyECDSA, error) {
+       panic("boringcrypto: not available")
+}
+func SignECDSA(priv *PrivateKeyECDSA, hash []byte) (r, s *big.Int, err error) {
+       panic("boringcrypto: not available")
+}
+func SignMarshalECDSA(priv *PrivateKeyECDSA, hash []byte) ([]byte, error) {
+       panic("boringcrypto: not available")
+}
+func VerifyECDSA(pub *PublicKeyECDSA, hash []byte, r, s *big.Int) bool {
+       panic("boringcrypto: not available")
+}
+
+type PublicKeyRSA struct{ _ int }
+type PrivateKeyRSA struct{ _ int }
+
+func DecryptRSAOAEP(h hash.Hash, priv *PrivateKeyRSA, ciphertext, label []byte) ([]byte, error) {
+       panic("boringcrypto: not available")
+}
+func DecryptRSAPKCS1(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) {
+       panic("boringcrypto: not available")
+}
+func DecryptRSANoPadding(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) {
+       panic("boringcrypto: not available")
+}
+func EncryptRSAOAEP(h hash.Hash, pub *PublicKeyRSA, msg, label []byte) ([]byte, error) {
+       panic("boringcrypto: not available")
+}
+func EncryptRSAPKCS1(pub *PublicKeyRSA, msg []byte) ([]byte, error) {
+       panic("boringcrypto: not available")
+}
+func EncryptRSANoPadding(pub *PublicKeyRSA, msg []byte) ([]byte, error) {
+       panic("boringcrypto: not available")
+}
+func GenerateKeyRSA(bits int) (N, E, D, P, Q, Dp, Dq, Qinv *big.Int, err error) {
+       panic("boringcrypto: not available")
+}
+func NewPrivateKeyRSA(N, E, D, P, Q, Dp, Dq, Qinv *big.Int) (*PrivateKeyRSA, error) {
+       panic("boringcrypto: not available")
+}
+func NewPublicKeyRSA(N, E *big.Int) (*PublicKeyRSA, error) { panic("boringcrypto: not available") }
+func SignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte) ([]byte, error) {
+       panic("boringcrypto: not available")
+}
+func SignRSAPSS(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte, saltLen int) ([]byte, error) {
+       panic("boringcrypto: not available")
+}
+func VerifyRSAPKCS1v15(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte) error {
+       panic("boringcrypto: not available")
+}
+func VerifyRSAPSS(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte, saltLen int) error {
+       panic("boringcrypto: not available")
+}
diff --git a/src/crypto/internal/boring/rand.go b/src/crypto/internal/boring/rand.go
new file mode 100644 (file)
index 0000000..c3fc27c
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2017 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.
+
+// +build linux,amd64
+// +build !android
+// +build !cmd_go_bootstrap
+// +build !msan
+
+package boring
+
+// #include "goboringcrypto.h"
+import "C"
+import "unsafe"
+
+type randReader int
+
+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 len(b), nil
+}
+
+const RandReader = randReader(0)
diff --git a/src/crypto/internal/boring/rsa.go b/src/crypto/internal/boring/rsa.go
new file mode 100644 (file)
index 0000000..a10831d
--- /dev/null
@@ -0,0 +1,350 @@
+// Copyright 2017 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.
+
+// +build linux,amd64
+// +build !android
+// +build !cmd_go_bootstrap
+// +build !msan
+
+package boring
+
+// #include "goboringcrypto.h"
+import "C"
+import (
+       "crypto"
+       "crypto/subtle"
+       "errors"
+       "hash"
+       "math/big"
+       "runtime"
+       "strconv"
+       "unsafe"
+)
+
+func GenerateKeyRSA(bits int) (N, E, D, P, Q, Dp, Dq, Qinv *big.Int, err error) {
+       bad := func(e error) (N, E, D, P, Q, Dp, Dq, Qinv *big.Int, err error) {
+               return nil, nil, nil, nil, nil, nil, nil, nil, e
+       }
+
+       key := C._goboringcrypto_RSA_new()
+       if key == nil {
+               return bad(fail("RSA_new"))
+       }
+       defer C._goboringcrypto_RSA_free(key)
+
+       if C._goboringcrypto_RSA_generate_key_fips(key, C.int(bits), nil) == 0 {
+               return bad(fail("RSA_generate_key_fips"))
+       }
+
+       var n, e, d, p, q, dp, dq, qinv *C.GO_BIGNUM
+       C._goboringcrypto_RSA_get0_key(key, &n, &e, &d)
+       C._goboringcrypto_RSA_get0_factors(key, &p, &q)
+       C._goboringcrypto_RSA_get0_crt_params(key, &dp, &dq, &qinv)
+       return bnToBig(n), bnToBig(e), bnToBig(d), bnToBig(p), bnToBig(q), bnToBig(dp), bnToBig(dq), bnToBig(qinv), nil
+}
+
+type PublicKeyRSA struct {
+       // _key MUST NOT be accessed directly. Instead, use the withKey method.
+       _key *C.GO_RSA
+}
+
+func NewPublicKeyRSA(N, E *big.Int) (*PublicKeyRSA, error) {
+       key := C._goboringcrypto_RSA_new()
+       if key == nil {
+               return nil, fail("RSA_new")
+       }
+       if !bigToBn(&key.n, N) ||
+               !bigToBn(&key.e, E) {
+               return nil, fail("BN_bin2bn")
+       }
+       k := &PublicKeyRSA{_key: key}
+       runtime.SetFinalizer(k, (*PublicKeyRSA).finalize)
+       return k, nil
+}
+
+func (k *PublicKeyRSA) finalize() {
+       C._goboringcrypto_RSA_free(k._key)
+}
+
+func (k *PublicKeyRSA) withKey(f func(*C.GO_RSA) C.int) C.int {
+       // Because of the finalizer, any time _key is passed to cgo, that call must
+       // be followed by a call to runtime.KeepAlive, to make sure k is not
+       // collected (and finalized) before the cgo call returns.
+       defer runtime.KeepAlive(k)
+       return f(k._key)
+}
+
+type PrivateKeyRSA struct {
+       // _key MUST NOT be accessed directly. Instead, use the withKey method.
+       _key *C.GO_RSA
+}
+
+func NewPrivateKeyRSA(N, E, D, P, Q, Dp, Dq, Qinv *big.Int) (*PrivateKeyRSA, error) {
+       key := C._goboringcrypto_RSA_new()
+       if key == nil {
+               return nil, fail("RSA_new")
+       }
+       if !bigToBn(&key.n, N) ||
+               !bigToBn(&key.e, E) ||
+               !bigToBn(&key.d, D) ||
+               !bigToBn(&key.p, P) ||
+               !bigToBn(&key.q, Q) ||
+               !bigToBn(&key.dmp1, Dp) ||
+               !bigToBn(&key.dmq1, Dq) ||
+               !bigToBn(&key.iqmp, Qinv) {
+               return nil, fail("BN_bin2bn")
+       }
+       k := &PrivateKeyRSA{_key: key}
+       runtime.SetFinalizer(k, (*PrivateKeyRSA).finalize)
+       return k, nil
+}
+
+func (k *PrivateKeyRSA) finalize() {
+       C._goboringcrypto_RSA_free(k._key)
+}
+
+func (k *PrivateKeyRSA) withKey(f func(*C.GO_RSA) C.int) C.int {
+       // Because of the finalizer, any time _key is passed to cgo, that call must
+       // be followed by a call to runtime.KeepAlive, to make sure k is not
+       // collected (and finalized) before the cgo call returns.
+       defer runtime.KeepAlive(k)
+       return f(k._key)
+}
+
+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) {
+       defer func() {
+               if err != nil {
+                       if pkey != nil {
+                               C._goboringcrypto_EVP_PKEY_free(pkey)
+                               pkey = nil
+                       }
+                       if ctx != nil {
+                               C._goboringcrypto_EVP_PKEY_CTX_free(ctx)
+                               ctx = nil
+                       }
+               }
+       }()
+
+       pkey = C._goboringcrypto_EVP_PKEY_new()
+       if pkey == nil {
+               return nil, nil, fail("EVP_PKEY_new")
+       }
+       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")
+       }
+       ctx = C._goboringcrypto_EVP_PKEY_CTX_new(pkey, nil)
+       if ctx == nil {
+               return nil, nil, fail("EVP_PKEY_CTX_new")
+       }
+       if init(ctx) == 0 {
+               return nil, nil, fail("EVP_PKEY_operation_init")
+       }
+       if C._goboringcrypto_EVP_PKEY_CTX_set_rsa_padding(ctx, padding) == 0 {
+               return nil, nil, fail("EVP_PKEY_CTX_set_rsa_padding")
+       }
+       if padding == C.GO_RSA_PKCS1_OAEP_PADDING {
+               md := hashToMD(h)
+               if md == nil {
+                       return nil, nil, errors.New("crypto/rsa: unsupported hash function")
+               }
+               if C._goboringcrypto_EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md) == 0 {
+                       return nil, nil, fail("EVP_PKEY_set_rsa_oaep_md")
+               }
+               // ctx takes ownership of label, so malloc a copy for BoringCrypto to free.
+               clabel := (*C.uint8_t)(C._goboringcrypto_OPENSSL_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)
+               if C._goboringcrypto_EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, clabel, C.size_t(len(label))) == 0 {
+                       return nil, nil, fail("EVP_PKEY_CTX_set0_rsa_oaep_label")
+               }
+       }
+       if padding == C.GO_RSA_PKCS1_PSS_PADDING {
+               if saltLen != 0 {
+                       if C._goboringcrypto_EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, C.int(saltLen)) == 0 {
+                               return nil, nil, fail("EVP_PKEY_set_rsa_pss_saltlen")
+                       }
+               }
+               md := cryptoHashToMD(ch)
+               if md == nil {
+                       return nil, nil, errors.New("crypto/rsa: unsupported hash function")
+               }
+               if C._goboringcrypto_EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, md) == 0 {
+                       return nil, nil, fail("EVP_PKEY_set_rsa_mgf1_md")
+               }
+       }
+
+       return pkey, ctx, nil
+}
+
+func cryptRSA(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,
+       crypt func(*C.GO_EVP_PKEY_CTX, *C.uint8_t, *C.size_t, *C.uint8_t, C.size_t) C.int,
+       in []byte) ([]byte, error) {
+
+       pkey, ctx, err := setupRSA(withKey, padding, h, label, saltLen, ch, init)
+       if err != nil {
+               return nil, err
+       }
+       defer C._goboringcrypto_EVP_PKEY_free(pkey)
+       defer C._goboringcrypto_EVP_PKEY_CTX_free(ctx)
+
+       var outLen C.size_t
+       if crypt(ctx, nil, &outLen, base(in), C.size_t(len(in))) == 0 {
+               return nil, fail("EVP_PKEY_decrypt/encrypt")
+       }
+       out := make([]byte, outLen)
+       if crypt(ctx, base(out), &outLen, base(in), C.size_t(len(in))) == 0 {
+               return nil, fail("EVP_PKEY_decrypt/encrypt")
+       }
+       return out[:outLen], nil
+}
+
+func DecryptRSAOAEP(h hash.Hash, priv *PrivateKeyRSA, ciphertext, label []byte) ([]byte, error) {
+       return cryptRSA(priv.withKey, C.GO_RSA_PKCS1_OAEP_PADDING, h, label, 0, 0, decryptInit, decrypt, ciphertext)
+}
+
+func EncryptRSAOAEP(h hash.Hash, pub *PublicKeyRSA, msg, label []byte) ([]byte, error) {
+       return cryptRSA(pub.withKey, C.GO_RSA_PKCS1_OAEP_PADDING, h, label, 0, 0, encryptInit, encrypt, msg)
+}
+
+func DecryptRSAPKCS1(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) {
+       return cryptRSA(priv.withKey, C.GO_RSA_PKCS1_PADDING, nil, nil, 0, 0, decryptInit, decrypt, ciphertext)
+}
+
+func EncryptRSAPKCS1(pub *PublicKeyRSA, msg []byte) ([]byte, error) {
+       return cryptRSA(pub.withKey, C.GO_RSA_PKCS1_PADDING, nil, nil, 0, 0, encryptInit, encrypt, msg)
+}
+
+func DecryptRSANoPadding(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) {
+       return cryptRSA(priv.withKey, C.GO_RSA_NO_PADDING, nil, nil, 0, 0, decryptInit, decrypt, ciphertext)
+}
+
+func EncryptRSANoPadding(pub *PublicKeyRSA, msg []byte) ([]byte, error) {
+       return cryptRSA(pub.withKey, C.GO_RSA_NO_PADDING, nil, nil, 0, 0, encryptInit, encrypt, msg)
+}
+
+// These dumb wrappers work around the fact that cgo functions cannot be used as values directly.
+
+func decryptInit(ctx *C.GO_EVP_PKEY_CTX) C.int {
+       return C._goboringcrypto_EVP_PKEY_decrypt_init(ctx)
+}
+
+func decrypt(ctx *C.GO_EVP_PKEY_CTX, out *C.uint8_t, outLen *C.size_t, in *C.uint8_t, inLen C.size_t) C.int {
+       return C._goboringcrypto_EVP_PKEY_decrypt(ctx, out, outLen, in, inLen)
+}
+
+func encryptInit(ctx *C.GO_EVP_PKEY_CTX) C.int {
+       return C._goboringcrypto_EVP_PKEY_encrypt_init(ctx)
+}
+
+func encrypt(ctx *C.GO_EVP_PKEY_CTX, out *C.uint8_t, outLen *C.size_t, in *C.uint8_t, inLen C.size_t) C.int {
+       return C._goboringcrypto_EVP_PKEY_encrypt(ctx, out, outLen, in, inLen)
+}
+
+func SignRSAPSS(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte, saltLen int) ([]byte, error) {
+       md := cryptoHashToMD(h)
+       if md == nil {
+               return nil, errors.New("crypto/rsa: unsupported hash function")
+       }
+       if saltLen == 0 {
+               saltLen = -1
+       }
+       var out []byte
+       var outLen C.size_t
+       if 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.size_t(len(out)),
+                       base(hashed), C.size_t(len(hashed)), md, nil, C.int(saltLen))
+       }) == 0 {
+               return nil, fail("RSA_sign_pss_mgf1")
+       }
+
+       return out[:outLen], nil
+}
+
+func VerifyRSAPSS(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte, saltLen int) error {
+       md := cryptoHashToMD(h)
+       if md == nil {
+               return errors.New("crypto/rsa: unsupported hash function")
+       }
+       if saltLen == 0 {
+               saltLen = -2 // auto-recover
+       }
+       if pub.withKey(func(key *C.GO_RSA) C.int {
+               return C._goboringcrypto_RSA_verify_pss_mgf1(key, base(hashed), C.size_t(len(hashed)),
+                       md, nil, C.int(saltLen), base(sig), C.size_t(len(sig)))
+       }) == 0 {
+               return fail("RSA_verify_pss_mgf1")
+       }
+       return nil
+}
+
+func SignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte) ([]byte, error) {
+       if h == 0 {
+               // No hashing.
+               var out []byte
+               var outLen C.size_t
+               if priv.withKey(func(key *C.GO_RSA) C.int {
+                       out = make([]byte, C._goboringcrypto_RSA_size(key))
+                       return C._goboringcrypto_RSA_sign_raw(key, &outLen, base(out), C.size_t(len(out)),
+                               base(hashed), C.size_t(len(hashed)), C.GO_RSA_PKCS1_PADDING)
+               }) == 0 {
+                       return nil, fail("RSA_sign_raw")
+               }
+               return out[:outLen], nil
+       }
+
+       md := cryptoHashToMD(h)
+       if md == nil {
+               return nil, errors.New("crypto/rsa: unsupported hash function: " + strconv.Itoa(int(h)))
+       }
+       nid := C._goboringcrypto_EVP_MD_type(md)
+       var out []byte
+       var outLen C.uint
+       if priv.withKey(func(key *C.GO_RSA) C.int {
+               out = make([]byte, C._goboringcrypto_RSA_size(key))
+               return C._goboringcrypto_RSA_sign(nid, base(hashed), C.uint(len(hashed)),
+                       base(out), &outLen, key)
+       }) == 0 {
+               return nil, fail("RSA_sign")
+       }
+       return out[:outLen], nil
+}
+
+func VerifyRSAPKCS1v15(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte) error {
+       if h == 0 {
+               var out []byte
+               var outLen C.size_t
+               if pub.withKey(func(key *C.GO_RSA) C.int {
+                       out = make([]byte, C._goboringcrypto_RSA_size(key))
+                       return C._goboringcrypto_RSA_verify_raw(key, &outLen, base(out),
+                               C.size_t(len(out)), base(sig), C.size_t(len(sig)), C.GO_RSA_PKCS1_PADDING)
+               }) == 0 {
+                       return fail("RSA_verify")
+               }
+               if subtle.ConstantTimeCompare(hashed, out[:outLen]) != 1 {
+                       return fail("RSA_verify")
+               }
+               return nil
+       }
+       md := cryptoHashToMD(h)
+       if md == nil {
+               return errors.New("crypto/rsa: unsupported hash function")
+       }
+       nid := C._goboringcrypto_EVP_MD_type(md)
+       if pub.withKey(func(key *C.GO_RSA) C.int {
+               return C._goboringcrypto_RSA_verify(nid, base(hashed), C.size_t(len(hashed)),
+                       base(sig), C.size_t(len(sig)), key)
+       }) == 0 {
+               return fail("RSA_verify")
+       }
+       return nil
+}
diff --git a/src/crypto/internal/boring/sha.go b/src/crypto/internal/boring/sha.go
new file mode 100644 (file)
index 0000000..5ca158c
--- /dev/null
@@ -0,0 +1,480 @@
+// Copyright 2017 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.
+
+// +build linux,amd64
+// +build !android
+// +build !cmd_go_bootstrap
+// +build !msan
+
+package boring
+
+// #include "goboringcrypto.h"
+import "C"
+import (
+       "errors"
+       "hash"
+       "unsafe"
+)
+
+// NewSHA1 returns a new SHA1 hash.
+func NewSHA1() hash.Hash {
+       h := new(sha1Hash)
+       h.Reset()
+       return h
+}
+
+type sha1Hash struct {
+       ctx C.GO_SHA_CTX
+       out [20]byte
+}
+
+type sha1Ctx struct {
+       h      [5]uint32
+       nl, nh uint32
+       x      [64]byte
+       nx     uint32
+}
+
+func (h *sha1Hash) Reset()               { C._goboringcrypto_SHA1_Init(&h.ctx) }
+func (h *sha1Hash) Size() int            { return 20 }
+func (h *sha1Hash) BlockSize() int       { return 64 }
+func (h *sha1Hash) Sum(in []byte) []byte { return append(in, h.sum()...) }
+
+func (h *sha1Hash) Write(p []byte) (int, error) {
+       if len(p) > 0 && C._goboringcrypto_SHA1_Update(&h.ctx, unsafe.Pointer(&p[0]), C.size_t(len(p))) == 0 {
+               panic("boringcrypto: SHA1_Update failed")
+       }
+       return len(p), nil
+}
+
+func (h0 *sha1Hash) sum() []byte {
+       h := *h0 // make copy so future Write+Sum is valid
+       if C._goboringcrypto_SHA1_Final((*C.uint8_t)(unsafe.Pointer(&h.out[0])), &h.ctx) == 0 {
+               panic("boringcrypto: SHA1_Final failed")
+       }
+       return h.out[:]
+}
+
+const (
+       sha1Magic         = "sha\x01"
+       sha1MarshaledSize = len(sha1Magic) + 5*4 + 64 + 8
+)
+
+func (h *sha1Hash) MarshalBinary() ([]byte, error) {
+       d := (*sha1Ctx)(unsafe.Pointer(&h.ctx))
+       b := make([]byte, 0, sha1MarshaledSize)
+       b = append(b, sha1Magic...)
+       b = appendUint32(b, d.h[0])
+       b = appendUint32(b, d.h[1])
+       b = appendUint32(b, d.h[2])
+       b = appendUint32(b, d.h[3])
+       b = appendUint32(b, d.h[4])
+       b = append(b, d.x[:d.nx]...)
+       b = b[:len(b)+len(d.x)-int(d.nx)] // already zero
+       b = appendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29)
+       return b, nil
+}
+
+func (h *sha1Hash) UnmarshalBinary(b []byte) error {
+       if len(b) < len(sha1Magic) || string(b[:len(sha1Magic)]) != sha1Magic {
+               return errors.New("crypto/sha1: invalid hash state identifier")
+       }
+       if len(b) != sha1MarshaledSize {
+               return errors.New("crypto/sha1: invalid hash state size")
+       }
+       d := (*sha1Ctx)(unsafe.Pointer(&h.ctx))
+       b = b[len(sha1Magic):]
+       b, d.h[0] = consumeUint32(b)
+       b, d.h[1] = consumeUint32(b)
+       b, d.h[2] = consumeUint32(b)
+       b, d.h[3] = consumeUint32(b)
+       b, d.h[4] = consumeUint32(b)
+       b = b[copy(d.x[:], b):]
+       b, n := consumeUint64(b)
+       d.nl = uint32(n << 3)
+       d.nh = uint32(n >> 29)
+       d.nx = uint32(n) % 64
+       return nil
+}
+
+// NewSHA224 returns a new SHA224 hash.
+func NewSHA224() hash.Hash {
+       h := new(sha224Hash)
+       h.Reset()
+       return h
+}
+
+type sha224Hash struct {
+       ctx C.GO_SHA256_CTX
+       out [224 / 8]byte
+}
+
+func (h *sha224Hash) Reset()               { C._goboringcrypto_SHA224_Init(&h.ctx) }
+func (h *sha224Hash) Size() int            { return 224 / 8 }
+func (h *sha224Hash) BlockSize() int       { return 64 }
+func (h *sha224Hash) Sum(in []byte) []byte { return append(in, h.sum()...) }
+
+func (h *sha224Hash) Write(p []byte) (int, error) {
+       if len(p) > 0 && C._goboringcrypto_SHA224_Update(&h.ctx, unsafe.Pointer(&p[0]), C.size_t(len(p))) == 0 {
+               panic("boringcrypto: SHA224_Update failed")
+       }
+       return len(p), nil
+}
+
+func (h0 *sha224Hash) sum() []byte {
+       h := *h0 // make copy so future Write+Sum is valid
+       if C._goboringcrypto_SHA224_Final((*C.uint8_t)(unsafe.Pointer(&h.out[0])), &h.ctx) == 0 {
+               panic("boringcrypto: SHA224_Final failed")
+       }
+       return h.out[:]
+}
+
+// NewSHA256 returns a new SHA256 hash.
+func NewSHA256() hash.Hash {
+       h := new(sha256Hash)
+       h.Reset()
+       return h
+}
+
+type sha256Hash struct {
+       ctx C.GO_SHA256_CTX
+       out [256 / 8]byte
+}
+
+func (h *sha256Hash) Reset()               { C._goboringcrypto_SHA256_Init(&h.ctx) }
+func (h *sha256Hash) Size() int            { return 256 / 8 }
+func (h *sha256Hash) BlockSize() int       { return 64 }
+func (h *sha256Hash) Sum(in []byte) []byte { return append(in, h.sum()...) }
+
+func (h *sha256Hash) Write(p []byte) (int, error) {
+       if len(p) > 0 && C._goboringcrypto_SHA256_Update(&h.ctx, unsafe.Pointer(&p[0]), C.size_t(len(p))) == 0 {
+               panic("boringcrypto: SHA256_Update failed")
+       }
+       return len(p), nil
+}
+
+func (h0 *sha256Hash) sum() []byte {
+       h := *h0 // make copy so future Write+Sum is valid
+       if C._goboringcrypto_SHA256_Final((*C.uint8_t)(unsafe.Pointer(&h.out[0])), &h.ctx) == 0 {
+               panic("boringcrypto: SHA256_Final failed")
+       }
+       return h.out[:]
+}
+
+const (
+       magic224         = "sha\x02"
+       magic256         = "sha\x03"
+       marshaledSize256 = len(magic256) + 8*4 + 64 + 8
+)
+
+type sha256Ctx struct {
+       h      [8]uint32
+       nl, nh uint32
+       x      [64]byte
+       nx     uint32
+}
+
+func (h *sha224Hash) MarshalBinary() ([]byte, error) {
+       d := (*sha256Ctx)(unsafe.Pointer(&h.ctx))
+       b := make([]byte, 0, marshaledSize256)
+       b = append(b, magic224...)
+       b = appendUint32(b, d.h[0])
+       b = appendUint32(b, d.h[1])
+       b = appendUint32(b, d.h[2])
+       b = appendUint32(b, d.h[3])
+       b = appendUint32(b, d.h[4])
+       b = appendUint32(b, d.h[5])
+       b = appendUint32(b, d.h[6])
+       b = appendUint32(b, d.h[7])
+       b = append(b, d.x[:d.nx]...)
+       b = b[:len(b)+len(d.x)-int(d.nx)] // already zero
+       b = appendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29)
+       return b, nil
+}
+
+func (h *sha256Hash) MarshalBinary() ([]byte, error) {
+       d := (*sha256Ctx)(unsafe.Pointer(&h.ctx))
+       b := make([]byte, 0, marshaledSize256)
+       b = append(b, magic256...)
+       b = appendUint32(b, d.h[0])
+       b = appendUint32(b, d.h[1])
+       b = appendUint32(b, d.h[2])
+       b = appendUint32(b, d.h[3])
+       b = appendUint32(b, d.h[4])
+       b = appendUint32(b, d.h[5])
+       b = appendUint32(b, d.h[6])
+       b = appendUint32(b, d.h[7])
+       b = append(b, d.x[:d.nx]...)
+       b = b[:len(b)+len(d.x)-int(d.nx)] // already zero
+       b = appendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29)
+       return b, nil
+}
+
+func (h *sha224Hash) UnmarshalBinary(b []byte) error {
+       if len(b) < len(magic224) || string(b[:len(magic224)]) != magic224 {
+               return errors.New("crypto/sha256: invalid hash state identifier")
+       }
+       if len(b) != marshaledSize256 {
+               return errors.New("crypto/sha256: invalid hash state size")
+       }
+       d := (*sha256Ctx)(unsafe.Pointer(&h.ctx))
+       b = b[len(magic224):]
+       b, d.h[0] = consumeUint32(b)
+       b, d.h[1] = consumeUint32(b)
+       b, d.h[2] = consumeUint32(b)
+       b, d.h[3] = consumeUint32(b)
+       b, d.h[4] = consumeUint32(b)
+       b, d.h[5] = consumeUint32(b)
+       b, d.h[6] = consumeUint32(b)
+       b, d.h[7] = consumeUint32(b)
+       b = b[copy(d.x[:], b):]
+       b, n := consumeUint64(b)
+       d.nl = uint32(n << 3)
+       d.nh = uint32(n >> 29)
+       d.nx = uint32(n) % 64
+       return nil
+}
+
+func (h *sha256Hash) UnmarshalBinary(b []byte) error {
+       if len(b) < len(magic256) || string(b[:len(magic256)]) != magic256 {
+               return errors.New("crypto/sha256: invalid hash state identifier")
+       }
+       if len(b) != marshaledSize256 {
+               return errors.New("crypto/sha256: invalid hash state size")
+       }
+       d := (*sha256Ctx)(unsafe.Pointer(&h.ctx))
+       b = b[len(magic256):]
+       b, d.h[0] = consumeUint32(b)
+       b, d.h[1] = consumeUint32(b)
+       b, d.h[2] = consumeUint32(b)
+       b, d.h[3] = consumeUint32(b)
+       b, d.h[4] = consumeUint32(b)
+       b, d.h[5] = consumeUint32(b)
+       b, d.h[6] = consumeUint32(b)
+       b, d.h[7] = consumeUint32(b)
+       b = b[copy(d.x[:], b):]
+       b, n := consumeUint64(b)
+       d.nl = uint32(n << 3)
+       d.nh = uint32(n >> 29)
+       d.nx = uint32(n) % 64
+       return nil
+}
+
+// NewSHA384 returns a new SHA384 hash.
+func NewSHA384() hash.Hash {
+       h := new(sha384Hash)
+       h.Reset()
+       return h
+}
+
+type sha384Hash struct {
+       ctx C.GO_SHA512_CTX
+       out [384 / 8]byte
+}
+
+func (h *sha384Hash) Reset()               { C._goboringcrypto_SHA384_Init(&h.ctx) }
+func (h *sha384Hash) Size() int            { return 384 / 8 }
+func (h *sha384Hash) BlockSize() int       { return 128 }
+func (h *sha384Hash) Sum(in []byte) []byte { return append(in, h.sum()...) }
+
+func (h *sha384Hash) Write(p []byte) (int, error) {
+       if len(p) > 0 && C._goboringcrypto_SHA384_Update(&h.ctx, unsafe.Pointer(&p[0]), C.size_t(len(p))) == 0 {
+               panic("boringcrypto: SHA384_Update failed")
+       }
+       return len(p), nil
+}
+
+func (h0 *sha384Hash) sum() []byte {
+       h := *h0 // make copy so future Write+Sum is valid
+       if C._goboringcrypto_SHA384_Final((*C.uint8_t)(unsafe.Pointer(&h.out[0])), &h.ctx) == 0 {
+               panic("boringcrypto: SHA384_Final failed")
+       }
+       return h.out[:]
+}
+
+// NewSHA512 returns a new SHA512 hash.
+func NewSHA512() hash.Hash {
+       h := new(sha512Hash)
+       h.Reset()
+       return h
+}
+
+type sha512Hash struct {
+       ctx C.GO_SHA512_CTX
+       out [512 / 8]byte
+}
+
+func (h *sha512Hash) Reset()               { C._goboringcrypto_SHA512_Init(&h.ctx) }
+func (h *sha512Hash) Size() int            { return 512 / 8 }
+func (h *sha512Hash) BlockSize() int       { return 128 }
+func (h *sha512Hash) Sum(in []byte) []byte { return append(in, h.sum()...) }
+
+func (h *sha512Hash) Write(p []byte) (int, error) {
+       if len(p) > 0 && C._goboringcrypto_SHA512_Update(&h.ctx, unsafe.Pointer(&p[0]), C.size_t(len(p))) == 0 {
+               panic("boringcrypto: SHA512_Update failed")
+       }
+       return len(p), nil
+}
+
+func (h0 *sha512Hash) sum() []byte {
+       h := *h0 // make copy so future Write+Sum is valid
+       if C._goboringcrypto_SHA512_Final((*C.uint8_t)(unsafe.Pointer(&h.out[0])), &h.ctx) == 0 {
+               panic("boringcrypto: SHA512_Final failed")
+       }
+       return h.out[:]
+}
+
+type sha512Ctx struct {
+       h      [8]uint64
+       nl, nh uint64
+       x      [128]byte
+       nx     uint32
+}
+
+const (
+       magic384         = "sha\x04"
+       magic512_224     = "sha\x05"
+       magic512_256     = "sha\x06"
+       magic512         = "sha\x07"
+       marshaledSize512 = len(magic512) + 8*8 + 128 + 8
+)
+
+var zero [128]byte
+
+func (h *sha384Hash) MarshalBinary() ([]byte, error) {
+       d := (*sha512Ctx)(unsafe.Pointer(&h.ctx))
+       b := make([]byte, 0, marshaledSize512)
+       b = append(b, magic384...)
+       b = appendUint64(b, d.h[0])
+       b = appendUint64(b, d.h[1])
+       b = appendUint64(b, d.h[2])
+       b = appendUint64(b, d.h[3])
+       b = appendUint64(b, d.h[4])
+       b = appendUint64(b, d.h[5])
+       b = appendUint64(b, d.h[6])
+       b = appendUint64(b, d.h[7])
+       b = append(b, d.x[:d.nx]...)
+       b = b[:len(b)+len(d.x)-int(d.nx)] // already zero
+       b = appendUint64(b, d.nl>>3|d.nh<<61)
+       return b, nil
+}
+
+func (h *sha512Hash) MarshalBinary() ([]byte, error) {
+       d := (*sha512Ctx)(unsafe.Pointer(&h.ctx))
+       b := make([]byte, 0, marshaledSize512)
+       b = append(b, magic512...)
+       b = appendUint64(b, d.h[0])
+       b = appendUint64(b, d.h[1])
+       b = appendUint64(b, d.h[2])
+       b = appendUint64(b, d.h[3])
+       b = appendUint64(b, d.h[4])
+       b = appendUint64(b, d.h[5])
+       b = appendUint64(b, d.h[6])
+       b = appendUint64(b, d.h[7])
+       b = append(b, d.x[:d.nx]...)
+       b = b[:len(b)+len(d.x)-int(d.nx)] // already zero
+       b = appendUint64(b, d.nl>>3|d.nh<<61)
+       return b, nil
+}
+
+func (h *sha384Hash) UnmarshalBinary(b []byte) error {
+       if len(b) < len(magic512) {
+               return errors.New("crypto/sha512: invalid hash state identifier")
+       }
+       if string(b[:len(magic384)]) != magic384 {
+               return errors.New("crypto/sha512: invalid hash state identifier")
+       }
+       if len(b) != marshaledSize512 {
+               return errors.New("crypto/sha512: invalid hash state size")
+       }
+       d := (*sha512Ctx)(unsafe.Pointer(&h.ctx))
+       b = b[len(magic512):]
+       b, d.h[0] = consumeUint64(b)
+       b, d.h[1] = consumeUint64(b)
+       b, d.h[2] = consumeUint64(b)
+       b, d.h[3] = consumeUint64(b)
+       b, d.h[4] = consumeUint64(b)
+       b, d.h[5] = consumeUint64(b)
+       b, d.h[6] = consumeUint64(b)
+       b, d.h[7] = consumeUint64(b)
+       b = b[copy(d.x[:], b):]
+       b, n := consumeUint64(b)
+       d.nl = n << 3
+       d.nh = n >> 61
+       d.nx = uint32(n) % 128
+       return nil
+}
+
+func (h *sha512Hash) UnmarshalBinary(b []byte) error {
+       if len(b) < len(magic512) {
+               return errors.New("crypto/sha512: invalid hash state identifier")
+       }
+       if string(b[:len(magic512)]) != magic512 {
+               return errors.New("crypto/sha512: invalid hash state identifier")
+       }
+       if len(b) != marshaledSize512 {
+               return errors.New("crypto/sha512: invalid hash state size")
+       }
+       d := (*sha512Ctx)(unsafe.Pointer(&h.ctx))
+       b = b[len(magic512):]
+       b, d.h[0] = consumeUint64(b)
+       b, d.h[1] = consumeUint64(b)
+       b, d.h[2] = consumeUint64(b)
+       b, d.h[3] = consumeUint64(b)
+       b, d.h[4] = consumeUint64(b)
+       b, d.h[5] = consumeUint64(b)
+       b, d.h[6] = consumeUint64(b)
+       b, d.h[7] = consumeUint64(b)
+       b = b[copy(d.x[:], b):]
+       b, n := consumeUint64(b)
+       d.nl = n << 3
+       d.nh = n >> 61
+       d.nx = uint32(n) % 128
+       return nil
+}
+
+func appendUint64(b []byte, x uint64) []byte {
+       var a [8]byte
+       putUint64(a[:], x)
+       return append(b, a[:]...)
+}
+
+func appendUint32(b []byte, x uint32) []byte {
+       var a [4]byte
+       putUint32(a[:], x)
+       return append(b, a[:]...)
+}
+
+func consumeUint64(b []byte) ([]byte, uint64) {
+       _ = b[7]
+       x := uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
+               uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
+       return b[8:], x
+}
+
+func consumeUint32(b []byte) ([]byte, uint32) {
+       _ = b[3]
+       x := uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
+       return b[4:], x
+}
+
+func putUint64(x []byte, s uint64) {
+       _ = x[7]
+       x[0] = byte(s >> 56)
+       x[1] = byte(s >> 48)
+       x[2] = byte(s >> 40)
+       x[3] = byte(s >> 32)
+       x[4] = byte(s >> 24)
+       x[5] = byte(s >> 16)
+       x[6] = byte(s >> 8)
+       x[7] = byte(s)
+}
+
+func putUint32(x []byte, s uint32) {
+       _ = x[3]
+       x[0] = byte(s >> 24)
+       x[1] = byte(s >> 16)
+       x[2] = byte(s >> 8)
+       x[3] = byte(s)
+}
diff --git a/src/crypto/internal/boring/sig/sig.go b/src/crypto/internal/boring/sig/sig.go
new file mode 100644 (file)
index 0000000..716c03c
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2017 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 sig holds “code signatures” that can be called
+// and will result in certain code sequences being linked into
+// the final binary. The functions themselves are no-ops.
+package sig
+
+// BoringCrypto indicates that the BoringCrypto module is present.
+func BoringCrypto()
+
+// FIPSOnly indicates that package crypto/tls/fipsonly is present.
+func FIPSOnly()
+
+// StandardCrypto indicates that standard Go crypto is present.
+func StandardCrypto()
diff --git a/src/crypto/internal/boring/sig/sig_amd64.s b/src/crypto/internal/boring/sig/sig_amd64.s
new file mode 100644 (file)
index 0000000..64e3462
--- /dev/null
@@ -0,0 +1,54 @@
+// Copyright 2017 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.
+
+#include "textflag.h"
+
+// These functions are no-ops, but you can search for their implementations
+// to find out whether they are linked into a particular binary.
+//
+// Each function consists of a two-byte jump over the next 29-bytes,
+// then a 5-byte indicator sequence unlikely to occur in real x86 instructions,
+// then a randomly-chosen 24-byte sequence, and finally a return instruction
+// (the target of the jump).
+//
+// These sequences are known to rsc.io/goversion.
+
+#define START \
+       BYTE $0xEB; BYTE $0x1D; BYTE $0xF4; BYTE $0x48; BYTE $0xF4; BYTE $0x4B; BYTE $0xF4
+
+#define END \
+       BYTE $0xC3
+
+// BoringCrypto indicates that BoringCrypto (in particular, its func init) is present.
+TEXT ·BoringCrypto(SB),NOSPLIT,$0
+       START
+       BYTE $0xB3; BYTE $0x32; BYTE $0xF5; BYTE $0x28;
+       BYTE $0x13; BYTE $0xA3; BYTE $0xB4; BYTE $0x50;
+       BYTE $0xD4; BYTE $0x41; BYTE $0xCC; BYTE $0x24;
+       BYTE $0x85; BYTE $0xF0; BYTE $0x01; BYTE $0x45;
+       BYTE $0x4E; BYTE $0x92; BYTE $0x10; BYTE $0x1B;
+       BYTE $0x1D; BYTE $0x2F; BYTE $0x19; BYTE $0x50;
+       END
+
+// StandardCrypto indicates that standard Go crypto is present.
+TEXT ·StandardCrypto(SB),NOSPLIT,$0
+       START
+       BYTE $0xba; BYTE $0xee; BYTE $0x4d; BYTE $0xfa;
+       BYTE $0x98; BYTE $0x51; BYTE $0xca; BYTE $0x56;
+       BYTE $0xa9; BYTE $0x11; BYTE $0x45; BYTE $0xe8;
+       BYTE $0x3e; BYTE $0x99; BYTE $0xc5; BYTE $0x9c;
+       BYTE $0xf9; BYTE $0x11; BYTE $0xcb; BYTE $0x8e;
+       BYTE $0x80; BYTE $0xda;  BYTE $0xf1; BYTE $0x2f;
+       END
+
+// FIPSOnly indicates that crypto/tls/fipsonly is present.
+TEXT ·FIPSOnly(SB),NOSPLIT,$0
+       START
+       BYTE $0x36; BYTE $0x3C; BYTE $0xB9; BYTE $0xCE;
+       BYTE $0x9D; BYTE $0x68; BYTE $0x04; BYTE $0x7D;
+       BYTE $0x31; BYTE $0xF2; BYTE $0x8D; BYTE $0x32;
+       BYTE $0x5D; BYTE $0x5C; BYTE $0xA5; BYTE $0x87;
+       BYTE $0x3F; BYTE $0x5D; BYTE $0x80; BYTE $0xCA;
+       BYTE $0xF6; BYTE $0xD6; BYTE $0x15; BYTE $0x1B;
+       END
diff --git a/src/crypto/internal/boring/sig/sig_other.s b/src/crypto/internal/boring/sig/sig_other.s
new file mode 100644 (file)
index 0000000..2eb3173
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2017 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.
+
+// These functions are no-ops.
+// On amd64 they have recognizable implementations, so that you can
+// search a particular binary to see if they are present.
+// On other platforms (those using this source file), they don't.
+
+// +build !amd64
+
+TEXT ·BoringCrypto(SB),$0
+       RET
+
+TEXT ·FIPSOnly(SB),$0
+       RET
+
+TEXT ·StandardCrypto(SB),$0
+       RET
index b4276df4e1100d9b1d5a79622162b27a12fbdf67..466208879991e1a12ecf92d34b53d71885ed1b08 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package crypto
+package crypto_test
 
 import (
        "crypto/aes"
index 548a5e4cb9a4d3d97c85d8459199324bd14443ce..8bc4abf40c69b5e3c9e5b03fd09ad3b9a36c5d18 100644 (file)
@@ -22,12 +22,18 @@ import (
        "time"
 )
 
+import "crypto/internal/boring"
+
 const urandomDevice = "/dev/urandom"
 
 // Easy implementation: read from /dev/urandom.
 // This is sufficient on Linux, OS X, and FreeBSD.
 
 func init() {
+       if boring.Enabled {
+               Reader = boring.RandReader
+               return
+       }
        if runtime.GOOS == "plan9" {
                Reader = newReader(nil)
        } else {
@@ -52,6 +58,7 @@ func warnBlocked() {
 }
 
 func (r *devReader) Read(b []byte) (n int, err error) {
+       boring.Unreachable()
        if atomic.CompareAndSwapInt32(&r.used, 0, 1) {
                // First use of randomness. Start timer to warn about
                // being blocked on entropy not being available.
@@ -121,6 +128,7 @@ type reader struct {
 }
 
 func (r *reader) Read(b []byte) (n int, err error) {
+       boring.Unreachable()
        r.mu.Lock()
        defer r.mu.Unlock()
        n = len(b)
diff --git a/src/crypto/rsa/boring.go b/src/crypto/rsa/boring.go
new file mode 100644 (file)
index 0000000..0f362a2
--- /dev/null
@@ -0,0 +1,124 @@
+// Copyright 2017 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 rsa
+
+import (
+       "crypto/internal/boring"
+       "math/big"
+       "sync/atomic"
+       "unsafe"
+)
+
+// Cached conversions from Go PublicKey/PrivateKey to BoringCrypto.
+//
+// A new 'boring atomic.Value' field in both PublicKey and PrivateKey
+// serves as a cache for the most recent conversion. The cache is an
+// atomic.Value because code might reasonably set up a key and then
+// (thinking it immutable) use it from multiple goroutines simultaneously.
+// The first operation initializes the cache; if there are multiple simultaneous
+// first operations, they will do redundant work but not step on each other.
+//
+// We could just assume that once used in a sign/verify/encrypt/decrypt operation,
+// a particular key is never again modified, but that has not been a
+// stated assumption before. Just in case there is any existing code that
+// does modify the key between operations, we save the original values
+// alongside the cached BoringCrypto key and check that the real key
+// still matches before using the cached key. The theory is that the real
+// operations are significantly more expensive than the comparison.
+
+type boringPub struct {
+       key  *boring.PublicKeyRSA
+       orig PublicKey
+}
+
+func boringPublicKey(pub *PublicKey) (*boring.PublicKeyRSA, error) {
+       b := (*boringPub)(atomic.LoadPointer(&pub.boring))
+       if b != nil && publicKeyEqual(&b.orig, pub) {
+               return b.key, nil
+       }
+
+       b = new(boringPub)
+       b.orig = copyPublicKey(pub)
+       key, err := boring.NewPublicKeyRSA(b.orig.N, big.NewInt(int64(b.orig.E)))
+       if err != nil {
+               return nil, err
+       }
+       b.key = key
+       atomic.StorePointer(&pub.boring, unsafe.Pointer(b))
+       return key, nil
+}
+
+type boringPriv struct {
+       key  *boring.PrivateKeyRSA
+       orig PrivateKey
+}
+
+func boringPrivateKey(priv *PrivateKey) (*boring.PrivateKeyRSA, error) {
+       b := (*boringPriv)(atomic.LoadPointer(&priv.boring))
+       if b != nil && privateKeyEqual(&b.orig, priv) {
+               return b.key, nil
+       }
+
+       b = new(boringPriv)
+       b.orig = copyPrivateKey(priv)
+
+       var N, E, D, P, Q, Dp, Dq, Qinv *big.Int
+       N = b.orig.N
+       E = big.NewInt(int64(b.orig.E))
+       D = b.orig.D
+       if len(b.orig.Primes) == 2 {
+               P = b.orig.Primes[0]
+               Q = b.orig.Primes[1]
+               Dp = b.orig.Precomputed.Dp
+               Dq = b.orig.Precomputed.Dq
+               Qinv = b.orig.Precomputed.Qinv
+       }
+       key, err := boring.NewPrivateKeyRSA(N, E, D, P, Q, Dp, Dq, Qinv)
+       if err != nil {
+               return nil, err
+       }
+       b.key = key
+       atomic.StorePointer(&priv.boring, unsafe.Pointer(b))
+       return key, nil
+}
+
+func publicKeyEqual(k1, k2 *PublicKey) bool {
+       return k1.N != nil &&
+               k1.N.Cmp(k2.N) == 0 &&
+               k1.E == k2.E
+}
+
+func copyPublicKey(k *PublicKey) PublicKey {
+       return PublicKey{
+               N: new(big.Int).Set(k.N),
+               E: k.E,
+       }
+}
+
+func privateKeyEqual(k1, k2 *PrivateKey) bool {
+       return publicKeyEqual(&k1.PublicKey, &k2.PublicKey) &&
+               k1.D.Cmp(k2.D) == 0
+}
+
+func copyPrivateKey(k *PrivateKey) PrivateKey {
+       dst := PrivateKey{
+               PublicKey: copyPublicKey(&k.PublicKey),
+               D:         new(big.Int).Set(k.D),
+       }
+       dst.Primes = make([]*big.Int, len(k.Primes))
+       for i, p := range k.Primes {
+               dst.Primes[i] = new(big.Int).Set(p)
+       }
+       if x := k.Precomputed.Dp; x != nil {
+               dst.Precomputed.Dp = new(big.Int).Set(x)
+       }
+       if x := k.Precomputed.Dq; x != nil {
+               dst.Precomputed.Dq = new(big.Int).Set(x)
+       }
+       if x := k.Precomputed.Qinv; x != nil {
+               dst.Precomputed.Qinv = new(big.Int).Set(x)
+       }
+       return dst
+}
diff --git a/src/crypto/rsa/boring_test.go b/src/crypto/rsa/boring_test.go
new file mode 100644 (file)
index 0000000..11dcdf8
--- /dev/null
@@ -0,0 +1,125 @@
+// Copyright 2017 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.
+
+// Note: Can run these tests against the non-BoringCrypto
+// version of the code by using "CGO_ENABLED=0 go test".
+
+package rsa
+
+import (
+       "crypto"
+       "crypto/rand"
+       "encoding/asn1"
+       "reflect"
+       "runtime"
+       "runtime/debug"
+       "sync"
+       "sync/atomic"
+       "testing"
+       "unsafe"
+)
+
+func TestBoringASN1Marshal(t *testing.T) {
+       k, err := GenerateKey(rand.Reader, 128)
+       if err != nil {
+               t.Fatal(err)
+       }
+       // This used to fail, because of the unexported 'boring' field.
+       // Now the compiler hides it [sic].
+       _, err = asn1.Marshal(k.PublicKey)
+       if err != nil {
+               t.Fatal(err)
+       }
+}
+
+func TestBoringDeepEqual(t *testing.T) {
+       k, err := GenerateKey(rand.Reader, 128)
+       if err != nil {
+               t.Fatal(err)
+       }
+       k.boring = nil // probably nil already but just in case
+       k2 := *k
+       k2.boring = unsafe.Pointer(k) // anything not nil, for this test
+       if !reflect.DeepEqual(k, &k2) {
+               // compiler should be hiding the boring field from reflection
+               t.Fatalf("DeepEqual compared boring fields")
+       }
+}
+
+func TestBoringVerify(t *testing.T) {
+       // Check that signatures that lack leading zeroes don't verify.
+       key := &PublicKey{
+               N: bigFromHex("c4fdf7b40a5477f206e6ee278eaef888ca73bf9128a9eef9f2f1ddb8b7b71a4c07cfa241f028a04edb405e4d916c61d6beabc333813dc7b484d2b3c52ee233c6a79b1eea4e9cc51596ba9cd5ac5aeb9df62d86ea051055b79d03f8a4fa9f38386f5bd17529138f3325d46801514ea9047977e0829ed728e68636802796801be1"),
+               E: 65537,
+       }
+
+       hash := fromHex("019c5571724fb5d0e47a4260c940e9803ba05a44")
+       paddedHash := fromHex("3021300906052b0e03021a05000414019c5571724fb5d0e47a4260c940e9803ba05a44")
+
+       // signature is one byte shorter than key.N.
+       sig := fromHex("5edfbeb6a73e7225ad3cc52724e2872e04260d7daf0d693c170d8c4b243b8767bc7785763533febc62ec2600c30603c433c095453ede59ff2fcabeb84ce32e0ed9d5cf15ffcbc816202b64370d4d77c1e9077d74e94a16fb4fa2e5bec23a56d7a73cf275f91691ae1801a976fcde09e981a2f6327ac27ea1fecf3185df0d56")
+
+       err := VerifyPKCS1v15(key, 0, paddedHash, sig)
+       if err == nil {
+               t.Errorf("raw: expected verification error")
+       }
+
+       err = VerifyPKCS1v15(key, crypto.SHA1, hash, sig)
+       if err == nil {
+               t.Errorf("sha1: expected verification error")
+       }
+}
+
+func TestBoringGenerateKey(t *testing.T) {
+       k, err := GenerateKey(rand.Reader, 2048) // 2048 is smallest size BoringCrypto might kick in for
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       // Non-Boring GenerateKey always sets CRTValues to a non-nil (possibly empty) slice.
+       if k.Precomputed.CRTValues == nil {
+               t.Fatalf("GenerateKey: Precomputed.CRTValues = nil")
+       }
+}
+
+func TestBoringFinalizers(t *testing.T) {
+       if runtime.GOOS == "nacl" || runtime.GOOS == "js" {
+               // Times out on nacl and js/wasm (without BoringCrypto)
+               // but not clear why - probably consuming rand.Reader too quickly
+               // and being throttled. Also doesn't really matter.
+               t.Skipf("skipping on %s/%s", runtime.GOOS, runtime.GOARCH)
+       }
+
+       k, err := GenerateKey(rand.Reader, 2048)
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       // Run test with GOGC=10, to make bug more likely.
+       // Without the KeepAlives, the loop usually dies after
+       // about 30 iterations.
+       defer debug.SetGCPercent(debug.SetGCPercent(10))
+       for n := 0; n < 200; n++ {
+               // Clear the underlying BoringCrypto object.
+               atomic.StorePointer(&k.boring, nil)
+
+               // Race to create the underlying BoringCrypto object.
+               // The ones that lose the race are prime candidates for
+               // being GC'ed too early if the finalizers are not being
+               // used correctly.
+               var wg sync.WaitGroup
+               for i := 0; i < 10; i++ {
+                       wg.Add(1)
+                       go func() {
+                               defer wg.Done()
+                               sum := make([]byte, 32)
+                               _, err := SignPKCS1v15(rand.Reader, k, crypto.SHA256, sum)
+                               if err != nil {
+                                       panic(err) // usually caused by memory corruption, so hard stop
+                               }
+                       }()
+               }
+               wg.Wait()
+       }
+}
index 0cbd6d004561c96fb9e641e0b92d637c49e43c90..213ddb4addbe4ff6860040e0ccb4d15f265183d9 100644 (file)
@@ -14,6 +14,8 @@ import (
        "crypto/internal/randutil"
 )
 
+import "crypto/internal/boring"
+
 // This file implements encryption and decryption using PKCS #1 v1.5 padding.
 
 // PKCS1v15DecrypterOpts is for passing options to PKCS #1 v1.5 decryption using
@@ -36,8 +38,8 @@ type PKCS1v15DecryptOptions struct {
 //
 // WARNING: use of this function to encrypt plaintexts other than
 // session keys is dangerous. Use RSA OAEP in new protocols.
-func EncryptPKCS1v15(rand io.Reader, pub *PublicKey, msg []byte) ([]byte, error) {
-       randutil.MaybeReadByte(rand)
+func EncryptPKCS1v15(random io.Reader, pub *PublicKey, msg []byte) ([]byte, error) {
+       randutil.MaybeReadByte(random)
 
        if err := checkPub(pub); err != nil {
                return nil, err
@@ -47,20 +49,37 @@ func EncryptPKCS1v15(rand io.Reader, pub *PublicKey, msg []byte) ([]byte, error)
                return nil, ErrMessageTooLong
        }
 
+       if boring.Enabled && random == boring.RandReader {
+               bkey, err := boringPublicKey(pub)
+               if err != nil {
+                       return nil, err
+               }
+               return boring.EncryptRSAPKCS1(bkey, msg)
+       }
+       boring.UnreachableExceptTests()
+
        // EM = 0x00 || 0x02 || PS || 0x00 || M
        em := make([]byte, k)
        em[1] = 2
        ps, mm := em[2:len(em)-len(msg)-1], em[len(em)-len(msg):]
-       err := nonZeroRandomBytes(ps, rand)
+       err := nonZeroRandomBytes(ps, random)
        if err != nil {
                return nil, err
        }
        em[len(em)-len(msg)-1] = 0
        copy(mm, msg)
 
+       if boring.Enabled {
+               var bkey *boring.PublicKeyRSA
+               bkey, err = boringPublicKey(pub)
+               if err != nil {
+                       return nil, err
+               }
+               return boring.EncryptRSANoPadding(bkey, em)
+       }
+
        m := new(big.Int).SetBytes(em)
        c := encrypt(new(big.Int), pub, m)
-
        return c.FillBytes(em), nil
 }
 
@@ -76,6 +95,19 @@ func DecryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) ([]byt
        if err := checkPub(&priv.PublicKey); err != nil {
                return nil, err
        }
+
+       if boring.Enabled {
+               bkey, err := boringPrivateKey(priv)
+               if err != nil {
+                       return nil, err
+               }
+               out, err := boring.DecryptRSAPKCS1(bkey, ciphertext)
+               if err != nil {
+                       return nil, ErrDecryption
+               }
+               return out, nil
+       }
+
        valid, out, index, err := decryptPKCS1v15(rand, priv, ciphertext)
        if err != nil {
                return nil, err
@@ -143,13 +175,26 @@ func decryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (valid
                return
        }
 
-       c := new(big.Int).SetBytes(ciphertext)
-       m, err := decrypt(rand, priv, c)
-       if err != nil {
-               return
+       if boring.Enabled {
+               var bkey *boring.PrivateKeyRSA
+               bkey, err = boringPrivateKey(priv)
+               if err != nil {
+                       return
+               }
+               em, err = boring.DecryptRSANoPadding(bkey, ciphertext)
+               if err != nil {
+                       return
+               }
+       } else {
+               c := new(big.Int).SetBytes(ciphertext)
+               var m *big.Int
+               m, err = decrypt(rand, priv, c)
+               if err != nil {
+                       return
+               }
+               em = m.FillBytes(make([]byte, k))
        }
 
-       em = m.FillBytes(make([]byte, k))
        firstByteIsZero := subtle.ConstantTimeByteEq(em[0], 0)
        secondByteIsTwo := subtle.ConstantTimeByteEq(em[1], 2)
 
@@ -228,7 +273,7 @@ var hashPrefixes = map[crypto.Hash][]byte{
 // messages is small, an attacker may be able to build a map from
 // messages to signatures and identify the signed messages. As ever,
 // signatures provide authenticity, not confidentiality.
-func SignPKCS1v15(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte) ([]byte, error) {
+func SignPKCS1v15(random io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte) ([]byte, error) {
        hashLen, prefix, err := pkcs1v15HashInfo(hash, len(hashed))
        if err != nil {
                return nil, err
@@ -240,6 +285,14 @@ func SignPKCS1v15(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []b
                return nil, ErrMessageTooLong
        }
 
+       if boring.Enabled {
+               bkey, err := boringPrivateKey(priv)
+               if err != nil {
+                       return nil, err
+               }
+               return boring.SignRSAPKCS1v15(bkey, hash, hashed)
+       }
+
        // EM = 0x00 || 0x01 || PS || 0x00 || T
        em := make([]byte, k)
        em[1] = 1
@@ -250,7 +303,7 @@ func SignPKCS1v15(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []b
        copy(em[k-hashLen:k], hashed)
 
        m := new(big.Int).SetBytes(em)
-       c, err := decryptAndCheck(rand, priv, m)
+       c, err := decryptAndCheck(random, priv, m)
        if err != nil {
                return nil, err
        }
@@ -264,6 +317,17 @@ func SignPKCS1v15(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []b
 // returning a nil error. If hash is zero then hashed is used directly. This
 // isn't advisable except for interoperability.
 func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) error {
+       if boring.Enabled {
+               bkey, err := boringPublicKey(pub)
+               if err != nil {
+                       return err
+               }
+               if err := boring.VerifyRSAPKCS1v15(bkey, hash, hashed, sig); err != nil {
+                       return ErrVerification
+               }
+               return nil
+       }
+
        hashLen, prefix, err := pkcs1v15HashInfo(hash, len(hashed))
        if err != nil {
                return err
index 26b8c5f26fefd249ab2ac03eab1383e2436653ee..c5d825b42a0962db27e3ea570e16ef3d4c6ba2a6 100644 (file)
@@ -65,7 +65,7 @@ func TestDecryptPKCS1v15(t *testing.T) {
                for i, test := range decryptPKCS1v15Tests {
                        out, err := decryptFunc(decodeBase64(test.in))
                        if err != nil {
-                               t.Errorf("#%d error decrypting", i)
+                               t.Errorf("#%d error decrypting: %v", i, err)
                        }
                        want := []byte(test.out)
                        if !bytes.Equal(out, want) {
index b2adbedb28fa859aa9ee0a23ac5313ca53370e02..cda1eafd6ec1f0d0b5601ef4fc1835dd6eba4c30 100644 (file)
@@ -15,6 +15,8 @@ import (
        "math/big"
 )
 
+import "crypto/internal/boring"
+
 // Per RFC 8017, Section 9.1
 //
 //     EM = MGF1 xor DB || H( 8*0x00 || mHash || salt ) || 0xbc
@@ -213,6 +215,21 @@ func signPSSWithSalt(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed,
        if err != nil {
                return nil, err
        }
+
+       if boring.Enabled {
+               bkey, err := boringPrivateKey(priv)
+               if err != nil {
+                       return nil, err
+               }
+               // Note: BoringCrypto takes care of the "AndCheck" part of "decryptAndCheck".
+               // (It's not just decrypt.)
+               s, err := boring.DecryptRSANoPadding(bkey, em)
+               if err != nil {
+                       return nil, err
+               }
+               return s, nil
+       }
+
        m := new(big.Int).SetBytes(em)
        c, err := decryptAndCheck(rand, priv, m)
        if err != nil {
@@ -274,6 +291,14 @@ func SignPSS(rand io.Reader, priv *PrivateKey, hash crypto.Hash, digest []byte,
                saltLength = hash.Size()
        }
 
+       if boring.Enabled && rand == boring.RandReader {
+               bkey, err := boringPrivateKey(priv)
+               if err != nil {
+                       return nil, err
+               }
+               return boring.SignRSAPSS(bkey, hash, digest, saltLength)
+       }
+
        salt := make([]byte, saltLength)
        if _, err := io.ReadFull(rand, salt); err != nil {
                return nil, err
@@ -288,6 +313,16 @@ func SignPSS(rand io.Reader, priv *PrivateKey, hash crypto.Hash, digest []byte,
 // argument may be nil, in which case sensible defaults are used. opts.Hash is
 // ignored.
 func VerifyPSS(pub *PublicKey, hash crypto.Hash, digest []byte, sig []byte, opts *PSSOptions) error {
+       if boring.Enabled {
+               bkey, err := boringPublicKey(pub)
+               if err != nil {
+                       return err
+               }
+               if err := boring.VerifyRSAPSS(bkey, hash, digest, sig, opts.saltLength()); err != nil {
+                       return ErrVerification
+               }
+               return nil
+       }
        if len(sig) != pub.Size() {
                return ErrVerification
        }
index dfa8d8bb5ad02e6feb3420348680c146b03740ad..32f6f0c3aa93dc92c776902ab2fbbc6b141e3f54 100644 (file)
@@ -9,7 +9,6 @@ import (
        "bytes"
        "compress/bzip2"
        "crypto"
-       _ "crypto/md5"
        "crypto/rand"
        "crypto/sha1"
        _ "crypto/sha256"
@@ -211,7 +210,7 @@ func TestPSSSigning(t *testing.T) {
                {8, 8, true},
        }
 
-       hash := crypto.MD5
+       hash := crypto.SHA1
        h := hash.New()
        h.Write([]byte("testing"))
        hashed := h.Sum(nil)
index 178ade666a15fc47a2325502b9247ea983c3470a..eece38598191414a129c940acca0215e6481cbd4 100644 (file)
@@ -35,6 +35,11 @@ import (
        "crypto/internal/randutil"
 )
 
+import (
+       "crypto/internal/boring"
+       "unsafe"
+)
+
 var bigZero = big.NewInt(0)
 var bigOne = big.NewInt(1)
 
@@ -42,6 +47,8 @@ var bigOne = big.NewInt(1)
 type PublicKey struct {
        N *big.Int // modulus
        E int      // public exponent
+
+       boring unsafe.Pointer
 }
 
 // Any methods implemented on PublicKey might need to also be implemented on
@@ -105,6 +112,8 @@ type PrivateKey struct {
        // Precomputed contains precomputed values that speed up private
        // operations, if available.
        Precomputed PrecomputedValues
+
+       boring unsafe.Pointer
 }
 
 // Public returns the public key corresponding to priv.
@@ -256,6 +265,32 @@ func GenerateKey(random io.Reader, bits int) (*PrivateKey, error) {
 func GenerateMultiPrimeKey(random io.Reader, nprimes int, bits int) (*PrivateKey, error) {
        randutil.MaybeReadByte(random)
 
+       if boring.Enabled && random == boring.RandReader && nprimes == 2 && (bits == 2048 || bits == 3072) {
+               N, E, D, P, Q, Dp, Dq, Qinv, err := boring.GenerateKeyRSA(bits)
+               if err != nil {
+                       return nil, err
+               }
+               e64 := E.Int64()
+               if !E.IsInt64() || int64(int(e64)) != e64 {
+                       return nil, errors.New("crypto/rsa: generated key exponent too large")
+               }
+               key := &PrivateKey{
+                       PublicKey: PublicKey{
+                               N: N,
+                               E: int(e64),
+                       },
+                       D:      D,
+                       Primes: []*big.Int{P, Q},
+                       Precomputed: PrecomputedValues{
+                               Dp:        Dp,
+                               Dq:        Dq,
+                               Qinv:      Qinv,
+                               CRTValues: make([]CRTValue, 0), // non-nil, to match Precompute
+                       },
+               }
+               return key, nil
+       }
+
        priv := new(PrivateKey)
        priv.E = 65537
 
@@ -385,6 +420,7 @@ func mgf1XOR(out []byte, hash hash.Hash, seed []byte) {
 var ErrMessageTooLong = errors.New("crypto/rsa: message too long for RSA public key size")
 
 func encrypt(c *big.Int, pub *PublicKey, m *big.Int) *big.Int {
+       boring.Unreachable()
        e := big.NewInt(int64(pub.E))
        c.Exp(m, e, pub.N)
        return c
@@ -417,6 +453,15 @@ func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, l
                return nil, ErrMessageTooLong
        }
 
+       if boring.Enabled && random == boring.RandReader {
+               bkey, err := boringPublicKey(pub)
+               if err != nil {
+                       return nil, err
+               }
+               return boring.EncryptRSAOAEP(hash, bkey, msg, label)
+       }
+       boring.UnreachableExceptTests()
+
        hash.Write(label)
        lHash := hash.Sum(nil)
        hash.Reset()
@@ -437,6 +482,15 @@ func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, l
        mgf1XOR(db, hash, seed)
        mgf1XOR(seed, hash, db)
 
+       if boring.Enabled {
+               var bkey *boring.PublicKeyRSA
+               bkey, err = boringPublicKey(pub)
+               if err != nil {
+                       return nil, err
+               }
+               return boring.EncryptRSANoPadding(bkey, em)
+       }
+
        m := new(big.Int)
        m.SetBytes(em)
        c := encrypt(new(big.Int), pub, m)
@@ -487,6 +541,9 @@ func (priv *PrivateKey) Precompute() {
 // decrypt performs an RSA decryption, resulting in a plaintext integer. If a
 // random source is given, RSA blinding is used.
 func decrypt(random io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int, err error) {
+       if len(priv.Primes) <= 2 {
+               boring.Unreachable()
+       }
        // TODO(agl): can we get away with reusing blinds?
        if c.Cmp(priv.N) > 0 {
                err = ErrDecryption
@@ -603,6 +660,17 @@ func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext
                return nil, ErrDecryption
        }
 
+       if boring.Enabled {
+               bkey, err := boringPrivateKey(priv)
+               if err != nil {
+                       return nil, err
+               }
+               out, err := boring.DecryptRSAOAEP(hash, bkey, ciphertext, label)
+               if err != nil {
+                       return nil, ErrDecryption
+               }
+               return out, nil
+       }
        c := new(big.Int).SetBytes(ciphertext)
 
        m, err := decrypt(random, priv, c)
index 84b167455f02f64ddc5ad5efa7df0b5d65954661..766d9a954f8d13f721f786372016990ade2d2a5a 100644 (file)
@@ -10,23 +10,27 @@ import (
        "crypto/rand"
        "crypto/sha1"
        "crypto/sha256"
+       "fmt"
        "math/big"
        "testing"
 )
 
+import "crypto/internal/boring"
+
 func TestKeyGeneration(t *testing.T) {
-       size := 1024
-       if testing.Short() {
-               size = 128
-       }
-       priv, err := GenerateKey(rand.Reader, size)
-       if err != nil {
-               t.Errorf("failed to generate key")
-       }
-       if bits := priv.N.BitLen(); bits != size {
-               t.Errorf("key too short (%d vs %d)", bits, size)
+       for _, size := range []int{128, 1024, 2048, 3072} {
+               priv, err := GenerateKey(rand.Reader, size)
+               if err != nil {
+                       t.Errorf("GenerateKey(%d): %v", size, err)
+               }
+               if bits := priv.N.BitLen(); bits != size {
+                       t.Errorf("key too short (%d vs %d)", bits, size)
+               }
+               testKeyBasics(t, priv)
+               if testing.Short() {
+                       break
+               }
        }
-       testKeyBasics(t, priv)
 }
 
 func Test3PrimeKeyGeneration(t *testing.T) {
@@ -110,6 +114,25 @@ func testKeyBasics(t *testing.T, priv *PrivateKey) {
                t.Errorf("private exponent too large")
        }
 
+       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)
+               }
+               return
+       }
+
        pub := &priv.PublicKey
        m := big.NewInt(42)
        c := encrypt(new(big.Int), pub, m)
@@ -158,6 +181,10 @@ func init() {
 }
 
 func BenchmarkRSA2048Decrypt(b *testing.B) {
+       if boring.Enabled {
+               b.Skip("no raw decrypt in BoringCrypto")
+       }
+
        b.StopTimer()
 
        c := fromBase10("8472002792838218989464636159316973636630013835787202418124758118372358261975764365740026024610403138425986214991379012696600761514742817632790916315594342398720903716529235119816755589383377471752116975374952783629225022962092351886861518911824745188989071172097120352727368980275252089141512321893536744324822590480751098257559766328893767334861211872318961900897793874075248286439689249972315699410830094164386544311554704755110361048571142336148077772023880664786019636334369759624917224888206329520528064315309519262325023881707530002540634660750469137117568199824615333883758410040459705787022909848740188613313")
@@ -180,6 +207,10 @@ func BenchmarkRSA2048Sign(b *testing.B) {
 }
 
 func Benchmark3PrimeRSA2048Decrypt(b *testing.B) {
+       if boring.Enabled {
+               b.Skip("no raw decrypt in BoringCrypto")
+       }
+
        b.StopTimer()
        priv := &PrivateKey{
                PublicKey: PublicKey{
@@ -222,7 +253,7 @@ func TestEncryptOAEP(t *testing.T) {
        n := new(big.Int)
        for i, test := range testEncryptOAEPData {
                n.SetString(test.modulus, 16)
-               public := PublicKey{n, test.e}
+               public := PublicKey{N: n, E: test.e}
 
                for j, message := range test.msgs {
                        randomSource := bytes.NewReader(message.seed)
@@ -247,7 +278,7 @@ func TestDecryptOAEP(t *testing.T) {
                n.SetString(test.modulus, 16)
                d.SetString(test.d, 16)
                private := new(PrivateKey)
-               private.PublicKey = PublicKey{n, test.e}
+               private.PublicKey = PublicKey{N: n, E: test.e}
                private.D = d
 
                for j, message := range test.msgs {
@@ -272,6 +303,36 @@ func TestDecryptOAEP(t *testing.T) {
        }
 }
 
+func TestEncryptDecryptOAEP(t *testing.T) {
+       sha256 := sha256.New()
+       n := new(big.Int)
+       d := new(big.Int)
+       for i, test := range testEncryptOAEPData {
+               n.SetString(test.modulus, 16)
+               d.SetString(test.d, 16)
+               priv := new(PrivateKey)
+               priv.PublicKey = PublicKey{N: n, E: test.e}
+               priv.D = d
+
+               for j, message := range test.msgs {
+                       label := []byte(fmt.Sprintf("hi#%d", j))
+                       enc, err := EncryptOAEP(sha256, rand.Reader, &priv.PublicKey, message.in, label)
+                       if err != nil {
+                               t.Errorf("#%d,%d: EncryptOAEP: %v", i, j, err)
+                               continue
+                       }
+                       dec, err := DecryptOAEP(sha256, rand.Reader, priv, enc, label)
+                       if err != nil {
+                               t.Errorf("#%d,%d: DecryptOAEP: %v", i, j, err)
+                               continue
+                       }
+                       if !bytes.Equal(dec, message.in) {
+                               t.Errorf("#%d,%d: round trip %q -> %q", i, j, message.in, dec)
+                       }
+               }
+       }
+}
+
 // testEncryptOAEPData contains a subset of the vectors from RSA's "Test vectors for RSA-OAEP".
 var testEncryptOAEPData = []testEncryptOAEPStruct{
        // Key 1
diff --git a/src/crypto/sha1/boring.go b/src/crypto/sha1/boring.go
new file mode 100644 (file)
index 0000000..44c2609
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2009 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.
+
+// Extra indirection here so that when building go_bootstrap
+// cmd/internal/boring is not even imported, so that we don't
+// have to maintain changes to cmd/dist's deps graph.
+
+// +build !cmd_go_bootstrap
+
+package sha1
+
+import (
+       "crypto/internal/boring"
+       "hash"
+)
+
+const boringEnabled = boring.Enabled
+
+func boringNewSHA1() hash.Hash { return boring.NewSHA1() }
+
+func boringUnreachable() { boring.Unreachable() }
diff --git a/src/crypto/sha1/notboring.go b/src/crypto/sha1/notboring.go
new file mode 100644 (file)
index 0000000..9726fcd
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2009 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.
+
+// +build cmd_go_bootstrap
+
+package sha1
+
+import (
+       "hash"
+)
+
+const boringEnabled = false
+
+func boringNewSHA1() hash.Hash { panic("boringcrypto: not available") }
+
+func boringUnreachable() {}
index 286a59d33d662bfa6fc955dea711f0a3d5eba6a8..329435f282f428c4771ec458e2f1d0e93c1c8ee7 100644 (file)
@@ -119,6 +119,9 @@ func (d *digest) Reset() {
 // implements encoding.BinaryMarshaler and encoding.BinaryUnmarshaler to
 // marshal and unmarshal the internal state of the hash.
 func New() hash.Hash {
+       if boringEnabled {
+               return boringNewSHA1()
+       }
        d := new(digest)
        d.Reset()
        return d
@@ -129,6 +132,7 @@ func (d *digest) Size() int { return Size }
 func (d *digest) BlockSize() int { return BlockSize }
 
 func (d *digest) Write(p []byte) (nn int, err error) {
+       boringUnreachable()
        nn = len(p)
        d.len += uint64(nn)
        if d.nx > 0 {
@@ -152,6 +156,7 @@ func (d *digest) Write(p []byte) (nn int, err error) {
 }
 
 func (d *digest) Sum(in []byte) []byte {
+       boringUnreachable()
        // Make a copy of d so that caller can keep writing and summing.
        d0 := *d
        hash := d0.checkSum()
@@ -259,6 +264,13 @@ func (d *digest) constSum() [Size]byte {
 
 // Sum returns the SHA-1 checksum of the data.
 func Sum(data []byte) [Size]byte {
+       if boringEnabled {
+               h := New()
+               h.Write(data)
+               var ret [Size]byte
+               h.Sum(ret[:0])
+               return ret
+       }
        var d digest
        d.Reset()
        d.Write(data)
index 681e928de2530ae7af7928b9b81d2d9eebaa522b..8e7a3d339cf5228030516cbcc67d367304f28bcb 100644 (file)
@@ -16,6 +16,8 @@ import (
        "testing"
 )
 
+import "crypto/internal/boring"
+
 type sha1Test struct {
        out       string
        in        string
@@ -77,6 +79,9 @@ func TestGolden(t *testing.T) {
                                io.WriteString(c, g.in[len(g.in)/2:])
                                sum = c.Sum(nil)
                        case 3:
+                               if boring.Enabled {
+                                       continue
+                               }
                                io.WriteString(c, g.in[0:len(g.in)/2])
                                c.(*digest).ConstantTimeSum(nil)
                                io.WriteString(c, g.in[len(g.in)/2:])
@@ -141,6 +146,9 @@ func TestBlockSize(t *testing.T) {
 
 // Tests that blockGeneric (pure Go) and block (in assembly for some architectures) match.
 func TestBlockGeneric(t *testing.T) {
+       if boring.Enabled {
+               t.Skip("BoringCrypto doesn't expose digest")
+       }
        for i := 1; i < 30; i++ { // arbitrary factor
                gen, asm := New().(*digest), New().(*digest)
                buf := make([]byte, BlockSize*i)
index e1cccf65a60307517d7adecf7dcefdbd47d88aa5..8b54a427d7d4c8c25cd650fe2703a8cbae0c4306 100644 (file)
@@ -13,6 +13,8 @@ import (
        "hash"
 )
 
+import "crypto/internal/boring"
+
 func init() {
        crypto.RegisterHash(crypto.SHA224, New224)
        crypto.RegisterHash(crypto.SHA256, New)
@@ -159,6 +161,9 @@ func (d *digest) Reset() {
 // encoding.BinaryUnmarshaler to marshal and unmarshal the internal
 // state of the hash.
 func New() hash.Hash {
+       if boring.Enabled {
+               return boring.NewSHA256()
+       }
        d := new(digest)
        d.Reset()
        return d
@@ -166,6 +171,9 @@ func New() hash.Hash {
 
 // New224 returns a new hash.Hash computing the SHA224 checksum.
 func New224() hash.Hash {
+       if boring.Enabled {
+               return boring.NewSHA224()
+       }
        d := new(digest)
        d.is224 = true
        d.Reset()
@@ -182,6 +190,7 @@ func (d *digest) Size() int {
 func (d *digest) BlockSize() int { return BlockSize }
 
 func (d *digest) Write(p []byte) (nn int, err error) {
+       boring.Unreachable()
        nn = len(p)
        d.len += uint64(nn)
        if d.nx > 0 {
@@ -205,6 +214,7 @@ func (d *digest) Write(p []byte) (nn int, err error) {
 }
 
 func (d *digest) Sum(in []byte) []byte {
+       boring.Unreachable()
        // Make a copy of d so that caller can keep writing and summing.
        d0 := *d
        hash := d0.checkSum()
@@ -252,6 +262,13 @@ func (d *digest) checkSum() [Size]byte {
 
 // Sum256 returns the SHA256 checksum of the data.
 func Sum256(data []byte) [Size]byte {
+       if boring.Enabled {
+               h := New()
+               h.Write(data)
+               var ret [Size]byte
+               h.Sum(ret[:0])
+               return ret
+       }
        var d digest
        d.Reset()
        d.Write(data)
@@ -260,6 +277,13 @@ func Sum256(data []byte) [Size]byte {
 
 // Sum224 returns the SHA224 checksum of the data.
 func Sum224(data []byte) (sum224 [Size224]byte) {
+       if boring.Enabled {
+               h := New224()
+               h.Write(data)
+               var ret [Size224]byte
+               h.Sum(ret[:0])
+               return ret
+       }
        var d digest
        d.is224 = true
        d.Reset()
index 433c5a4c5e6254e9cd0acdd33f9a3c15bdb724a9..13178fb21f5ed44cfe5bc595de25d1960413901d 100644 (file)
@@ -16,6 +16,8 @@ import (
        "testing"
 )
 
+import "crypto/internal/boring"
+
 type sha256Test struct {
        out       string
        in        string
@@ -216,6 +218,9 @@ func TestBlockSize(t *testing.T) {
 
 // Tests that blockGeneric (pure Go) and block (in assembly for some architectures) match.
 func TestBlockGeneric(t *testing.T) {
+       if boring.Enabled {
+               t.Skip("BoringCrypto doesn't expose digest")
+       }
        gen, asm := New().(*digest), New().(*digest)
        buf := make([]byte, BlockSize*20) // arbitrary factor
        rand.Read(buf)
index 9c143a2a2817786095b94b2775db18210ff3a7be..1a2cef317c34023325ac805c2365606f1e551fb6 100644 (file)
@@ -17,6 +17,8 @@ import (
        "hash"
 )
 
+import "crypto/internal/boring"
+
 func init() {
        crypto.RegisterHash(crypto.SHA384, New384)
        crypto.RegisterHash(crypto.SHA512, New)
@@ -211,6 +213,9 @@ func consumeUint64(b []byte) ([]byte, uint64) {
 
 // New returns a new hash.Hash computing the SHA-512 checksum.
 func New() hash.Hash {
+       if boring.Enabled {
+               return boring.NewSHA512()
+       }
        d := &digest{function: crypto.SHA512}
        d.Reset()
        return d
@@ -232,6 +237,9 @@ func New512_256() hash.Hash {
 
 // New384 returns a new hash.Hash computing the SHA-384 checksum.
 func New384() hash.Hash {
+       if boring.Enabled {
+               return boring.NewSHA384()
+       }
        d := &digest{function: crypto.SHA384}
        d.Reset()
        return d
@@ -253,6 +261,9 @@ func (d *digest) Size() int {
 func (d *digest) BlockSize() int { return BlockSize }
 
 func (d *digest) Write(p []byte) (nn int, err error) {
+       if d.function != crypto.SHA512_224 && d.function != crypto.SHA512_256 {
+               boring.Unreachable()
+       }
        nn = len(p)
        d.len += uint64(nn)
        if d.nx > 0 {
@@ -276,6 +287,9 @@ func (d *digest) Write(p []byte) (nn int, err error) {
 }
 
 func (d *digest) Sum(in []byte) []byte {
+       if d.function != crypto.SHA512_224 && d.function != crypto.SHA512_256 {
+               boring.Unreachable()
+       }
        // Make a copy of d so that caller can keep writing and summing.
        d0 := new(digest)
        *d0 = *d
@@ -330,6 +344,13 @@ func (d *digest) checkSum() [Size]byte {
 
 // Sum512 returns the SHA512 checksum of the data.
 func Sum512(data []byte) [Size]byte {
+       if boring.Enabled {
+               h := New()
+               h.Write(data)
+               var ret [Size]byte
+               h.Sum(ret[:0])
+               return ret
+       }
        d := digest{function: crypto.SHA512}
        d.Reset()
        d.Write(data)
@@ -338,6 +359,13 @@ func Sum512(data []byte) [Size]byte {
 
 // Sum384 returns the SHA384 checksum of the data.
 func Sum384(data []byte) (sum384 [Size384]byte) {
+       if boring.Enabled {
+               h := New384()
+               h.Write(data)
+               var ret [Size384]byte
+               h.Sum(ret[:0])
+               return ret
+       }
        d := digest{function: crypto.SHA384}
        d.Reset()
        d.Write(data)
index 59998b1d38d7450c29ec2d5d191194f060fa20f2..6964bef8f7f8ec6bfe9b09dd66d688a3dc2bdd21 100644 (file)
@@ -17,6 +17,8 @@ import (
        "testing"
 )
 
+import "crypto/internal/boring"
+
 type sha512Test struct {
        out       string
        in        string
@@ -822,6 +824,9 @@ func TestBlockSize(t *testing.T) {
 
 // Tests that blockGeneric (pure Go) and block (in assembly for some architectures) match.
 func TestBlockGeneric(t *testing.T) {
+       if boring.Enabled {
+               t.Skip("BoringCrypto doesn't expose digest")
+       }
        gen, asm := New().(*digest), New().(*digest)
        buf := make([]byte, BlockSize*20) // arbitrary factor
        rand.Read(buf)
index a9df0da6d624b1b39b3b0813a93573e0319e1ac1..17595f0c358fae882e90faa9a913d986a6ea8f6f 100644 (file)
@@ -241,6 +241,9 @@ func selectSignatureScheme(vers uint16, c *Certificate, peerAlgs []SignatureSche
        // Pick signature scheme in the peer's preference order, as our
        // preference order is not configurable.
        for _, preferredAlg := range peerAlgs {
+               if needFIPS() && !isSupportedSignatureAlgorithm(preferredAlg, fipsSupportedSignatureAlgorithms) {
+                       continue
+               }
                if isSupportedSignatureAlgorithm(preferredAlg, supportedAlgs) {
                        return preferredAlg, nil
                }
index c42e3491e46f16873c2195397bbdd56e9536b2a5..c23d93f3c0855d83c38579d15594c051deb75535 100644 (file)
@@ -153,7 +153,7 @@ func TestLegacyTypeAndHash(t *testing.T) {
 // TestSupportedSignatureAlgorithms checks that all supportedSignatureAlgorithms
 // have valid type and hash information.
 func TestSupportedSignatureAlgorithms(t *testing.T) {
-       for _, sigAlg := range supportedSignatureAlgorithms {
+       for _, sigAlg := range supportedSignatureAlgorithms() {
                sigType, hash, err := typeAndHashFromSignatureScheme(sigAlg)
                if err != nil {
                        t.Errorf("%v: unexpected error: %v", sigAlg, err)
diff --git a/src/crypto/tls/boring.go b/src/crypto/tls/boring.go
new file mode 100644 (file)
index 0000000..d61deb5
--- /dev/null
@@ -0,0 +1,132 @@
+// Copyright 2017 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 tls
+
+import (
+       "crypto/ecdsa"
+       "crypto/internal/boring"
+       "crypto/internal/boring/fipstls"
+       "crypto/rsa"
+       "crypto/x509"
+)
+
+// boringEnabled is an alias of boring.Enabled to avoid a new import in common.go.
+const boringEnabled = boring.Enabled
+
+// needFIPS returns fipstls.Required(); it avoids a new import in common.go.
+func needFIPS() bool {
+       return fipstls.Required()
+}
+
+// fipsMinVersion replaces c.minVersion in FIPS-only mode.
+func fipsMinVersion(c *Config) uint16 {
+       // FIPS requires TLS 1.2.
+       return VersionTLS12
+}
+
+// fipsMaxVersion replaces c.maxVersion in FIPS-only mode.
+func fipsMaxVersion(c *Config) uint16 {
+       // FIPS requires TLS 1.2.
+       return VersionTLS12
+}
+
+// default defaultFIPSCurvePreferences is the FIPS-allowed curves,
+// in preference order (most preferable first).
+var defaultFIPSCurvePreferences = []CurveID{CurveP256, CurveP384, CurveP521}
+
+// fipsCurvePreferences replaces c.curvePreferences in FIPS-only mode.
+func fipsCurvePreferences(c *Config) []CurveID {
+       if c == nil || len(c.CurvePreferences) == 0 {
+               return defaultFIPSCurvePreferences
+       }
+       var list []CurveID
+       for _, id := range c.CurvePreferences {
+               for _, allowed := range defaultFIPSCurvePreferences {
+                       if id == allowed {
+                               list = append(list, id)
+                               break
+                       }
+               }
+       }
+       return list
+}
+
+// default FIPSCipherSuites is the FIPS-allowed cipher suites,
+// in preference order (most preferable first).
+var defaultFIPSCipherSuites = []uint16{
+       TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+       TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+       TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+       TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+       TLS_RSA_WITH_AES_128_GCM_SHA256,
+       TLS_RSA_WITH_AES_256_GCM_SHA384,
+}
+
+// fipsCipherSuites replaces c.cipherSuites in FIPS-only mode.
+func fipsCipherSuites(c *Config) []uint16 {
+       if c == nil || c.CipherSuites == nil {
+               return defaultFIPSCipherSuites
+       }
+       var list []uint16
+       for _, id := range c.CipherSuites {
+               for _, allowed := range defaultFIPSCipherSuites {
+                       if id == allowed {
+                               list = append(list, id)
+                               break
+                       }
+               }
+       }
+       return list
+}
+
+// isBoringCertificate reports whether a certificate may be used
+// when constructing a verified chain.
+// It is called for each leaf, intermediate, and root certificate.
+func isBoringCertificate(c *x509.Certificate) bool {
+       if !needFIPS() {
+               // Everything is OK if we haven't forced FIPS-only mode.
+               return true
+       }
+
+       // Otherwise the key must be RSA 2048, RSA 3072, or ECDSA P-256.
+       switch k := c.PublicKey.(type) {
+       default:
+               return false
+       case *rsa.PublicKey:
+               if size := k.N.BitLen(); size != 2048 && size != 3072 {
+                       return false
+               }
+       case *ecdsa.PublicKey:
+               if name := k.Curve.Params().Name; name != "P-256" && name != "P-384" {
+                       return false
+               }
+       }
+
+       return true
+}
+
+// fipsSupportedSignatureAlgorithms currently are a subset of
+// defaultSupportedSignatureAlgorithms without Ed25519 and SHA-1.
+var fipsSupportedSignatureAlgorithms = []SignatureScheme{
+       PSSWithSHA256,
+       PSSWithSHA384,
+       PSSWithSHA512,
+       PKCS1WithSHA256,
+       ECDSAWithP256AndSHA256,
+       PKCS1WithSHA384,
+       ECDSAWithP384AndSHA384,
+       PKCS1WithSHA512,
+       ECDSAWithP521AndSHA512,
+}
+
+// supportedSignatureAlgorithms returns the supported signature algorithms.
+func supportedSignatureAlgorithms() []SignatureScheme {
+       if !needFIPS() {
+               return defaultSupportedSignatureAlgorithms
+       }
+       return fipsSupportedSignatureAlgorithms
+}
+
+var testingOnlyForceClientHelloSignatureAlgorithms []SignatureScheme
diff --git a/src/crypto/tls/boring_test.go b/src/crypto/tls/boring_test.go
new file mode 100644 (file)
index 0000000..6ad72fa
--- /dev/null
@@ -0,0 +1,630 @@
+// Copyright 2017 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 tls
+
+import (
+       "crypto/ecdsa"
+       "crypto/elliptic"
+       "crypto/internal/boring/fipstls"
+       "crypto/rand"
+       "crypto/rsa"
+       "crypto/x509"
+       "crypto/x509/pkix"
+       "encoding/pem"
+       "fmt"
+       "math/big"
+       "net"
+       "runtime"
+       "strings"
+       "testing"
+       "time"
+)
+
+func TestBoringServerProtocolVersion(t *testing.T) {
+       test := func(name string, v uint16, msg string) {
+               t.Run(name, func(t *testing.T) {
+                       serverConfig := testConfig.Clone()
+                       serverConfig.MinVersion = VersionSSL30
+                       clientHello := &clientHelloMsg{
+                               vers:               v,
+                               random:             make([]byte, 32),
+                               cipherSuites:       allCipherSuites(),
+                               compressionMethods: []uint8{compressionNone},
+                               supportedVersions:  []uint16{v},
+                       }
+                       testClientHelloFailure(t, serverConfig, clientHello, msg)
+               })
+       }
+
+       test("VersionTLS10", VersionTLS10, "")
+       test("VersionTLS11", VersionTLS11, "")
+       test("VersionTLS12", VersionTLS12, "")
+       test("VersionTLS13", VersionTLS13, "")
+
+       fipstls.Force()
+       defer fipstls.Abandon()
+       test("VersionSSL30", VersionSSL30, "client offered only unsupported versions")
+       test("VersionTLS10", VersionTLS10, "client offered only unsupported versions")
+       test("VersionTLS11", VersionTLS11, "client offered only unsupported versions")
+       test("VersionTLS12", VersionTLS12, "")
+       test("VersionTLS13", VersionTLS13, "client offered only unsupported versions")
+}
+
+func isBoringVersion(v uint16) bool {
+       return v == VersionTLS12
+}
+
+func isBoringCipherSuite(id uint16) bool {
+       switch id {
+       case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+               TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+               TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+               TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+               TLS_RSA_WITH_AES_128_GCM_SHA256,
+               TLS_RSA_WITH_AES_256_GCM_SHA384:
+               return true
+       }
+       return false
+}
+
+func isBoringCurve(id CurveID) bool {
+       switch id {
+       case CurveP256, CurveP384, CurveP521:
+               return true
+       }
+       return false
+}
+
+func isECDSA(id uint16) bool {
+       for _, suite := range cipherSuites {
+               if suite.id == id {
+                       return suite.flags&suiteECSign == suiteECSign
+               }
+       }
+       panic(fmt.Sprintf("unknown cipher suite %#x", id))
+}
+
+func isBoringSignatureScheme(alg SignatureScheme) bool {
+       switch alg {
+       default:
+               return false
+       case PKCS1WithSHA256,
+               ECDSAWithP256AndSHA256,
+               PKCS1WithSHA384,
+               ECDSAWithP384AndSHA384,
+               PKCS1WithSHA512,
+               ECDSAWithP521AndSHA512,
+               PSSWithSHA256,
+               PSSWithSHA384,
+               PSSWithSHA512:
+               // ok
+       }
+       return true
+}
+
+func TestBoringServerCipherSuites(t *testing.T) {
+       serverConfig := testConfig.Clone()
+       serverConfig.CipherSuites = allCipherSuites()
+       serverConfig.Certificates = make([]Certificate, 1)
+
+       for _, id := range allCipherSuites() {
+               if isECDSA(id) {
+                       serverConfig.Certificates[0].Certificate = [][]byte{testECDSACertificate}
+                       serverConfig.Certificates[0].PrivateKey = testECDSAPrivateKey
+               } else {
+                       serverConfig.Certificates[0].Certificate = [][]byte{testRSACertificate}
+                       serverConfig.Certificates[0].PrivateKey = testRSAPrivateKey
+               }
+               serverConfig.BuildNameToCertificate()
+               t.Run(fmt.Sprintf("suite=%#x", id), func(t *testing.T) {
+                       clientHello := &clientHelloMsg{
+                               vers:               VersionTLS12,
+                               random:             make([]byte, 32),
+                               cipherSuites:       []uint16{id},
+                               compressionMethods: []uint8{compressionNone},
+                               supportedCurves:    defaultCurvePreferences,
+                               supportedPoints:    []uint8{pointFormatUncompressed},
+                       }
+
+                       testClientHello(t, serverConfig, clientHello)
+                       t.Run("fipstls", func(t *testing.T) {
+                               fipstls.Force()
+                               defer fipstls.Abandon()
+                               msg := ""
+                               if !isBoringCipherSuite(id) {
+                                       msg = "no cipher suite supported by both client and server"
+                               }
+                               testClientHelloFailure(t, serverConfig, clientHello, msg)
+                       })
+               })
+       }
+}
+
+func TestBoringServerCurves(t *testing.T) {
+       serverConfig := testConfig.Clone()
+       serverConfig.Certificates = make([]Certificate, 1)
+       serverConfig.Certificates[0].Certificate = [][]byte{testECDSACertificate}
+       serverConfig.Certificates[0].PrivateKey = testECDSAPrivateKey
+       serverConfig.BuildNameToCertificate()
+
+       for _, curveid := range defaultCurvePreferences {
+               t.Run(fmt.Sprintf("curve=%d", curveid), func(t *testing.T) {
+                       clientHello := &clientHelloMsg{
+                               vers:               VersionTLS12,
+                               random:             make([]byte, 32),
+                               cipherSuites:       []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
+                               compressionMethods: []uint8{compressionNone},
+                               supportedCurves:    []CurveID{curveid},
+                               supportedPoints:    []uint8{pointFormatUncompressed},
+                       }
+
+                       testClientHello(t, serverConfig, clientHello)
+
+                       // With fipstls forced, bad curves should be rejected.
+                       t.Run("fipstls", func(t *testing.T) {
+                               fipstls.Force()
+                               defer fipstls.Abandon()
+                               msg := ""
+                               if !isBoringCurve(curveid) {
+                                       msg = "no cipher suite supported by both client and server"
+                               }
+                               testClientHelloFailure(t, serverConfig, clientHello, msg)
+                       })
+               })
+       }
+}
+
+func boringHandshake(t *testing.T, clientConfig, serverConfig *Config) (clientErr, serverErr error) {
+       c, s := localPipe(t)
+       client := Client(c, clientConfig)
+       server := Server(s, serverConfig)
+       done := make(chan error, 1)
+       go func() {
+               done <- client.Handshake()
+               c.Close()
+       }()
+       serverErr = server.Handshake()
+       s.Close()
+       clientErr = <-done
+       return
+}
+
+func TestBoringServerSignatureAndHash(t *testing.T) {
+       defer func() {
+               testingOnlyForceClientHelloSignatureAlgorithms = nil
+       }()
+
+       for _, sigHash := range defaultSupportedSignatureAlgorithms {
+               t.Run(fmt.Sprintf("%#x", sigHash), func(t *testing.T) {
+                       serverConfig := testConfig.Clone()
+                       serverConfig.Certificates = make([]Certificate, 1)
+
+                       testingOnlyForceClientHelloSignatureAlgorithms = []SignatureScheme{sigHash}
+
+                       sigType, _, _ := typeAndHashFromSignatureScheme(sigHash)
+                       switch sigType {
+                       case signaturePKCS1v15, signatureRSAPSS:
+                               serverConfig.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}
+                               serverConfig.Certificates[0].Certificate = [][]byte{testRSA2048Certificate}
+                               serverConfig.Certificates[0].PrivateKey = testRSA2048PrivateKey
+                       case signatureEd25519:
+                               serverConfig.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}
+                               serverConfig.Certificates[0].Certificate = [][]byte{testEd25519Certificate}
+                               serverConfig.Certificates[0].PrivateKey = testEd25519PrivateKey
+                       case signatureECDSA:
+                               serverConfig.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}
+                               serverConfig.Certificates[0].Certificate = [][]byte{testECDSACertificate}
+                               serverConfig.Certificates[0].PrivateKey = testECDSAPrivateKey
+                       }
+                       serverConfig.BuildNameToCertificate()
+                       // PKCS#1 v1.5 signature algorithms can't be used standalone in TLS
+                       // 1.3, and the ECDSA ones bind to the curve used.
+                       serverConfig.MaxVersion = VersionTLS12
+
+                       clientErr, serverErr := boringHandshake(t, testConfig, serverConfig)
+                       if clientErr != nil {
+                               t.Fatalf("expected handshake with %#x to succeed; client error: %v; server error: %v", sigHash, clientErr, serverErr)
+                       }
+
+                       // With fipstls forced, bad curves should be rejected.
+                       t.Run("fipstls", func(t *testing.T) {
+                               fipstls.Force()
+                               defer fipstls.Abandon()
+                               clientErr, _ := boringHandshake(t, testConfig, serverConfig)
+                               if isBoringSignatureScheme(sigHash) {
+                                       if clientErr != nil {
+                                               t.Fatalf("expected handshake with %#x to succeed; err=%v", sigHash, clientErr)
+                                       }
+                               } else {
+                                       if clientErr == nil {
+                                               t.Fatalf("expected handshake with %#x to fail, but it succeeded", sigHash)
+                                       }
+                               }
+                       })
+               })
+       }
+}
+
+func TestBoringClientHello(t *testing.T) {
+       // Test that no matter what we put in the client config,
+       // the client does not offer non-FIPS configurations.
+       fipstls.Force()
+       defer fipstls.Abandon()
+
+       c, s := net.Pipe()
+       defer c.Close()
+       defer s.Close()
+
+       clientConfig := testConfig.Clone()
+       // All sorts of traps for the client to avoid.
+       clientConfig.MinVersion = VersionSSL30
+       clientConfig.MaxVersion = VersionTLS13
+       clientConfig.CipherSuites = allCipherSuites()
+       clientConfig.CurvePreferences = defaultCurvePreferences
+
+       go Client(c, testConfig).Handshake()
+       srv := Server(s, testConfig)
+       msg, err := srv.readHandshake()
+       if err != nil {
+               t.Fatal(err)
+       }
+       hello, ok := msg.(*clientHelloMsg)
+       if !ok {
+               t.Fatalf("unexpected message type %T", msg)
+       }
+
+       if !isBoringVersion(hello.vers) {
+               t.Errorf("client vers=%#x, want %#x (TLS 1.2)", hello.vers, VersionTLS12)
+       }
+       for _, v := range hello.supportedVersions {
+               if !isBoringVersion(v) {
+                       t.Errorf("client offered disallowed version %#x", v)
+               }
+       }
+       for _, id := range hello.cipherSuites {
+               if !isBoringCipherSuite(id) {
+                       t.Errorf("client offered disallowed suite %#x", id)
+               }
+       }
+       for _, id := range hello.supportedCurves {
+               if !isBoringCurve(id) {
+                       t.Errorf("client offered disallowed curve %d", id)
+               }
+       }
+       for _, sigHash := range hello.supportedSignatureAlgorithms {
+               if !isBoringSignatureScheme(sigHash) {
+                       t.Errorf("client offered disallowed signature-and-hash %v", sigHash)
+               }
+       }
+}
+
+func TestBoringCertAlgs(t *testing.T) {
+       // NaCl, arm and wasm time out generating keys. Nothing in this test is architecture-specific, so just don't bother on those.
+       if runtime.GOOS == "nacl" || runtime.GOARCH == "arm" || runtime.GOOS == "js" {
+               t.Skipf("skipping on %s/%s because key generation takes too long", runtime.GOOS, runtime.GOARCH)
+       }
+
+       // Set up some roots, intermediate CAs, and leaf certs with various algorithms.
+       // X_Y is X signed by Y.
+       R1 := boringCert(t, "R1", boringRSAKey(t, 2048), nil, boringCertCA|boringCertFIPSOK)
+       R2 := boringCert(t, "R2", boringRSAKey(t, 4096), nil, boringCertCA)
+
+       M1_R1 := boringCert(t, "M1_R1", boringECDSAKey(t, elliptic.P256()), R1, boringCertCA|boringCertFIPSOK)
+       M2_R1 := boringCert(t, "M2_R1", boringECDSAKey(t, elliptic.P224()), R1, boringCertCA)
+
+       I_R1 := boringCert(t, "I_R1", boringRSAKey(t, 3072), R1, boringCertCA|boringCertFIPSOK)
+       I_R2 := boringCert(t, "I_R2", I_R1.key, R2, boringCertCA|boringCertFIPSOK)
+       I_M1 := boringCert(t, "I_M1", I_R1.key, M1_R1, boringCertCA|boringCertFIPSOK)
+       I_M2 := boringCert(t, "I_M2", I_R1.key, M2_R1, boringCertCA|boringCertFIPSOK)
+
+       L1_I := boringCert(t, "L1_I", boringECDSAKey(t, elliptic.P384()), I_R1, boringCertLeaf|boringCertFIPSOK)
+       L2_I := boringCert(t, "L2_I", boringRSAKey(t, 1024), I_R1, boringCertLeaf)
+
+       // boringCert checked that isBoringCertificate matches the caller's boringCertFIPSOK bit.
+       // If not, no point in building bigger end-to-end tests.
+       if t.Failed() {
+               t.Fatalf("isBoringCertificate failures; not continuing")
+       }
+
+       // client verifying server cert
+       testServerCert := func(t *testing.T, desc string, pool *x509.CertPool, key interface{}, list [][]byte, ok bool) {
+               clientConfig := testConfig.Clone()
+               clientConfig.RootCAs = pool
+               clientConfig.InsecureSkipVerify = false
+               clientConfig.ServerName = "example.com"
+
+               serverConfig := testConfig.Clone()
+               serverConfig.Certificates = []Certificate{{Certificate: list, PrivateKey: key}}
+               serverConfig.BuildNameToCertificate()
+
+               clientErr, _ := boringHandshake(t, clientConfig, serverConfig)
+
+               if (clientErr == nil) == ok {
+                       if ok {
+                               t.Logf("%s: accept", desc)
+                       } else {
+                               t.Logf("%s: reject", desc)
+                       }
+               } else {
+                       if ok {
+                               t.Errorf("%s: BAD reject (%v)", desc, clientErr)
+                       } else {
+                               t.Errorf("%s: BAD accept", desc)
+                       }
+               }
+       }
+
+       // server verifying client cert
+       testClientCert := func(t *testing.T, desc string, pool *x509.CertPool, key interface{}, list [][]byte, ok bool) {
+               clientConfig := testConfig.Clone()
+               clientConfig.ServerName = "example.com"
+               clientConfig.Certificates = []Certificate{{Certificate: list, PrivateKey: key}}
+
+               serverConfig := testConfig.Clone()
+               serverConfig.ClientCAs = pool
+               serverConfig.ClientAuth = RequireAndVerifyClientCert
+
+               _, serverErr := boringHandshake(t, clientConfig, serverConfig)
+
+               if (serverErr == nil) == ok {
+                       if ok {
+                               t.Logf("%s: accept", desc)
+                       } else {
+                               t.Logf("%s: reject", desc)
+                       }
+               } else {
+                       if ok {
+                               t.Errorf("%s: BAD reject (%v)", desc, serverErr)
+                       } else {
+                               t.Errorf("%s: BAD accept", desc)
+                       }
+               }
+       }
+
+       // Run simple basic test with known answers before proceeding to
+       // 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)
+       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)
+       fipstls.Abandon()
+
+       if t.Failed() {
+               t.Fatal("basic test failed, skipping exhaustive test")
+       }
+
+       if testing.Short() {
+               t.Logf("basic test passed; skipping exhaustive test in -short mode")
+               return
+       }
+
+       for l := 1; l <= 2; l++ {
+               leaf := L1_I
+               if l == 2 {
+                       leaf = L2_I
+               }
+               for i := 0; i < 64; i++ {
+                       reachable := map[string]bool{leaf.parentOrg: true}
+                       reachableFIPS := map[string]bool{leaf.parentOrg: leaf.fipsOK}
+                       list := [][]byte{leaf.der}
+                       listName := leaf.name
+                       addList := func(cond int, c *boringCertificate) {
+                               if cond != 0 {
+                                       list = append(list, c.der)
+                                       listName += "," + c.name
+                                       if reachable[c.org] {
+                                               reachable[c.parentOrg] = true
+                                       }
+                                       if reachableFIPS[c.org] && c.fipsOK {
+                                               reachableFIPS[c.parentOrg] = true
+                                       }
+                               }
+                       }
+                       addList(i&1, I_R1)
+                       addList(i&2, I_R2)
+                       addList(i&4, I_M1)
+                       addList(i&8, I_M2)
+                       addList(i&16, M1_R1)
+                       addList(i&32, M2_R1)
+
+                       for r := 1; r <= 3; r++ {
+                               pool := x509.NewCertPool()
+                               rootName := ","
+                               shouldVerify := false
+                               shouldVerifyFIPS := false
+                               addRoot := func(cond int, c *boringCertificate) {
+                                       if cond != 0 {
+                                               rootName += "," + c.name
+                                               pool.AddCert(c.cert)
+                                               if reachable[c.org] {
+                                                       shouldVerify = true
+                                               }
+                                               if reachableFIPS[c.org] && c.fipsOK {
+                                                       shouldVerifyFIPS = true
+                                               }
+                                       }
+                               }
+                               addRoot(r&1, R1)
+                               addRoot(r&2, R2)
+                               rootName = rootName[1:] // strip leading comma
+                               testServerCert(t, listName+"->"+rootName[1:], pool, leaf.key, list, shouldVerify)
+                               testClientCert(t, listName+"->"+rootName[1:]+"(client cert)", pool, leaf.key, list, shouldVerify)
+                               fipstls.Force()
+                               testServerCert(t, listName+"->"+rootName[1:]+" (fips)", pool, leaf.key, list, shouldVerifyFIPS)
+                               testClientCert(t, listName+"->"+rootName[1:]+" (fips, client cert)", pool, leaf.key, list, shouldVerifyFIPS)
+                               fipstls.Abandon()
+                       }
+               }
+       }
+}
+
+const (
+       boringCertCA = iota
+       boringCertLeaf
+       boringCertFIPSOK = 0x80
+)
+
+func boringRSAKey(t *testing.T, size int) *rsa.PrivateKey {
+       k, err := rsa.GenerateKey(rand.Reader, size)
+       if err != nil {
+               t.Fatal(err)
+       }
+       return k
+}
+
+func boringECDSAKey(t *testing.T, curve elliptic.Curve) *ecdsa.PrivateKey {
+       k, err := ecdsa.GenerateKey(curve, rand.Reader)
+       if err != nil {
+               t.Fatal(err)
+       }
+       return k
+}
+
+type boringCertificate struct {
+       name      string
+       org       string
+       parentOrg string
+       der       []byte
+       cert      *x509.Certificate
+       key       interface{}
+       fipsOK    bool
+}
+
+func boringCert(t *testing.T, name string, key interface{}, parent *boringCertificate, mode int) *boringCertificate {
+       org := name
+       parentOrg := ""
+       if i := strings.Index(org, "_"); i >= 0 {
+               org = org[:i]
+               parentOrg = name[i+1:]
+       }
+       tmpl := &x509.Certificate{
+               SerialNumber: big.NewInt(1),
+               Subject: pkix.Name{
+                       Organization: []string{org},
+               },
+               NotBefore: time.Unix(0, 0),
+               NotAfter:  time.Unix(0, 0),
+
+               KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
+               ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
+               BasicConstraintsValid: true,
+       }
+       if mode&^boringCertFIPSOK == boringCertLeaf {
+               tmpl.DNSNames = []string{"example.com"}
+       } else {
+               tmpl.IsCA = true
+               tmpl.KeyUsage |= x509.KeyUsageCertSign
+       }
+
+       var pcert *x509.Certificate
+       var pkey interface{}
+       if parent != nil {
+               pcert = parent.cert
+               pkey = parent.key
+       } else {
+               pcert = tmpl
+               pkey = key
+       }
+
+       var pub interface{}
+       var desc string
+       switch k := key.(type) {
+       case *rsa.PrivateKey:
+               pub = &k.PublicKey
+               desc = fmt.Sprintf("RSA-%d", k.N.BitLen())
+       case *ecdsa.PrivateKey:
+               pub = &k.PublicKey
+               desc = "ECDSA-" + k.Curve.Params().Name
+       default:
+               t.Fatalf("invalid key %T", key)
+       }
+
+       der, err := x509.CreateCertificate(rand.Reader, tmpl, pcert, pub, pkey)
+       if err != nil {
+               t.Fatal(err)
+       }
+       cert, err := x509.ParseCertificate(der)
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       // Tell isBoringCertificate to enforce FIPS restrictions for this check.
+       fipstls.Force()
+       defer fipstls.Abandon()
+
+       fipsOK := mode&boringCertFIPSOK != 0
+       if isBoringCertificate(cert) != fipsOK {
+               t.Errorf("isBoringCertificate(cert with %s key) = %v, want %v", desc, !fipsOK, fipsOK)
+       }
+       return &boringCertificate{name, org, parentOrg, der, cert, key, fipsOK}
+}
+
+// A self-signed test certificate with an RSA key of size 2048, for testing
+// RSA-PSS with SHA512. SAN of example.golang.
+var (
+       testRSA2048Certificate []byte
+       testRSA2048PrivateKey  *rsa.PrivateKey
+)
+
+func init() {
+       block, _ := pem.Decode([]byte(`
+-----BEGIN CERTIFICATE-----
+MIIC/zCCAeegAwIBAgIRALHHX/kh4+4zMU9DarzBEcQwDQYJKoZIhvcNAQELBQAw
+EjEQMA4GA1UEChMHQWNtZSBDbzAeFw0xMTAxMDExNTA0MDVaFw0yMDEyMjkxNTA0
+MDVaMBIxEDAOBgNVBAoTB0FjbWUgQ28wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
+ggEKAoIBAQCf8fk0N6ieCBX4IOVIfKitt4kGcOQLeimCfsjqqHcysMIVGEtFSM6E
+4Ay141f/7IqdW0UtIqNb4PXhROID7yDxR284xL6XbCuv/t5hP3UcehYc3hmLiyVd
+MkZQiZWtfUUJf/1qOtM+ohNg59LRWp4d+6iX0la1JL3EwCIckkNjJ9hQbF7Pb2CS
++ES9Yo55KAap8KOblpcR8MBSN38bqnwjfQdCXvOEOjam2HUxKzEFX5MA+fA0me4C
+ioCcCRLWKl+GoN9F8fABfoZ+T+2eal4DLuO95rXR8SrOIVBh3XFOr/RVhjtXcNVF
+ZKcvDt6d68V6jAKAYKm5nlj9GPpd4v+rAgMBAAGjUDBOMA4GA1UdDwEB/wQEAwIF
+oDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMBkGA1UdEQQSMBCC
+DmV4YW1wbGUuZ29sYW5nMA0GCSqGSIb3DQEBCwUAA4IBAQCOoYsVcFCBhboqe3WH
+dC6V7XXXECmnjh01r8h80yv0NR379nSD3cw2M+HKvaXysWqrl5hjGVKw0vtwD81r
+V4JzDu7IfIog5m8+QNC+7LqDZsz88vDKOrsoySVOmUCgmCKFXew+LA+eO/iQEJTr
+7ensddOeXJEp27Ed5vW+kmWW3Qmglc2Gwy8wFrMDIqnrnOzBA4oCnDEgtXJt0zog
+nRwbfEMAWi1aQRy5dT9KA3SP9mo5SeTFSzGGHiE4s4gHUe7jvsAFF2qgtD6+wH6s
+z9b6shxnC7g5IlBKhI7SVB/Uqt2ydJ+kH1YbjMcIq6NAM5eNMKgZuJr3+zwsSgwh
+GNaE
+-----END CERTIFICATE-----`))
+       testRSA2048Certificate = block.Bytes
+
+       block, _ = pem.Decode([]byte(`
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAn/H5NDeonggV+CDlSHyorbeJBnDkC3opgn7I6qh3MrDCFRhL
+RUjOhOAMteNX/+yKnVtFLSKjW+D14UTiA+8g8UdvOMS+l2wrr/7eYT91HHoWHN4Z
+i4slXTJGUImVrX1FCX/9ajrTPqITYOfS0VqeHfuol9JWtSS9xMAiHJJDYyfYUGxe
+z29gkvhEvWKOeSgGqfCjm5aXEfDAUjd/G6p8I30HQl7zhDo2pth1MSsxBV+TAPnw
+NJnuAoqAnAkS1ipfhqDfRfHwAX6Gfk/tnmpeAy7jvea10fEqziFQYd1xTq/0VYY7
+V3DVRWSnLw7enevFeowCgGCpuZ5Y/Rj6XeL/qwIDAQABAoIBAQCNpMZifd/vg42h
+HdCvLuZaYS0R7SunFlpoXEsltGdLFsnp0IfoJZ/ugFQBSAIIfLwMumU6oXA1z7Uv
+98aIYV61DePrTCDVDFBsHbNmP8JAo8WtbusEbwd5zyoB7LYG2+clkJklWE73KqUq
+rmI+UJeyScl2Gin7ZTxBXz1WPBk9VwcnwkeaXpgASIBW23fhECM9gnYEEwaBez5T
+6Me8d1tHtYQv7vsKe7ro9w9/HKrRXejqYKK1LxkhfFriyV+m8LZJZn2nXOa6G3gF
+Nb8Qk1Uk5PUBENBmyMFJhT4M/uuSq4YtMrrO2gi8Q+fPhuGzc5SshYKRBp0W4P5r
+mtVCtEFRAoGBAMENBIFLrV2+HsGj0xYFasKov/QPe6HSTR1Hh2IZONp+oK4oszWE
+jBT4VcnITmpl6tC1Wy4GcrxjNgKIFZAj+1x1LUULdorXkuG8yr0tAhG9zNyfWsSy
+PrSovC0UVbzr8Jxxla+kQVxEQQqWQxPlEVuL8kXaIDA6Lyt1Hpua2LvPAoGBANQZ
+c6Lq2T7+BxLxNdi2m8kZzej5kgzBp/XdVsbFWRlebIX2KrFHsrHzT9PUk3DE1vZK
+M6pzTt94nQhWSkDgCaw1SohElJ3HFIFwcusF1SJAc3pQepd8ug6IYdlpDMLtBj/P
+/5P6BVUtgo05E4+I/T3iYatmglQxTtlZ0RkSV2llAoGBALOXkKFX7ahPvf0WksDh
+uTfuFOTPoowgQG0EpgW0wRdCxeg/JLic3lSD0gsttQV2WsRecryWcxaelRg10RmO
+38BbogmhaF4xvgsSvujOfiZTE8oK1T43M+6NKsIlML3YILbpU/9aJxPWy0s2DqDr
+cQJhZrlk+pzjBA7Bnf/URdwxAoGAKR/CNw14D+mrL3YLbbiCXiydqxVwxv5pdZdz
+8thi3TNcsWC4iGURdcVqbfUinVPdJiXe/Kac3WGCeRJaFVgbKAOxLti1RB5MkIhg
+D8eyupBqk4W1L1gkrxqsdj4TFlxkwMywjl2E2S4YyQ8PBt6V04DoVRZsIKzqz+PF
+UionPq0CgYBCYXvqioJhPewkOq/Y5wrDBeZW1FQK5QD9W5M8/5zxd4rdvJtjhbJp
+oOrtvMdrl6upy9Hz4BJD3FXwVFiPFE7jqeNqi0F21viLxBPMMD3UODF6LL5EyLiR
+9V4xVMS8KXxvg7rxsuqzMPscViaWUL6WNVBhsD2+92dHxSXzz5EJKQ==
+-----END RSA PRIVATE KEY-----`))
+       var err error
+       testRSA2048PrivateKey, err = x509.ParsePKCS1PrivateKey(block.Bytes)
+       if err != nil {
+               panic(err)
+       }
+}
index 9a356758fbfc5dc09835bc6db3c1cee86983f5f1..6596562fb13ecfa8f7aeec0455a48775e6392f39 100644 (file)
@@ -4,6 +4,8 @@
 
 package tls
 
+import "crypto/internal/boring"
+
 import (
        "crypto"
        "crypto/aes"
@@ -249,7 +251,13 @@ func cipherAES(key, iv []byte, isRead bool) interface{} {
 
 // macSHA1 returns a SHA-1 based constant time MAC.
 func macSHA1(key []byte) hash.Hash {
-       return hmac.New(newConstantTimeHash(sha1.New), key)
+       h := sha1.New
+       // The BoringCrypto SHA1 does not have a constant-time
+       // checksum function, so don't try to use it.
+       if !boring.Enabled {
+               h = newConstantTimeHash(h)
+       }
+       return hmac.New(h, key)
 }
 
 // macSHA256 returns a SHA-256 based MAC. This is only supported in TLS 1.2 and
@@ -329,6 +337,10 @@ func (f *xorNonceAEAD) Open(out, nonce, ciphertext, additionalData []byte) ([]by
        return result, err
 }
 
+type gcmtls interface {
+       NewGCMTLS() (cipher.AEAD, error)
+}
+
 func aeadAESGCM(key, noncePrefix []byte) aead {
        if len(noncePrefix) != noncePrefixLength {
                panic("tls: internal error: wrong nonce length")
@@ -337,7 +349,13 @@ func aeadAESGCM(key, noncePrefix []byte) aead {
        if err != nil {
                panic(err)
        }
-       aead, err := cipher.NewGCM(aes)
+       var aead cipher.AEAD
+       if aesTLS, ok := aes.(gcmtls); ok {
+               aead, err = aesTLS.NewGCMTLS()
+       } else {
+               boring.Unreachable()
+               aead, err = cipher.NewGCM(aes)
+       }
        if err != nil {
                panic(err)
        }
@@ -397,6 +415,7 @@ func (c *cthWrapper) Write(p []byte) (int, error) { return c.h.Write(p) }
 func (c *cthWrapper) Sum(b []byte) []byte         { return c.h.ConstantTimeSum(b) }
 
 func newConstantTimeHash(h func() hash.Hash) func() hash.Hash {
+       boring.Unreachable()
        return func() hash.Hash {
                return &cthWrapper{h().(constantTimeHash)}
        }
index eec6e1ebbd9060559637c9d2476046b2665a4bed..2564dfee9e4cd9cc1f9a2c1be839ee5cd4b39388 100644 (file)
@@ -173,11 +173,11 @@ const (
 // hash function associated with the Ed25519 signature scheme.
 var directSigning crypto.Hash = 0
 
-// supportedSignatureAlgorithms contains the signature and hash algorithms that
+// defaultSupportedSignatureAlgorithms contains the signature and hash algorithms that
 // the code advertises as supported in a TLS 1.2+ ClientHello and in a TLS 1.2+
 // CertificateRequest. The two fields are merged to match with TLS 1.3.
 // Note that in TLS 1.2, the ECDSA algorithms are not constrained to P-256, etc.
-var supportedSignatureAlgorithms = []SignatureScheme{
+var defaultSupportedSignatureAlgorithms = []SignatureScheme{
        PSSWithSHA256,
        ECDSAWithP256AndSHA256,
        Ed25519,
@@ -925,6 +925,9 @@ func (c *Config) time() time.Time {
 }
 
 func (c *Config) cipherSuites() []uint16 {
+       if needFIPS() {
+               return fipsCipherSuites(c)
+       }
        s := c.CipherSuites
        if s == nil {
                s = defaultCipherSuites()
@@ -942,6 +945,9 @@ var supportedVersions = []uint16{
 func (c *Config) supportedVersions() []uint16 {
        versions := make([]uint16, 0, len(supportedVersions))
        for _, v := range supportedVersions {
+               if needFIPS() && (v < fipsMinVersion(c) || v > fipsMaxVersion(c)) {
+                       continue
+               }
                if c != nil && c.MinVersion != 0 && v < c.MinVersion {
                        continue
                }
@@ -978,6 +984,9 @@ func supportedVersionsFromMax(maxVersion uint16) []uint16 {
 var defaultCurvePreferences = []CurveID{X25519, CurveP256, CurveP384, CurveP521}
 
 func (c *Config) curvePreferences() []CurveID {
+       if needFIPS() {
+               return fipsCurvePreferences(c)
+       }
        if c == nil || len(c.CurvePreferences) == 0 {
                return defaultCurvePreferences
        }
@@ -1449,7 +1458,8 @@ var (
 func initDefaultCipherSuites() {
        var topCipherSuites []uint16
 
-       if hasAESGCMHardwareSupport {
+       if hasAESGCMHardwareSupport || boringEnabled {
+               // If BoringCrypto is enabled, always prioritize AES-GCM.
                // If AES-GCM hardware is provided then prioritise AES-GCM
                // cipher suites.
                topCipherSuites = []uint16{
diff --git a/src/crypto/tls/fipsonly/fipsonly.go b/src/crypto/tls/fipsonly/fipsonly.go
new file mode 100644 (file)
index 0000000..85b3532
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2017 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 fipsonly restricts all TLS configuration to FIPS-approved settings.
+//
+// The effect is triggered by importing the package anywhere in a program, as in:
+//
+//     import _ "crypto/tls/fipsonly"
+//
+// This package only exists in the dev.boringcrypto branch of Go.
+package fipsonly
+
+// This functionality is provided as a side effect of an import to make
+// it trivial to add to an existing program. It requires only a single line
+// added to an existing source file, or it can be done by adding a whole
+// new source file and not modifying any existing source files.
+
+import (
+       "crypto/internal/boring/fipstls"
+       "crypto/internal/boring/sig"
+)
+
+func init() {
+       fipstls.Force()
+       sig.FIPSOnly()
+}
diff --git a/src/crypto/tls/fipsonly/fipsonly_test.go b/src/crypto/tls/fipsonly/fipsonly_test.go
new file mode 100644 (file)
index 0000000..facd248
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2017 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 fipsonly
+
+import (
+       "crypto/internal/boring/fipstls"
+       "testing"
+)
+
+func Test(t *testing.T) {
+       if !fipstls.Required() {
+               t.Fatal("fipstls.Required() = false, must be true")
+       }
+}
index e684b21d527223e850e8a74d802e9ac0521e9753..94747a7c4109a8c22e923747c79e7a72ee12b21d 100644 (file)
@@ -113,7 +113,10 @@ func (c *Conn) makeClientHello() (*clientHelloMsg, ecdheParameters, error) {
        }
 
        if hello.vers >= VersionTLS12 {
-               hello.supportedSignatureAlgorithms = supportedSignatureAlgorithms
+               hello.supportedSignatureAlgorithms = supportedSignatureAlgorithms()
+       }
+       if testingOnlyForceClientHelloSignatureAlgorithms != nil {
+               hello.supportedSignatureAlgorithms = testingOnlyForceClientHelloSignatureAlgorithms
        }
 
        var params ecdheParameters
@@ -835,6 +838,8 @@ func (c *Conn) verifyServerCertificate(certificates [][]byte) error {
 
        if !c.config.InsecureSkipVerify {
                opts := x509.VerifyOptions{
+                       IsBoring: isBoringCertificate,
+
                        Roots:         c.config.RootCAs,
                        CurrentTime:   c.config.time(),
                        DNSName:       c.config.ServerName,
index daa5d97fd35548c4871a2f7f7ffa3b6e5da013a7..c2db16dcf2a84480bec0b75e12ec9225b56f5ae9 100644 (file)
@@ -39,6 +39,10 @@ type clientHandshakeStateTLS13 struct {
 func (hs *clientHandshakeStateTLS13) handshake() error {
        c := hs.c
 
+       if needFIPS() {
+               return errors.New("tls: internal error: TLS 1.3 reached in FIPS mode")
+       }
+
        // The server must not select TLS 1.3 in a renegotiation. See RFC 8446,
        // sections 4.1.2 and 4.1.3.
        if c.handshakes > 0 {
@@ -474,7 +478,7 @@ func (hs *clientHandshakeStateTLS13) readServerCertificate() error {
        }
 
        // See RFC 8446, Section 4.4.3.
-       if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms) {
+       if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms()) {
                c.sendAlert(alertIllegalParameter)
                return errors.New("tls: certificate used with invalid signature algorithm")
        }
index bb8aea86700509d82222e73ae6f30eedb59ef1f7..8821670e9ae432803fce44b136f502c2aa020d60 100644 (file)
@@ -147,10 +147,10 @@ func (*clientHelloMsg) Generate(rand *rand.Rand, size int) reflect.Value {
                }
        }
        if rand.Intn(10) > 5 {
-               m.supportedSignatureAlgorithms = supportedSignatureAlgorithms
+               m.supportedSignatureAlgorithms = supportedSignatureAlgorithms()
        }
        if rand.Intn(10) > 5 {
-               m.supportedSignatureAlgorithmsCert = supportedSignatureAlgorithms
+               m.supportedSignatureAlgorithmsCert = supportedSignatureAlgorithms()
        }
        for i := 0; i < rand.Intn(5); i++ {
                m.alpnProtocols = append(m.alpnProtocols, randomString(rand.Intn(20)+1, rand))
@@ -369,10 +369,10 @@ func (*certificateRequestMsgTLS13) Generate(rand *rand.Rand, size int) reflect.V
                m.scts = true
        }
        if rand.Intn(10) > 5 {
-               m.supportedSignatureAlgorithms = supportedSignatureAlgorithms
+               m.supportedSignatureAlgorithms = supportedSignatureAlgorithms()
        }
        if rand.Intn(10) > 5 {
-               m.supportedSignatureAlgorithmsCert = supportedSignatureAlgorithms
+               m.supportedSignatureAlgorithmsCert = supportedSignatureAlgorithms()
        }
        if rand.Intn(10) > 5 {
                m.certificateAuthorities = make([][]byte, 3)
index 9c3e0f636ea7b548776ad75bf7ff112c65e7c571..9b05a27251c079ae1b97ec173c92fa06beb0da88 100644 (file)
@@ -313,7 +313,8 @@ func (hs *serverHandshakeState) pickCipherSuite() error {
 
                // If we don't have hardware support for AES-GCM, prefer other AEAD
                // ciphers even if the client prioritized AES-GCM.
-               if !hasAESGCMHardwareSupport {
+               // If BoringCrypto is enabled, always prioritize AES-GCM.
+               if !hasAESGCMHardwareSupport && !boringEnabled {
                        preferenceList = deprioritizeAES(preferenceList)
                }
        }
@@ -515,7 +516,7 @@ func (hs *serverHandshakeState) doFullHandshake() error {
                }
                if c.vers >= VersionTLS12 {
                        certReq.hasSignatureAlgorithm = true
-                       certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms
+                       certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms()
                }
 
                // An empty list of certificateAuthorities signals to
@@ -786,6 +787,8 @@ func (c *Conn) processCertsFromClient(certificate Certificate) error {
 
        if c.config.ClientAuth >= VerifyClientCertIfGiven && len(certs) > 0 {
                opts := x509.VerifyOptions{
+                       IsBoring: isBoringCertificate,
+
                        Roots:         c.config.ClientCAs,
                        CurrentTime:   c.config.time(),
                        Intermediates: x509.NewCertPool(),
index d6bf9e439b01c3e50b509085675ddf2a5953e60a..050a321e7f3119ba5aa93b5552c624a38a1bfde0 100644 (file)
@@ -1688,6 +1688,7 @@ func TestAESCipherReordering(t *testing.T) {
                preferServerCipherSuites bool
                serverCiphers            []uint16
                expectedCipher           uint16
+               boringExpectedCipher     uint16 // If non-zero, used when BoringCrypto is enabled.
        }{
                {
                        name: "server has hardware AES, client doesn't (pick ChaCha)",
@@ -1723,8 +1724,9 @@ func TestAESCipherReordering(t *testing.T) {
                                TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
                                TLS_RSA_WITH_AES_128_CBC_SHA,
                        },
-                       serverHasAESGCM: false,
-                       expectedCipher:  TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+                       serverHasAESGCM:      false,
+                       expectedCipher:       TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+                       boringExpectedCipher: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, // When BoringCrypto is enabled, AES-GCM is prioritized even without server hardware.
                },
                {
                        name: "client prefers AES-GCM, server has hardware AES (pick AES-GCM)",
@@ -1775,8 +1777,9 @@ func TestAESCipherReordering(t *testing.T) {
                                TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
                                TLS_RSA_WITH_AES_128_CBC_SHA,
                        },
-                       serverHasAESGCM: false,
-                       expectedCipher:  TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+                       serverHasAESGCM:      false,
+                       expectedCipher:       TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+                       boringExpectedCipher: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, // When BoringCrypto is enabled, AES-GCM is prioritized even without server hardware.
                },
                {
                        name: "client supports multiple AES-GCM, server doesn't have hardware AES and doesn't support ChaCha (pick corrent AES-GCM)",
@@ -1820,8 +1823,12 @@ func TestAESCipherReordering(t *testing.T) {
                                t.Errorf("pickCipherSuite failed: %s", err)
                        }
 
-                       if tc.expectedCipher != hs.suite.id {
-                               t.Errorf("unexpected cipher chosen: want %d, got %d", tc.expectedCipher, hs.suite.id)
+                       want := tc.expectedCipher
+                       if boringEnabled && tc.boringExpectedCipher != 0 {
+                               want = tc.boringExpectedCipher
+                       }
+                       if want != hs.suite.id {
+                               t.Errorf("unexpected cipher chosen: want %d, got %d", want, hs.suite.id)
                        }
                })
        }
@@ -1837,6 +1844,7 @@ func TestAESCipherReordering13(t *testing.T) {
                serverHasAESGCM          bool
                preferServerCipherSuites bool
                expectedCipher           uint16
+               boringExpectedCipher     uint16 // If non-zero, used when BoringCrypto is enabled.
        }{
                {
                        name: "server has hardware AES, client doesn't (pick ChaCha)",
@@ -1867,6 +1875,7 @@ func TestAESCipherReordering13(t *testing.T) {
                        serverHasAESGCM:          false,
                        preferServerCipherSuites: true,
                        expectedCipher:           TLS_CHACHA20_POLY1305_SHA256,
+                       boringExpectedCipher:     TLS_AES_128_GCM_SHA256, // When BoringCrypto is enabled, AES-GCM is prioritized even without server hardware.
                },
                {
                        name: "client prefers AES and sends GREASE, server doesn't have hardware, prefer server ciphers (pick ChaCha)",
@@ -1878,6 +1887,7 @@ func TestAESCipherReordering13(t *testing.T) {
                        serverHasAESGCM:          false,
                        preferServerCipherSuites: true,
                        expectedCipher:           TLS_CHACHA20_POLY1305_SHA256,
+                       boringExpectedCipher:     TLS_AES_128_GCM_SHA256, // When BoringCrypto is enabled, AES-GCM is prioritized even without server hardware.
                },
                {
                        name: "client prefers AES, server doesn't (pick ChaCha)",
@@ -1885,8 +1895,9 @@ func TestAESCipherReordering13(t *testing.T) {
                                TLS_AES_128_GCM_SHA256,
                                TLS_CHACHA20_POLY1305_SHA256,
                        },
-                       serverHasAESGCM: false,
-                       expectedCipher:  TLS_CHACHA20_POLY1305_SHA256,
+                       serverHasAESGCM:      false,
+                       expectedCipher:       TLS_CHACHA20_POLY1305_SHA256,
+                       boringExpectedCipher: TLS_AES_128_GCM_SHA256, // When BoringCrypto is enabled, AES-GCM is prioritized even without server hardware.
                },
                {
                        name: "client prefers AES, server has hardware AES (pick AES)",
@@ -1933,8 +1944,12 @@ func TestAESCipherReordering13(t *testing.T) {
                                t.Errorf("pickCipherSuite failed: %s", err)
                        }
 
-                       if tc.expectedCipher != hs.suite.id {
-                               t.Errorf("unexpected cipher chosen: want %d, got %d", tc.expectedCipher, hs.suite.id)
+                       want := tc.expectedCipher
+                       if boringEnabled && tc.boringExpectedCipher != 0 {
+                               want = tc.boringExpectedCipher
+                       }
+                       if want != hs.suite.id {
+                               t.Errorf("unexpected cipher chosen: want %d, got %d", want, hs.suite.id)
                        }
                })
        }
index c2c288aed4325b280f435fcb26239d0d9f49780e..3e1255919f135a2bb6ae5147ae4ed1a198a94441 100644 (file)
@@ -42,6 +42,10 @@ type serverHandshakeStateTLS13 struct {
 func (hs *serverHandshakeStateTLS13) handshake() error {
        c := hs.c
 
+       if needFIPS() {
+               return errors.New("tls: internal error: TLS 1.3 reached in FIPS mode")
+       }
+
        // For an overview of the TLS 1.3 handshake, see RFC 8446, Section 2.
        if err := hs.processClientHello(); err != nil {
                return err
@@ -164,7 +168,8 @@ func (hs *serverHandshakeStateTLS13) processClientHello() error {
 
                // If we don't have hardware support for AES-GCM, prefer other AEAD
                // ciphers even if the client prioritized AES-GCM.
-               if !hasAESGCMHardwareSupport {
+               // If BoringCrypto is enabled, always prioritize AES-GCM.
+               if !hasAESGCMHardwareSupport && !boringEnabled {
                        preferenceList = deprioritizeAES(preferenceList)
                }
        }
@@ -597,7 +602,7 @@ func (hs *serverHandshakeStateTLS13) sendServerCertificate() error {
                certReq := new(certificateRequestMsgTLS13)
                certReq.ocspStapling = true
                certReq.scts = true
-               certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms
+               certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms()
                if c.config.ClientCAs != nil {
                        certReq.certificateAuthorities = c.config.ClientCAs.Subjects()
                }
@@ -816,7 +821,7 @@ func (hs *serverHandshakeStateTLS13) readClientCertificate() error {
                }
 
                // See RFC 8446, Section 4.4.3.
-               if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms) {
+               if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms()) {
                        c.sendAlert(alertIllegalParameter)
                        return errors.New("tls: client certificate used with invalid signature algorithm")
                }
index 46afb2698a919ddb64131ee9d5df0958f2063309..3e343dd531c2b0dfd1cf37b4c758ae1fb6f2ccc1 100644 (file)
@@ -195,6 +195,11 @@ var errNotParsed = errors.New("x509: missing ASN.1 contents; use ParseCertificat
 
 // VerifyOptions contains parameters for Certificate.Verify.
 type VerifyOptions struct {
+       // IsBoring is a validity check for BoringCrypto.
+       // If not nil, it will be called to check whether a given certificate
+       // can be used for constructing verification chains.
+       IsBoring func(*Certificate) bool
+
        // DNSName, if set, is checked against the leaf certificate with
        // Certificate.VerifyHostname or the platform verifier.
        DNSName string
@@ -725,6 +730,13 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V
                }
        }
 
+       if opts.IsBoring != nil && !opts.IsBoring(c) {
+               // IncompatibleUsage is not quite right here,
+               // but it's also the "no chains found" error
+               // and is close enough.
+               return CertificateInvalidError{c, IncompatibleUsage, ""}
+       }
+
        return nil
 }
 
index 217fadf5bd48600402cd310192d735c7731d9037..35e07ea04ced0a5a0ef3a5fa3a669a29a54c86ee 100644 (file)
@@ -1837,6 +1837,7 @@ func splitQuoted(s string) (r []string, err error) {
 //     $GOARCH
 //     cgo (if cgo is enabled)
 //     !cgo (if cgo is disabled)
+//     boringcrypto
 //     ctxt.Compiler
 //     !ctxt.Compiler
 //     tag (if tag is listed in ctxt.BuildTags or ctxt.ReleaseTags)
@@ -1891,6 +1892,10 @@ func (ctxt *Context) match(name string, allTags map[string]bool) bool {
        if ctxt.GOOS == "ios" && name == "darwin" {
                return true
        }
+       // Let applications know that the Go+BoringCrypto toolchain is in use.
+       if name == "boringcrypto" {
+               return true
+       }
 
        // other tags
        for _, tag := range ctxt.BuildTags {
index e5c849e8f53ea318e22def37a46108ee14d057b5..8849f5fd0531d11d9aee322d22234fec83f28724 100644 (file)
@@ -327,7 +327,7 @@ var depsRules = `
 
        # Bulk of the standard library must not use cgo.
        # The prohibition stops at net and os/user.
-       C !< fmt, go/types, CRYPTO-MATH;
+       C !< fmt, go/types;
 
        CGO, OS
        < plugin;
@@ -381,37 +381,35 @@ var depsRules = `
        NET, log
        < net/mail;
 
-       # CRYPTO is core crypto algorithms - no cgo, fmt, net.
-       # Unfortunately, stuck with reflect via encoding/binary.
-       encoding/binary, golang.org/x/sys/cpu, hash
+       NONE < crypto/internal/boring/sig;
+       sync/atomic < crypto/internal/boring/fipstls;
+
+       encoding/binary, golang.org/x/sys/cpu, hash,
+       FMT, math/big,
+       CGO, crypto/internal/boring/sig, crypto/internal/boring/fipstls
        < crypto
        < crypto/subtle
        < crypto/internal/subtle
        < crypto/cipher
+       < encoding/asn1
+       < crypto/internal/boring
        < crypto/aes, crypto/des, crypto/hmac, crypto/md5, crypto/rc4,
          crypto/sha1, crypto/sha256, crypto/sha512
-       < CRYPTO;
-
-       CGO, fmt, net !< CRYPTO;
-
-       # CRYPTO-MATH is core bignum-based crypto - no cgo, net; fmt now ok.
-       CRYPTO, FMT, math/big
        < crypto/rand
        < crypto/internal/randutil
        < crypto/ed25519/internal/edwards25519
        < crypto/ed25519
-       < encoding/asn1
        < golang.org/x/crypto/cryptobyte/asn1
        < golang.org/x/crypto/cryptobyte
        < golang.org/x/crypto/curve25519
        < crypto/dsa, crypto/elliptic, crypto/rsa
        < crypto/ecdsa
-       < CRYPTO-MATH;
+       < CRYPTO-BORING;
 
-       CGO, net !< CRYPTO-MATH;
+       net !< CRYPTO-BORING;
 
        # TLS, Prince of Dependencies.
-       CRYPTO-MATH, NET, container/list, encoding/hex, encoding/pem
+       CRYPTO-BORING, NET, container/list, encoding/hex, encoding/pem
        < golang.org/x/crypto/internal/subtle
        < golang.org/x/crypto/chacha20
        < golang.org/x/crypto/poly1305
@@ -422,6 +420,12 @@ var depsRules = `
        < crypto/x509
        < crypto/tls;
 
+       crypto/internal/boring/sig, crypto/internal/boring/fipstls
+       < crypto/tls/fipsonly;
+
+       crypto/internal/boring
+       < crypto/boring;
+
        # crypto-aware packages
 
        NET, crypto/rand, mime/quotedprintable
diff --git a/src/internal/boringtest/boring.go b/src/internal/boringtest/boring.go
new file mode 100644 (file)
index 0000000..bea1276
--- /dev/null
@@ -0,0 +1,8 @@
+// Copyright 2017 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.
+
+// Nothing to see here but the tests.
+// This file keeps 'go install internal/...' working.
+
+package boring
diff --git a/src/internal/boringtest/boring_test.go b/src/internal/boringtest/boring_test.go
new file mode 100644 (file)
index 0000000..a6b07ed
--- /dev/null
@@ -0,0 +1,47 @@
+// Copyright 2017 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.
+
+// Like crypto/rsa/boring_test.go but outside the crypto/ tree.
+// Tests what happens if a package outside the crypto/ tree
+// "adopts" a struct definition. This happens in golang.org/x/crypto/ssh.
+
+package boring
+
+import (
+       "crypto/rand"
+       "crypto/rsa"
+       "encoding/asn1"
+       "reflect"
+       "testing"
+)
+
+type publicKey rsa.PublicKey
+
+func TestBoringASN1Marshal(t *testing.T) {
+       k, err := rsa.GenerateKey(rand.Reader, 128)
+       if err != nil {
+               t.Fatal(err)
+       }
+       pk := (*publicKey)(&k.PublicKey)
+       // This used to fail, because of the unexported 'boring' field.
+       // Now the compiler hides it [sic].
+       _, err = asn1.Marshal(*pk)
+       if err != nil {
+               t.Fatal(err)
+       }
+}
+
+func TestBoringDeepEqual(t *testing.T) {
+       k0, err := rsa.GenerateKey(rand.Reader, 128)
+       if err != nil {
+               t.Fatal(err)
+       }
+       k := (*publicKey)(&k0.PublicKey)
+       k2 := *k
+       rsa.EncryptPKCS1v15(rand.Reader, (*rsa.PublicKey)(&k2), []byte("hello")) // initialize hidden boring field
+       if !reflect.DeepEqual(k, &k2) {
+               // compiler should be hiding the boring field from reflection
+               t.Fatalf("DeepEqual compared boring fields")
+       }
+}
index 5d25ed4bb64f5f0c039823ea9edba9631ee3d34d..b60cabfe86aacc506efd984b5af6efd3ea0ac220 100644 (file)
@@ -6,9 +6,9 @@ package race_test
 
 import (
        "bytes"
-       "crypto/sha1"
        "errors"
        "fmt"
+       "hash/crc32"
        "io"
        "os"
        "runtime"
@@ -1924,7 +1924,7 @@ func TestRaceIssue5567(t *testing.T) {
                        err = nil
                }
        }()
-       h := sha1.New()
+       h := crc32.New(crc32.MakeTable(0x12345678))
        for b := range in {
                h.Write(b)
        }
diff --git a/src/runtime/runtime_boring.go b/src/runtime/runtime_boring.go
new file mode 100644 (file)
index 0000000..5a98b20
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2017 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 runtime
+
+import _ "unsafe" // for go:linkname
+
+//go:linkname boring_runtime_arg0 crypto/internal/boring.runtime_arg0
+func boring_runtime_arg0() string {
+       // On Windows, argslice is not set, and it's too much work to find argv0.
+       if len(argslice) == 0 {
+               return ""
+       }
+       return argslice[0]
+}
+
+//go:linkname fipstls_runtime_arg0 crypto/internal/boring/fipstls.runtime_arg0
+func fipstls_runtime_arg0() string { return boring_runtime_arg0() }