mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
all: REVERSE MERGE dev.boringcrypto (cdcb4b6) into master
This commit is a REVERSE MERGE. It merges dev.boringcrypto back into its parent branch, master. This marks the end of development on dev.boringcrypto. Manual Changes: - git rm README.boringcrypto.md - git rm -r misc/boring - git rm src/cmd/internal/notsha256/sha256block_arm64.s - git cherry-pick -n 5856aa74 # remove GOEXPERIMENT=boringcrypto forcing in cmd/dist There are some minor cleanups like merging import statements that I will apply in a follow-up CL. Merge List: + 2022-04-29cdcb4b6ef3[dev.boringcrypto] cmd/compile: remove the awful boringcrypto kludge + 2022-04-29e845f572ec[dev.boringcrypto] crypto/ecdsa, crypto/rsa: use boring.Cache + 2022-04-29a840bf871e[dev.boringcrypto] crypto/internal/boring: add GC-aware cache + 2022-04-290184fe5ece[dev.boringcrypto] crypto/x509: remove VerifyOptions.IsBoring + 2022-04-299e9c7a0aec[dev.boringcrypto] crypto/..., go/build: align deps test with standard rules + 2022-04-290ec08283c8[dev.boringcrypto] crypto/internal/boring: make SHA calls allocation-free + 2022-04-293cb10d14b7[dev.boringcrypto] crypto/internal/boring: avoid allocation in big.Int conversion + 2022-04-29509776be5d[dev.boringcrypto] cmd/dist: default to use of boringcrypto + 2022-04-29f4c0f42f99[dev.boringcrypto] all: add boringcrypto build tags + 2022-04-291f0547c4ec[dev.boringcrypto] cmd/go: pass dependency syso to cgo too + 2022-04-29e5407501cb[dev.boringcrypto] cmd: use notsha256 instead of md5, sha1, sha256 + 2022-04-29fe006d6410[dev.boringcrypto] cmd/internal/notsha256: add new package + 2022-04-27ec7f5165dd[dev.boringcrypto] all: merge master into dev.boringcrypto + 2022-04-22ca6fd39cf6[dev.boringcrypto] misc/boring: skip long tests during build.release + 2022-04-2119e4b10f2f[dev.boringcrypto] all: merge master into dev.boringcrypto + 2022-04-20e07d63964b[dev.boringcrypto] all: merge master into dev.boringcrypto + 2022-04-131f11660f54[dev.boringcrypto] misc/boring: add new releases to RELEASES file + 2022-04-13bc3e5d0ab7[dev.boringcrypto] misc/boring: remove -trust and individual reviewers + 2022-04-054739b353bb[dev.boringcrypto] all: merge master into dev.boringcrypto + 2022-03-309d6ab825f6[dev.boringcrypto] make.bash: disable GOEXPERIMENT when using bootstrap toolchain + 2022-03-30d1405d7410[dev.boringcrypto] crypto/internal/boring: update build instructions to use podman + 2022-03-2950b8f490e1[dev.boringcrypto] all: merge master into dev.boringcrypto + 2022-03-150af0e19368[dev.boringcrypto] misc/boring: add new releases to RELEASES file + 2022-03-07f492793839[dev.boringcrypto] all: merge master into dev.boringcrypto + 2022-03-07768804dfdd[dev.boringcrypto] misc/boring: add new releases to RELEASES file + 2022-02-118521d1ea34[dev.boringcrypto] misc/boring: use go install cmd@latest for installing command + 2022-02-11b75258fdd8[dev.boringcrypto] misc/boring: add new releases to RELEASES file + 2022-02-0874d25c624c[dev.boringcrypto] all: merge master into dev.boringcrypto + 2022-02-03e14fee553a[dev.boringcrypto] all: merge master into dev.boringcrypto + 2022-01-14d382493a20[dev.boringcrypto] misc/boring: add new releases to RELEASES file + 2021-12-09069bbf5434[dev.boringcrypto] misc/boring: add new releases to RELEASES file + 2021-12-0621fa0b2199[dev.boringcrypto] crypto/internal/boring: add -pthread linker flag + 2021-12-03a38b43e4ab[dev.boringcrypto] misc/boring: add new releases to RELEASES file + 2021-11-0916215e5340[dev.boringcrypto] cmd/compile: disable version test on boringcrypto + 2021-11-08c9858c7bdc[dev.boringcrypto] all: merge master into dev.boringcrypto + 2021-11-05ed07c49cb6[dev.boringcrypto] all: merge master into dev.boringcrypto + 2021-11-05dc2658558d[dev.boringcrypto] misc/boring: add new releases to RELEASES file + 2021-10-2869d5e469a4[dev.boringcrypto] all: convert +build to //go:build lines in boring-specific files + 2021-10-082840ccbc05[dev.boringcrypto] misc/boring: add new releases to RELEASES file + 2021-10-08114aa69932[dev.boringcrypto] misc/boring: fix Docker Hub references + 2021-10-087d26add6d5[dev.boringcrypto] misc/boring: publish to Artifact Registry + 2021-08-275ae200d526[dev.boringcrypto] crypto/tls: permit P-521 in FIPS mode + 2021-08-26083811d079[dev.boringcrypto] crypto/tls: use correct config in TestBoringClientHello + 2021-08-16c7e7ce5ec1[dev.boringcrypto] all: merge commit57c115e1into dev.boringcrypto + 2021-08-101fb58d6cad[dev.boringcrypto] misc/boring: add new releases to RELEASES file + 2021-07-14934db9f0d6[dev.boringcrypto] misc/boring: add new releases to RELEASES file + 2021-06-08a890a4de30[dev.boringcrypto] misc/boring: add new releases to RELEASES file + 2021-05-13ed1f812cef[dev.boringcrypto] all: merge commit9d0819b27c(CL 314609) into dev.boringcrypto + 2021-05-10ad1b6f3ee0[dev.boringcrypto] misc/boring: add new releases to RELEASES file + 2021-04-2111061407d6[dev.boringcrypto] misc/boring: add new releases to RELEASES file + 2021-03-23b397e0c028[dev.boringcrypto] misc/boring: add new releases to RELEASES file + 2021-03-15128cecc70b[dev.boringcrypto] misc/boring: add new releases to RELEASES file + 2021-03-105e2f5a38c4[dev.boringcrypto] misc/boring: add new releases to RELEASES file + 2021-02-2642089e72fd[dev.boringcrypto] api: add crypto/boring.Enabled + 2021-02-2403cd666173[dev.boringcrypto] all: merge master (5b76343) into dev.boringcrypto + 2021-02-170f210b75f9[dev.boringcrypto] all: merge master (2f0da6d) into dev.boringcrypto + 2021-02-121aea1b199f[dev.boringcrypto] misc/boring: support codereview.cfg in merge.sh + 2021-02-070d34d85dee[dev.boringcrypto] crypto/internal/boring: remove .llvm_addrsig section + 2021-02-07325e03a64f[dev.boringcrypto] all: add codereview.cfg + 2021-02-05d4f73546c8[dev.boringcrypto] misc/boring: add new releases to RELEASES file + 2021-01-20cf8ed7cca4[dev.boringcrypto] misc/boring: add new releases to RELEASES file + 2021-01-20f22137d785[dev.boringcrypto] misc/boring: add -trust and roland@ to merge.sh and release.sh + 2020-12-12e5c7bd0efa[dev.boringcrypto] misc/boring: add new releases to RELEASES file + 2020-12-025934c434c1[dev.boringcrypto] all: merge master into dev.boringcrypto + 2020-12-01dea96ada17[dev.boringcrypto] all: merge master into dev.boringcrypto + 2020-11-18906d6e362b[dev.boringcrypto] all: merge master into dev.boringcrypto + 2020-11-1895ceba18d3[dev.boringcrypto] crypto/hmac: merge up to2a206c7and skip test + 2020-11-170985c1bd2d[dev.boringcrypto] all: merge master into dev.boringcrypto + 2020-11-16af814af6e7[dev.boringcrypto] misc/boring: add new releases to RELEASES file + 2020-11-05f42bd50779[dev.boringcrypto] crypto/internal/boring: update BoringCrypto module to certificate 3678 + 2020-10-19ceda58bfd0[dev.boringcrypto] misc/boring: add new releases to RELEASES file + 2020-09-29af85c47233[dev.boringcrypto] misc/boring: bump version to b6 + 2020-09-29f9b86a6562[dev.boringcrypto] go/build: satisfy the boringcrypto build tag + 2020-09-29ef2b318974[dev.boringcrypto] crypto/boring: expose boring.Enabled() + 2020-09-143782421230[dev.boringcrypto] misc/boring: add new releases to RELEASES file + 2020-08-186bbe47ccb6[dev.boringcrypto] misc/boring: add new releases to RELEASES file + 2020-07-216e6e0b73d6[dev.boringcrypto] misc/boring: add new releases to RELEASES file + 2020-07-09d85ef2b979[dev.boringcrypto] all: merge master into dev.boringcrypto + 2020-07-09a91ad4250c[dev.boringcrypto] all: merge master into dev.boringcrypto + 2020-06-105beb39baf8[dev.boringcrypto] misc/boring: add new releases to RELEASES file + 2020-05-07dd98c0ca3f[dev.boringcrypto] all: merge master into dev.boringcrypto + 2020-05-07a9d2e3abf7[dev.boringcrypto] all: merge master into dev.boringcrypto + 2020-05-07c19c0a047b[dev.boringcrypto] misc/boring: add new releases to RELEASES file + 2020-05-0736c94f8421[dev.boringcrypto] crypto/internal/boring: reject short signatures in VerifyRSAPKCS1v15 + 2020-05-07ee159d2f35[dev.boringcrypto] misc/boring: add new releases to RELEASES file + 2020-04-08e067ce5225[dev.boringcrypto] all: merge master into dev.boringcrypto + 2020-03-0379284c2873[dev.boringcrypto] crypto/internal/boring: make accesses to RSA types with finalizers safer + 2020-03-026c64b188a5[dev.boringcrypto] crypto/internal/boring: update BoringCrypto module to certificate 3318 + 2020-02-2813355c78ff[dev.boringcrypto] misc/boring: add go1.14b4 to RELEASES file + 2020-02-284980c6b317[dev.boringcrypto] misc/boring: x/build/cmd/release doesn't take subrepo flags anymore + 2020-02-28601da81916[dev.boringcrypto] misc/boring: make merge.sh and release.sh a little more robust + 2020-02-1409bc5e8723[dev.boringcrypto] misc/boring: add new releases to RELEASES file + 2020-02-06f96dfe6b73[dev.boringcrypto] misc/boring: add go1.13.7b4 and go1.12.16b4 releases to RELEASES file + 2020-02-052f9b2e75c4[dev.boringcrypto] misc/docker: update Dockerfile to match recent Buster based golang images + 2020-02-05527880d05c[dev.boringcrypto] misc/boring: update default CL reviewer to katie@golang.org + 2019-11-2550ada481fb[dev.boringcrypto] misc/boring: add new releases to RELEASES file + 2019-11-206657395adf[dev.boringcrypto] all: merge master into dev.boringcrypto + 2019-11-20ab0a649d44[dev.boringcrypto] all: merge master into dev.boringcrypto + 2019-11-1962ce702c77[dev.boringcrypto] all: merge master into dev.boringcrypto + 2019-10-25e8f14494a0[dev.boringcrypto] misc/boring: add go1.13.3b4 and go1.12.12b4 to RELEASES file + 2019-10-17988e4d832e[dev.boringcrypto] misc/boring: add go1.13.2b4 and go1.12.11b4 to RELEASES file + 2019-10-11974fd1301a[dev.boringcrypto] misc/boring: publish to Docker Hub all releases, not only the latest + 2019-09-2762ce8cd3ad[dev.boringcrypto] misc/boring: add go1.13.1b4 and go1.12.10b4 to RELEASES file + 2019-09-10489d268683[dev.boringcrypto] misc/boring: add Go+BoringCrypto 1.13b4 to RELEASES file + 2019-09-04e0ee09095c[dev.boringcrypto] all: merge master into dev.boringcrypto + 2019-09-03ff197f326f[dev.boringcrypto] all: merge master into dev.boringcrypto + 2019-08-215a1705286e[dev.boringcrypto] misc/boring: add go1.12.9b4 to RELEASES + 2019-08-151ebc594b3c[dev.boringcrypto] misc/boring: add go1.12.8b4 and go1.11.13b4 to RELEASES + 2019-08-139417029290[dev.boringcrypto] misc/boring: remove download of releaselet.go in build.release + 2019-08-052691091a4amisc/boring: add Go 1.11.12b4 and 1.12.7b4 to RELEASES + 2019-07-196eccf6a6cd[dev.boringcrypto] misc/boring: add scripts to automate merges and releases + 2019-06-2798188f3001[dev.boringcrypto] all: merge master into dev.boringcrypto + 2019-06-135c354e66d1[dev.boringcrypto] misc/boring: add go1.12.6b4 and go1.11.11b4 releases + 2019-06-099bf9e7d4b2[dev.boringcrypto] crypto: move crypto/internal/boring imports to reduce merge conflicts + 2019-06-05324f8365be[dev.boringcrypto] all: merge master into dev.boringcrypto + 2019-05-28e48f228c9b[dev.boringcrypto] all: merge master into dev.boringcrypto + 2019-05-1442e353245c[dev.boringcrypto] misc/boring: add go1.12.5b4 release + 2019-03-29211a13fd44[dev.boringcrypto] misc/boring: add go1.11.6b4 to RELEASES + 2019-03-28347af7f060[dev.boringcrypto] misc/boring: add go1.12.1b4 and update build scripts + 2019-02-27a10558f870[dev.boringcrypto] all: merge master into dev.boringcrypto + 2019-02-084ed8ad4d69[dev.boringcrypto] all: merge master into dev.boringcrypto + 2019-01-2414c64dbc4a[dev.boringcrypto] misc/boring: add go1.10.8b4 and go1.11.5b4 + 2018-12-153f9e53f346[dev.boringcrypto] misc/boring: add go1.10.7b4 and go1.11.4b4 releases + 2018-12-1492d975e906[dev.boringcrypto] misc/boring: add go1.11.2b4 release + 2018-11-14c524da4917[dev.boringcrypto] crypto/tls: test for TLS 1.3 to be disabled in FIPS mode + 2018-11-14bfd6d30118[dev.boringcrypto] all: merge master into dev.boringcrypto + 2018-11-140007017f96[dev.boringcrypto] all: merge master into dev.boringcrypto + 2018-11-143169778c15[dev.boringcrypto] all: merge master into dev.boringcrypto + 2018-11-14ab37582eb0[dev.boringcrypto] all: merge master into dev.boringcrypto + 2018-11-14e8b3500d5c[dev.boringcrypto] all: merge master into dev.boringcrypto + 2018-11-14de153ac2a1[dev.boringcrypto] all: merge master into dev.boringcrypto + 2018-11-140cbb11c720[dev.boringcrypto] cmd/compile: by default accept any language + 2018-11-1311e916773e[dev.boringcrypto] all: merge master into dev.boringcrypto + 2018-11-13af07f7734b[dev.boringcrypto] all: merge master into dev.boringcrypto + 2018-10-2513bf5b80e8[dev.boringcrypto] all: merge master into dev.boringcrypto + 2018-10-15623650b27a[dev.boringcrypto] all: merge master into dev.boringcrypto + 2018-10-0136c789b1fd[dev.boringcrypto] misc/boring: add go1.10.4b4 and go1.11b4 releases + 2018-09-07693875e3f2[dev.boringcrypto] crypto/internal/boring: avoid an allocation in AES-GCM Seal and Open + 2018-09-064d1aa482b8[dev.boringcrypto] all: merge master into dev.boringcrypto + 2018-08-047eb1677c01[dev.boringcrypto] crypto/internal/boring: fix aesCipher implementation of gcmAble + 2018-07-11eaa3e94eb8[dev.boringcrypto] misc/boring: add go1.9.7b4 and go1.10.3b4 releases + 2018-07-115f0402a26b[dev.boringcrypto] misc/boring: support build.release on macOS + 2018-07-0377db076129[dev.boringcrypto] all: merge master into dev.boringcrypto + 2018-06-13b77f5e4c85[dev.boringcrypto] crypto/rsa: drop random source reading emulation + 2018-06-08a4b7722ffa[dev.boringcrypto] all: merge master into dev.boringcrypto + 2018-05-2918db93d7e6[dev.boringcrypto] crypto/tls: restore AES-GCM priority when BoringCrypto is enabled + 2018-05-253d9a6ac709[dev.boringcrypto] all: merge master into dev.boringcrypto + 2018-05-18019a994e32[dev.boringcrypto] crypto/rsa: fix boringFakeRandomBlind to work with (*big.Int).ModInverse + 2018-05-17a3f9ce3313[dev.boringcrypto] all: merge master into dev.boringcrypto + 2018-02-09528dad8c72[dev.cryptoboring] misc/boring: update README for Bazel + 2018-02-06c3d83ee31c[dev.boringcrypto] misc/boring: add go1.9.3b4 to RELEASES + 2017-12-13f62a24349d[dev.boringcrypto] all: merge go1.10beta1 into dev.boringcrypto + 2017-12-063e52f22ece[dev.boringcrypto] crypto/internal/boring: add MarshalBinary/UnmarshalBinary to hashes + 2017-12-065379f7847f[dev.boringcrypto] all: merge master (more nearly Go 1.10 beta 1) into dev.boringcrypto + 2017-12-06185e6094fd[dev.boringcrypto] all: merge master (nearly Go 1.10 beta 1) into dev.boringcrypto + 2017-11-20c36033a379[dev.boringcrypto] misc/boring: add go1.9.2b4 release + 2017-11-20cda3c6f91d[dev.boringcrypto] all: merge go1.9.2 into dev.boringcrypto + 2017-10-252ea7d3461b[release-branch.go1.9] go1.9.2 + 2017-10-25d93cb46280[release-branch.go1.9] runtime: use simple, more robust fastrandn + 2017-10-2578952c06c5[release-branch.go1.9] cmd/compile: fix sign-extension merging rules + 2017-10-2579996e4a1d[release-branch.go1.9] cmd/compile: avoid generating large offsets + 2017-10-25f36b12657c[release-branch.go1.9] runtime: in cpuProfile.addExtra, set p.lostExtra to 0 after flush + 2017-10-25dffc9319f1[release-branch.go1.9] cmd/cgo: support large unsigned macro again + 2017-10-2533ce1682c7[release-branch.go1.9] cmd/cgo: avoid using common names for sniffing + 2017-10-25f69668e1d0[release-branch.go1.9] os: skip TestPipeThreads as flaky for 1.9 + 2017-10-259be38a15e4[release-branch.go1.9] runtime: avoid monotonic time zero on systems with low-res timers + 2017-10-258bb333a9c0[release-branch.go1.9] doc: document Go 1.9.2 + 2017-10-250758d2b9da[release-branch.go1.9] cmd/go: clean up x.exe properly in TestImportMain + 2017-10-25d487b15a61[release-branch.go1.9] cmd/compile: omit ICE diagnostics after normal error messages + 2017-10-25fd17253587[release-branch.go1.9] database/sql: prevent race in driver by locking dc in Next + 2017-10-257e7cb30475[release-branch.go1.9] internal/poll: only call SetFileCompletionNotificationModes for sockets + 2017-10-25f259aed082[release-branch.go1.9] internal/poll: do not call SetFileCompletionNotificationModes if it is broken + 2017-10-2539d4bb9c0f[release-branch.go1.9] cmd/go: correct directory used in checkNestedVCS test + 2017-10-25bfc22319aa[release-branch.go1.9] crypto/x509: reject intermediates with unknown critical extensions. + 2017-10-25a1e34abfb3[release-branch.go1.9] net/smtp: NewClient: set tls field to true when already using a TLS connection + 2017-10-257dadd8d517[release-branch.go1.9] net: increase expected time to dial a closed port on all Darwin ports + 2017-10-25d80889341c[release-branch.go1.9] cmd/compile: fix merge rules for panic calls + 2017-10-2587b3a27839[release-branch.go1.9] net: bump TestDialerDualStackFDLeak timeout on iOS + 2017-10-25ebfcdef901[release-branch.go1.9] runtime: make runtime.GC() trigger GC even if GOGC=off + 2017-10-250ab99b396d[release-branch.go1.9] cmd/compile: fix regression in PPC64.rules move zero + 2017-10-258d4279c111[release-branch.go1.9] internal/poll: be explicit when using runtime netpoller + 2017-10-251ded8334f7[release-branch.go1.9] cmd/compile/internal/syntax: fix source buffer refilling + 2017-10-25ff8289f879[release-branch.go1.9] reflect: fix pointer past-the-end in Call with zero-sized return value + 2017-10-25bd34e74134[release-branch.go1.9] log: fix data race on log.Output + 2017-10-250b55d8dbfc[release-branch.go1.9] cmd/compile: replace GOROOT in //line directives + 2017-10-255c48811aec[release-branch.go1.9] cmd/compile: limit the number of simultaneously opened files to avoid EMFILE/ENFILE errors + 2017-10-258c7fa95ad3[release-branch.go1.9] expvar: make (*Map).Init clear existing keys + 2017-10-25ccd5abc105[release-branch.go1.9] cmd/compile: simplify "missing function body" error message + 2017-10-252e4358c960[release-branch.go1.9] time: fix documentation of Round, Truncate behavior for d <= 0 + 2017-10-25c6388d381e[release-branch.go1.9] runtime: capture runtimeInitTime after nanotime is initialized + 2017-10-25724638c9d8[release-branch.go1.9] crypto/x509: skip TestSystemRoots + 2017-10-25ed3b0d63b7[release-branch.go1.9] internal/poll: add tests for Windows file and serial ports + 2017-10-0493322a5b3d[release-branch.go1.9] doc: add missing "Minor revisions" header for 1.9 + 2017-10-047f40c1214d[release-branch.go1.9] go1.9.1 + 2017-10-04598433b17a[release-branch.go1.9] doc: document go1.9.1 and go1.8.4 + 2017-10-04815cad3ed0[release-branch.go1.9] doc/1.9: add mention of net/http.LocalAddrContextKey + 2017-10-041900d34a10[release-branch.go1.9] net/smtp: fix PlainAuth to refuse to send passwords to non-TLS servers + 2017-10-04a39bcecea6[release-branch.go1.9] cmd/go: reject update of VCS inside VCS + 2017-10-04d9e64910af[release-branch.go1.9] runtime: deflake TestPeriodicGC + 2017-09-28adc1f587ac[dev.boringcrypto] misc/boring: add src releases + 2017-09-254038503543[dev.boringcrypto] misc/boring: add go1.8.3b4 + 2017-09-25d724c60b4d[dev.boringcrypto] misc/boring: update README + 2017-09-2270bada9db3[dev.boringcrypto] misc/boring: add go1.9b4 release + 2017-09-22e6ad24cde7[dev.boringcrypto] all: merge go1.9 into dev.boringcrypto + 2017-09-22431e071eed[dev.boringcrypto] misc/boring: add go1.9rc2b4 release + 2017-09-22cc6e26b2e1[dev.boringcrypto] api: add crypto/x509.VerifyOptions.IsBoring to make release builder happy + 2017-09-22bac02b14b5[dev.boringcrypto] misc/boring: update VERSION + 2017-09-223ed08db261[dev.boringcrypto] crypto/tls/fipsonly: new package to force FIPS-allowed TLS settings + 2017-09-202ba76155cd[dev.boringcrypto] crypto/internal/boring: fix finalizer-induced crashes + 2017-09-1832dc9b247f[dev.boringcrypto] cmd/go: exclude SysoFiles when using -msan + 2017-09-189f025cbdeb[dev.boringcrypto] crypto/internal/boring: fall back to standard crypto when using -msan + 2017-09-1889ba9e3541[dev.boringcrypto] crypto/aes: panic on invalid dst, src overlap + 2017-09-18a929f3a04d[dev.boringcrypto] crypto/rsa: fix boring GenerateKey to set non-nil Precomputed.CRTValues + 2017-09-18aa4a4a80ff[dev.boringcrypto] crypto/internal/boring: fix detection of tests to allow *.test and *_test + 2017-09-18c9e2d9eb06[dev.boringcrypto] crypto/rsa: add test for, fix observable reads from custom randomness + 2017-09-18e773ea9aa3[dev.boringcrypto] crypto/hmac: add test for Write/Sum after Sum + 2017-09-188fa8f42cb3[dev.boringcrypto] crypto/internal/boring: allow hmac operations after Sum + 2017-09-1807f6ce9d39[dev.boringcrypto] crypto/internal/boring: handle RSA verification of short signatures + 2017-09-14e8eec3fbdb[dev.boringcrypto] cmd/compile: refine BoringCrypto kludge + 2017-08-307b49445d0f[dev.boringcrypto] cmd/compile: hide new boring fields from reflection + 2017-08-3081b9d733b0[dev.boringcrypto] crypto/hmac: test empty key + 2017-08-30f6358bdb6c[dev.boringcrypto] crypto/internal/boring: fix NewHMAC with empty key + 2017-08-309c307d8039[dev.boringcrypto] crypto/internal/cipherhw: fix AESGCMSupport for BoringCrypto + 2017-08-26f48a9fb815[dev.boringcrypto] misc/boring: release packaging + 2017-08-2594fb8224b2[dev.boringcrypto] crypto/internal/boring: disable for android & non-cgo builds + 2017-08-257ff9fcafbd[dev.boringcrypto] crypto/internal/boring: clear "executable stack" bit from syso + 2017-08-24c8aec4095e[release-branch.go1.9] go1.9 + 2017-08-24b8c9ef9f09[release-branch.go1.9] doc: add go1.9 to golang.org/project + 2017-08-24136f4a6b2a[release-branch.go1.9] doc: document go1.9 + 2017-08-24867be4c60c[release-branch.go1.9] doc/go1.9: fix typo in Moved GOROOT + 2017-08-24d1351fbc31[dev.boringcrypto] cmd/link: allow internal linking for crypto/internal/boring + 2017-08-24991652dcf0[dev.boringcrypto] cmd/link: work around DWARF symbol bug + 2017-08-229a4e7942ea[release-branch.go1.9] cmd/compile: remove gc.Sysfunc calls from 387 backend + 2017-08-22ff38035a62[release-branch.go1.9] doc/go1.9: fix typo in crypto/x509 of "Minor changes to the library". + 2017-08-197e9e3a06cb[dev.boringcrypto] crypto/rsa: use BoringCrypto + 2017-08-19bc38fda367[dev.boringcrypto] crypto/ecdsa: use unsafe.Pointer instead of atomic.Value + 2017-08-1842046e8989[release-branch.go1.9] runtime: fix false positive race in profile label reading + 2017-08-18fbf7e1f295[release-branch.go1.9] testing: don't fail all tests after racy test failure + 2017-08-1821312a4b5e[release-branch.go1.9] cmd/dist: update deps.go for current dependencies + 2017-08-185927854f7d[release-branch.go1.9] cmd/compile: add rules handling unsigned div/mod by constant 1<<63 + 2017-08-1865717b2dca[release-branch.go1.9] runtime: fix usleep by correctly setting nanoseconds parameter for pselect6 + 2017-08-17b1f201e951[dev.boringcrypto] crypto/ecdsa: use BoringCrypto + 2017-08-172efded1cd2[dev.boringcrypto] crypto/tls: use TLS-specific AES-GCM mode if available + 2017-08-17335a0f87bf[dev.boringcrypto] crypto/aes: implement TLS-specific AES-GCM mode from BoringCrypto + 2017-08-178d05ec9e58[dev.boringcrypto] crypto/aes: use BoringCrypto + 2017-08-1774e33c43e9[dev.boringcrypto] crypto/hmac: use BoringCrypto + 2017-08-1796d6718e4f[dev.boringcrypto] crypto/sha1,sha256,sha512: use BoringCrypto + 2017-08-17e0e2bbdd00[dev.boringcrypto] runtime/race: move TestRaceIssue5567 from sha1 to crc32 + 2017-08-17fe02ba30f1[dev.boringcrypto] crypto/rand: use BoringCrypto + 2017-08-176e70f88f84[dev.boringcrypto] crypto/internal/boring: add initial BoringCrypto access + 2017-08-16dcdcc38440[dev.boringcrypto] add README.boringcrypto.md, update VERSION + 2017-08-1619b89a22df[dev.boringcrypto] cmd/link: implement R_X86_64_PC64 relocations + 2017-08-07048c9cfaac[release-branch.go1.9] go1.9rc2 + 2017-08-07cff0de3da3[release-branch.go1.9] all: merge master into release-branch.go1.9 + 2017-07-31196492a299[release-branch.go1.9] runtime: map bitmap and spans during heap initialization + 2017-07-311a6d87d4bf[release-branch.go1.9] runtime: fall back to small mmaps if we fail to grow reservation + 2017-07-277320506bc5[release-branch.go1.9] cmd/dist: skip moved GOROOT on Go's Windows builders when not sharding tests + 2017-07-2465c6c88a94[release-branch.go1.9] go1.9rc1 + 2017-07-24fbc9b49790[release-branch.go1.9] cmd/compile: consider exported flag in namedata Change-Id: I5344e8e4813a9a0900f6633499a3ddf22895a4d5
This commit is contained in:
commit
f771edd7f9
112 changed files with 7065 additions and 110 deletions
|
|
@ -57,7 +57,7 @@ func runWithEnv(t *testing.T, msg string, env []string, args ...string) {
|
|||
func goCmd(t *testing.T, args ...string) string {
|
||||
newargs := []string{args[0]}
|
||||
if *testX && args[0] != "env" {
|
||||
newargs = append(newargs, "-x")
|
||||
newargs = append(newargs, "-x", "-ldflags=-v")
|
||||
}
|
||||
newargs = append(newargs, args[1:]...)
|
||||
c := exec.Command("go", newargs...)
|
||||
|
|
|
|||
17
src/cmd/api/goapi_boring_test.go
Normal file
17
src/cmd/api/goapi_boring_test.go
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright 2022 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.
|
||||
|
||||
//go:build boringcrypto
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
func init() {
|
||||
fmt.Printf("SKIP with boringcrypto enabled\n")
|
||||
os.Exit(0)
|
||||
}
|
||||
|
|
@ -11,7 +11,6 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"flag"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
|
|
@ -28,6 +27,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"cmd/internal/edit"
|
||||
"cmd/internal/notsha256"
|
||||
"cmd/internal/objabi"
|
||||
)
|
||||
|
||||
|
|
@ -331,8 +331,8 @@ func main() {
|
|||
// we use to coordinate between gcc and ourselves.
|
||||
// We already put _cgo_ at the beginning, so the main
|
||||
// concern is other cgo wrappers for the same functions.
|
||||
// Use the beginning of the md5 of the input to disambiguate.
|
||||
h := md5.New()
|
||||
// Use the beginning of the notsha256 of the input to disambiguate.
|
||||
h := notsha256.New()
|
||||
io.WriteString(h, *importPath)
|
||||
fs := make([]*File, len(goFiles))
|
||||
for i, input := range goFiles {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,10 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// When using GOEXPERIMENT=boringcrypto, the test program links in the boringcrypto syso,
|
||||
// which does not respect GOAMD64, so we skip the test if boringcrypto is enabled.
|
||||
//go:build !boringcrypto
|
||||
|
||||
package amd64_test
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@
|
|||
package liveness
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"fmt"
|
||||
"os"
|
||||
"sort"
|
||||
|
|
@ -30,6 +29,7 @@ import (
|
|||
"cmd/compile/internal/ssa"
|
||||
"cmd/compile/internal/typebits"
|
||||
"cmd/compile/internal/types"
|
||||
"cmd/internal/notsha256"
|
||||
"cmd/internal/obj"
|
||||
"cmd/internal/objabi"
|
||||
"cmd/internal/src"
|
||||
|
|
@ -959,7 +959,7 @@ func (lv *liveness) enableClobber() {
|
|||
// Clobber only functions where the hash of the function name matches a pattern.
|
||||
// Useful for binary searching for a miscompiled function.
|
||||
hstr := ""
|
||||
for _, b := range sha1.Sum([]byte(lv.f.Name)) {
|
||||
for _, b := range notsha256.Sum256([]byte(lv.f.Name)) {
|
||||
hstr += fmt.Sprintf("%08b", b)
|
||||
}
|
||||
if !strings.HasSuffix(hstr, h) {
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ import (
|
|||
"cmd/compile/internal/abi"
|
||||
"cmd/compile/internal/base"
|
||||
"cmd/compile/internal/types"
|
||||
"cmd/internal/notsha256"
|
||||
"cmd/internal/src"
|
||||
"crypto/sha1"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
|
|
@ -854,7 +854,7 @@ func (f *Func) DebugHashMatch(evname string) bool {
|
|||
// We use this feature to do a binary search to
|
||||
// find a function that is incorrectly compiled.
|
||||
hstr := ""
|
||||
for _, b := range sha1.Sum([]byte(name)) {
|
||||
for _, b := range notsha256.Sum256([]byte(name)) {
|
||||
hstr += fmt.Sprintf("%08b", b)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,10 +6,11 @@ package ssa
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"cmd/internal/src"
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"cmd/internal/notsha256"
|
||||
"cmd/internal/src"
|
||||
)
|
||||
|
||||
func printFunc(f *Func) {
|
||||
|
|
@ -17,7 +18,7 @@ func printFunc(f *Func) {
|
|||
}
|
||||
|
||||
func hashFunc(f *Func) []byte {
|
||||
h := sha256.New()
|
||||
h := notsha256.New()
|
||||
p := stringFuncPrinter{w: h, printDead: true}
|
||||
fprintFunc(p, f)
|
||||
return h.Sum(nil)
|
||||
|
|
@ -32,7 +33,7 @@ func (f *Func) String() string {
|
|||
|
||||
// rewriteHash returns a hash of f suitable for detecting rewrite cycles.
|
||||
func (f *Func) rewriteHash() string {
|
||||
h := sha256.New()
|
||||
h := notsha256.New()
|
||||
p := stringFuncPrinter{w: h, printDead: false}
|
||||
fprintFunc(p, f)
|
||||
return fmt.Sprintf("%x", h.Sum(nil))
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
package staticdata
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"go/constant"
|
||||
"io"
|
||||
|
|
@ -20,6 +19,7 @@ import (
|
|||
"cmd/compile/internal/objw"
|
||||
"cmd/compile/internal/typecheck"
|
||||
"cmd/compile/internal/types"
|
||||
"cmd/internal/notsha256"
|
||||
"cmd/internal/obj"
|
||||
"cmd/internal/objabi"
|
||||
"cmd/internal/src"
|
||||
|
|
@ -73,7 +73,7 @@ func StringSym(pos src.XPos, s string) (data *obj.LSym) {
|
|||
// Indulge in some paranoia by writing the length of s, too,
|
||||
// as protection against length extension attacks.
|
||||
// Same pattern is known to fileStringSym below.
|
||||
h := sha256.New()
|
||||
h := notsha256.New()
|
||||
io.WriteString(h, s)
|
||||
symname = fmt.Sprintf(stringSymPattern, len(s), h.Sum(nil))
|
||||
} else {
|
||||
|
|
@ -131,7 +131,7 @@ func fileStringSym(pos src.XPos, file string, readonly bool, hash []byte) (*obj.
|
|||
sym = slicedata(pos, string(data)).Linksym()
|
||||
}
|
||||
if len(hash) > 0 {
|
||||
sum := sha256.Sum256(data)
|
||||
sum := notsha256.Sum256(data)
|
||||
copy(hash, sum[:])
|
||||
}
|
||||
return sym, size, nil
|
||||
|
|
@ -148,7 +148,7 @@ func fileStringSym(pos src.XPos, file string, readonly bool, hash []byte) (*obj.
|
|||
// Compute hash if needed for read-only content hashing or if the caller wants it.
|
||||
var sum []byte
|
||||
if readonly || len(hash) > 0 {
|
||||
h := sha256.New()
|
||||
h := notsha256.New()
|
||||
n, err := io.Copy(h, f)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
|
|
|
|||
|
|
@ -236,7 +236,6 @@ package typecheck
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"go/constant"
|
||||
|
|
@ -250,6 +249,7 @@ import (
|
|||
"cmd/compile/internal/ir"
|
||||
"cmd/compile/internal/types"
|
||||
"cmd/internal/goobj"
|
||||
"cmd/internal/notsha256"
|
||||
"cmd/internal/src"
|
||||
)
|
||||
|
||||
|
|
@ -353,7 +353,7 @@ func WriteExports(out io.Writer, extensions bool) {
|
|||
hdr.uint64(dataLen)
|
||||
|
||||
// Flush output.
|
||||
h := md5.New()
|
||||
h := notsha256.New()
|
||||
wr := io.MultiWriter(out, h)
|
||||
io.Copy(wr, &hdr)
|
||||
io.Copy(wr, &p.strings)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ package types
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"go/constant"
|
||||
|
|
@ -15,6 +14,7 @@ import (
|
|||
"sync"
|
||||
|
||||
"cmd/compile/internal/base"
|
||||
"cmd/internal/notsha256"
|
||||
)
|
||||
|
||||
// BuiltinPkg is a fake package that declares the universe block.
|
||||
|
|
@ -771,7 +771,7 @@ func FmtConst(v constant.Value, sharp bool) string {
|
|||
func TypeHash(t *Type) uint32 {
|
||||
p := tconv(t, 0, fmtTypeIDHash)
|
||||
|
||||
// Using MD5 is overkill, but reduces accidental collisions.
|
||||
h := md5.Sum([]byte(p))
|
||||
// Using SHA256 is overkill, but reduces accidental collisions.
|
||||
h := notsha256.Sum256([]byte(p))
|
||||
return binary.LittleEndian.Uint32(h[:4])
|
||||
}
|
||||
|
|
|
|||
1
src/cmd/dist/buildtool.go
vendored
1
src/cmd/dist/buildtool.go
vendored
|
|
@ -44,6 +44,7 @@ var bootstrapDirs = []string{
|
|||
"cmd/internal/edit",
|
||||
"cmd/internal/gcprog",
|
||||
"cmd/internal/goobj",
|
||||
"cmd/internal/notsha256",
|
||||
"cmd/internal/obj/...",
|
||||
"cmd/internal/objabi",
|
||||
"cmd/internal/pkgpath",
|
||||
|
|
|
|||
22
src/cmd/go/go_boring_test.go
Normal file
22
src/cmd/go/go_boring_test.go
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
// 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.
|
||||
|
||||
//go:build boringcrypto
|
||||
|
||||
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"))
|
||||
}
|
||||
|
|
@ -1903,8 +1903,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()
|
||||
|
|
@ -1923,6 +1927,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.
|
||||
|
|
|
|||
|
|
@ -401,6 +401,12 @@ func (p *Package) copyBuild(opts PackageOpts, 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
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import (
|
|||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
|
@ -2993,7 +2994,26 @@ func (b *Builder) dynimport(a *Action, p *load.Package, objdir, importGo, cgoExe
|
|||
return err
|
||||
}
|
||||
|
||||
linkobj := str.StringList(ofile, outObj, mkAbsFiles(p.Dir, p.SysoFiles))
|
||||
// Gather .syso files from this package and all (transitive) dependencies.
|
||||
var syso []string
|
||||
seen := make(map[*Action]bool)
|
||||
var gatherSyso func(*Action)
|
||||
gatherSyso = func(a1 *Action) {
|
||||
if seen[a1] {
|
||||
return
|
||||
}
|
||||
seen[a1] = true
|
||||
if p1 := a1.Package; p1 != nil {
|
||||
syso = append(syso, mkAbsFiles(p1.Dir, p1.SysoFiles)...)
|
||||
}
|
||||
for _, a2 := range a1.Deps {
|
||||
gatherSyso(a2)
|
||||
}
|
||||
}
|
||||
gatherSyso(a)
|
||||
sort.Strings(syso)
|
||||
str.Uniq(&syso)
|
||||
linkobj := str.StringList(ofile, outObj, syso)
|
||||
dynobj := objdir + "_cgo_.o"
|
||||
|
||||
ldflags := cgoLDFLAGS
|
||||
|
|
|
|||
54
src/cmd/go/testdata/script/link_syso_deps.txt
vendored
Normal file
54
src/cmd/go/testdata/script/link_syso_deps.txt
vendored
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
# Test that syso in deps is available to cgo.
|
||||
|
||||
[!gc] skip
|
||||
[!cgo] skip
|
||||
|
||||
# External linking is not supported on linux/ppc64.
|
||||
# See: https://github.com/golang/go/issues/8912
|
||||
[linux] [ppc64] skip
|
||||
|
||||
cc -c -o syso/x.syso syso/x.c
|
||||
cc -c -o syso2/x.syso syso2/x.c
|
||||
go build m/cgo
|
||||
|
||||
-- go.mod --
|
||||
module m
|
||||
|
||||
go 1.18
|
||||
-- cgo/x.go --
|
||||
package cgo
|
||||
|
||||
// extern void f(void);
|
||||
// extern void g(void);
|
||||
import "C"
|
||||
|
||||
func F() {
|
||||
C.f()
|
||||
}
|
||||
|
||||
func G() {
|
||||
C.g()
|
||||
}
|
||||
|
||||
-- cgo/x2.go --
|
||||
package cgo
|
||||
|
||||
import _ "m/syso"
|
||||
|
||||
-- syso/x.c --
|
||||
//go:build ignore
|
||||
|
||||
void f() {}
|
||||
|
||||
-- syso/x.go --
|
||||
package syso
|
||||
|
||||
import _ "m/syso2"
|
||||
|
||||
-- syso2/x.c --
|
||||
//go:build ignore
|
||||
|
||||
void g() {}
|
||||
|
||||
-- syso2/x.go --
|
||||
package syso2
|
||||
|
|
@ -11,10 +11,11 @@
|
|||
package codesign
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"debug/macho"
|
||||
"encoding/binary"
|
||||
"io"
|
||||
|
||||
"cmd/internal/notsha256"
|
||||
)
|
||||
|
||||
// Code signature layout.
|
||||
|
|
@ -190,7 +191,7 @@ func Size(codeSize int64, id string) int64 {
|
|||
nhashes := (codeSize + pageSize - 1) / pageSize
|
||||
idOff := int64(codeDirectorySize)
|
||||
hashOff := idOff + int64(len(id)+1)
|
||||
cdirSz := hashOff + nhashes*sha256.Size
|
||||
cdirSz := hashOff + nhashes*notsha256.Size
|
||||
return int64(superBlobSize+blobSize) + cdirSz
|
||||
}
|
||||
|
||||
|
|
@ -226,7 +227,7 @@ func Sign(out []byte, data io.Reader, id string, codeSize, textOff, textSize int
|
|||
identOffset: uint32(idOff),
|
||||
nCodeSlots: uint32(nhashes),
|
||||
codeLimit: uint32(codeSize),
|
||||
hashSize: sha256.Size,
|
||||
hashSize: notsha256.Size,
|
||||
hashType: CS_HASHTYPE_SHA256,
|
||||
pageSize: uint8(pageSizeBits),
|
||||
execSegBase: uint64(textOff),
|
||||
|
|
@ -245,8 +246,12 @@ func Sign(out []byte, data io.Reader, id string, codeSize, textOff, textSize int
|
|||
outp = puts(outp, []byte(id+"\000"))
|
||||
|
||||
// emit hashes
|
||||
// NOTE(rsc): These must be SHA256, but for cgo bootstrap reasons
|
||||
// we cannot import crypto/sha256 when GOEXPERIMENT=boringcrypto
|
||||
// and the host is linux/amd64. So we use NOT-SHA256
|
||||
// and then apply a NOT ourselves to get SHA256. Sigh.
|
||||
var buf [pageSize]byte
|
||||
h := sha256.New()
|
||||
h := notsha256.New()
|
||||
p := 0
|
||||
for p < int(codeSize) {
|
||||
n, err := io.ReadFull(data, buf[:])
|
||||
|
|
@ -263,6 +268,9 @@ func Sign(out []byte, data io.Reader, id string, codeSize, textOff, textSize int
|
|||
h.Reset()
|
||||
h.Write(buf[:n])
|
||||
b := h.Sum(nil)
|
||||
for i := range b {
|
||||
b[i] ^= 0xFF // convert notsha256 to sha256
|
||||
}
|
||||
outp = puts(outp, b[:])
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ package goobj
|
|||
|
||||
import (
|
||||
"cmd/internal/bio"
|
||||
"crypto/sha1"
|
||||
"cmd/internal/notsha256"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
|
@ -367,7 +367,7 @@ const Hash64Size = 8
|
|||
// Hash
|
||||
type HashType [HashSize]byte
|
||||
|
||||
const HashSize = sha1.Size
|
||||
const HashSize = notsha256.Size
|
||||
|
||||
// Relocation.
|
||||
//
|
||||
|
|
|
|||
41
src/cmd/internal/notsha256/example_test.go
Normal file
41
src/cmd/internal/notsha256/example_test.go
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
// Copyright 2016 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 notsha256_test
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
func ExampleSum256() {
|
||||
sum := sha256.Sum256([]byte("hello world\n"))
|
||||
fmt.Printf("%x", sum)
|
||||
// Output: a948904f2f0f479b8f8197694b30184b0d2ed1c1cd2a1ec0fb85d299a192a447
|
||||
}
|
||||
|
||||
func ExampleNew() {
|
||||
h := sha256.New()
|
||||
h.Write([]byte("hello world\n"))
|
||||
fmt.Printf("%x", h.Sum(nil))
|
||||
// Output: a948904f2f0f479b8f8197694b30184b0d2ed1c1cd2a1ec0fb85d299a192a447
|
||||
}
|
||||
|
||||
func ExampleNew_file() {
|
||||
f, err := os.Open("file.txt")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
h := sha256.New()
|
||||
if _, err := io.Copy(h, f); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Printf("%x", h.Sum(nil))
|
||||
}
|
||||
141
src/cmd/internal/notsha256/sha256.go
Normal file
141
src/cmd/internal/notsha256/sha256.go
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
// 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.
|
||||
|
||||
// Package notsha256 implements the NOTSHA256 algorithm,
|
||||
// a hash defined as bitwise NOT of SHA256.
|
||||
// It is used in situations where exact fidelity to SHA256 is unnecessary.
|
||||
// In particular, it is used in the compiler toolchain,
|
||||
// which cannot depend directly on cgo when GOEXPERIMENT=boringcrypto
|
||||
// (and in that mode the real sha256 uses cgo).
|
||||
package notsha256
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"hash"
|
||||
)
|
||||
|
||||
// The size of a checksum in bytes.
|
||||
const Size = 32
|
||||
|
||||
// The blocksize in bytes.
|
||||
const BlockSize = 64
|
||||
|
||||
const (
|
||||
chunk = 64
|
||||
init0 = 0x6A09E667
|
||||
init1 = 0xBB67AE85
|
||||
init2 = 0x3C6EF372
|
||||
init3 = 0xA54FF53A
|
||||
init4 = 0x510E527F
|
||||
init5 = 0x9B05688C
|
||||
init6 = 0x1F83D9AB
|
||||
init7 = 0x5BE0CD19
|
||||
)
|
||||
|
||||
// digest represents the partial evaluation of a checksum.
|
||||
type digest struct {
|
||||
h [8]uint32
|
||||
x [chunk]byte
|
||||
nx int
|
||||
len uint64
|
||||
}
|
||||
|
||||
func (d *digest) Reset() {
|
||||
d.h[0] = init0
|
||||
d.h[1] = init1
|
||||
d.h[2] = init2
|
||||
d.h[3] = init3
|
||||
d.h[4] = init4
|
||||
d.h[5] = init5
|
||||
d.h[6] = init6
|
||||
d.h[7] = init7
|
||||
d.nx = 0
|
||||
d.len = 0
|
||||
}
|
||||
|
||||
// New returns a new hash.Hash computing the NOTSHA256 checksum.
|
||||
// state of the hash.
|
||||
func New() hash.Hash {
|
||||
d := new(digest)
|
||||
d.Reset()
|
||||
return d
|
||||
}
|
||||
|
||||
func (d *digest) Size() int {
|
||||
return Size
|
||||
}
|
||||
|
||||
func (d *digest) BlockSize() int { return BlockSize }
|
||||
|
||||
func (d *digest) Write(p []byte) (nn int, err error) {
|
||||
nn = len(p)
|
||||
d.len += uint64(nn)
|
||||
if d.nx > 0 {
|
||||
n := copy(d.x[d.nx:], p)
|
||||
d.nx += n
|
||||
if d.nx == chunk {
|
||||
block(d, d.x[:])
|
||||
d.nx = 0
|
||||
}
|
||||
p = p[n:]
|
||||
}
|
||||
if len(p) >= chunk {
|
||||
n := len(p) &^ (chunk - 1)
|
||||
block(d, p[:n])
|
||||
p = p[n:]
|
||||
}
|
||||
if len(p) > 0 {
|
||||
d.nx = copy(d.x[:], p)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (d *digest) Sum(in []byte) []byte {
|
||||
// Make a copy of d so that caller can keep writing and summing.
|
||||
d0 := *d
|
||||
hash := d0.checkSum()
|
||||
return append(in, hash[:]...)
|
||||
}
|
||||
|
||||
func (d *digest) checkSum() [Size]byte {
|
||||
len := d.len
|
||||
// Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
|
||||
var tmp [64]byte
|
||||
tmp[0] = 0x80
|
||||
if len%64 < 56 {
|
||||
d.Write(tmp[0 : 56-len%64])
|
||||
} else {
|
||||
d.Write(tmp[0 : 64+56-len%64])
|
||||
}
|
||||
|
||||
// Length in bits.
|
||||
len <<= 3
|
||||
binary.BigEndian.PutUint64(tmp[:], len)
|
||||
d.Write(tmp[0:8])
|
||||
|
||||
if d.nx != 0 {
|
||||
panic("d.nx != 0")
|
||||
}
|
||||
|
||||
var digest [Size]byte
|
||||
|
||||
binary.BigEndian.PutUint32(digest[0:], d.h[0]^0xFFFFFFFF)
|
||||
binary.BigEndian.PutUint32(digest[4:], d.h[1]^0xFFFFFFFF)
|
||||
binary.BigEndian.PutUint32(digest[8:], d.h[2]^0xFFFFFFFF)
|
||||
binary.BigEndian.PutUint32(digest[12:], d.h[3]^0xFFFFFFFF)
|
||||
binary.BigEndian.PutUint32(digest[16:], d.h[4]^0xFFFFFFFF)
|
||||
binary.BigEndian.PutUint32(digest[20:], d.h[5]^0xFFFFFFFF)
|
||||
binary.BigEndian.PutUint32(digest[24:], d.h[6]^0xFFFFFFFF)
|
||||
binary.BigEndian.PutUint32(digest[28:], d.h[7]^0xFFFFFFFF)
|
||||
|
||||
return digest
|
||||
}
|
||||
|
||||
// Sum256 returns the SHA256 checksum of the data.
|
||||
func Sum256(data []byte) [Size]byte {
|
||||
var d digest
|
||||
d.Reset()
|
||||
d.Write(data)
|
||||
return d.checkSum()
|
||||
}
|
||||
175
src/cmd/internal/notsha256/sha256_test.go
Normal file
175
src/cmd/internal/notsha256/sha256_test.go
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
// 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.
|
||||
|
||||
// SHA256 hash algorithm. See FIPS 180-2.
|
||||
|
||||
package notsha256
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type sha256Test struct {
|
||||
out string
|
||||
in string
|
||||
unused string // marshal state, to keep table in sync with crypto/sha256
|
||||
}
|
||||
|
||||
var golden = []sha256Test{
|
||||
{"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
|
||||
{"ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", "a", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"},
|
||||
{"fb8e20fc2e4c3f248c60c39bd652f3c1347298bb977b8b4d5903b85055620603", "ab", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"},
|
||||
{"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", "abc", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"},
|
||||
{"88d4266fd4e6338d13b845fcf289579d209c897823b9217da3e161936f031589", "abcd", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19ab\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02"},
|
||||
{"36bbe50ed96841d10443bcb670d6554f0a34b761be67ec9c4a8ad2c0c44ca42c", "abcde", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19ab\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02"},
|
||||
{"bef57ec7f53a6d40beb640a780a639c83bc29ac8a9816f1fc6c5c6dcd93c4721", "abcdef", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19abc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03"},
|
||||
{"7d1a54127b222502f5b79b5fb0803061152a44f92b37e23c6527baf665d4da9a", "abcdefg", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19abc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03"},
|
||||
{"9c56cc51b374c3ba189210d5b6d4bf57790d351c96c47c02190ecf1e430635ab", "abcdefgh", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19abcd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04"},
|
||||
{"19cc02f26df43cc571bc9ed7b0c4d29224a3ec229529221725ef76d021c8326f", "abcdefghi", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19abcd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04"},
|
||||
{"72399361da6a7754fec986dca5b7cbaf1c810a28ded4abaf56b2106d06cb78b0", "abcdefghij", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19abcde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05"},
|
||||
{"a144061c271f152da4d151034508fed1c138b8c976339de229c3bb6d4bbb4fce", "Discard medicine more than two years old.", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19Discard medicine mor\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14"},
|
||||
{"6dae5caa713a10ad04b46028bf6dad68837c581616a1589a265a11288d4bb5c4", "He who has a shady past knows that nice guys finish last.", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19He who has a shady past know\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c"},
|
||||
{"ae7a702a9509039ddbf29f0765e70d0001177914b86459284dab8b348c2dce3f", "I wouldn't marry him with a ten foot pole.", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19I wouldn't marry him \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15"},
|
||||
{"6748450b01c568586715291dfa3ee018da07d36bb7ea6f180c1af6270215c64f", "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19Free! Free!/A trip/to Mars/f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c"},
|
||||
{"14b82014ad2b11f661b5ae6a99b75105c2ffac278cd071cd6c05832793635774", "The days of the digital watch are numbered. -Tom Stoppard", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19The days of the digital watch\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d"},
|
||||
{"7102cfd76e2e324889eece5d6c41921b1e142a4ac5a2692be78803097f6a48d8", "Nepal premier won't resign.", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19Nepal premier\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r"},
|
||||
{"23b1018cd81db1d67983c5f7417c44da9deb582459e378d7a068552ea649dc9f", "For every action there is an equal and opposite government program.", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19For every action there is an equa\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00!"},
|
||||
{"8001f190dfb527261c4cfcab70c98e8097a7a1922129bc4096950e57c7999a5a", "His money is twice tainted: 'taint yours and 'taint mine.", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19His money is twice tainted: \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c"},
|
||||
{"8c87deb65505c3993eb24b7a150c4155e82eee6960cf0c3a8114ff736d69cad5", "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19There is no reason for any individual to hav\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,"},
|
||||
{"bfb0a67a19cdec3646498b2e0f751bddc41bba4b7f30081b0b932aad214d16d7", "It's a tiny change to the code and not completely disgusting. - Bob Manchek", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19It's a tiny change to the code and no\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%"},
|
||||
{"7f9a0b9bf56332e19f5a0ec1ad9c1425a153da1c624868fda44561d6b74daf36", "size: a.out: bad magic", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19size: a.out\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\f"},
|
||||
{"b13f81b8aad9e3666879af19886140904f7f429ef083286195982a7588858cfc", "The major problem is with sendmail. -Mark Horton", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19The major problem is wit\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18"},
|
||||
{"b26c38d61519e894480c70c8374ea35aa0ad05b2ae3d6674eec5f52a69305ed4", "Give me a rock, paper and scissors and I will move the world. CCFestoon", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19Give me a rock, paper and scissors a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$"},
|
||||
{"049d5e26d4f10222cd841a119e38bd8d2e0d1129728688449575d4ff42b842c1", "If the enemy is within range, then so are you.", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19If the enemy is within \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17"},
|
||||
{"0e116838e3cc1c1a14cd045397e29b4d087aa11b0853fc69ec82e90330d60949", "It's well we cannot hear the screams/That we create in others' dreams.", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19It's well we cannot hear the scream\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00#"},
|
||||
{"4f7d8eb5bcf11de2a56b971021a444aa4eafd6ecd0f307b5109e4e776cd0fe46", "You remind me of a TV show, but that's all right: I watch it anyway.", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19You remind me of a TV show, but th\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\""},
|
||||
{"61c0cc4c4bd8406d5120b3fb4ebc31ce87667c162f29468b3c779675a85aebce", "C is as portable as Stonehedge!!", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19C is as portable\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10"},
|
||||
{"1fb2eb3688093c4a3f80cd87a5547e2ce940a4f923243a79a2a1e242220693ac", "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19Even if I could be Shakespeare, I think I sh\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,"},
|
||||
{"395585ce30617b62c80b93e8208ce866d4edc811a177fdb4b82d3911d8696423", "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction. Lewis-Randall Rule", "sha\x03\x93\x14\xc8z\x87\x0e\vo\xf1E\x0f\xa4V\xb2a\x00\x87\xb5ǔ\xfc\xeaV\u009eg\xbc\x17\xb1\x85њem\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B"},
|
||||
{"4f9b189a13d030838269dce846b16a1ce9ce81fe63e65de2f636863336a98fe6", "How can you write a big system without C++? -Paul Glick", "sha\x03j\t\xe6g\xbbg\xae\x85<n\xf3r\xa5O\xf5:Q\x0eR\u007f\x9b\x05h\x8c\x1f\x83٫[\xe0\xcd\x19How can you write a big syst\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c"},
|
||||
}
|
||||
|
||||
var not = strings.NewReplacer(
|
||||
"0", "f",
|
||||
"1", "e",
|
||||
"2", "d",
|
||||
"3", "c",
|
||||
"4", "b",
|
||||
"5", "a",
|
||||
"6", "9",
|
||||
"7", "8",
|
||||
"8", "7",
|
||||
"9", "6",
|
||||
"a", "5",
|
||||
"b", "4",
|
||||
"c", "3",
|
||||
"d", "2",
|
||||
"e", "1",
|
||||
"f", "0",
|
||||
)
|
||||
|
||||
func TestGolden(t *testing.T) {
|
||||
for i := 0; i < len(golden); i++ {
|
||||
g := golden[i]
|
||||
gout := not.Replace(g.out)
|
||||
s := fmt.Sprintf("%x", Sum256([]byte(g.in)))
|
||||
if s != gout {
|
||||
t.Fatalf("Sum256 function: sha256(%s) = %s want %s", g.in, s, gout)
|
||||
}
|
||||
c := New()
|
||||
for j := 0; j < 3; j++ {
|
||||
if j < 2 {
|
||||
io.WriteString(c, g.in)
|
||||
} else {
|
||||
io.WriteString(c, g.in[0:len(g.in)/2])
|
||||
c.Sum(nil)
|
||||
io.WriteString(c, g.in[len(g.in)/2:])
|
||||
}
|
||||
s := fmt.Sprintf("%x", c.Sum(nil))
|
||||
if s != gout {
|
||||
t.Fatalf("sha256[%d](%s) = %s want %s", j, g.in, s, gout)
|
||||
}
|
||||
c.Reset()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSize(t *testing.T) {
|
||||
c := New()
|
||||
if got := c.Size(); got != Size {
|
||||
t.Errorf("Size = %d; want %d", got, Size)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBlockSize(t *testing.T) {
|
||||
c := New()
|
||||
if got := c.BlockSize(); got != BlockSize {
|
||||
t.Errorf("BlockSize = %d want %d", got, BlockSize)
|
||||
}
|
||||
}
|
||||
|
||||
// Tests that blockGeneric (pure Go) and block (in assembly for some architectures) match.
|
||||
func TestBlockGeneric(t *testing.T) {
|
||||
gen, asm := New().(*digest), New().(*digest)
|
||||
buf := make([]byte, BlockSize*20) // arbitrary factor
|
||||
rand.Read(buf)
|
||||
blockGeneric(gen, buf)
|
||||
block(asm, buf)
|
||||
if *gen != *asm {
|
||||
t.Error("block and blockGeneric resulted in different states")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAllocations(t *testing.T) {
|
||||
in := []byte("hello, world!")
|
||||
out := make([]byte, 0, Size)
|
||||
h := New()
|
||||
n := int(testing.AllocsPerRun(10, func() {
|
||||
h.Reset()
|
||||
h.Write(in)
|
||||
out = h.Sum(out[:0])
|
||||
}))
|
||||
if n > 0 {
|
||||
t.Errorf("allocs = %d, want 0", n)
|
||||
}
|
||||
}
|
||||
|
||||
var bench = New()
|
||||
var buf = make([]byte, 8192)
|
||||
|
||||
func benchmarkSize(b *testing.B, size int) {
|
||||
sum := make([]byte, bench.Size())
|
||||
b.Run("New", func(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
b.SetBytes(int64(size))
|
||||
for i := 0; i < b.N; i++ {
|
||||
bench.Reset()
|
||||
bench.Write(buf[:size])
|
||||
bench.Sum(sum[:0])
|
||||
}
|
||||
})
|
||||
b.Run("Sum256", func(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
b.SetBytes(int64(size))
|
||||
for i := 0; i < b.N; i++ {
|
||||
Sum256(buf[:size])
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkHash8Bytes(b *testing.B) {
|
||||
benchmarkSize(b, 8)
|
||||
}
|
||||
|
||||
func BenchmarkHash1K(b *testing.B) {
|
||||
benchmarkSize(b, 1024)
|
||||
}
|
||||
|
||||
func BenchmarkHash8K(b *testing.B) {
|
||||
benchmarkSize(b, 8192)
|
||||
}
|
||||
128
src/cmd/internal/notsha256/sha256block.go
Normal file
128
src/cmd/internal/notsha256/sha256block.go
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
// 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.
|
||||
|
||||
// SHA256 block step.
|
||||
// In its own file so that a faster assembly or C version
|
||||
// can be substituted easily.
|
||||
|
||||
package notsha256
|
||||
|
||||
import "math/bits"
|
||||
|
||||
var _K = []uint32{
|
||||
0x428a2f98,
|
||||
0x71374491,
|
||||
0xb5c0fbcf,
|
||||
0xe9b5dba5,
|
||||
0x3956c25b,
|
||||
0x59f111f1,
|
||||
0x923f82a4,
|
||||
0xab1c5ed5,
|
||||
0xd807aa98,
|
||||
0x12835b01,
|
||||
0x243185be,
|
||||
0x550c7dc3,
|
||||
0x72be5d74,
|
||||
0x80deb1fe,
|
||||
0x9bdc06a7,
|
||||
0xc19bf174,
|
||||
0xe49b69c1,
|
||||
0xefbe4786,
|
||||
0x0fc19dc6,
|
||||
0x240ca1cc,
|
||||
0x2de92c6f,
|
||||
0x4a7484aa,
|
||||
0x5cb0a9dc,
|
||||
0x76f988da,
|
||||
0x983e5152,
|
||||
0xa831c66d,
|
||||
0xb00327c8,
|
||||
0xbf597fc7,
|
||||
0xc6e00bf3,
|
||||
0xd5a79147,
|
||||
0x06ca6351,
|
||||
0x14292967,
|
||||
0x27b70a85,
|
||||
0x2e1b2138,
|
||||
0x4d2c6dfc,
|
||||
0x53380d13,
|
||||
0x650a7354,
|
||||
0x766a0abb,
|
||||
0x81c2c92e,
|
||||
0x92722c85,
|
||||
0xa2bfe8a1,
|
||||
0xa81a664b,
|
||||
0xc24b8b70,
|
||||
0xc76c51a3,
|
||||
0xd192e819,
|
||||
0xd6990624,
|
||||
0xf40e3585,
|
||||
0x106aa070,
|
||||
0x19a4c116,
|
||||
0x1e376c08,
|
||||
0x2748774c,
|
||||
0x34b0bcb5,
|
||||
0x391c0cb3,
|
||||
0x4ed8aa4a,
|
||||
0x5b9cca4f,
|
||||
0x682e6ff3,
|
||||
0x748f82ee,
|
||||
0x78a5636f,
|
||||
0x84c87814,
|
||||
0x8cc70208,
|
||||
0x90befffa,
|
||||
0xa4506ceb,
|
||||
0xbef9a3f7,
|
||||
0xc67178f2,
|
||||
}
|
||||
|
||||
func blockGeneric(dig *digest, p []byte) {
|
||||
var w [64]uint32
|
||||
h0, h1, h2, h3, h4, h5, h6, h7 := dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7]
|
||||
for len(p) >= chunk {
|
||||
// Can interlace the computation of w with the
|
||||
// rounds below if needed for speed.
|
||||
for i := 0; i < 16; i++ {
|
||||
j := i * 4
|
||||
w[i] = uint32(p[j])<<24 | uint32(p[j+1])<<16 | uint32(p[j+2])<<8 | uint32(p[j+3])
|
||||
}
|
||||
for i := 16; i < 64; i++ {
|
||||
v1 := w[i-2]
|
||||
t1 := (bits.RotateLeft32(v1, -17)) ^ (bits.RotateLeft32(v1, -19)) ^ (v1 >> 10)
|
||||
v2 := w[i-15]
|
||||
t2 := (bits.RotateLeft32(v2, -7)) ^ (bits.RotateLeft32(v2, -18)) ^ (v2 >> 3)
|
||||
w[i] = t1 + w[i-7] + t2 + w[i-16]
|
||||
}
|
||||
|
||||
a, b, c, d, e, f, g, h := h0, h1, h2, h3, h4, h5, h6, h7
|
||||
|
||||
for i := 0; i < 64; i++ {
|
||||
t1 := h + ((bits.RotateLeft32(e, -6)) ^ (bits.RotateLeft32(e, -11)) ^ (bits.RotateLeft32(e, -25))) + ((e & f) ^ (^e & g)) + _K[i] + w[i]
|
||||
|
||||
t2 := ((bits.RotateLeft32(a, -2)) ^ (bits.RotateLeft32(a, -13)) ^ (bits.RotateLeft32(a, -22))) + ((a & b) ^ (a & c) ^ (b & c))
|
||||
|
||||
h = g
|
||||
g = f
|
||||
f = e
|
||||
e = d + t1
|
||||
d = c
|
||||
c = b
|
||||
b = a
|
||||
a = t1 + t2
|
||||
}
|
||||
|
||||
h0 += a
|
||||
h1 += b
|
||||
h2 += c
|
||||
h3 += d
|
||||
h4 += e
|
||||
h5 += f
|
||||
h6 += g
|
||||
h7 += h
|
||||
|
||||
p = p[chunk:]
|
||||
}
|
||||
|
||||
dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7] = h0, h1, h2, h3, h4, h5, h6, h7
|
||||
}
|
||||
283
src/cmd/internal/notsha256/sha256block_386.s
Normal file
283
src/cmd/internal/notsha256/sha256block_386.s
Normal file
|
|
@ -0,0 +1,283 @@
|
|||
// Copyright 2013 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.
|
||||
|
||||
// SHA256 block routine. See sha256block.go for Go equivalent.
|
||||
//
|
||||
// The algorithm is detailed in FIPS 180-4:
|
||||
//
|
||||
// https://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
|
||||
//
|
||||
// Wt = Mt; for 0 <= t <= 15
|
||||
// Wt = SIGMA1(Wt-2) + SIGMA0(Wt-15) + Wt-16; for 16 <= t <= 63
|
||||
//
|
||||
// a = H0
|
||||
// b = H1
|
||||
// c = H2
|
||||
// d = H3
|
||||
// e = H4
|
||||
// f = H5
|
||||
// g = H6
|
||||
// h = H7
|
||||
//
|
||||
// for t = 0 to 63 {
|
||||
// T1 = h + BIGSIGMA1(e) + Ch(e,f,g) + Kt + Wt
|
||||
// T2 = BIGSIGMA0(a) + Maj(a,b,c)
|
||||
// h = g
|
||||
// g = f
|
||||
// f = e
|
||||
// e = d + T1
|
||||
// d = c
|
||||
// c = b
|
||||
// b = a
|
||||
// a = T1 + T2
|
||||
// }
|
||||
//
|
||||
// H0 = a + H0
|
||||
// H1 = b + H1
|
||||
// H2 = c + H2
|
||||
// H3 = d + H3
|
||||
// H4 = e + H4
|
||||
// H5 = f + H5
|
||||
// H6 = g + H6
|
||||
// H7 = h + H7
|
||||
|
||||
// Wt = Mt; for 0 <= t <= 15
|
||||
#define MSGSCHEDULE0(index) \
|
||||
MOVL (index*4)(SI), AX; \
|
||||
BSWAPL AX; \
|
||||
MOVL AX, (index*4)(BP)
|
||||
|
||||
// Wt = SIGMA1(Wt-2) + Wt-7 + SIGMA0(Wt-15) + Wt-16; for 16 <= t <= 63
|
||||
// SIGMA0(x) = ROTR(7,x) XOR ROTR(18,x) XOR SHR(3,x)
|
||||
// SIGMA1(x) = ROTR(17,x) XOR ROTR(19,x) XOR SHR(10,x)
|
||||
#define MSGSCHEDULE1(index) \
|
||||
MOVL ((index-2)*4)(BP), AX; \
|
||||
MOVL AX, CX; \
|
||||
RORL $17, AX; \
|
||||
MOVL CX, DX; \
|
||||
RORL $19, CX; \
|
||||
SHRL $10, DX; \
|
||||
MOVL ((index-15)*4)(BP), BX; \
|
||||
XORL CX, AX; \
|
||||
MOVL BX, CX; \
|
||||
XORL DX, AX; \
|
||||
RORL $7, BX; \
|
||||
MOVL CX, DX; \
|
||||
SHRL $3, DX; \
|
||||
RORL $18, CX; \
|
||||
ADDL ((index-7)*4)(BP), AX; \
|
||||
XORL CX, BX; \
|
||||
XORL DX, BX; \
|
||||
ADDL ((index-16)*4)(BP), BX; \
|
||||
ADDL BX, AX; \
|
||||
MOVL AX, ((index)*4)(BP)
|
||||
|
||||
// Calculate T1 in AX - uses AX, BX, CX and DX registers.
|
||||
// Wt is passed in AX.
|
||||
// T1 = h + BIGSIGMA1(e) + Ch(e, f, g) + Kt + Wt
|
||||
// BIGSIGMA1(x) = ROTR(6,x) XOR ROTR(11,x) XOR ROTR(25,x)
|
||||
// Ch(x, y, z) = (x AND y) XOR (NOT x AND z)
|
||||
#define SHA256T1(const, e, f, g, h) \
|
||||
MOVL (h*4)(DI), BX; \
|
||||
ADDL AX, BX; \
|
||||
MOVL (e*4)(DI), AX; \
|
||||
ADDL $const, BX; \
|
||||
MOVL (e*4)(DI), CX; \
|
||||
RORL $6, AX; \
|
||||
MOVL (e*4)(DI), DX; \
|
||||
RORL $11, CX; \
|
||||
XORL CX, AX; \
|
||||
MOVL (e*4)(DI), CX; \
|
||||
RORL $25, DX; \
|
||||
ANDL (f*4)(DI), CX; \
|
||||
XORL AX, DX; \
|
||||
MOVL (e*4)(DI), AX; \
|
||||
NOTL AX; \
|
||||
ADDL DX, BX; \
|
||||
ANDL (g*4)(DI), AX; \
|
||||
XORL CX, AX; \
|
||||
ADDL BX, AX
|
||||
|
||||
// Calculate T2 in BX - uses AX, BX, CX and DX registers.
|
||||
// T2 = BIGSIGMA0(a) + Maj(a, b, c)
|
||||
// BIGSIGMA0(x) = ROTR(2,x) XOR ROTR(13,x) XOR ROTR(22,x)
|
||||
// Maj(x, y, z) = (x AND y) XOR (x AND z) XOR (y AND z)
|
||||
#define SHA256T2(a, b, c) \
|
||||
MOVL (a*4)(DI), AX; \
|
||||
MOVL (c*4)(DI), BX; \
|
||||
RORL $2, AX; \
|
||||
MOVL (a*4)(DI), DX; \
|
||||
ANDL (b*4)(DI), BX; \
|
||||
RORL $13, DX; \
|
||||
MOVL (a*4)(DI), CX; \
|
||||
ANDL (c*4)(DI), CX; \
|
||||
XORL DX, AX; \
|
||||
XORL CX, BX; \
|
||||
MOVL (a*4)(DI), DX; \
|
||||
MOVL (b*4)(DI), CX; \
|
||||
RORL $22, DX; \
|
||||
ANDL (a*4)(DI), CX; \
|
||||
XORL CX, BX; \
|
||||
XORL DX, AX; \
|
||||
ADDL AX, BX
|
||||
|
||||
// Calculate T1 and T2, then e = d + T1 and a = T1 + T2.
|
||||
// The values for e and a are stored in d and h, ready for rotation.
|
||||
#define SHA256ROUND(index, const, a, b, c, d, e, f, g, h) \
|
||||
SHA256T1(const, e, f, g, h); \
|
||||
MOVL AX, 292(SP); \
|
||||
SHA256T2(a, b, c); \
|
||||
MOVL 292(SP), AX; \
|
||||
ADDL AX, BX; \
|
||||
ADDL AX, (d*4)(DI); \
|
||||
MOVL BX, (h*4)(DI)
|
||||
|
||||
#define SHA256ROUND0(index, const, a, b, c, d, e, f, g, h) \
|
||||
MSGSCHEDULE0(index); \
|
||||
SHA256ROUND(index, const, a, b, c, d, e, f, g, h)
|
||||
|
||||
#define SHA256ROUND1(index, const, a, b, c, d, e, f, g, h) \
|
||||
MSGSCHEDULE1(index); \
|
||||
SHA256ROUND(index, const, a, b, c, d, e, f, g, h)
|
||||
|
||||
TEXT ·block(SB),0,$296-16
|
||||
MOVL p_base+4(FP), SI
|
||||
MOVL p_len+8(FP), DX
|
||||
SHRL $6, DX
|
||||
SHLL $6, DX
|
||||
|
||||
LEAL (SI)(DX*1), DI
|
||||
MOVL DI, 288(SP)
|
||||
CMPL SI, DI
|
||||
JEQ end
|
||||
|
||||
LEAL 256(SP), DI // variables
|
||||
|
||||
MOVL dig+0(FP), BP
|
||||
MOVL (0*4)(BP), AX // a = H0
|
||||
MOVL AX, (0*4)(DI)
|
||||
MOVL (1*4)(BP), BX // b = H1
|
||||
MOVL BX, (1*4)(DI)
|
||||
MOVL (2*4)(BP), CX // c = H2
|
||||
MOVL CX, (2*4)(DI)
|
||||
MOVL (3*4)(BP), DX // d = H3
|
||||
MOVL DX, (3*4)(DI)
|
||||
MOVL (4*4)(BP), AX // e = H4
|
||||
MOVL AX, (4*4)(DI)
|
||||
MOVL (5*4)(BP), BX // f = H5
|
||||
MOVL BX, (5*4)(DI)
|
||||
MOVL (6*4)(BP), CX // g = H6
|
||||
MOVL CX, (6*4)(DI)
|
||||
MOVL (7*4)(BP), DX // h = H7
|
||||
MOVL DX, (7*4)(DI)
|
||||
|
||||
loop:
|
||||
MOVL SP, BP // message schedule
|
||||
|
||||
SHA256ROUND0(0, 0x428a2f98, 0, 1, 2, 3, 4, 5, 6, 7)
|
||||
SHA256ROUND0(1, 0x71374491, 7, 0, 1, 2, 3, 4, 5, 6)
|
||||
SHA256ROUND0(2, 0xb5c0fbcf, 6, 7, 0, 1, 2, 3, 4, 5)
|
||||
SHA256ROUND0(3, 0xe9b5dba5, 5, 6, 7, 0, 1, 2, 3, 4)
|
||||
SHA256ROUND0(4, 0x3956c25b, 4, 5, 6, 7, 0, 1, 2, 3)
|
||||
SHA256ROUND0(5, 0x59f111f1, 3, 4, 5, 6, 7, 0, 1, 2)
|
||||
SHA256ROUND0(6, 0x923f82a4, 2, 3, 4, 5, 6, 7, 0, 1)
|
||||
SHA256ROUND0(7, 0xab1c5ed5, 1, 2, 3, 4, 5, 6, 7, 0)
|
||||
SHA256ROUND0(8, 0xd807aa98, 0, 1, 2, 3, 4, 5, 6, 7)
|
||||
SHA256ROUND0(9, 0x12835b01, 7, 0, 1, 2, 3, 4, 5, 6)
|
||||
SHA256ROUND0(10, 0x243185be, 6, 7, 0, 1, 2, 3, 4, 5)
|
||||
SHA256ROUND0(11, 0x550c7dc3, 5, 6, 7, 0, 1, 2, 3, 4)
|
||||
SHA256ROUND0(12, 0x72be5d74, 4, 5, 6, 7, 0, 1, 2, 3)
|
||||
SHA256ROUND0(13, 0x80deb1fe, 3, 4, 5, 6, 7, 0, 1, 2)
|
||||
SHA256ROUND0(14, 0x9bdc06a7, 2, 3, 4, 5, 6, 7, 0, 1)
|
||||
SHA256ROUND0(15, 0xc19bf174, 1, 2, 3, 4, 5, 6, 7, 0)
|
||||
|
||||
SHA256ROUND1(16, 0xe49b69c1, 0, 1, 2, 3, 4, 5, 6, 7)
|
||||
SHA256ROUND1(17, 0xefbe4786, 7, 0, 1, 2, 3, 4, 5, 6)
|
||||
SHA256ROUND1(18, 0x0fc19dc6, 6, 7, 0, 1, 2, 3, 4, 5)
|
||||
SHA256ROUND1(19, 0x240ca1cc, 5, 6, 7, 0, 1, 2, 3, 4)
|
||||
SHA256ROUND1(20, 0x2de92c6f, 4, 5, 6, 7, 0, 1, 2, 3)
|
||||
SHA256ROUND1(21, 0x4a7484aa, 3, 4, 5, 6, 7, 0, 1, 2)
|
||||
SHA256ROUND1(22, 0x5cb0a9dc, 2, 3, 4, 5, 6, 7, 0, 1)
|
||||
SHA256ROUND1(23, 0x76f988da, 1, 2, 3, 4, 5, 6, 7, 0)
|
||||
SHA256ROUND1(24, 0x983e5152, 0, 1, 2, 3, 4, 5, 6, 7)
|
||||
SHA256ROUND1(25, 0xa831c66d, 7, 0, 1, 2, 3, 4, 5, 6)
|
||||
SHA256ROUND1(26, 0xb00327c8, 6, 7, 0, 1, 2, 3, 4, 5)
|
||||
SHA256ROUND1(27, 0xbf597fc7, 5, 6, 7, 0, 1, 2, 3, 4)
|
||||
SHA256ROUND1(28, 0xc6e00bf3, 4, 5, 6, 7, 0, 1, 2, 3)
|
||||
SHA256ROUND1(29, 0xd5a79147, 3, 4, 5, 6, 7, 0, 1, 2)
|
||||
SHA256ROUND1(30, 0x06ca6351, 2, 3, 4, 5, 6, 7, 0, 1)
|
||||
SHA256ROUND1(31, 0x14292967, 1, 2, 3, 4, 5, 6, 7, 0)
|
||||
SHA256ROUND1(32, 0x27b70a85, 0, 1, 2, 3, 4, 5, 6, 7)
|
||||
SHA256ROUND1(33, 0x2e1b2138, 7, 0, 1, 2, 3, 4, 5, 6)
|
||||
SHA256ROUND1(34, 0x4d2c6dfc, 6, 7, 0, 1, 2, 3, 4, 5)
|
||||
SHA256ROUND1(35, 0x53380d13, 5, 6, 7, 0, 1, 2, 3, 4)
|
||||
SHA256ROUND1(36, 0x650a7354, 4, 5, 6, 7, 0, 1, 2, 3)
|
||||
SHA256ROUND1(37, 0x766a0abb, 3, 4, 5, 6, 7, 0, 1, 2)
|
||||
SHA256ROUND1(38, 0x81c2c92e, 2, 3, 4, 5, 6, 7, 0, 1)
|
||||
SHA256ROUND1(39, 0x92722c85, 1, 2, 3, 4, 5, 6, 7, 0)
|
||||
SHA256ROUND1(40, 0xa2bfe8a1, 0, 1, 2, 3, 4, 5, 6, 7)
|
||||
SHA256ROUND1(41, 0xa81a664b, 7, 0, 1, 2, 3, 4, 5, 6)
|
||||
SHA256ROUND1(42, 0xc24b8b70, 6, 7, 0, 1, 2, 3, 4, 5)
|
||||
SHA256ROUND1(43, 0xc76c51a3, 5, 6, 7, 0, 1, 2, 3, 4)
|
||||
SHA256ROUND1(44, 0xd192e819, 4, 5, 6, 7, 0, 1, 2, 3)
|
||||
SHA256ROUND1(45, 0xd6990624, 3, 4, 5, 6, 7, 0, 1, 2)
|
||||
SHA256ROUND1(46, 0xf40e3585, 2, 3, 4, 5, 6, 7, 0, 1)
|
||||
SHA256ROUND1(47, 0x106aa070, 1, 2, 3, 4, 5, 6, 7, 0)
|
||||
SHA256ROUND1(48, 0x19a4c116, 0, 1, 2, 3, 4, 5, 6, 7)
|
||||
SHA256ROUND1(49, 0x1e376c08, 7, 0, 1, 2, 3, 4, 5, 6)
|
||||
SHA256ROUND1(50, 0x2748774c, 6, 7, 0, 1, 2, 3, 4, 5)
|
||||
SHA256ROUND1(51, 0x34b0bcb5, 5, 6, 7, 0, 1, 2, 3, 4)
|
||||
SHA256ROUND1(52, 0x391c0cb3, 4, 5, 6, 7, 0, 1, 2, 3)
|
||||
SHA256ROUND1(53, 0x4ed8aa4a, 3, 4, 5, 6, 7, 0, 1, 2)
|
||||
SHA256ROUND1(54, 0x5b9cca4f, 2, 3, 4, 5, 6, 7, 0, 1)
|
||||
SHA256ROUND1(55, 0x682e6ff3, 1, 2, 3, 4, 5, 6, 7, 0)
|
||||
SHA256ROUND1(56, 0x748f82ee, 0, 1, 2, 3, 4, 5, 6, 7)
|
||||
SHA256ROUND1(57, 0x78a5636f, 7, 0, 1, 2, 3, 4, 5, 6)
|
||||
SHA256ROUND1(58, 0x84c87814, 6, 7, 0, 1, 2, 3, 4, 5)
|
||||
SHA256ROUND1(59, 0x8cc70208, 5, 6, 7, 0, 1, 2, 3, 4)
|
||||
SHA256ROUND1(60, 0x90befffa, 4, 5, 6, 7, 0, 1, 2, 3)
|
||||
SHA256ROUND1(61, 0xa4506ceb, 3, 4, 5, 6, 7, 0, 1, 2)
|
||||
SHA256ROUND1(62, 0xbef9a3f7, 2, 3, 4, 5, 6, 7, 0, 1)
|
||||
SHA256ROUND1(63, 0xc67178f2, 1, 2, 3, 4, 5, 6, 7, 0)
|
||||
|
||||
MOVL dig+0(FP), BP
|
||||
MOVL (0*4)(BP), AX // H0 = a + H0
|
||||
ADDL (0*4)(DI), AX
|
||||
MOVL AX, (0*4)(DI)
|
||||
MOVL AX, (0*4)(BP)
|
||||
MOVL (1*4)(BP), BX // H1 = b + H1
|
||||
ADDL (1*4)(DI), BX
|
||||
MOVL BX, (1*4)(DI)
|
||||
MOVL BX, (1*4)(BP)
|
||||
MOVL (2*4)(BP), CX // H2 = c + H2
|
||||
ADDL (2*4)(DI), CX
|
||||
MOVL CX, (2*4)(DI)
|
||||
MOVL CX, (2*4)(BP)
|
||||
MOVL (3*4)(BP), DX // H3 = d + H3
|
||||
ADDL (3*4)(DI), DX
|
||||
MOVL DX, (3*4)(DI)
|
||||
MOVL DX, (3*4)(BP)
|
||||
MOVL (4*4)(BP), AX // H4 = e + H4
|
||||
ADDL (4*4)(DI), AX
|
||||
MOVL AX, (4*4)(DI)
|
||||
MOVL AX, (4*4)(BP)
|
||||
MOVL (5*4)(BP), BX // H5 = f + H5
|
||||
ADDL (5*4)(DI), BX
|
||||
MOVL BX, (5*4)(DI)
|
||||
MOVL BX, (5*4)(BP)
|
||||
MOVL (6*4)(BP), CX // H6 = g + H6
|
||||
ADDL (6*4)(DI), CX
|
||||
MOVL CX, (6*4)(DI)
|
||||
MOVL CX, (6*4)(BP)
|
||||
MOVL (7*4)(BP), DX // H7 = h + H7
|
||||
ADDL (7*4)(DI), DX
|
||||
MOVL DX, (7*4)(DI)
|
||||
MOVL DX, (7*4)(BP)
|
||||
|
||||
ADDL $64, SI
|
||||
CMPL SI, 288(SP)
|
||||
JB loop
|
||||
|
||||
end:
|
||||
RET
|
||||
7
src/cmd/internal/notsha256/sha256block_amd64.go
Normal file
7
src/cmd/internal/notsha256/sha256block_amd64.go
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
// 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 notsha256
|
||||
|
||||
var useAVX2 = false
|
||||
424
src/cmd/internal/notsha256/sha256block_amd64.s
Normal file
424
src/cmd/internal/notsha256/sha256block_amd64.s
Normal file
|
|
@ -0,0 +1,424 @@
|
|||
// Copyright 2013 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"
|
||||
|
||||
// SHA256 block routine. See sha256block.go for Go equivalent.
|
||||
//
|
||||
// The algorithm is detailed in FIPS 180-4:
|
||||
//
|
||||
// https://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
|
||||
|
||||
// Wt = Mt; for 0 <= t <= 15
|
||||
// Wt = SIGMA1(Wt-2) + SIGMA0(Wt-15) + Wt-16; for 16 <= t <= 63
|
||||
//
|
||||
// a = H0
|
||||
// b = H1
|
||||
// c = H2
|
||||
// d = H3
|
||||
// e = H4
|
||||
// f = H5
|
||||
// g = H6
|
||||
// h = H7
|
||||
//
|
||||
// for t = 0 to 63 {
|
||||
// T1 = h + BIGSIGMA1(e) + Ch(e,f,g) + Kt + Wt
|
||||
// T2 = BIGSIGMA0(a) + Maj(a,b,c)
|
||||
// h = g
|
||||
// g = f
|
||||
// f = e
|
||||
// e = d + T1
|
||||
// d = c
|
||||
// c = b
|
||||
// b = a
|
||||
// a = T1 + T2
|
||||
// }
|
||||
//
|
||||
// H0 = a + H0
|
||||
// H1 = b + H1
|
||||
// H2 = c + H2
|
||||
// H3 = d + H3
|
||||
// H4 = e + H4
|
||||
// H5 = f + H5
|
||||
// H6 = g + H6
|
||||
// H7 = h + H7
|
||||
|
||||
// Wt = Mt; for 0 <= t <= 15
|
||||
#define MSGSCHEDULE0(index) \
|
||||
MOVL (index*4)(SI), AX; \
|
||||
BSWAPL AX; \
|
||||
MOVL AX, (index*4)(BP)
|
||||
|
||||
// Wt = SIGMA1(Wt-2) + Wt-7 + SIGMA0(Wt-15) + Wt-16; for 16 <= t <= 63
|
||||
// SIGMA0(x) = ROTR(7,x) XOR ROTR(18,x) XOR SHR(3,x)
|
||||
// SIGMA1(x) = ROTR(17,x) XOR ROTR(19,x) XOR SHR(10,x)
|
||||
#define MSGSCHEDULE1(index) \
|
||||
MOVL ((index-2)*4)(BP), AX; \
|
||||
MOVL AX, CX; \
|
||||
RORL $17, AX; \
|
||||
MOVL CX, DX; \
|
||||
RORL $19, CX; \
|
||||
SHRL $10, DX; \
|
||||
MOVL ((index-15)*4)(BP), BX; \
|
||||
XORL CX, AX; \
|
||||
MOVL BX, CX; \
|
||||
XORL DX, AX; \
|
||||
RORL $7, BX; \
|
||||
MOVL CX, DX; \
|
||||
SHRL $3, DX; \
|
||||
RORL $18, CX; \
|
||||
ADDL ((index-7)*4)(BP), AX; \
|
||||
XORL CX, BX; \
|
||||
XORL DX, BX; \
|
||||
ADDL ((index-16)*4)(BP), BX; \
|
||||
ADDL BX, AX; \
|
||||
MOVL AX, ((index)*4)(BP)
|
||||
|
||||
// Calculate T1 in AX - uses AX, CX and DX registers.
|
||||
// h is also used as an accumulator. Wt is passed in AX.
|
||||
// T1 = h + BIGSIGMA1(e) + Ch(e, f, g) + Kt + Wt
|
||||
// BIGSIGMA1(x) = ROTR(6,x) XOR ROTR(11,x) XOR ROTR(25,x)
|
||||
// Ch(x, y, z) = (x AND y) XOR (NOT x AND z)
|
||||
#define SHA256T1(const, e, f, g, h) \
|
||||
ADDL AX, h; \
|
||||
MOVL e, AX; \
|
||||
ADDL $const, h; \
|
||||
MOVL e, CX; \
|
||||
RORL $6, AX; \
|
||||
MOVL e, DX; \
|
||||
RORL $11, CX; \
|
||||
XORL CX, AX; \
|
||||
MOVL e, CX; \
|
||||
RORL $25, DX; \
|
||||
ANDL f, CX; \
|
||||
XORL AX, DX; \
|
||||
MOVL e, AX; \
|
||||
NOTL AX; \
|
||||
ADDL DX, h; \
|
||||
ANDL g, AX; \
|
||||
XORL CX, AX; \
|
||||
ADDL h, AX
|
||||
|
||||
// Calculate T2 in BX - uses BX, CX, DX and DI registers.
|
||||
// T2 = BIGSIGMA0(a) + Maj(a, b, c)
|
||||
// BIGSIGMA0(x) = ROTR(2,x) XOR ROTR(13,x) XOR ROTR(22,x)
|
||||
// Maj(x, y, z) = (x AND y) XOR (x AND z) XOR (y AND z)
|
||||
#define SHA256T2(a, b, c) \
|
||||
MOVL a, DI; \
|
||||
MOVL c, BX; \
|
||||
RORL $2, DI; \
|
||||
MOVL a, DX; \
|
||||
ANDL b, BX; \
|
||||
RORL $13, DX; \
|
||||
MOVL a, CX; \
|
||||
ANDL c, CX; \
|
||||
XORL DX, DI; \
|
||||
XORL CX, BX; \
|
||||
MOVL a, DX; \
|
||||
MOVL b, CX; \
|
||||
RORL $22, DX; \
|
||||
ANDL a, CX; \
|
||||
XORL CX, BX; \
|
||||
XORL DX, DI; \
|
||||
ADDL DI, BX
|
||||
|
||||
// Calculate T1 and T2, then e = d + T1 and a = T1 + T2.
|
||||
// The values for e and a are stored in d and h, ready for rotation.
|
||||
#define SHA256ROUND(index, const, a, b, c, d, e, f, g, h) \
|
||||
SHA256T1(const, e, f, g, h); \
|
||||
SHA256T2(a, b, c); \
|
||||
MOVL BX, h; \
|
||||
ADDL AX, d; \
|
||||
ADDL AX, h
|
||||
|
||||
#define SHA256ROUND0(index, const, a, b, c, d, e, f, g, h) \
|
||||
MSGSCHEDULE0(index); \
|
||||
SHA256ROUND(index, const, a, b, c, d, e, f, g, h)
|
||||
|
||||
#define SHA256ROUND1(index, const, a, b, c, d, e, f, g, h) \
|
||||
MSGSCHEDULE1(index); \
|
||||
SHA256ROUND(index, const, a, b, c, d, e, f, g, h)
|
||||
|
||||
TEXT ·block(SB), 0, $536-32
|
||||
MOVQ p_base+8(FP), SI
|
||||
MOVQ p_len+16(FP), DX
|
||||
SHRQ $6, DX
|
||||
SHLQ $6, DX
|
||||
|
||||
LEAQ (SI)(DX*1), DI
|
||||
MOVQ DI, 256(SP)
|
||||
CMPQ SI, DI
|
||||
JEQ end
|
||||
|
||||
MOVQ dig+0(FP), BP
|
||||
MOVL (0*4)(BP), R8 // a = H0
|
||||
MOVL (1*4)(BP), R9 // b = H1
|
||||
MOVL (2*4)(BP), R10 // c = H2
|
||||
MOVL (3*4)(BP), R11 // d = H3
|
||||
MOVL (4*4)(BP), R12 // e = H4
|
||||
MOVL (5*4)(BP), R13 // f = H5
|
||||
MOVL (6*4)(BP), R14 // g = H6
|
||||
MOVL (7*4)(BP), R15 // h = H7
|
||||
|
||||
loop:
|
||||
MOVQ SP, BP
|
||||
|
||||
SHA256ROUND0(0, 0x428a2f98, R8, R9, R10, R11, R12, R13, R14, R15)
|
||||
SHA256ROUND0(1, 0x71374491, R15, R8, R9, R10, R11, R12, R13, R14)
|
||||
SHA256ROUND0(2, 0xb5c0fbcf, R14, R15, R8, R9, R10, R11, R12, R13)
|
||||
SHA256ROUND0(3, 0xe9b5dba5, R13, R14, R15, R8, R9, R10, R11, R12)
|
||||
SHA256ROUND0(4, 0x3956c25b, R12, R13, R14, R15, R8, R9, R10, R11)
|
||||
SHA256ROUND0(5, 0x59f111f1, R11, R12, R13, R14, R15, R8, R9, R10)
|
||||
SHA256ROUND0(6, 0x923f82a4, R10, R11, R12, R13, R14, R15, R8, R9)
|
||||
SHA256ROUND0(7, 0xab1c5ed5, R9, R10, R11, R12, R13, R14, R15, R8)
|
||||
SHA256ROUND0(8, 0xd807aa98, R8, R9, R10, R11, R12, R13, R14, R15)
|
||||
SHA256ROUND0(9, 0x12835b01, R15, R8, R9, R10, R11, R12, R13, R14)
|
||||
SHA256ROUND0(10, 0x243185be, R14, R15, R8, R9, R10, R11, R12, R13)
|
||||
SHA256ROUND0(11, 0x550c7dc3, R13, R14, R15, R8, R9, R10, R11, R12)
|
||||
SHA256ROUND0(12, 0x72be5d74, R12, R13, R14, R15, R8, R9, R10, R11)
|
||||
SHA256ROUND0(13, 0x80deb1fe, R11, R12, R13, R14, R15, R8, R9, R10)
|
||||
SHA256ROUND0(14, 0x9bdc06a7, R10, R11, R12, R13, R14, R15, R8, R9)
|
||||
SHA256ROUND0(15, 0xc19bf174, R9, R10, R11, R12, R13, R14, R15, R8)
|
||||
|
||||
SHA256ROUND1(16, 0xe49b69c1, R8, R9, R10, R11, R12, R13, R14, R15)
|
||||
SHA256ROUND1(17, 0xefbe4786, R15, R8, R9, R10, R11, R12, R13, R14)
|
||||
SHA256ROUND1(18, 0x0fc19dc6, R14, R15, R8, R9, R10, R11, R12, R13)
|
||||
SHA256ROUND1(19, 0x240ca1cc, R13, R14, R15, R8, R9, R10, R11, R12)
|
||||
SHA256ROUND1(20, 0x2de92c6f, R12, R13, R14, R15, R8, R9, R10, R11)
|
||||
SHA256ROUND1(21, 0x4a7484aa, R11, R12, R13, R14, R15, R8, R9, R10)
|
||||
SHA256ROUND1(22, 0x5cb0a9dc, R10, R11, R12, R13, R14, R15, R8, R9)
|
||||
SHA256ROUND1(23, 0x76f988da, R9, R10, R11, R12, R13, R14, R15, R8)
|
||||
SHA256ROUND1(24, 0x983e5152, R8, R9, R10, R11, R12, R13, R14, R15)
|
||||
SHA256ROUND1(25, 0xa831c66d, R15, R8, R9, R10, R11, R12, R13, R14)
|
||||
SHA256ROUND1(26, 0xb00327c8, R14, R15, R8, R9, R10, R11, R12, R13)
|
||||
SHA256ROUND1(27, 0xbf597fc7, R13, R14, R15, R8, R9, R10, R11, R12)
|
||||
SHA256ROUND1(28, 0xc6e00bf3, R12, R13, R14, R15, R8, R9, R10, R11)
|
||||
SHA256ROUND1(29, 0xd5a79147, R11, R12, R13, R14, R15, R8, R9, R10)
|
||||
SHA256ROUND1(30, 0x06ca6351, R10, R11, R12, R13, R14, R15, R8, R9)
|
||||
SHA256ROUND1(31, 0x14292967, R9, R10, R11, R12, R13, R14, R15, R8)
|
||||
SHA256ROUND1(32, 0x27b70a85, R8, R9, R10, R11, R12, R13, R14, R15)
|
||||
SHA256ROUND1(33, 0x2e1b2138, R15, R8, R9, R10, R11, R12, R13, R14)
|
||||
SHA256ROUND1(34, 0x4d2c6dfc, R14, R15, R8, R9, R10, R11, R12, R13)
|
||||
SHA256ROUND1(35, 0x53380d13, R13, R14, R15, R8, R9, R10, R11, R12)
|
||||
SHA256ROUND1(36, 0x650a7354, R12, R13, R14, R15, R8, R9, R10, R11)
|
||||
SHA256ROUND1(37, 0x766a0abb, R11, R12, R13, R14, R15, R8, R9, R10)
|
||||
SHA256ROUND1(38, 0x81c2c92e, R10, R11, R12, R13, R14, R15, R8, R9)
|
||||
SHA256ROUND1(39, 0x92722c85, R9, R10, R11, R12, R13, R14, R15, R8)
|
||||
SHA256ROUND1(40, 0xa2bfe8a1, R8, R9, R10, R11, R12, R13, R14, R15)
|
||||
SHA256ROUND1(41, 0xa81a664b, R15, R8, R9, R10, R11, R12, R13, R14)
|
||||
SHA256ROUND1(42, 0xc24b8b70, R14, R15, R8, R9, R10, R11, R12, R13)
|
||||
SHA256ROUND1(43, 0xc76c51a3, R13, R14, R15, R8, R9, R10, R11, R12)
|
||||
SHA256ROUND1(44, 0xd192e819, R12, R13, R14, R15, R8, R9, R10, R11)
|
||||
SHA256ROUND1(45, 0xd6990624, R11, R12, R13, R14, R15, R8, R9, R10)
|
||||
SHA256ROUND1(46, 0xf40e3585, R10, R11, R12, R13, R14, R15, R8, R9)
|
||||
SHA256ROUND1(47, 0x106aa070, R9, R10, R11, R12, R13, R14, R15, R8)
|
||||
SHA256ROUND1(48, 0x19a4c116, R8, R9, R10, R11, R12, R13, R14, R15)
|
||||
SHA256ROUND1(49, 0x1e376c08, R15, R8, R9, R10, R11, R12, R13, R14)
|
||||
SHA256ROUND1(50, 0x2748774c, R14, R15, R8, R9, R10, R11, R12, R13)
|
||||
SHA256ROUND1(51, 0x34b0bcb5, R13, R14, R15, R8, R9, R10, R11, R12)
|
||||
SHA256ROUND1(52, 0x391c0cb3, R12, R13, R14, R15, R8, R9, R10, R11)
|
||||
SHA256ROUND1(53, 0x4ed8aa4a, R11, R12, R13, R14, R15, R8, R9, R10)
|
||||
SHA256ROUND1(54, 0x5b9cca4f, R10, R11, R12, R13, R14, R15, R8, R9)
|
||||
SHA256ROUND1(55, 0x682e6ff3, R9, R10, R11, R12, R13, R14, R15, R8)
|
||||
SHA256ROUND1(56, 0x748f82ee, R8, R9, R10, R11, R12, R13, R14, R15)
|
||||
SHA256ROUND1(57, 0x78a5636f, R15, R8, R9, R10, R11, R12, R13, R14)
|
||||
SHA256ROUND1(58, 0x84c87814, R14, R15, R8, R9, R10, R11, R12, R13)
|
||||
SHA256ROUND1(59, 0x8cc70208, R13, R14, R15, R8, R9, R10, R11, R12)
|
||||
SHA256ROUND1(60, 0x90befffa, R12, R13, R14, R15, R8, R9, R10, R11)
|
||||
SHA256ROUND1(61, 0xa4506ceb, R11, R12, R13, R14, R15, R8, R9, R10)
|
||||
SHA256ROUND1(62, 0xbef9a3f7, R10, R11, R12, R13, R14, R15, R8, R9)
|
||||
SHA256ROUND1(63, 0xc67178f2, R9, R10, R11, R12, R13, R14, R15, R8)
|
||||
|
||||
MOVQ dig+0(FP), BP
|
||||
ADDL (0*4)(BP), R8 // H0 = a + H0
|
||||
MOVL R8, (0*4)(BP)
|
||||
ADDL (1*4)(BP), R9 // H1 = b + H1
|
||||
MOVL R9, (1*4)(BP)
|
||||
ADDL (2*4)(BP), R10 // H2 = c + H2
|
||||
MOVL R10, (2*4)(BP)
|
||||
ADDL (3*4)(BP), R11 // H3 = d + H3
|
||||
MOVL R11, (3*4)(BP)
|
||||
ADDL (4*4)(BP), R12 // H4 = e + H4
|
||||
MOVL R12, (4*4)(BP)
|
||||
ADDL (5*4)(BP), R13 // H5 = f + H5
|
||||
MOVL R13, (5*4)(BP)
|
||||
ADDL (6*4)(BP), R14 // H6 = g + H6
|
||||
MOVL R14, (6*4)(BP)
|
||||
ADDL (7*4)(BP), R15 // H7 = h + H7
|
||||
MOVL R15, (7*4)(BP)
|
||||
|
||||
ADDQ $64, SI
|
||||
CMPQ SI, 256(SP)
|
||||
JB loop
|
||||
|
||||
end:
|
||||
RET
|
||||
|
||||
// shuffle byte order from LE to BE
|
||||
DATA flip_mask<>+0x00(SB)/8, $0x0405060700010203
|
||||
DATA flip_mask<>+0x08(SB)/8, $0x0c0d0e0f08090a0b
|
||||
DATA flip_mask<>+0x10(SB)/8, $0x0405060700010203
|
||||
DATA flip_mask<>+0x18(SB)/8, $0x0c0d0e0f08090a0b
|
||||
GLOBL flip_mask<>(SB), 8, $32
|
||||
|
||||
// shuffle xBxA -> 00BA
|
||||
DATA shuff_00BA<>+0x00(SB)/8, $0x0b0a090803020100
|
||||
DATA shuff_00BA<>+0x08(SB)/8, $0xFFFFFFFFFFFFFFFF
|
||||
DATA shuff_00BA<>+0x10(SB)/8, $0x0b0a090803020100
|
||||
DATA shuff_00BA<>+0x18(SB)/8, $0xFFFFFFFFFFFFFFFF
|
||||
GLOBL shuff_00BA<>(SB), 8, $32
|
||||
|
||||
// shuffle xDxC -> DC00
|
||||
DATA shuff_DC00<>+0x00(SB)/8, $0xFFFFFFFFFFFFFFFF
|
||||
DATA shuff_DC00<>+0x08(SB)/8, $0x0b0a090803020100
|
||||
DATA shuff_DC00<>+0x10(SB)/8, $0xFFFFFFFFFFFFFFFF
|
||||
DATA shuff_DC00<>+0x18(SB)/8, $0x0b0a090803020100
|
||||
GLOBL shuff_DC00<>(SB), 8, $32
|
||||
|
||||
// Round specific constants
|
||||
DATA K256<>+0x00(SB)/4, $0x428a2f98 // k1
|
||||
DATA K256<>+0x04(SB)/4, $0x71374491 // k2
|
||||
DATA K256<>+0x08(SB)/4, $0xb5c0fbcf // k3
|
||||
DATA K256<>+0x0c(SB)/4, $0xe9b5dba5 // k4
|
||||
DATA K256<>+0x10(SB)/4, $0x428a2f98 // k1
|
||||
DATA K256<>+0x14(SB)/4, $0x71374491 // k2
|
||||
DATA K256<>+0x18(SB)/4, $0xb5c0fbcf // k3
|
||||
DATA K256<>+0x1c(SB)/4, $0xe9b5dba5 // k4
|
||||
|
||||
DATA K256<>+0x20(SB)/4, $0x3956c25b // k5 - k8
|
||||
DATA K256<>+0x24(SB)/4, $0x59f111f1
|
||||
DATA K256<>+0x28(SB)/4, $0x923f82a4
|
||||
DATA K256<>+0x2c(SB)/4, $0xab1c5ed5
|
||||
DATA K256<>+0x30(SB)/4, $0x3956c25b
|
||||
DATA K256<>+0x34(SB)/4, $0x59f111f1
|
||||
DATA K256<>+0x38(SB)/4, $0x923f82a4
|
||||
DATA K256<>+0x3c(SB)/4, $0xab1c5ed5
|
||||
|
||||
DATA K256<>+0x40(SB)/4, $0xd807aa98 // k9 - k12
|
||||
DATA K256<>+0x44(SB)/4, $0x12835b01
|
||||
DATA K256<>+0x48(SB)/4, $0x243185be
|
||||
DATA K256<>+0x4c(SB)/4, $0x550c7dc3
|
||||
DATA K256<>+0x50(SB)/4, $0xd807aa98
|
||||
DATA K256<>+0x54(SB)/4, $0x12835b01
|
||||
DATA K256<>+0x58(SB)/4, $0x243185be
|
||||
DATA K256<>+0x5c(SB)/4, $0x550c7dc3
|
||||
|
||||
DATA K256<>+0x60(SB)/4, $0x72be5d74 // k13 - k16
|
||||
DATA K256<>+0x64(SB)/4, $0x80deb1fe
|
||||
DATA K256<>+0x68(SB)/4, $0x9bdc06a7
|
||||
DATA K256<>+0x6c(SB)/4, $0xc19bf174
|
||||
DATA K256<>+0x70(SB)/4, $0x72be5d74
|
||||
DATA K256<>+0x74(SB)/4, $0x80deb1fe
|
||||
DATA K256<>+0x78(SB)/4, $0x9bdc06a7
|
||||
DATA K256<>+0x7c(SB)/4, $0xc19bf174
|
||||
|
||||
DATA K256<>+0x80(SB)/4, $0xe49b69c1 // k17 - k20
|
||||
DATA K256<>+0x84(SB)/4, $0xefbe4786
|
||||
DATA K256<>+0x88(SB)/4, $0x0fc19dc6
|
||||
DATA K256<>+0x8c(SB)/4, $0x240ca1cc
|
||||
DATA K256<>+0x90(SB)/4, $0xe49b69c1
|
||||
DATA K256<>+0x94(SB)/4, $0xefbe4786
|
||||
DATA K256<>+0x98(SB)/4, $0x0fc19dc6
|
||||
DATA K256<>+0x9c(SB)/4, $0x240ca1cc
|
||||
|
||||
DATA K256<>+0xa0(SB)/4, $0x2de92c6f // k21 - k24
|
||||
DATA K256<>+0xa4(SB)/4, $0x4a7484aa
|
||||
DATA K256<>+0xa8(SB)/4, $0x5cb0a9dc
|
||||
DATA K256<>+0xac(SB)/4, $0x76f988da
|
||||
DATA K256<>+0xb0(SB)/4, $0x2de92c6f
|
||||
DATA K256<>+0xb4(SB)/4, $0x4a7484aa
|
||||
DATA K256<>+0xb8(SB)/4, $0x5cb0a9dc
|
||||
DATA K256<>+0xbc(SB)/4, $0x76f988da
|
||||
|
||||
DATA K256<>+0xc0(SB)/4, $0x983e5152 // k25 - k28
|
||||
DATA K256<>+0xc4(SB)/4, $0xa831c66d
|
||||
DATA K256<>+0xc8(SB)/4, $0xb00327c8
|
||||
DATA K256<>+0xcc(SB)/4, $0xbf597fc7
|
||||
DATA K256<>+0xd0(SB)/4, $0x983e5152
|
||||
DATA K256<>+0xd4(SB)/4, $0xa831c66d
|
||||
DATA K256<>+0xd8(SB)/4, $0xb00327c8
|
||||
DATA K256<>+0xdc(SB)/4, $0xbf597fc7
|
||||
|
||||
DATA K256<>+0xe0(SB)/4, $0xc6e00bf3 // k29 - k32
|
||||
DATA K256<>+0xe4(SB)/4, $0xd5a79147
|
||||
DATA K256<>+0xe8(SB)/4, $0x06ca6351
|
||||
DATA K256<>+0xec(SB)/4, $0x14292967
|
||||
DATA K256<>+0xf0(SB)/4, $0xc6e00bf3
|
||||
DATA K256<>+0xf4(SB)/4, $0xd5a79147
|
||||
DATA K256<>+0xf8(SB)/4, $0x06ca6351
|
||||
DATA K256<>+0xfc(SB)/4, $0x14292967
|
||||
|
||||
DATA K256<>+0x100(SB)/4, $0x27b70a85
|
||||
DATA K256<>+0x104(SB)/4, $0x2e1b2138
|
||||
DATA K256<>+0x108(SB)/4, $0x4d2c6dfc
|
||||
DATA K256<>+0x10c(SB)/4, $0x53380d13
|
||||
DATA K256<>+0x110(SB)/4, $0x27b70a85
|
||||
DATA K256<>+0x114(SB)/4, $0x2e1b2138
|
||||
DATA K256<>+0x118(SB)/4, $0x4d2c6dfc
|
||||
DATA K256<>+0x11c(SB)/4, $0x53380d13
|
||||
|
||||
DATA K256<>+0x120(SB)/4, $0x650a7354
|
||||
DATA K256<>+0x124(SB)/4, $0x766a0abb
|
||||
DATA K256<>+0x128(SB)/4, $0x81c2c92e
|
||||
DATA K256<>+0x12c(SB)/4, $0x92722c85
|
||||
DATA K256<>+0x130(SB)/4, $0x650a7354
|
||||
DATA K256<>+0x134(SB)/4, $0x766a0abb
|
||||
DATA K256<>+0x138(SB)/4, $0x81c2c92e
|
||||
DATA K256<>+0x13c(SB)/4, $0x92722c85
|
||||
|
||||
DATA K256<>+0x140(SB)/4, $0xa2bfe8a1
|
||||
DATA K256<>+0x144(SB)/4, $0xa81a664b
|
||||
DATA K256<>+0x148(SB)/4, $0xc24b8b70
|
||||
DATA K256<>+0x14c(SB)/4, $0xc76c51a3
|
||||
DATA K256<>+0x150(SB)/4, $0xa2bfe8a1
|
||||
DATA K256<>+0x154(SB)/4, $0xa81a664b
|
||||
DATA K256<>+0x158(SB)/4, $0xc24b8b70
|
||||
DATA K256<>+0x15c(SB)/4, $0xc76c51a3
|
||||
|
||||
DATA K256<>+0x160(SB)/4, $0xd192e819
|
||||
DATA K256<>+0x164(SB)/4, $0xd6990624
|
||||
DATA K256<>+0x168(SB)/4, $0xf40e3585
|
||||
DATA K256<>+0x16c(SB)/4, $0x106aa070
|
||||
DATA K256<>+0x170(SB)/4, $0xd192e819
|
||||
DATA K256<>+0x174(SB)/4, $0xd6990624
|
||||
DATA K256<>+0x178(SB)/4, $0xf40e3585
|
||||
DATA K256<>+0x17c(SB)/4, $0x106aa070
|
||||
|
||||
DATA K256<>+0x180(SB)/4, $0x19a4c116
|
||||
DATA K256<>+0x184(SB)/4, $0x1e376c08
|
||||
DATA K256<>+0x188(SB)/4, $0x2748774c
|
||||
DATA K256<>+0x18c(SB)/4, $0x34b0bcb5
|
||||
DATA K256<>+0x190(SB)/4, $0x19a4c116
|
||||
DATA K256<>+0x194(SB)/4, $0x1e376c08
|
||||
DATA K256<>+0x198(SB)/4, $0x2748774c
|
||||
DATA K256<>+0x19c(SB)/4, $0x34b0bcb5
|
||||
|
||||
DATA K256<>+0x1a0(SB)/4, $0x391c0cb3
|
||||
DATA K256<>+0x1a4(SB)/4, $0x4ed8aa4a
|
||||
DATA K256<>+0x1a8(SB)/4, $0x5b9cca4f
|
||||
DATA K256<>+0x1ac(SB)/4, $0x682e6ff3
|
||||
DATA K256<>+0x1b0(SB)/4, $0x391c0cb3
|
||||
DATA K256<>+0x1b4(SB)/4, $0x4ed8aa4a
|
||||
DATA K256<>+0x1b8(SB)/4, $0x5b9cca4f
|
||||
DATA K256<>+0x1bc(SB)/4, $0x682e6ff3
|
||||
|
||||
DATA K256<>+0x1c0(SB)/4, $0x748f82ee
|
||||
DATA K256<>+0x1c4(SB)/4, $0x78a5636f
|
||||
DATA K256<>+0x1c8(SB)/4, $0x84c87814
|
||||
DATA K256<>+0x1cc(SB)/4, $0x8cc70208
|
||||
DATA K256<>+0x1d0(SB)/4, $0x748f82ee
|
||||
DATA K256<>+0x1d4(SB)/4, $0x78a5636f
|
||||
DATA K256<>+0x1d8(SB)/4, $0x84c87814
|
||||
DATA K256<>+0x1dc(SB)/4, $0x8cc70208
|
||||
|
||||
DATA K256<>+0x1e0(SB)/4, $0x90befffa
|
||||
DATA K256<>+0x1e4(SB)/4, $0xa4506ceb
|
||||
DATA K256<>+0x1e8(SB)/4, $0xbef9a3f7
|
||||
DATA K256<>+0x1ec(SB)/4, $0xc67178f2
|
||||
DATA K256<>+0x1f0(SB)/4, $0x90befffa
|
||||
DATA K256<>+0x1f4(SB)/4, $0xa4506ceb
|
||||
DATA K256<>+0x1f8(SB)/4, $0xbef9a3f7
|
||||
DATA K256<>+0x1fc(SB)/4, $0xc67178f2
|
||||
|
||||
GLOBL K256<>(SB), (NOPTR + RODATA), $512
|
||||
12
src/cmd/internal/notsha256/sha256block_decl.go
Normal file
12
src/cmd/internal/notsha256/sha256block_decl.go
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright 2013 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.
|
||||
|
||||
//go:build 386 || amd64 || ppc64le || ppc64
|
||||
// +build 386 amd64 ppc64le ppc64
|
||||
|
||||
package notsha256
|
||||
|
||||
//go:noescape
|
||||
|
||||
func block(dig *digest, p []byte)
|
||||
12
src/cmd/internal/notsha256/sha256block_generic.go
Normal file
12
src/cmd/internal/notsha256/sha256block_generic.go
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright 2016 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.
|
||||
|
||||
//go:build !amd64 && !386 && !ppc64le && !ppc64
|
||||
// +build !amd64,!386,!ppc64le,!ppc64
|
||||
|
||||
package notsha256
|
||||
|
||||
func block(dig *digest, p []byte) {
|
||||
blockGeneric(dig, p)
|
||||
}
|
||||
424
src/cmd/internal/notsha256/sha256block_ppc64x.s
Normal file
424
src/cmd/internal/notsha256/sha256block_ppc64x.s
Normal file
|
|
@ -0,0 +1,424 @@
|
|||
// Copyright 2016 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.
|
||||
|
||||
//go:build ppc64 || ppc64le
|
||||
// +build ppc64 ppc64le
|
||||
|
||||
// Based on CRYPTOGAMS code with the following comment:
|
||||
// # ====================================================================
|
||||
// # Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
|
||||
// # project. The module is, however, dual licensed under OpenSSL and
|
||||
// # CRYPTOGAMS licenses depending on where you obtain it. For further
|
||||
// # details see http://www.openssl.org/~appro/cryptogams/.
|
||||
// # ====================================================================
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// SHA256 block routine. See sha256block.go for Go equivalent.
|
||||
//
|
||||
// The algorithm is detailed in FIPS 180-4:
|
||||
//
|
||||
// https://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
|
||||
//
|
||||
// Wt = Mt; for 0 <= t <= 15
|
||||
// Wt = SIGMA1(Wt-2) + SIGMA0(Wt-15) + Wt-16; for 16 <= t <= 63
|
||||
//
|
||||
// a = H0
|
||||
// b = H1
|
||||
// c = H2
|
||||
// d = H3
|
||||
// e = H4
|
||||
// f = H5
|
||||
// g = H6
|
||||
// h = H7
|
||||
//
|
||||
// for t = 0 to 63 {
|
||||
// T1 = h + BIGSIGMA1(e) + Ch(e,f,g) + Kt + Wt
|
||||
// T2 = BIGSIGMA0(a) + Maj(a,b,c)
|
||||
// h = g
|
||||
// g = f
|
||||
// f = e
|
||||
// e = d + T1
|
||||
// d = c
|
||||
// c = b
|
||||
// b = a
|
||||
// a = T1 + T2
|
||||
// }
|
||||
//
|
||||
// H0 = a + H0
|
||||
// H1 = b + H1
|
||||
// H2 = c + H2
|
||||
// H3 = d + H3
|
||||
// H4 = e + H4
|
||||
// H5 = f + H5
|
||||
// H6 = g + H6
|
||||
// H7 = h + H7
|
||||
|
||||
#define CTX R3
|
||||
#define INP R4
|
||||
#define END R5
|
||||
#define TBL R6
|
||||
#define IDX R7
|
||||
#define LEN R9
|
||||
#define TEMP R12
|
||||
|
||||
#define HEX00 R0
|
||||
#define HEX10 R10
|
||||
|
||||
// V0-V7 are A-H
|
||||
// V8-V23 are used for the message schedule
|
||||
#define KI V24
|
||||
#define FUNC V25
|
||||
#define S0 V26
|
||||
#define S1 V27
|
||||
#define s0 V28
|
||||
#define s1 V29
|
||||
#define LEMASK V31 // Permutation control register for little endian
|
||||
|
||||
// 4 copies of each Kt, to fill all 4 words of a vector register
|
||||
DATA ·kcon+0x000(SB)/8, $0x428a2f98428a2f98
|
||||
DATA ·kcon+0x008(SB)/8, $0x428a2f98428a2f98
|
||||
DATA ·kcon+0x010(SB)/8, $0x7137449171374491
|
||||
DATA ·kcon+0x018(SB)/8, $0x7137449171374491
|
||||
DATA ·kcon+0x020(SB)/8, $0xb5c0fbcfb5c0fbcf
|
||||
DATA ·kcon+0x028(SB)/8, $0xb5c0fbcfb5c0fbcf
|
||||
DATA ·kcon+0x030(SB)/8, $0xe9b5dba5e9b5dba5
|
||||
DATA ·kcon+0x038(SB)/8, $0xe9b5dba5e9b5dba5
|
||||
DATA ·kcon+0x040(SB)/8, $0x3956c25b3956c25b
|
||||
DATA ·kcon+0x048(SB)/8, $0x3956c25b3956c25b
|
||||
DATA ·kcon+0x050(SB)/8, $0x59f111f159f111f1
|
||||
DATA ·kcon+0x058(SB)/8, $0x59f111f159f111f1
|
||||
DATA ·kcon+0x060(SB)/8, $0x923f82a4923f82a4
|
||||
DATA ·kcon+0x068(SB)/8, $0x923f82a4923f82a4
|
||||
DATA ·kcon+0x070(SB)/8, $0xab1c5ed5ab1c5ed5
|
||||
DATA ·kcon+0x078(SB)/8, $0xab1c5ed5ab1c5ed5
|
||||
DATA ·kcon+0x080(SB)/8, $0xd807aa98d807aa98
|
||||
DATA ·kcon+0x088(SB)/8, $0xd807aa98d807aa98
|
||||
DATA ·kcon+0x090(SB)/8, $0x12835b0112835b01
|
||||
DATA ·kcon+0x098(SB)/8, $0x12835b0112835b01
|
||||
DATA ·kcon+0x0A0(SB)/8, $0x243185be243185be
|
||||
DATA ·kcon+0x0A8(SB)/8, $0x243185be243185be
|
||||
DATA ·kcon+0x0B0(SB)/8, $0x550c7dc3550c7dc3
|
||||
DATA ·kcon+0x0B8(SB)/8, $0x550c7dc3550c7dc3
|
||||
DATA ·kcon+0x0C0(SB)/8, $0x72be5d7472be5d74
|
||||
DATA ·kcon+0x0C8(SB)/8, $0x72be5d7472be5d74
|
||||
DATA ·kcon+0x0D0(SB)/8, $0x80deb1fe80deb1fe
|
||||
DATA ·kcon+0x0D8(SB)/8, $0x80deb1fe80deb1fe
|
||||
DATA ·kcon+0x0E0(SB)/8, $0x9bdc06a79bdc06a7
|
||||
DATA ·kcon+0x0E8(SB)/8, $0x9bdc06a79bdc06a7
|
||||
DATA ·kcon+0x0F0(SB)/8, $0xc19bf174c19bf174
|
||||
DATA ·kcon+0x0F8(SB)/8, $0xc19bf174c19bf174
|
||||
DATA ·kcon+0x100(SB)/8, $0xe49b69c1e49b69c1
|
||||
DATA ·kcon+0x108(SB)/8, $0xe49b69c1e49b69c1
|
||||
DATA ·kcon+0x110(SB)/8, $0xefbe4786efbe4786
|
||||
DATA ·kcon+0x118(SB)/8, $0xefbe4786efbe4786
|
||||
DATA ·kcon+0x120(SB)/8, $0x0fc19dc60fc19dc6
|
||||
DATA ·kcon+0x128(SB)/8, $0x0fc19dc60fc19dc6
|
||||
DATA ·kcon+0x130(SB)/8, $0x240ca1cc240ca1cc
|
||||
DATA ·kcon+0x138(SB)/8, $0x240ca1cc240ca1cc
|
||||
DATA ·kcon+0x140(SB)/8, $0x2de92c6f2de92c6f
|
||||
DATA ·kcon+0x148(SB)/8, $0x2de92c6f2de92c6f
|
||||
DATA ·kcon+0x150(SB)/8, $0x4a7484aa4a7484aa
|
||||
DATA ·kcon+0x158(SB)/8, $0x4a7484aa4a7484aa
|
||||
DATA ·kcon+0x160(SB)/8, $0x5cb0a9dc5cb0a9dc
|
||||
DATA ·kcon+0x168(SB)/8, $0x5cb0a9dc5cb0a9dc
|
||||
DATA ·kcon+0x170(SB)/8, $0x76f988da76f988da
|
||||
DATA ·kcon+0x178(SB)/8, $0x76f988da76f988da
|
||||
DATA ·kcon+0x180(SB)/8, $0x983e5152983e5152
|
||||
DATA ·kcon+0x188(SB)/8, $0x983e5152983e5152
|
||||
DATA ·kcon+0x190(SB)/8, $0xa831c66da831c66d
|
||||
DATA ·kcon+0x198(SB)/8, $0xa831c66da831c66d
|
||||
DATA ·kcon+0x1A0(SB)/8, $0xb00327c8b00327c8
|
||||
DATA ·kcon+0x1A8(SB)/8, $0xb00327c8b00327c8
|
||||
DATA ·kcon+0x1B0(SB)/8, $0xbf597fc7bf597fc7
|
||||
DATA ·kcon+0x1B8(SB)/8, $0xbf597fc7bf597fc7
|
||||
DATA ·kcon+0x1C0(SB)/8, $0xc6e00bf3c6e00bf3
|
||||
DATA ·kcon+0x1C8(SB)/8, $0xc6e00bf3c6e00bf3
|
||||
DATA ·kcon+0x1D0(SB)/8, $0xd5a79147d5a79147
|
||||
DATA ·kcon+0x1D8(SB)/8, $0xd5a79147d5a79147
|
||||
DATA ·kcon+0x1E0(SB)/8, $0x06ca635106ca6351
|
||||
DATA ·kcon+0x1E8(SB)/8, $0x06ca635106ca6351
|
||||
DATA ·kcon+0x1F0(SB)/8, $0x1429296714292967
|
||||
DATA ·kcon+0x1F8(SB)/8, $0x1429296714292967
|
||||
DATA ·kcon+0x200(SB)/8, $0x27b70a8527b70a85
|
||||
DATA ·kcon+0x208(SB)/8, $0x27b70a8527b70a85
|
||||
DATA ·kcon+0x210(SB)/8, $0x2e1b21382e1b2138
|
||||
DATA ·kcon+0x218(SB)/8, $0x2e1b21382e1b2138
|
||||
DATA ·kcon+0x220(SB)/8, $0x4d2c6dfc4d2c6dfc
|
||||
DATA ·kcon+0x228(SB)/8, $0x4d2c6dfc4d2c6dfc
|
||||
DATA ·kcon+0x230(SB)/8, $0x53380d1353380d13
|
||||
DATA ·kcon+0x238(SB)/8, $0x53380d1353380d13
|
||||
DATA ·kcon+0x240(SB)/8, $0x650a7354650a7354
|
||||
DATA ·kcon+0x248(SB)/8, $0x650a7354650a7354
|
||||
DATA ·kcon+0x250(SB)/8, $0x766a0abb766a0abb
|
||||
DATA ·kcon+0x258(SB)/8, $0x766a0abb766a0abb
|
||||
DATA ·kcon+0x260(SB)/8, $0x81c2c92e81c2c92e
|
||||
DATA ·kcon+0x268(SB)/8, $0x81c2c92e81c2c92e
|
||||
DATA ·kcon+0x270(SB)/8, $0x92722c8592722c85
|
||||
DATA ·kcon+0x278(SB)/8, $0x92722c8592722c85
|
||||
DATA ·kcon+0x280(SB)/8, $0xa2bfe8a1a2bfe8a1
|
||||
DATA ·kcon+0x288(SB)/8, $0xa2bfe8a1a2bfe8a1
|
||||
DATA ·kcon+0x290(SB)/8, $0xa81a664ba81a664b
|
||||
DATA ·kcon+0x298(SB)/8, $0xa81a664ba81a664b
|
||||
DATA ·kcon+0x2A0(SB)/8, $0xc24b8b70c24b8b70
|
||||
DATA ·kcon+0x2A8(SB)/8, $0xc24b8b70c24b8b70
|
||||
DATA ·kcon+0x2B0(SB)/8, $0xc76c51a3c76c51a3
|
||||
DATA ·kcon+0x2B8(SB)/8, $0xc76c51a3c76c51a3
|
||||
DATA ·kcon+0x2C0(SB)/8, $0xd192e819d192e819
|
||||
DATA ·kcon+0x2C8(SB)/8, $0xd192e819d192e819
|
||||
DATA ·kcon+0x2D0(SB)/8, $0xd6990624d6990624
|
||||
DATA ·kcon+0x2D8(SB)/8, $0xd6990624d6990624
|
||||
DATA ·kcon+0x2E0(SB)/8, $0xf40e3585f40e3585
|
||||
DATA ·kcon+0x2E8(SB)/8, $0xf40e3585f40e3585
|
||||
DATA ·kcon+0x2F0(SB)/8, $0x106aa070106aa070
|
||||
DATA ·kcon+0x2F8(SB)/8, $0x106aa070106aa070
|
||||
DATA ·kcon+0x300(SB)/8, $0x19a4c11619a4c116
|
||||
DATA ·kcon+0x308(SB)/8, $0x19a4c11619a4c116
|
||||
DATA ·kcon+0x310(SB)/8, $0x1e376c081e376c08
|
||||
DATA ·kcon+0x318(SB)/8, $0x1e376c081e376c08
|
||||
DATA ·kcon+0x320(SB)/8, $0x2748774c2748774c
|
||||
DATA ·kcon+0x328(SB)/8, $0x2748774c2748774c
|
||||
DATA ·kcon+0x330(SB)/8, $0x34b0bcb534b0bcb5
|
||||
DATA ·kcon+0x338(SB)/8, $0x34b0bcb534b0bcb5
|
||||
DATA ·kcon+0x340(SB)/8, $0x391c0cb3391c0cb3
|
||||
DATA ·kcon+0x348(SB)/8, $0x391c0cb3391c0cb3
|
||||
DATA ·kcon+0x350(SB)/8, $0x4ed8aa4a4ed8aa4a
|
||||
DATA ·kcon+0x358(SB)/8, $0x4ed8aa4a4ed8aa4a
|
||||
DATA ·kcon+0x360(SB)/8, $0x5b9cca4f5b9cca4f
|
||||
DATA ·kcon+0x368(SB)/8, $0x5b9cca4f5b9cca4f
|
||||
DATA ·kcon+0x370(SB)/8, $0x682e6ff3682e6ff3
|
||||
DATA ·kcon+0x378(SB)/8, $0x682e6ff3682e6ff3
|
||||
DATA ·kcon+0x380(SB)/8, $0x748f82ee748f82ee
|
||||
DATA ·kcon+0x388(SB)/8, $0x748f82ee748f82ee
|
||||
DATA ·kcon+0x390(SB)/8, $0x78a5636f78a5636f
|
||||
DATA ·kcon+0x398(SB)/8, $0x78a5636f78a5636f
|
||||
DATA ·kcon+0x3A0(SB)/8, $0x84c8781484c87814
|
||||
DATA ·kcon+0x3A8(SB)/8, $0x84c8781484c87814
|
||||
DATA ·kcon+0x3B0(SB)/8, $0x8cc702088cc70208
|
||||
DATA ·kcon+0x3B8(SB)/8, $0x8cc702088cc70208
|
||||
DATA ·kcon+0x3C0(SB)/8, $0x90befffa90befffa
|
||||
DATA ·kcon+0x3C8(SB)/8, $0x90befffa90befffa
|
||||
DATA ·kcon+0x3D0(SB)/8, $0xa4506ceba4506ceb
|
||||
DATA ·kcon+0x3D8(SB)/8, $0xa4506ceba4506ceb
|
||||
DATA ·kcon+0x3E0(SB)/8, $0xbef9a3f7bef9a3f7
|
||||
DATA ·kcon+0x3E8(SB)/8, $0xbef9a3f7bef9a3f7
|
||||
DATA ·kcon+0x3F0(SB)/8, $0xc67178f2c67178f2
|
||||
DATA ·kcon+0x3F8(SB)/8, $0xc67178f2c67178f2
|
||||
DATA ·kcon+0x400(SB)/8, $0x0000000000000000
|
||||
DATA ·kcon+0x408(SB)/8, $0x0000000000000000
|
||||
|
||||
#ifdef GOARCH_ppc64le
|
||||
DATA ·kcon+0x410(SB)/8, $0x1011121310111213 // permutation control vectors
|
||||
DATA ·kcon+0x418(SB)/8, $0x1011121300010203
|
||||
DATA ·kcon+0x420(SB)/8, $0x1011121310111213
|
||||
DATA ·kcon+0x428(SB)/8, $0x0405060700010203
|
||||
DATA ·kcon+0x430(SB)/8, $0x1011121308090a0b
|
||||
DATA ·kcon+0x438(SB)/8, $0x0405060700010203
|
||||
#else
|
||||
DATA ·kcon+0x410(SB)/8, $0x1011121300010203
|
||||
DATA ·kcon+0x418(SB)/8, $0x1011121310111213 // permutation control vectors
|
||||
DATA ·kcon+0x420(SB)/8, $0x0405060700010203
|
||||
DATA ·kcon+0x428(SB)/8, $0x1011121310111213
|
||||
DATA ·kcon+0x430(SB)/8, $0x0001020304050607
|
||||
DATA ·kcon+0x438(SB)/8, $0x08090a0b10111213
|
||||
#endif
|
||||
|
||||
GLOBL ·kcon(SB), RODATA, $1088
|
||||
|
||||
#define SHA256ROUND0(a, b, c, d, e, f, g, h, xi) \
|
||||
VSEL g, f, e, FUNC; \
|
||||
VSHASIGMAW $15, e, $1, S1; \
|
||||
VADDUWM xi, h, h; \
|
||||
VSHASIGMAW $0, a, $1, S0; \
|
||||
VADDUWM FUNC, h, h; \
|
||||
VXOR b, a, FUNC; \
|
||||
VADDUWM S1, h, h; \
|
||||
VSEL b, c, FUNC, FUNC; \
|
||||
VADDUWM KI, g, g; \
|
||||
VADDUWM h, d, d; \
|
||||
VADDUWM FUNC, S0, S0; \
|
||||
LVX (TBL)(IDX), KI; \
|
||||
ADD $16, IDX; \
|
||||
VADDUWM S0, h, h
|
||||
|
||||
#define SHA256ROUND1(a, b, c, d, e, f, g, h, xi, xj, xj_1, xj_9, xj_14) \
|
||||
VSHASIGMAW $0, xj_1, $0, s0; \
|
||||
VSEL g, f, e, FUNC; \
|
||||
VSHASIGMAW $15, e, $1, S1; \
|
||||
VADDUWM xi, h, h; \
|
||||
VSHASIGMAW $0, a, $1, S0; \
|
||||
VSHASIGMAW $15, xj_14, $0, s1; \
|
||||
VADDUWM FUNC, h, h; \
|
||||
VXOR b, a, FUNC; \
|
||||
VADDUWM xj_9, xj, xj; \
|
||||
VADDUWM S1, h, h; \
|
||||
VSEL b, c, FUNC, FUNC; \
|
||||
VADDUWM KI, g, g; \
|
||||
VADDUWM h, d, d; \
|
||||
VADDUWM FUNC, S0, S0; \
|
||||
VADDUWM s0, xj, xj; \
|
||||
LVX (TBL)(IDX), KI; \
|
||||
ADD $16, IDX; \
|
||||
VADDUWM S0, h, h; \
|
||||
VADDUWM s1, xj, xj
|
||||
|
||||
#ifdef GOARCH_ppc64le
|
||||
#define VPERMLE(va,vb,vc,vt) VPERM va, vb, vc, vt
|
||||
#else
|
||||
#define VPERMLE(va,vb,vc,vt)
|
||||
#endif
|
||||
|
||||
// func block(dig *digest, p []byte)
|
||||
TEXT ·block(SB),0,$0-32
|
||||
MOVD dig+0(FP), CTX
|
||||
MOVD p_base+8(FP), INP
|
||||
MOVD p_len+16(FP), LEN
|
||||
|
||||
SRD $6, LEN
|
||||
SLD $6, LEN
|
||||
ADD INP, LEN, END
|
||||
|
||||
CMP INP, END
|
||||
BEQ end
|
||||
|
||||
MOVD $·kcon(SB), TBL
|
||||
MOVWZ $0x10, HEX10
|
||||
MOVWZ $8, IDX
|
||||
|
||||
#ifdef GOARCH_ppc64le
|
||||
LVSL (IDX)(R0), LEMASK
|
||||
VSPLTISB $0x0F, KI
|
||||
VXOR KI, LEMASK, LEMASK
|
||||
#endif
|
||||
|
||||
LXVW4X (CTX)(HEX00), VS32 // v0 = vs32
|
||||
LXVW4X (CTX)(HEX10), VS36 // v4 = vs36
|
||||
|
||||
// unpack the input values into vector registers
|
||||
VSLDOI $4, V0, V0, V1
|
||||
VSLDOI $8, V0, V0, V2
|
||||
VSLDOI $12, V0, V0, V3
|
||||
VSLDOI $4, V4, V4, V5
|
||||
VSLDOI $8, V4, V4, V6
|
||||
VSLDOI $12, V4, V4, V7
|
||||
|
||||
loop:
|
||||
LVX (TBL)(HEX00), KI
|
||||
MOVWZ $16, IDX
|
||||
|
||||
LXVD2X (INP)(R0), VS40 // load v8 (=vs40) in advance
|
||||
ADD $16, INP
|
||||
|
||||
// Offload to VSR24-31 (aka FPR24-31)
|
||||
XXLOR V0, V0, VS24
|
||||
XXLOR V1, V1, VS25
|
||||
XXLOR V2, V2, VS26
|
||||
XXLOR V3, V3, VS27
|
||||
XXLOR V4, V4, VS28
|
||||
XXLOR V5, V5, VS29
|
||||
XXLOR V6, V6, VS30
|
||||
XXLOR V7, V7, VS31
|
||||
|
||||
VADDUWM KI, V7, V7 // h+K[i]
|
||||
LVX (TBL)(IDX), KI
|
||||
ADD $16, IDX
|
||||
|
||||
VPERMLE(V8, V8, LEMASK, V8)
|
||||
SHA256ROUND0(V0, V1, V2, V3, V4, V5, V6, V7, V8)
|
||||
VSLDOI $4, V8, V8, V9
|
||||
SHA256ROUND0(V7, V0, V1, V2, V3, V4, V5, V6, V9)
|
||||
VSLDOI $4, V9, V9, V10
|
||||
SHA256ROUND0(V6, V7, V0, V1, V2, V3, V4, V5, V10)
|
||||
LXVD2X (INP)(R0), VS44 // load v12 (=vs44) in advance
|
||||
ADD $16, INP, INP
|
||||
VSLDOI $4, V10, V10, V11
|
||||
SHA256ROUND0(V5, V6, V7, V0, V1, V2, V3, V4, V11)
|
||||
VPERMLE(V12, V12, LEMASK, V12)
|
||||
SHA256ROUND0(V4, V5, V6, V7, V0, V1, V2, V3, V12)
|
||||
VSLDOI $4, V12, V12, V13
|
||||
SHA256ROUND0(V3, V4, V5, V6, V7, V0, V1, V2, V13)
|
||||
VSLDOI $4, V13, V13, V14
|
||||
SHA256ROUND0(V2, V3, V4, V5, V6, V7, V0, V1, V14)
|
||||
LXVD2X (INP)(R0), VS48 // load v16 (=vs48) in advance
|
||||
ADD $16, INP, INP
|
||||
VSLDOI $4, V14, V14, V15
|
||||
SHA256ROUND0(V1, V2, V3, V4, V5, V6, V7, V0, V15)
|
||||
VPERMLE(V16, V16, LEMASK, V16)
|
||||
SHA256ROUND0(V0, V1, V2, V3, V4, V5, V6, V7, V16)
|
||||
VSLDOI $4, V16, V16, V17
|
||||
SHA256ROUND0(V7, V0, V1, V2, V3, V4, V5, V6, V17)
|
||||
VSLDOI $4, V17, V17, V18
|
||||
SHA256ROUND0(V6, V7, V0, V1, V2, V3, V4, V5, V18)
|
||||
VSLDOI $4, V18, V18, V19
|
||||
LXVD2X (INP)(R0), VS52 // load v20 (=vs52) in advance
|
||||
ADD $16, INP, INP
|
||||
SHA256ROUND0(V5, V6, V7, V0, V1, V2, V3, V4, V19)
|
||||
VPERMLE(V20, V20, LEMASK, V20)
|
||||
SHA256ROUND0(V4, V5, V6, V7, V0, V1, V2, V3, V20)
|
||||
VSLDOI $4, V20, V20, V21
|
||||
SHA256ROUND0(V3, V4, V5, V6, V7, V0, V1, V2, V21)
|
||||
VSLDOI $4, V21, V21, V22
|
||||
SHA256ROUND0(V2, V3, V4, V5, V6, V7, V0, V1, V22)
|
||||
VSLDOI $4, V22, V22, V23
|
||||
SHA256ROUND1(V1, V2, V3, V4, V5, V6, V7, V0, V23, V8, V9, V17, V22)
|
||||
|
||||
MOVWZ $3, TEMP
|
||||
MOVWZ TEMP, CTR
|
||||
|
||||
L16_xx:
|
||||
SHA256ROUND1(V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V18, V23)
|
||||
SHA256ROUND1(V7, V0, V1, V2, V3, V4, V5, V6, V9, V10, V11, V19, V8)
|
||||
SHA256ROUND1(V6, V7, V0, V1, V2, V3, V4, V5, V10, V11, V12, V20, V9)
|
||||
SHA256ROUND1(V5, V6, V7, V0, V1, V2, V3, V4, V11, V12, V13, V21, V10)
|
||||
SHA256ROUND1(V4, V5, V6, V7, V0, V1, V2, V3, V12, V13, V14, V22, V11)
|
||||
SHA256ROUND1(V3, V4, V5, V6, V7, V0, V1, V2, V13, V14, V15, V23, V12)
|
||||
SHA256ROUND1(V2, V3, V4, V5, V6, V7, V0, V1, V14, V15, V16, V8, V13)
|
||||
SHA256ROUND1(V1, V2, V3, V4, V5, V6, V7, V0, V15, V16, V17, V9, V14)
|
||||
SHA256ROUND1(V0, V1, V2, V3, V4, V5, V6, V7, V16, V17, V18, V10, V15)
|
||||
SHA256ROUND1(V7, V0, V1, V2, V3, V4, V5, V6, V17, V18, V19, V11, V16)
|
||||
SHA256ROUND1(V6, V7, V0, V1, V2, V3, V4, V5, V18, V19, V20, V12, V17)
|
||||
SHA256ROUND1(V5, V6, V7, V0, V1, V2, V3, V4, V19, V20, V21, V13, V18)
|
||||
SHA256ROUND1(V4, V5, V6, V7, V0, V1, V2, V3, V20, V21, V22, V14, V19)
|
||||
SHA256ROUND1(V3, V4, V5, V6, V7, V0, V1, V2, V21, V22, V23, V15, V20)
|
||||
SHA256ROUND1(V2, V3, V4, V5, V6, V7, V0, V1, V22, V23, V8, V16, V21)
|
||||
SHA256ROUND1(V1, V2, V3, V4, V5, V6, V7, V0, V23, V8, V9, V17, V22)
|
||||
|
||||
BC 0x10, 0, L16_xx // bdnz
|
||||
|
||||
XXLOR VS24, VS24, V10
|
||||
|
||||
XXLOR VS25, VS25, V11
|
||||
VADDUWM V10, V0, V0
|
||||
XXLOR VS26, VS26, V12
|
||||
VADDUWM V11, V1, V1
|
||||
XXLOR VS27, VS27, V13
|
||||
VADDUWM V12, V2, V2
|
||||
XXLOR VS28, VS28, V14
|
||||
VADDUWM V13, V3, V3
|
||||
XXLOR VS29, VS29, V15
|
||||
VADDUWM V14, V4, V4
|
||||
XXLOR VS30, VS30, V16
|
||||
VADDUWM V15, V5, V5
|
||||
XXLOR VS31, VS31, V17
|
||||
VADDUWM V16, V6, V6
|
||||
VADDUWM V17, V7, V7
|
||||
|
||||
CMPU INP, END
|
||||
BLT loop
|
||||
|
||||
LVX (TBL)(IDX), V8
|
||||
ADD $16, IDX
|
||||
VPERM V0, V1, KI, V0
|
||||
LVX (TBL)(IDX), V9
|
||||
VPERM V4, V5, KI, V4
|
||||
VPERM V0, V2, V8, V0
|
||||
VPERM V4, V6, V8, V4
|
||||
VPERM V0, V3, V9, V0
|
||||
VPERM V4, V7, V9, V4
|
||||
STXVD2X VS32, (CTX+HEX00) // v0 = vs32
|
||||
STXVD2X VS36, (CTX+HEX10) // v4 = vs36
|
||||
|
||||
end:
|
||||
RET
|
||||
|
||||
|
|
@ -10,9 +10,9 @@ import (
|
|||
"bytes"
|
||||
"cmd/internal/bio"
|
||||
"cmd/internal/goobj"
|
||||
"cmd/internal/notsha256"
|
||||
"cmd/internal/objabi"
|
||||
"cmd/internal/sys"
|
||||
"crypto/sha1"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
|
|
@ -460,7 +460,7 @@ func contentHash64(s *LSym) goobj.Hash64Type {
|
|||
// For now, we assume there is no circular dependencies among
|
||||
// hashed symbols.
|
||||
func (w *writer) contentHash(s *LSym) goobj.HashType {
|
||||
h := sha1.New()
|
||||
h := notsha256.New()
|
||||
var tmp [14]byte
|
||||
|
||||
// Include the size of the symbol in the hash.
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@ package obj
|
|||
|
||||
import (
|
||||
"cmd/internal/goobj"
|
||||
"cmd/internal/notsha256"
|
||||
"cmd/internal/objabi"
|
||||
"crypto/md5"
|
||||
"fmt"
|
||||
"internal/buildcfg"
|
||||
"log"
|
||||
|
|
@ -175,7 +175,7 @@ func (ctxt *Link) Int64Sym(i int64) *LSym {
|
|||
|
||||
// GCLocalsSym generates a content-addressable sym containing data.
|
||||
func (ctxt *Link) GCLocalsSym(data []byte) *LSym {
|
||||
return ctxt.LookupInit(fmt.Sprintf("gclocals·%x", md5.Sum(data)), func(lsym *LSym) {
|
||||
return ctxt.LookupInit(fmt.Sprintf("gclocals·%x", notsha256.Sum256(data)), func(lsym *LSym) {
|
||||
lsym.P = data
|
||||
lsym.Set(AttrContentAddressable, true)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@
|
|||
package ld
|
||||
|
||||
import (
|
||||
"cmd/internal/notsha256"
|
||||
"cmd/internal/objabi"
|
||||
"cmd/internal/sys"
|
||||
"cmd/link/internal/loader"
|
||||
"cmd/link/internal/sym"
|
||||
"crypto/sha1"
|
||||
"debug/elf"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
|
|
@ -1533,10 +1533,10 @@ func (ctxt *Link) doelf() {
|
|||
sb.SetType(sym.SRODATA)
|
||||
ldr.SetAttrSpecial(s, true)
|
||||
sb.SetReachable(true)
|
||||
sb.SetSize(sha1.Size)
|
||||
sb.SetSize(notsha256.Size)
|
||||
|
||||
sort.Sort(byPkg(ctxt.Library))
|
||||
h := sha1.New()
|
||||
h := notsha256.New()
|
||||
for _, l := range ctxt.Library {
|
||||
h.Write(l.Fingerprint[:])
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ import (
|
|||
"bytes"
|
||||
"cmd/internal/bio"
|
||||
"cmd/internal/goobj"
|
||||
"cmd/internal/notsha256"
|
||||
"cmd/internal/objabi"
|
||||
"cmd/internal/sys"
|
||||
"cmd/link/internal/loadelf"
|
||||
|
|
@ -42,7 +43,6 @@ import (
|
|||
"cmd/link/internal/loadpe"
|
||||
"cmd/link/internal/loadxcoff"
|
||||
"cmd/link/internal/sym"
|
||||
"crypto/sha1"
|
||||
"debug/elf"
|
||||
"debug/macho"
|
||||
"encoding/base64"
|
||||
|
|
@ -929,7 +929,7 @@ func typeSymbolMangle(name string) string {
|
|||
if len(name) <= 14 && !strings.Contains(name, "@") { // Issue 19529
|
||||
return name
|
||||
}
|
||||
hash := sha1.Sum([]byte(name))
|
||||
hash := notsha256.Sum256([]byte(name))
|
||||
prefix := "type."
|
||||
if name[5] == '.' {
|
||||
prefix = "type.."
|
||||
|
|
@ -1059,6 +1059,8 @@ var hostobj []Hostobj
|
|||
// These packages can use internal linking mode.
|
||||
// Others trigger external mode.
|
||||
var internalpkg = []string{
|
||||
"crypto/internal/boring",
|
||||
"crypto/internal/boring/syso",
|
||||
"crypto/x509",
|
||||
"net",
|
||||
"os/user",
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"cmd/internal/notsha256"
|
||||
"flag"
|
||||
"fmt"
|
||||
"go/build"
|
||||
|
|
@ -142,7 +142,7 @@ func testDisasm(t *testing.T, srcfname string, printCode bool, printGnuAsm bool,
|
|||
goarch = f[1]
|
||||
}
|
||||
|
||||
hash := md5.Sum([]byte(fmt.Sprintf("%v-%v-%v-%v", srcfname, flags, printCode, printGnuAsm)))
|
||||
hash := notsha256.Sum256([]byte(fmt.Sprintf("%v-%v-%v-%v", srcfname, flags, printCode, printGnuAsm)))
|
||||
hello := filepath.Join(tmp, fmt.Sprintf("hello-%x.exe", hash))
|
||||
args := []string{"build", "-o", hello}
|
||||
args = append(args, flags...)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
}
|
||||
|
|
|
|||
21
src/crypto/boring/boring.go
Normal file
21
src/crypto/boring/boring.go
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
// 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.
|
||||
|
||||
//go:build boringcrypto
|
||||
|
||||
// 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
|
||||
}
|
||||
22
src/crypto/boring/boring_test.go
Normal file
22
src/crypto/boring/boring_test.go
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
// 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.
|
||||
|
||||
//go:build boringcrypto
|
||||
|
||||
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")
|
||||
}
|
||||
}
|
||||
14
src/crypto/boring/notboring_test.go
Normal file
14
src/crypto/boring/notboring_test.go
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
// 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.
|
||||
|
||||
//go:build (goexperiment.boringcrypto && !boringcrypto) || (!goexperiment.boringcrypto && boringcrypto)
|
||||
// +build goexperiment.boringcrypto,!boringcrypto !goexperiment.boringcrypto,boringcrypto
|
||||
|
||||
package boring_test
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestNotBoring(t *testing.T) {
|
||||
t.Error("goexperiment.boringcrypto and boringcrypto should be equivalent build tags")
|
||||
}
|
||||
106
src/crypto/ecdsa/boring.go
Normal file
106
src/crypto/ecdsa/boring.go
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
// 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.
|
||||
|
||||
//go:build boringcrypto
|
||||
|
||||
package ecdsa
|
||||
|
||||
import (
|
||||
"crypto/internal/boring"
|
||||
"crypto/internal/boring/bbig"
|
||||
"math/big"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Cached conversions from Go PublicKey/PrivateKey to BoringCrypto.
|
||||
//
|
||||
// The first operation on a PublicKey or PrivateKey makes a parallel
|
||||
// BoringCrypto key and saves it in pubCache or privCache.
|
||||
//
|
||||
// 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.
|
||||
|
||||
var pubCache boring.Cache
|
||||
var privCache boring.Cache
|
||||
|
||||
func init() {
|
||||
pubCache.Register()
|
||||
privCache.Register()
|
||||
}
|
||||
|
||||
type boringPub struct {
|
||||
key *boring.PublicKeyECDSA
|
||||
orig PublicKey
|
||||
}
|
||||
|
||||
func boringPublicKey(pub *PublicKey) (*boring.PublicKeyECDSA, error) {
|
||||
b := (*boringPub)(pubCache.Get(unsafe.Pointer(pub)))
|
||||
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, bbig.Enc(b.orig.X), bbig.Enc(b.orig.Y))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b.key = key
|
||||
pubCache.Put(unsafe.Pointer(pub), unsafe.Pointer(b))
|
||||
return key, nil
|
||||
}
|
||||
|
||||
type boringPriv struct {
|
||||
key *boring.PrivateKeyECDSA
|
||||
orig PrivateKey
|
||||
}
|
||||
|
||||
func boringPrivateKey(priv *PrivateKey) (*boring.PrivateKeyECDSA, error) {
|
||||
b := (*boringPriv)(privCache.Get(unsafe.Pointer(priv)))
|
||||
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, bbig.Enc(b.orig.X), bbig.Enc(b.orig.Y), bbig.Enc(b.orig.D))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b.key = key
|
||||
privCache.Put(unsafe.Pointer(priv), 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),
|
||||
}
|
||||
}
|
||||
|
|
@ -24,12 +24,15 @@ import (
|
|||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/elliptic"
|
||||
"crypto/internal/boring/bbig"
|
||||
"crypto/internal/randutil"
|
||||
"crypto/sha512"
|
||||
"errors"
|
||||
"io"
|
||||
"math/big"
|
||||
|
||||
"crypto/internal/boring"
|
||||
|
||||
"golang.org/x/crypto/cryptobyte"
|
||||
"golang.org/x/crypto/cryptobyte/asn1"
|
||||
)
|
||||
|
|
@ -107,6 +110,15 @@ func (priv *PrivateKey) Equal(x crypto.PrivateKey) bool {
|
|||
// where the private part is kept in, for example, a hardware module. Common
|
||||
// uses can use the SignASN1 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
|
||||
|
|
@ -143,6 +155,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: bbig.Dec(x), Y: bbig.Dec(y)}, D: bbig.Dec(d)}, nil
|
||||
}
|
||||
boring.UnreachableExceptTests()
|
||||
|
||||
k, err := randFieldElement(c, rand)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -194,6 +215,29 @@ 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
|
||||
}
|
||||
sig, err := boring.SignMarshalECDSA(b, hash)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
var r, s big.Int
|
||||
var inner cryptobyte.String
|
||||
input := cryptobyte.String(sig)
|
||||
if !input.ReadASN1(&inner, asn1.SEQUENCE) ||
|
||||
!input.Empty() ||
|
||||
!inner.ReadASN1Integer(&r) ||
|
||||
!inner.ReadASN1Integer(&s) ||
|
||||
!inner.Empty() {
|
||||
return nil, nil, errors.New("invalid ASN.1 from boringcrypto")
|
||||
}
|
||||
return &r, &s, nil
|
||||
}
|
||||
boring.UnreachableExceptTests()
|
||||
|
||||
// This implementation derives the nonce from an AES-CTR CSPRNG keyed by:
|
||||
//
|
||||
// SHA2-512(priv.D || entropy || hash)[:32]
|
||||
|
|
@ -290,6 +334,24 @@ func SignASN1(rand io.Reader, priv *PrivateKey, hash []byte) ([]byte, error) {
|
|||
// return value records whether the signature is valid. Most applications should
|
||||
// use VerifyASN1 instead of dealing directly with r, s.
|
||||
func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool {
|
||||
if boring.Enabled {
|
||||
key, err := boringPublicKey(pub)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
var b cryptobyte.Builder
|
||||
b.AddASN1(asn1.SEQUENCE, func(b *cryptobyte.Builder) {
|
||||
b.AddASN1BigInt(r)
|
||||
b.AddASN1BigInt(s)
|
||||
})
|
||||
sig, err := b.Bytes()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return boring.VerifyECDSA(key, hash, sig)
|
||||
}
|
||||
boring.UnreachableExceptTests()
|
||||
|
||||
c := pub.Curve
|
||||
N := c.Params().N
|
||||
|
||||
|
|
|
|||
16
src/crypto/ecdsa/notboring.go
Normal file
16
src/crypto/ecdsa/notboring.go
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright 2022 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.
|
||||
|
||||
//go:build !boringcrypto
|
||||
|
||||
package ecdsa
|
||||
|
||||
import "crypto/internal/boring"
|
||||
|
||||
func boringPublicKey(*PublicKey) (*boring.PublicKeyECDSA, error) {
|
||||
panic("boringcrypto: not available")
|
||||
}
|
||||
func boringPrivateKey(*PrivateKey) (*boring.PrivateKeyECDSA, error) {
|
||||
panic("boringcrypto: not available")
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ import (
|
|||
"bytes"
|
||||
"compress/gzip"
|
||||
"crypto"
|
||||
"crypto/internal/boring"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"os"
|
||||
|
|
@ -186,6 +187,9 @@ func TestMalleability(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestAllocations(t *testing.T) {
|
||||
if boring.Enabled {
|
||||
t.Skip("skipping allocations test with BoringCrypto")
|
||||
}
|
||||
if strings.HasSuffix(os.Getenv("GO_BUILDER_NAME"), "-noopt") {
|
||||
t.Skip("skipping allocations test without relevant optimizations")
|
||||
}
|
||||
|
|
@ -199,7 +203,7 @@ func TestAllocations(t *testing.T) {
|
|||
t.Fatal("signature didn't verify")
|
||||
}
|
||||
}); allocs > 0 {
|
||||
t.Errorf("expected zero allocations, got %0.1v", allocs)
|
||||
t.Errorf("expected zero allocations, got %0.1f", allocs)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
44
src/crypto/internal/boring/Dockerfile
Normal file
44
src/crypto/internal/boring/Dockerfile
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
# 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.
|
||||
#
|
||||
# $ podman build -t goboring:140sp3678 .
|
||||
# $ podman run -it --name goboring-140sp3678 goboring:140sp3678
|
||||
# $ podman cp goboring-140sp3678:/boring/godriver/goboringcrypto_linux_amd64.syso syso
|
||||
# $ sha256sum syso/goboringcrypto_linux_amd64.syso # compare to docker output
|
||||
#
|
||||
# The podman commands may need to run under sudo to work around a subuid/subgid bug.
|
||||
|
||||
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"]
|
||||
202
src/crypto/internal/boring/LICENSE
Normal file
202
src/crypto/internal/boring/LICENSE
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
The Go source code and supporting files in this directory
|
||||
are covered by the usual Go license (see ../../../../LICENSE).
|
||||
|
||||
When building with GOEXPERIMENT=boringcrypto, the following applies.
|
||||
|
||||
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.
|
||||
389
src/crypto/internal/boring/aes.go
Normal file
389
src/crypto/internal/boring/aes.go
Normal file
|
|
@ -0,0 +1,389 @@
|
|||
// 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.
|
||||
|
||||
//go:build boringcrypto && linux && amd64 && !android && !cmd_go_bootstrap && !msan
|
||||
// +build boringcrypto,linux,amd64,!android,!cmd_go_bootstrap,!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)
|
||||
}
|
||||
33
src/crypto/internal/boring/bbig/big.go
Normal file
33
src/crypto/internal/boring/bbig/big.go
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright 2022 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 bbig
|
||||
|
||||
import (
|
||||
"crypto/internal/boring"
|
||||
"math/big"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func Enc(b *big.Int) boring.BigInt {
|
||||
if b == nil {
|
||||
return nil
|
||||
}
|
||||
x := b.Bits()
|
||||
if len(x) == 0 {
|
||||
return boring.BigInt{}
|
||||
}
|
||||
return unsafe.Slice((*uint)(&x[0]), len(x))
|
||||
}
|
||||
|
||||
func Dec(b boring.BigInt) *big.Int {
|
||||
if b == nil {
|
||||
return nil
|
||||
}
|
||||
if len(b) == 0 {
|
||||
return new(big.Int)
|
||||
}
|
||||
x := unsafe.Slice((*big.Word)(&b[0]), len(b))
|
||||
return new(big.Int).SetBits(x)
|
||||
}
|
||||
109
src/crypto/internal/boring/boring.go
Normal file
109
src/crypto/internal/boring/boring.go
Normal file
|
|
@ -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.
|
||||
|
||||
//go:build boringcrypto && linux && amd64 && !android && !cmd_go_bootstrap && !msan
|
||||
// +build boringcrypto,linux,amd64,!android,!cmd_go_bootstrap,!msan
|
||||
|
||||
package boring
|
||||
|
||||
/*
|
||||
// goboringcrypto_linux_amd64.syso references pthread functions.
|
||||
#cgo LDFLAGS: "-pthread"
|
||||
|
||||
#include "goboringcrypto.h"
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"crypto/internal/boring/sig"
|
||||
_ "crypto/internal/boring/syso"
|
||||
"math/bits"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
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 wbase(b BigInt) *C.uint8_t {
|
||||
if len(b) == 0 {
|
||||
return nil
|
||||
}
|
||||
return (*C.uint8_t)(unsafe.Pointer(&b[0]))
|
||||
}
|
||||
|
||||
const wordBytes = bits.UintSize / 8
|
||||
|
||||
func bigToBN(x BigInt) *C.GO_BIGNUM {
|
||||
return C._goboringcrypto_BN_le2bn(wbase(x), C.size_t(len(x)*wordBytes), nil)
|
||||
}
|
||||
|
||||
func bnToBig(bn *C.GO_BIGNUM) BigInt {
|
||||
x := make(BigInt, (C._goboringcrypto_BN_num_bytes(bn)+wordBytes-1)/wordBytes)
|
||||
if C._goboringcrypto_BN_bn2le_padded(wbase(x), C.size_t(len(x)*wordBytes), bn) == 0 {
|
||||
panic("boringcrypto: bignum conversion failed")
|
||||
}
|
||||
return x
|
||||
}
|
||||
|
||||
func bigToBn(bnp **C.GO_BIGNUM, b BigInt) bool {
|
||||
if *bnp != nil {
|
||||
C._goboringcrypto_BN_free(*bnp)
|
||||
*bnp = nil
|
||||
}
|
||||
if b == nil {
|
||||
return true
|
||||
}
|
||||
bn := bigToBN(b)
|
||||
if bn == nil {
|
||||
return false
|
||||
}
|
||||
*bnp = bn
|
||||
return true
|
||||
}
|
||||
|
||||
// noescape hides a pointer from escape analysis. noescape is
|
||||
// the identity function but escape analysis doesn't think the
|
||||
// output depends on the input. noescape is inlined and currently
|
||||
// compiles down to zero instructions.
|
||||
// USE CAREFULLY!
|
||||
//
|
||||
//go:nosplit
|
||||
func noescape(p unsafe.Pointer) unsafe.Pointer {
|
||||
x := uintptr(p)
|
||||
return unsafe.Pointer(x ^ 0)
|
||||
}
|
||||
34
src/crypto/internal/boring/boring_test.go
Normal file
34
src/crypto/internal/boring/boring_test.go
Normal file
|
|
@ -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()
|
||||
}
|
||||
196
src/crypto/internal/boring/build.sh
Executable file
196
src/crypto/internal/boring/build.sh
Executable file
|
|
@ -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
|
||||
140
src/crypto/internal/boring/cache.go
Normal file
140
src/crypto/internal/boring/cache.go
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
// Copyright 2022 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
|
||||
|
||||
import (
|
||||
"sync/atomic"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// A Cache is a GC-friendly concurrent map from unsafe.Pointer to
|
||||
// unsafe.Pointer. It is meant to be used for maintaining shadow
|
||||
// BoringCrypto state associated with certain allocated structs, in
|
||||
// particular public and private RSA and ECDSA keys.
|
||||
//
|
||||
// The cache is GC-friendly in the sense that the keys do not
|
||||
// indefinitely prevent the garbage collector from collecting them.
|
||||
// Instead, at the start of each GC, the cache is cleared entirely. That
|
||||
// is, the cache is lossy, and the loss happens at the start of each GC.
|
||||
// This means that clients need to be able to cope with cache entries
|
||||
// disappearing, but it also means that clients don't need to worry about
|
||||
// cache entries keeping the keys from being collected.
|
||||
//
|
||||
// TODO(rsc): Make Cache generic once consumers can handle that.
|
||||
type Cache struct {
|
||||
// ptable is an atomic *[cacheSize]unsafe.Pointer,
|
||||
// where each unsafe.Pointer is an atomic *cacheEntry.
|
||||
// The runtime atomically stores nil to ptable at the start of each GC.
|
||||
ptable unsafe.Pointer
|
||||
}
|
||||
|
||||
// A cacheEntry is a single entry in the linked list for a given hash table entry.
|
||||
type cacheEntry struct {
|
||||
k unsafe.Pointer // immutable once created
|
||||
v unsafe.Pointer // read and written atomically to allow updates
|
||||
next *cacheEntry // immutable once linked into table
|
||||
}
|
||||
|
||||
func registerCache(unsafe.Pointer) // provided by runtime
|
||||
|
||||
// Register registers the cache with the runtime,
|
||||
// so that c.ptable can be cleared at the start of each GC.
|
||||
// Register must be called during package initialization.
|
||||
func (c *Cache) Register() {
|
||||
registerCache(unsafe.Pointer(&c.ptable))
|
||||
}
|
||||
|
||||
// cacheSize is the number of entries in the hash table.
|
||||
// The hash is the pointer value mod cacheSize, a prime.
|
||||
// Collisions are resolved by maintaining a linked list in each hash slot.
|
||||
const cacheSize = 1021
|
||||
|
||||
// table returns a pointer to the current cache hash table,
|
||||
// coping with the possibility of the GC clearing it out from under us.
|
||||
func (c *Cache) table() *[cacheSize]unsafe.Pointer {
|
||||
for {
|
||||
p := atomic.LoadPointer(&c.ptable)
|
||||
if p == nil {
|
||||
p = unsafe.Pointer(new([cacheSize]unsafe.Pointer))
|
||||
if !atomic.CompareAndSwapPointer(&c.ptable, nil, p) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
return (*[cacheSize]unsafe.Pointer)(p)
|
||||
}
|
||||
}
|
||||
|
||||
// Clear clears the cache.
|
||||
// The runtime does this automatically at each garbage collection;
|
||||
// this method is exposed only for testing.
|
||||
func (c *Cache) Clear() {
|
||||
// The runtime does this at the start of every garbage collection
|
||||
// (itself, not by calling this function).
|
||||
atomic.StorePointer(&c.ptable, nil)
|
||||
}
|
||||
|
||||
// Get returns the cached value associated with v,
|
||||
// which is either the value v corresponding to the most recent call to Put(k, v)
|
||||
// or nil if that cache entry has been dropped.
|
||||
func (c *Cache) Get(k unsafe.Pointer) unsafe.Pointer {
|
||||
head := &c.table()[uintptr(k)%cacheSize]
|
||||
e := (*cacheEntry)(atomic.LoadPointer(head))
|
||||
for ; e != nil; e = e.next {
|
||||
if e.k == k {
|
||||
return atomic.LoadPointer(&e.v)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Put sets the cached value associated with k to v.
|
||||
func (c *Cache) Put(k, v unsafe.Pointer) {
|
||||
head := &c.table()[uintptr(k)%cacheSize]
|
||||
|
||||
// Strategy is to walk the linked list at head,
|
||||
// same as in Get, to look for existing entry.
|
||||
// If we find one, we update v atomically in place.
|
||||
// If not, then we race to replace the start = *head
|
||||
// we observed with a new k, v entry.
|
||||
// If we win that race, we're done.
|
||||
// Otherwise, we try the whole thing again,
|
||||
// with two optimizations:
|
||||
//
|
||||
// 1. We track in noK the start of the section of
|
||||
// the list that we've confirmed has no entry for k.
|
||||
// The next time down the list, we can stop at noK,
|
||||
// because new entries are inserted at the front of the list.
|
||||
// This guarantees we never traverse an entry
|
||||
// multiple times.
|
||||
//
|
||||
// 2. We only allocate the entry to be added once,
|
||||
// saving it in add for the next attempt.
|
||||
var add, noK *cacheEntry
|
||||
n := 0
|
||||
for {
|
||||
e := (*cacheEntry)(atomic.LoadPointer(head))
|
||||
start := e
|
||||
for ; e != nil && e != noK; e = e.next {
|
||||
if e.k == k {
|
||||
atomic.StorePointer(&e.v, v)
|
||||
return
|
||||
}
|
||||
n++
|
||||
}
|
||||
if add == nil {
|
||||
add = &cacheEntry{k, v, nil}
|
||||
}
|
||||
add.next = start
|
||||
if n >= 1000 {
|
||||
// If an individual list gets too long, which shouldn't happen,
|
||||
// throw it away to avoid quadratic lookup behavior.
|
||||
add.next = nil
|
||||
}
|
||||
if atomic.CompareAndSwapPointer(head, unsafe.Pointer(start), unsafe.Pointer(add)) {
|
||||
return
|
||||
}
|
||||
noK = start
|
||||
}
|
||||
}
|
||||
120
src/crypto/internal/boring/cache_test.go
Normal file
120
src/crypto/internal/boring/cache_test.go
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
// Copyright 2022 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
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var registeredCache Cache
|
||||
|
||||
func init() {
|
||||
registeredCache.Register()
|
||||
}
|
||||
|
||||
func TestCache(t *testing.T) {
|
||||
// Use unregistered cache for functionality tests,
|
||||
// to keep the runtime from clearing behind our backs.
|
||||
c := new(Cache)
|
||||
|
||||
// Create many entries.
|
||||
seq := uint32(0)
|
||||
next := func() unsafe.Pointer {
|
||||
x := new(int)
|
||||
*x = int(atomic.AddUint32(&seq, 1))
|
||||
return unsafe.Pointer(x)
|
||||
}
|
||||
m := make(map[unsafe.Pointer]unsafe.Pointer)
|
||||
for i := 0; i < 10000; i++ {
|
||||
k := next()
|
||||
v := next()
|
||||
m[k] = v
|
||||
c.Put(k, v)
|
||||
}
|
||||
|
||||
// Overwrite a random 20% of those.
|
||||
n := 0
|
||||
for k := range m {
|
||||
v := next()
|
||||
m[k] = v
|
||||
c.Put(k, v)
|
||||
if n++; n >= 2000 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Check results.
|
||||
str := func(p unsafe.Pointer) string {
|
||||
if p == nil {
|
||||
return "nil"
|
||||
}
|
||||
return fmt.Sprint(*(*int)(p))
|
||||
}
|
||||
for k, v := range m {
|
||||
if cv := c.Get(k); cv != v {
|
||||
t.Fatalf("c.Get(%v) = %v, want %v", str(k), str(cv), str(v))
|
||||
}
|
||||
}
|
||||
|
||||
c.Clear()
|
||||
for k := range m {
|
||||
if cv := c.Get(k); cv != nil {
|
||||
t.Fatalf("after GC, c.Get(%v) = %v, want nil", str(k), str(cv))
|
||||
}
|
||||
}
|
||||
|
||||
// Check that registered cache is cleared at GC.
|
||||
c = ®isteredCache
|
||||
for k, v := range m {
|
||||
c.Put(k, v)
|
||||
}
|
||||
runtime.GC()
|
||||
for k := range m {
|
||||
if cv := c.Get(k); cv != nil {
|
||||
t.Fatalf("after Clear, c.Get(%v) = %v, want nil", str(k), str(cv))
|
||||
}
|
||||
}
|
||||
|
||||
// Check that cache works for concurrent access.
|
||||
// Lists are discarded if they reach 1000 entries,
|
||||
// and there are cacheSize list heads, so we should be
|
||||
// able to do 100 * cacheSize entries with no problem at all.
|
||||
c = new(Cache)
|
||||
var barrier, wg sync.WaitGroup
|
||||
const N = 100
|
||||
barrier.Add(N)
|
||||
wg.Add(N)
|
||||
var lost int32
|
||||
for i := 0; i < N; i++ {
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
m := make(map[unsafe.Pointer]unsafe.Pointer)
|
||||
for j := 0; j < cacheSize; j++ {
|
||||
k, v := next(), next()
|
||||
m[k] = v
|
||||
c.Put(k, v)
|
||||
}
|
||||
barrier.Done()
|
||||
barrier.Wait()
|
||||
|
||||
for k, v := range m {
|
||||
if cv := c.Get(k); cv != v {
|
||||
t.Errorf("c.Get(%v) = %v, want %v", str(k), str(cv), str(v))
|
||||
atomic.AddInt32(&lost, +1)
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
if lost != 0 {
|
||||
t.Errorf("lost %d entries", lost)
|
||||
}
|
||||
}
|
||||
19
src/crypto/internal/boring/doc.go
Normal file
19
src/crypto/internal/boring/doc.go
Normal file
|
|
@ -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 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
|
||||
|
||||
// A BigInt is the raw words from a BigInt.
|
||||
// This definition allows us to avoid importing math/big.
|
||||
// Conversion between BigInt and *big.Int is in crypto/internal/boring/bbig.
|
||||
type BigInt []uint
|
||||
174
src/crypto/internal/boring/ecdsa.go
Normal file
174
src/crypto/internal/boring/ecdsa.go
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
// 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.
|
||||
|
||||
//go:build boringcrypto && linux && amd64 && !android && !cmd_go_bootstrap && !msan
|
||||
// +build boringcrypto,linux,amd64,!android,!cmd_go_bootstrap,!msan
|
||||
|
||||
package boring
|
||||
|
||||
// #include "goboringcrypto.h"
|
||||
import "C"
|
||||
import (
|
||||
"errors"
|
||||
"runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type ecdsaSignature struct {
|
||||
R, S BigInt
|
||||
}
|
||||
|
||||
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 BigInt) (*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 BigInt) (*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 BigInt, D BigInt) (*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 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, sig []byte) bool {
|
||||
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 BigInt, 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
|
||||
}
|
||||
12
src/crypto/internal/boring/fipstls/stub.s
Normal file
12
src/crypto/internal/boring/fipstls/stub.s
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
// 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.
|
||||
|
||||
//go:build boringcrypto
|
||||
|
||||
// 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).
|
||||
52
src/crypto/internal/boring/fipstls/tls.go
Normal file
52
src/crypto/internal/boring/fipstls/tls.go
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
// 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.
|
||||
|
||||
//go:build boringcrypto
|
||||
|
||||
// Package fipstls allows control over whether crypto/tls requires FIPS-approved settings.
|
||||
// This package only exists with GOEXPERIMENT=boringcrypto, but the effects are independent
|
||||
// of the use of BoringCrypto.
|
||||
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
|
||||
}
|
||||
239
src/crypto/internal/boring/goboringcrypto.h
Normal file
239
src/crypto/internal/boring/goboringcrypto.h
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
// 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*);
|
||||
GO_BIGNUM* _goboringcrypto_BN_le2bn(const uint8_t*, size_t, GO_BIGNUM*);
|
||||
size_t _goboringcrypto_BN_bn2bin(const GO_BIGNUM*, uint8_t*);
|
||||
int _goboringcrypto_BN_bn2le_padded(uint8_t*, size_t, const GO_BIGNUM*);
|
||||
|
||||
// #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);
|
||||
154
src/crypto/internal/boring/hmac.go
Normal file
154
src/crypto/internal/boring/hmac.go
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
// 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.
|
||||
|
||||
//go:build boringcrypto && linux && amd64 && !android && !cmd_go_bootstrap && !msan
|
||||
// +build boringcrypto,linux,amd64,!android,!cmd_go_bootstrap,!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...)
|
||||
}
|
||||
112
src/crypto/internal/boring/notboring.go
Normal file
112
src/crypto/internal/boring/notboring.go
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
// 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.
|
||||
|
||||
//go:build !boringcrypto || !linux || !amd64 || !cgo || android || cmd_go_bootstrap || msan
|
||||
// +build !boringcrypto !linux !amd64 !cgo android cmd_go_bootstrap msan
|
||||
|
||||
package boring
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/cipher"
|
||||
"crypto/internal/boring/sig"
|
||||
"hash"
|
||||
)
|
||||
|
||||
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 SHA1([]byte) [20]byte { panic("boringcrypto: not available") }
|
||||
func SHA224([]byte) [28]byte { panic("boringcrypto: not available") }
|
||||
func SHA256([]byte) [32]byte { panic("boringcrypto: not available") }
|
||||
func SHA384([]byte) [48]byte { panic("boringcrypto: not available") }
|
||||
func SHA512([]byte) [64]byte { 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 BigInt, err error) {
|
||||
panic("boringcrypto: not available")
|
||||
}
|
||||
func NewPrivateKeyECDSA(curve string, X, Y, D BigInt) (*PrivateKeyECDSA, error) {
|
||||
panic("boringcrypto: not available")
|
||||
}
|
||||
func NewPublicKeyECDSA(curve string, X, Y BigInt) (*PublicKeyECDSA, error) {
|
||||
panic("boringcrypto: not available")
|
||||
}
|
||||
func SignMarshalECDSA(priv *PrivateKeyECDSA, hash []byte) ([]byte, error) {
|
||||
panic("boringcrypto: not available")
|
||||
}
|
||||
func VerifyECDSA(pub *PublicKeyECDSA, hash []byte, sig []byte) 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 BigInt, err error) {
|
||||
panic("boringcrypto: not available")
|
||||
}
|
||||
func NewPrivateKeyRSA(N, E, D, P, Q, Dp, Dq, Qinv BigInt) (*PrivateKeyRSA, error) {
|
||||
panic("boringcrypto: not available")
|
||||
}
|
||||
func NewPublicKeyRSA(N, E BigInt) (*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")
|
||||
}
|
||||
25
src/crypto/internal/boring/rand.go
Normal file
25
src/crypto/internal/boring/rand.go
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
// 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.
|
||||
|
||||
//go:build boringcrypto && linux && amd64 && !android && !cmd_go_bootstrap && !msan
|
||||
// +build boringcrypto,linux,amd64,!android,!cmd_go_bootstrap,!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)
|
||||
347
src/crypto/internal/boring/rsa.go
Normal file
347
src/crypto/internal/boring/rsa.go
Normal file
|
|
@ -0,0 +1,347 @@
|
|||
// 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.
|
||||
|
||||
//go:build boringcrypto && linux && amd64 && !android && !cmd_go_bootstrap && !msan
|
||||
// +build boringcrypto,linux,amd64,!android,!cmd_go_bootstrap,!msan
|
||||
|
||||
package boring
|
||||
|
||||
// #include "goboringcrypto.h"
|
||||
import "C"
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/subtle"
|
||||
"errors"
|
||||
"hash"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func GenerateKeyRSA(bits int) (N, E, D, P, Q, Dp, Dq, Qinv BigInt, err error) {
|
||||
bad := func(e error) (N, E, D, P, Q, Dp, Dq, Qinv BigInt, 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 BigInt) (*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 BigInt) (*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
|
||||
}
|
||||
597
src/crypto/internal/boring/sha.go
Normal file
597
src/crypto/internal/boring/sha.go
Normal file
|
|
@ -0,0 +1,597 @@
|
|||
// 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.
|
||||
|
||||
//go:build boringcrypto && linux && amd64 && !android && !cmd_go_bootstrap && !msan
|
||||
// +build boringcrypto,linux,amd64,!android,!cmd_go_bootstrap,!msan
|
||||
|
||||
package boring
|
||||
|
||||
/*
|
||||
#include "goboringcrypto.h"
|
||||
|
||||
int
|
||||
_goboringcrypto_gosha1(void *p, size_t n, void *out)
|
||||
{
|
||||
GO_SHA_CTX ctx;
|
||||
_goboringcrypto_SHA1_Init(&ctx);
|
||||
return _goboringcrypto_SHA1_Update(&ctx, p, n) &&
|
||||
_goboringcrypto_SHA1_Final(out, &ctx);
|
||||
}
|
||||
|
||||
int
|
||||
_goboringcrypto_gosha224(void *p, size_t n, void *out)
|
||||
{
|
||||
GO_SHA256_CTX ctx;
|
||||
_goboringcrypto_SHA224_Init(&ctx);
|
||||
return _goboringcrypto_SHA224_Update(&ctx, p, n) &&
|
||||
_goboringcrypto_SHA224_Final(out, &ctx);
|
||||
}
|
||||
|
||||
int
|
||||
_goboringcrypto_gosha256(void *p, size_t n, void *out)
|
||||
{
|
||||
GO_SHA256_CTX ctx;
|
||||
_goboringcrypto_SHA256_Init(&ctx);
|
||||
return _goboringcrypto_SHA256_Update(&ctx, p, n) &&
|
||||
_goboringcrypto_SHA256_Final(out, &ctx);
|
||||
}
|
||||
|
||||
int
|
||||
_goboringcrypto_gosha384(void *p, size_t n, void *out)
|
||||
{
|
||||
GO_SHA512_CTX ctx;
|
||||
_goboringcrypto_SHA384_Init(&ctx);
|
||||
return _goboringcrypto_SHA384_Update(&ctx, p, n) &&
|
||||
_goboringcrypto_SHA384_Final(out, &ctx);
|
||||
}
|
||||
|
||||
int
|
||||
_goboringcrypto_gosha512(void *p, size_t n, void *out)
|
||||
{
|
||||
GO_SHA512_CTX ctx;
|
||||
_goboringcrypto_SHA512_Init(&ctx);
|
||||
return _goboringcrypto_SHA512_Update(&ctx, p, n) &&
|
||||
_goboringcrypto_SHA512_Final(out, &ctx);
|
||||
}
|
||||
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"errors"
|
||||
"hash"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func addr(p []byte) unsafe.Pointer {
|
||||
if len(p) == 0 {
|
||||
return nil
|
||||
}
|
||||
return unsafe.Pointer(&p[0])
|
||||
}
|
||||
|
||||
func SHA1(p []byte) (sum [20]byte) {
|
||||
if C._goboringcrypto_gosha1(noescape(addr(p)), C.size_t(len(p)), noescape(unsafe.Pointer(&sum[0]))) == 0 {
|
||||
panic("boringcrypto: SHA1 failed")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func SHA224(p []byte) (sum [28]byte) {
|
||||
if C._goboringcrypto_gosha224(noescape(addr(p)), C.size_t(len(p)), noescape(unsafe.Pointer(&sum[0]))) == 0 {
|
||||
panic("boringcrypto: SHA224 failed")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func SHA256(p []byte) (sum [32]byte) {
|
||||
if C._goboringcrypto_gosha256(noescape(addr(p)), C.size_t(len(p)), noescape(unsafe.Pointer(&sum[0]))) == 0 {
|
||||
panic("boringcrypto: SHA256 failed")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func SHA384(p []byte) (sum [48]byte) {
|
||||
if C._goboringcrypto_gosha384(noescape(addr(p)), C.size_t(len(p)), noescape(unsafe.Pointer(&sum[0]))) == 0 {
|
||||
panic("boringcrypto: SHA384 failed")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func SHA512(p []byte) (sum [64]byte) {
|
||||
if C._goboringcrypto_gosha512(noescape(addr(p)), C.size_t(len(p)), noescape(unsafe.Pointer(&sum[0]))) == 0 {
|
||||
panic("boringcrypto: SHA512 failed")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 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) noescapeCtx() *C.GO_SHA_CTX {
|
||||
return (*C.GO_SHA_CTX)(noescape(unsafe.Pointer(&h.ctx)))
|
||||
}
|
||||
|
||||
func (h *sha1Hash) Reset() {
|
||||
C._goboringcrypto_SHA1_Init(h.noescapeCtx())
|
||||
}
|
||||
|
||||
func (h *sha1Hash) Size() int { return 20 }
|
||||
func (h *sha1Hash) BlockSize() int { return 64 }
|
||||
func (h *sha1Hash) Sum(dst []byte) []byte { return h.sum(dst) }
|
||||
|
||||
func (h *sha1Hash) Write(p []byte) (int, error) {
|
||||
if len(p) > 0 && C._goboringcrypto_SHA1_Update(h.noescapeCtx(), noescape(addr(p)), C.size_t(len(p))) == 0 {
|
||||
panic("boringcrypto: SHA1_Update failed")
|
||||
}
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
func (h0 *sha1Hash) sum(dst []byte) []byte {
|
||||
h := *h0 // make copy so future Write+Sum is valid
|
||||
if C._goboringcrypto_SHA1_Final((*C.uint8_t)(noescape(unsafe.Pointer(&h.out[0]))), h.noescapeCtx()) == 0 {
|
||||
panic("boringcrypto: SHA1_Final failed")
|
||||
}
|
||||
return append(dst, 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) noescapeCtx() *C.GO_SHA256_CTX {
|
||||
return (*C.GO_SHA256_CTX)(noescape(unsafe.Pointer(&h.ctx)))
|
||||
}
|
||||
|
||||
func (h *sha224Hash) Reset() {
|
||||
C._goboringcrypto_SHA224_Init(h.noescapeCtx())
|
||||
}
|
||||
func (h *sha224Hash) Size() int { return 224 / 8 }
|
||||
func (h *sha224Hash) BlockSize() int { return 64 }
|
||||
func (h *sha224Hash) Sum(dst []byte) []byte { return h.sum(dst) }
|
||||
|
||||
func (h *sha224Hash) Write(p []byte) (int, error) {
|
||||
if len(p) > 0 && C._goboringcrypto_SHA224_Update(h.noescapeCtx(), noescape(addr(p)), C.size_t(len(p))) == 0 {
|
||||
panic("boringcrypto: SHA224_Update failed")
|
||||
}
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
func (h0 *sha224Hash) sum(dst []byte) []byte {
|
||||
h := *h0 // make copy so future Write+Sum is valid
|
||||
if C._goboringcrypto_SHA224_Final((*C.uint8_t)(noescape(unsafe.Pointer(&h.out[0]))), h.noescapeCtx()) == 0 {
|
||||
panic("boringcrypto: SHA224_Final failed")
|
||||
}
|
||||
return append(dst, 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) noescapeCtx() *C.GO_SHA256_CTX {
|
||||
return (*C.GO_SHA256_CTX)(noescape(unsafe.Pointer(&h.ctx)))
|
||||
}
|
||||
|
||||
func (h *sha256Hash) Reset() {
|
||||
C._goboringcrypto_SHA256_Init(h.noescapeCtx())
|
||||
}
|
||||
func (h *sha256Hash) Size() int { return 256 / 8 }
|
||||
func (h *sha256Hash) BlockSize() int { return 64 }
|
||||
func (h *sha256Hash) Sum(dst []byte) []byte { return h.sum(dst) }
|
||||
|
||||
func (h *sha256Hash) Write(p []byte) (int, error) {
|
||||
if len(p) > 0 && C._goboringcrypto_SHA256_Update(h.noescapeCtx(), noescape(addr(p)), C.size_t(len(p))) == 0 {
|
||||
panic("boringcrypto: SHA256_Update failed")
|
||||
}
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
func (h0 *sha256Hash) sum(dst []byte) []byte {
|
||||
h := *h0 // make copy so future Write+Sum is valid
|
||||
if C._goboringcrypto_SHA256_Final((*C.uint8_t)(noescape(unsafe.Pointer(&h.out[0]))), h.noescapeCtx()) == 0 {
|
||||
panic("boringcrypto: SHA256_Final failed")
|
||||
}
|
||||
return append(dst, 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) noescapeCtx() *C.GO_SHA512_CTX {
|
||||
return (*C.GO_SHA512_CTX)(noescape(unsafe.Pointer(&h.ctx)))
|
||||
}
|
||||
|
||||
func (h *sha384Hash) Reset() {
|
||||
C._goboringcrypto_SHA384_Init(h.noescapeCtx())
|
||||
}
|
||||
func (h *sha384Hash) Size() int { return 384 / 8 }
|
||||
func (h *sha384Hash) BlockSize() int { return 128 }
|
||||
func (h *sha384Hash) Sum(dst []byte) []byte { return h.sum(dst) }
|
||||
|
||||
func (h *sha384Hash) Write(p []byte) (int, error) {
|
||||
if len(p) > 0 && C._goboringcrypto_SHA384_Update(h.noescapeCtx(), noescape(addr(p)), C.size_t(len(p))) == 0 {
|
||||
panic("boringcrypto: SHA384_Update failed")
|
||||
}
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
func (h0 *sha384Hash) sum(dst []byte) []byte {
|
||||
h := *h0 // make copy so future Write+Sum is valid
|
||||
if C._goboringcrypto_SHA384_Final((*C.uint8_t)(noescape(unsafe.Pointer(&h.out[0]))), h.noescapeCtx()) == 0 {
|
||||
panic("boringcrypto: SHA384_Final failed")
|
||||
}
|
||||
return append(dst, 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) noescapeCtx() *C.GO_SHA512_CTX {
|
||||
return (*C.GO_SHA512_CTX)(noescape(unsafe.Pointer(&h.ctx)))
|
||||
}
|
||||
|
||||
func (h *sha512Hash) Reset() {
|
||||
C._goboringcrypto_SHA512_Init(h.noescapeCtx())
|
||||
}
|
||||
func (h *sha512Hash) Size() int { return 512 / 8 }
|
||||
func (h *sha512Hash) BlockSize() int { return 128 }
|
||||
func (h *sha512Hash) Sum(dst []byte) []byte { return h.sum(dst) }
|
||||
|
||||
func (h *sha512Hash) Write(p []byte) (int, error) {
|
||||
if len(p) > 0 && C._goboringcrypto_SHA512_Update(h.noescapeCtx(), noescape(addr(p)), C.size_t(len(p))) == 0 {
|
||||
panic("boringcrypto: SHA512_Update failed")
|
||||
}
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
func (h0 *sha512Hash) sum(dst []byte) []byte {
|
||||
h := *h0 // make copy so future Write+Sum is valid
|
||||
if C._goboringcrypto_SHA512_Final((*C.uint8_t)(noescape(unsafe.Pointer(&h.out[0]))), h.noescapeCtx()) == 0 {
|
||||
panic("boringcrypto: SHA512_Final failed")
|
||||
}
|
||||
return append(dst, 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
|
||||
)
|
||||
|
||||
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)
|
||||
}
|
||||
17
src/crypto/internal/boring/sig/sig.go
Normal file
17
src/crypto/internal/boring/sig/sig.go
Normal file
|
|
@ -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()
|
||||
54
src/crypto/internal/boring/sig/sig_amd64.s
Normal file
54
src/crypto/internal/boring/sig/sig_amd64.s
Normal file
|
|
@ -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
|
||||
20
src/crypto/internal/boring/sig/sig_other.s
Normal file
20
src/crypto/internal/boring/sig/sig_other.s
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
// 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.
|
||||
|
||||
//go:build !amd64
|
||||
// +build !amd64
|
||||
|
||||
TEXT ·BoringCrypto(SB),$0
|
||||
RET
|
||||
|
||||
TEXT ·FIPSOnly(SB),$0
|
||||
RET
|
||||
|
||||
TEXT ·StandardCrypto(SB),$0
|
||||
RET
|
||||
6
src/crypto/internal/boring/stub.s
Normal file
6
src/crypto/internal/boring/stub.s
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
// Copyright 2022 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 file is here to silence an error about registerCache not having a body.
|
||||
// (The body is provided by package runtime.)
|
||||
BIN
src/crypto/internal/boring/syso/goboringcrypto_linux_amd64.syso
Normal file
BIN
src/crypto/internal/boring/syso/goboringcrypto_linux_amd64.syso
Normal file
Binary file not shown.
9
src/crypto/internal/boring/syso/syso.go
Normal file
9
src/crypto/internal/boring/syso/syso.go
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
// Copyright 2022 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.
|
||||
|
||||
//go:build boringcrypto
|
||||
|
||||
// This package only exists with GOEXPERIMENT=boringcrypto.
|
||||
// It provides the actual syso file.
|
||||
package syso
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -19,9 +19,15 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
import "crypto/internal/boring"
|
||||
|
||||
const urandomDevice = "/dev/urandom"
|
||||
|
||||
func init() {
|
||||
if boring.Enabled {
|
||||
Reader = boring.RandReader
|
||||
return
|
||||
}
|
||||
Reader = &reader{}
|
||||
}
|
||||
|
||||
|
|
@ -59,6 +65,7 @@ func warnBlocked() {
|
|||
}
|
||||
|
||||
func (r *reader) Read(b []byte) (n int, err error) {
|
||||
boring.Unreachable()
|
||||
if atomic.CompareAndSwapUint32(&r.used, 0, 1) {
|
||||
// First use of randomness. Start timer to warn about
|
||||
// being blocked on entropy not being available.
|
||||
|
|
|
|||
130
src/crypto/rsa/boring.go
Normal file
130
src/crypto/rsa/boring.go
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
// 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.
|
||||
|
||||
//go:build boringcrypto
|
||||
|
||||
package rsa
|
||||
|
||||
import (
|
||||
"crypto/internal/boring"
|
||||
"crypto/internal/boring/bbig"
|
||||
"math/big"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Cached conversions from Go PublicKey/PrivateKey to BoringCrypto.
|
||||
//
|
||||
// The first operation on a PublicKey or PrivateKey makes a parallel
|
||||
// BoringCrypto key and saves it in pubCache or privCache.
|
||||
//
|
||||
// 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
|
||||
}
|
||||
|
||||
var pubCache boring.Cache
|
||||
var privCache boring.Cache
|
||||
|
||||
func init() {
|
||||
pubCache.Register()
|
||||
privCache.Register()
|
||||
}
|
||||
|
||||
func boringPublicKey(pub *PublicKey) (*boring.PublicKeyRSA, error) {
|
||||
b := (*boringPub)(pubCache.Get(unsafe.Pointer(pub)))
|
||||
if b != nil && publicKeyEqual(&b.orig, pub) {
|
||||
return b.key, nil
|
||||
}
|
||||
|
||||
b = new(boringPub)
|
||||
b.orig = copyPublicKey(pub)
|
||||
key, err := boring.NewPublicKeyRSA(bbig.Enc(b.orig.N), bbig.Enc(big.NewInt(int64(b.orig.E))))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b.key = key
|
||||
pubCache.Put(unsafe.Pointer(pub), unsafe.Pointer(b))
|
||||
return key, nil
|
||||
}
|
||||
|
||||
type boringPriv struct {
|
||||
key *boring.PrivateKeyRSA
|
||||
orig PrivateKey
|
||||
}
|
||||
|
||||
func boringPrivateKey(priv *PrivateKey) (*boring.PrivateKeyRSA, error) {
|
||||
b := (*boringPriv)(privCache.Get(unsafe.Pointer(priv)))
|
||||
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(bbig.Enc(N), bbig.Enc(E), bbig.Enc(D), bbig.Enc(P), bbig.Enc(Q), bbig.Enc(Dp), bbig.Enc(Dq), bbig.Enc(Qinv))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b.key = key
|
||||
privCache.Put(unsafe.Pointer(priv), 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
|
||||
}
|
||||
130
src/crypto/rsa/boring_test.go
Normal file
130
src/crypto/rsa/boring_test.go
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
// 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.
|
||||
|
||||
//go:build boringcrypto
|
||||
|
||||
// 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"
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
"sync"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBoringASN1Marshal(t *testing.T) {
|
||||
k, err := GenerateKey(rand.Reader, 128)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, err = asn1.Marshal(k.PublicKey)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
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 BenchmarkBoringVerify(b *testing.B) {
|
||||
// Check that signatures that lack leading zeroes don't verify.
|
||||
key := &PublicKey{
|
||||
N: bigFromHex("c4fdf7b40a5477f206e6ee278eaef888ca73bf9128a9eef9f2f1ddb8b7b71a4c07cfa241f028a04edb405e4d916c61d6beabc333813dc7b484d2b3c52ee233c6a79b1eea4e9cc51596ba9cd5ac5aeb9df62d86ea051055b79d03f8a4fa9f38386f5bd17529138f3325d46801514ea9047977e0829ed728e68636802796801be1"),
|
||||
E: 65537,
|
||||
}
|
||||
|
||||
hash := fromHex("019c5571724fb5d0e47a4260c940e9803ba05a44")
|
||||
|
||||
// signature is one byte shorter than key.N.
|
||||
sig := fromHex("5edfbeb6a73e7225ad3cc52724e2872e04260d7daf0d693c170d8c4b243b8767bc7785763533febc62ec2600c30603c433c095453ede59ff2fcabeb84ce32e0ed9d5cf15ffcbc816202b64370d4d77c1e9077d74e94a16fb4fa2e5bec23a56d7a73cf275f91691ae1801a976fcde09e981a2f6327ac27ea1fecf3185df0d56")
|
||||
|
||||
b.ReportAllocs()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
err := VerifyPKCS1v15(key, crypto.SHA1, hash, sig)
|
||||
if err == nil {
|
||||
b.Fatalf("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 cache.
|
||||
privCache.Clear()
|
||||
|
||||
// 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()
|
||||
}
|
||||
}
|
||||
16
src/crypto/rsa/notboring.go
Normal file
16
src/crypto/rsa/notboring.go
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright 2022 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.
|
||||
|
||||
//go:build !boringcrypto
|
||||
|
||||
package rsa
|
||||
|
||||
import "crypto/internal/boring"
|
||||
|
||||
func boringPublicKey(*PublicKey) (*boring.PublicKeyRSA, error) {
|
||||
panic("boringcrypto: not available")
|
||||
}
|
||||
func boringPrivateKey(*PrivateKey) (*boring.PrivateKeyRSA, error) {
|
||||
panic("boringcrypto: not available")
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
||||
|
|
@ -230,7 +275,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
|
||||
|
|
@ -242,6 +287,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
|
||||
|
|
@ -252,7 +305,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
|
||||
}
|
||||
|
|
@ -266,6 +319,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
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@ package rsa
|
|||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/internal/boring"
|
||||
"crypto/internal/boring/bbig"
|
||||
"crypto/internal/randutil"
|
||||
"crypto/rand"
|
||||
"crypto/subtle"
|
||||
"errors"
|
||||
|
|
@ -31,8 +34,6 @@ import (
|
|||
"io"
|
||||
"math"
|
||||
"math/big"
|
||||
|
||||
"crypto/internal/randutil"
|
||||
)
|
||||
|
||||
var bigZero = big.NewInt(0)
|
||||
|
|
@ -256,6 +257,40 @@ 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) {
|
||||
bN, bE, bD, bP, bQ, bDp, bDq, bQinv, err := boring.GenerateKeyRSA(bits)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
N := bbig.Dec(bN)
|
||||
E := bbig.Dec(bE)
|
||||
D := bbig.Dec(bD)
|
||||
P := bbig.Dec(bP)
|
||||
Q := bbig.Dec(bQ)
|
||||
Dp := bbig.Dec(bDp)
|
||||
Dq := bbig.Dec(bDq)
|
||||
Qinv := bbig.Dec(bQinv)
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
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
|
||||
}
|
||||
}
|
||||
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)
|
||||
}
|
||||
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
|
||||
|
|
|
|||
25
src/crypto/sha1/boring.go
Normal file
25
src/crypto/sha1/boring.go
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
// 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.
|
||||
|
||||
//go:build !cmd_go_bootstrap && cgo
|
||||
// +build !cmd_go_bootstrap,cgo
|
||||
|
||||
package sha1
|
||||
|
||||
import (
|
||||
"crypto/internal/boring"
|
||||
"hash"
|
||||
)
|
||||
|
||||
const boringEnabled = boring.Enabled
|
||||
|
||||
func boringNewSHA1() hash.Hash { return boring.NewSHA1() }
|
||||
|
||||
func boringUnreachable() { boring.Unreachable() }
|
||||
|
||||
func boringSHA1(p []byte) [20]byte { return boring.SHA1(p) }
|
||||
20
src/crypto/sha1/notboring.go
Normal file
20
src/crypto/sha1/notboring.go
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
// 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.
|
||||
|
||||
//go:build cmd_go_bootstrap || !cgo
|
||||
// +build cmd_go_bootstrap !cgo
|
||||
|
||||
package sha1
|
||||
|
||||
import (
|
||||
"hash"
|
||||
)
|
||||
|
||||
const boringEnabled = false
|
||||
|
||||
func boringNewSHA1() hash.Hash { panic("boringcrypto: not available") }
|
||||
|
||||
func boringUnreachable() {}
|
||||
|
||||
func boringSHA1([]byte) [20]byte { panic("boringcrypto: not available") }
|
||||
|
|
@ -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,9 @@ func (d *digest) constSum() [Size]byte {
|
|||
|
||||
// Sum returns the SHA-1 checksum of the data.
|
||||
func Sum(data []byte) [Size]byte {
|
||||
if boringEnabled {
|
||||
return boringSHA1(data)
|
||||
}
|
||||
var d digest
|
||||
d.Reset()
|
||||
d.Write(data)
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ package sha1
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/internal/boring"
|
||||
"crypto/rand"
|
||||
"encoding"
|
||||
"fmt"
|
||||
|
|
@ -77,6 +78,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 +145,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)
|
||||
|
|
@ -211,6 +218,9 @@ func TestLargeHashes(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestAllocations(t *testing.T) {
|
||||
if boring.Enabled {
|
||||
t.Skip("BoringCrypto doesn't allocate the same way as stdlib")
|
||||
}
|
||||
in := []byte("hello, world!")
|
||||
out := make([]byte, 0, Size)
|
||||
h := New()
|
||||
|
|
@ -228,13 +238,23 @@ var bench = New()
|
|||
var buf = make([]byte, 8192)
|
||||
|
||||
func benchmarkSize(b *testing.B, size int) {
|
||||
b.SetBytes(int64(size))
|
||||
sum := make([]byte, bench.Size())
|
||||
for i := 0; i < b.N; i++ {
|
||||
bench.Reset()
|
||||
bench.Write(buf[:size])
|
||||
bench.Sum(sum[:0])
|
||||
}
|
||||
b.Run("New", func(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
b.SetBytes(int64(size))
|
||||
for i := 0; i < b.N; i++ {
|
||||
bench.Reset()
|
||||
bench.Write(buf[:size])
|
||||
bench.Sum(sum[:0])
|
||||
}
|
||||
})
|
||||
b.Run("Sum", func(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
b.SetBytes(int64(size))
|
||||
for i := 0; i < b.N; i++ {
|
||||
Sum(buf[:size])
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkHash8Bytes(b *testing.B) {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ package sha256
|
|||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/internal/boring"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"hash"
|
||||
|
|
@ -159,6 +160,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 +170,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 +189,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 +213,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 +261,9 @@ func (d *digest) checkSum() [Size]byte {
|
|||
|
||||
// Sum256 returns the SHA256 checksum of the data.
|
||||
func Sum256(data []byte) [Size]byte {
|
||||
if boring.Enabled {
|
||||
return boring.SHA256(data)
|
||||
}
|
||||
var d digest
|
||||
d.Reset()
|
||||
d.Write(data)
|
||||
|
|
@ -260,6 +272,9 @@ func Sum256(data []byte) [Size]byte {
|
|||
|
||||
// Sum224 returns the SHA224 checksum of the data.
|
||||
func Sum224(data []byte) [Size224]byte {
|
||||
if boring.Enabled {
|
||||
return boring.SHA224(data)
|
||||
}
|
||||
var d digest
|
||||
d.is224 = true
|
||||
d.Reset()
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ package sha256
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/internal/boring"
|
||||
"crypto/rand"
|
||||
"encoding"
|
||||
"fmt"
|
||||
|
|
@ -216,6 +217,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)
|
||||
|
|
@ -290,6 +294,9 @@ func TestLargeHashes(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestAllocations(t *testing.T) {
|
||||
if boring.Enabled {
|
||||
t.Skip("BoringCrypto doesn't allocate the same way as stdlib")
|
||||
}
|
||||
in := []byte("hello, world!")
|
||||
out := make([]byte, 0, Size)
|
||||
h := New()
|
||||
|
|
@ -307,13 +314,30 @@ var bench = New()
|
|||
var buf = make([]byte, 8192)
|
||||
|
||||
func benchmarkSize(b *testing.B, size int) {
|
||||
b.SetBytes(int64(size))
|
||||
sum := make([]byte, bench.Size())
|
||||
for i := 0; i < b.N; i++ {
|
||||
bench.Reset()
|
||||
bench.Write(buf[:size])
|
||||
bench.Sum(sum[:0])
|
||||
}
|
||||
b.Run("New", func(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
b.SetBytes(int64(size))
|
||||
for i := 0; i < b.N; i++ {
|
||||
bench.Reset()
|
||||
bench.Write(buf[:size])
|
||||
bench.Sum(sum[:0])
|
||||
}
|
||||
})
|
||||
b.Run("Sum224", func(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
b.SetBytes(int64(size))
|
||||
for i := 0; i < b.N; i++ {
|
||||
Sum224(buf[:size])
|
||||
}
|
||||
})
|
||||
b.Run("Sum256", func(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
b.SetBytes(int64(size))
|
||||
for i := 0; i < b.N; i++ {
|
||||
Sum256(buf[:size])
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkHash8Bytes(b *testing.B) {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ package sha512
|
|||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/internal/boring"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"hash"
|
||||
|
|
@ -211,6 +212,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 +236,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 +260,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 +286,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 +343,9 @@ func (d *digest) checkSum() [Size]byte {
|
|||
|
||||
// Sum512 returns the SHA512 checksum of the data.
|
||||
func Sum512(data []byte) [Size]byte {
|
||||
if boring.Enabled {
|
||||
return boring.SHA512(data)
|
||||
}
|
||||
d := digest{function: crypto.SHA512}
|
||||
d.Reset()
|
||||
d.Write(data)
|
||||
|
|
@ -338,6 +354,9 @@ func Sum512(data []byte) [Size]byte {
|
|||
|
||||
// Sum384 returns the SHA384 checksum of the data.
|
||||
func Sum384(data []byte) [Size384]byte {
|
||||
if boring.Enabled {
|
||||
return boring.SHA384(data)
|
||||
}
|
||||
d := digest{function: crypto.SHA384}
|
||||
d.Reset()
|
||||
d.Write(data)
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ package sha512
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/internal/boring"
|
||||
"crypto/rand"
|
||||
"encoding"
|
||||
"encoding/hex"
|
||||
|
|
@ -822,6 +823,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)
|
||||
|
|
@ -889,6 +893,9 @@ func TestLargeHashes(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestAllocations(t *testing.T) {
|
||||
if boring.Enabled {
|
||||
t.Skip("BoringCrypto doesn't allocate the same way as stdlib")
|
||||
}
|
||||
in := []byte("hello, world!")
|
||||
out := make([]byte, 0, Size)
|
||||
h := New()
|
||||
|
|
@ -906,13 +913,30 @@ var bench = New()
|
|||
var buf = make([]byte, 8192)
|
||||
|
||||
func benchmarkSize(b *testing.B, size int) {
|
||||
b.SetBytes(int64(size))
|
||||
sum := make([]byte, bench.Size())
|
||||
for i := 0; i < b.N; i++ {
|
||||
bench.Reset()
|
||||
bench.Write(buf[:size])
|
||||
bench.Sum(sum[:0])
|
||||
}
|
||||
b.Run("New", func(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
b.SetBytes(int64(size))
|
||||
for i := 0; i < b.N; i++ {
|
||||
bench.Reset()
|
||||
bench.Write(buf[:size])
|
||||
bench.Sum(sum[:0])
|
||||
}
|
||||
})
|
||||
b.Run("Sum384", func(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
b.SetBytes(int64(size))
|
||||
for i := 0; i < b.N; i++ {
|
||||
Sum384(buf[:size])
|
||||
}
|
||||
})
|
||||
b.Run("Sum512", func(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
b.SetBytes(int64(size))
|
||||
for i := 0; i < b.N; i++ {
|
||||
Sum512(buf[:size])
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkHash8Bytes(b *testing.B) {
|
||||
|
|
|
|||
|
|
@ -169,6 +169,7 @@ var rsaSignatureSchemes = []struct {
|
|||
// and optionally filtered by its explicit SupportedSignatureAlgorithms.
|
||||
//
|
||||
// This function must be kept in sync with supportedSignatureAlgorithms.
|
||||
// FIPS filtering is applied in the caller, selectSignatureScheme.
|
||||
func signatureSchemesForCertificate(version uint16, cert *Certificate) []SignatureScheme {
|
||||
priv, ok := cert.PrivateKey.(crypto.Signer)
|
||||
if !ok {
|
||||
|
|
@ -241,6 +242,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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
98
src/crypto/tls/boring.go
Normal file
98
src/crypto/tls/boring.go
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
// 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.
|
||||
|
||||
//go:build boringcrypto
|
||||
|
||||
package tls
|
||||
|
||||
import (
|
||||
"crypto/internal/boring/fipstls"
|
||||
)
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// defaultCipherSuitesFIPS are the FIPS-allowed cipher suites.
|
||||
var defaultCipherSuitesFIPS = []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 defaultCipherSuitesFIPS
|
||||
}
|
||||
list := make([]uint16, 0, len(defaultCipherSuitesFIPS))
|
||||
for _, id := range c.CipherSuites {
|
||||
for _, allowed := range defaultCipherSuitesFIPS {
|
||||
if id == allowed {
|
||||
list = append(list, id)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
616
src/crypto/tls/boring_test.go
Normal file
616
src/crypto/tls/boring_test.go
Normal file
|
|
@ -0,0 +1,616 @@
|
|||
// 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.
|
||||
|
||||
//go:build boringcrypto
|
||||
|
||||
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, clientConfig).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)
|
||||
|
||||
// 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{}
|
||||
switch k := key.(type) {
|
||||
case *rsa.PrivateKey:
|
||||
pub = &k.PublicKey
|
||||
case *ecdsa.PrivateKey:
|
||||
pub = &k.PublicKey
|
||||
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)
|
||||
}
|
||||
|
||||
fipsOK := mode&boringCertFIPSOK != 0
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
package tls
|
||||
|
||||
import "crypto/internal/boring"
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/aes"
|
||||
|
|
@ -421,7 +423,13 @@ func cipherAES(key, iv []byte, isRead bool) any {
|
|||
|
||||
// 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
|
||||
|
|
@ -509,7 +517,16 @@ func aeadAESGCM(key, noncePrefix []byte) aead {
|
|||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
aead, err := cipher.NewGCM(aes)
|
||||
type gcmtls interface {
|
||||
NewGCMTLS() (cipher.AEAD, error)
|
||||
}
|
||||
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)
|
||||
}
|
||||
|
|
@ -569,6 +586,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)}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -171,11 +171,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,
|
||||
|
|
@ -960,6 +960,9 @@ func (c *Config) time() time.Time {
|
|||
}
|
||||
|
||||
func (c *Config) cipherSuites() []uint16 {
|
||||
if needFIPS() {
|
||||
return fipsCipherSuites(c)
|
||||
}
|
||||
if c.CipherSuites != nil {
|
||||
return c.CipherSuites
|
||||
}
|
||||
|
|
@ -981,6 +984,9 @@ const roleServer = false
|
|||
func (c *Config) supportedVersions(isClient bool) []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) &&
|
||||
isClient && v < VersionTLS12 {
|
||||
continue
|
||||
|
|
@ -1021,6 +1027,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
|
||||
}
|
||||
|
|
|
|||
29
src/crypto/tls/fipsonly/fipsonly.go
Normal file
29
src/crypto/tls/fipsonly/fipsonly.go
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
// 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.
|
||||
|
||||
//go:build boringcrypto
|
||||
|
||||
// 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 when using Go compiled with GOEXPERIMENT=boringcrypto.
|
||||
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()
|
||||
}
|
||||
18
src/crypto/tls/fipsonly/fipsonly_test.go
Normal file
18
src/crypto/tls/fipsonly/fipsonly_test.go
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
// 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.
|
||||
|
||||
//go:build boringcrypto
|
||||
|
||||
package fipsonly
|
||||
|
||||
import (
|
||||
"crypto/internal/boring/fipstls"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test(t *testing.T) {
|
||||
if !fipstls.Required() {
|
||||
t.Fatal("fipstls.Required() = false, must be true")
|
||||
}
|
||||
}
|
||||
|
|
@ -34,6 +34,8 @@ type clientHandshakeState struct {
|
|||
session *ClientSessionState
|
||||
}
|
||||
|
||||
var testingOnlyForceClientHelloSignatureAlgorithms []SignatureScheme
|
||||
|
||||
func (c *Conn) makeClientHello() (*clientHelloMsg, ecdheParameters, error) {
|
||||
config := c.config
|
||||
if len(config.ServerName) == 0 && !config.InsecureSkipVerify {
|
||||
|
|
@ -117,7 +119,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
|
||||
|
|
@ -861,6 +866,7 @@ func (c *Conn) verifyServerCertificate(certificates [][]byte) error {
|
|||
DNSName: c.config.ServerName,
|
||||
Intermediates: x509.NewCertPool(),
|
||||
}
|
||||
|
||||
for _, cert := range certs[1:] {
|
||||
opts.Intermediates.AddCert(cert)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,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 {
|
||||
|
|
@ -470,7 +474,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")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -148,10 +148,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))
|
||||
|
|
@ -370,10 +370,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)
|
||||
|
|
|
|||
|
|
@ -541,7 +541,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
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue