Handle CORS requests (#6289)
parent
6fb58a8cdc
commit
34d06f4c6b
@ -0,0 +1,22 @@ |
|||||||
|
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package integrations |
||||||
|
|
||||||
|
import ( |
||||||
|
"net/http" |
||||||
|
"testing" |
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert" |
||||||
|
) |
||||||
|
|
||||||
|
func TestCORSNotSet(t *testing.T) { |
||||||
|
prepareTestEnv(t) |
||||||
|
req := NewRequestf(t, "GET", "/api/v1/version") |
||||||
|
session := loginUser(t, "user2") |
||||||
|
resp := session.MakeRequest(t, req, http.StatusOK) |
||||||
|
assert.Equal(t, resp.Code, http.StatusOK) |
||||||
|
corsHeader := resp.Header().Get("Access-Control-Allow-Origin") |
||||||
|
assert.Equal(t, corsHeader, "", "Access-Control-Allow-Origin: generated header should match") // header not set
|
||||||
|
} |
@ -0,0 +1,41 @@ |
|||||||
|
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package setting |
||||||
|
|
||||||
|
import ( |
||||||
|
"time" |
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/log" |
||||||
|
|
||||||
|
"github.com/go-macaron/cors" |
||||||
|
) |
||||||
|
|
||||||
|
var ( |
||||||
|
// CORSConfig defines CORS settings
|
||||||
|
CORSConfig cors.Options |
||||||
|
// EnableCORS defines whether CORS settings is enabled or not
|
||||||
|
EnableCORS bool |
||||||
|
) |
||||||
|
|
||||||
|
func newCORSService() { |
||||||
|
sec := Cfg.Section("cors") |
||||||
|
// Check cors setting.
|
||||||
|
EnableCORS = sec.Key("ENABLED").MustBool(false) |
||||||
|
|
||||||
|
maxAge := sec.Key("MAX_AGE").MustDuration(10 * time.Minute) |
||||||
|
|
||||||
|
CORSConfig = cors.Options{ |
||||||
|
Scheme: sec.Key("SCHEME").String(), |
||||||
|
AllowDomain: sec.Key("ALLOW_DOMAIN").String(), |
||||||
|
AllowSubdomain: sec.Key("ALLOW_SUBDOMAIN").MustBool(), |
||||||
|
Methods: sec.Key("METHODS").Strings(","), |
||||||
|
MaxAgeSeconds: int(maxAge.Seconds()), |
||||||
|
AllowCredentials: sec.Key("ALLOW_CREDENTIALS").MustBool(), |
||||||
|
} |
||||||
|
|
||||||
|
if EnableCORS { |
||||||
|
log.Info("CORS Service Enabled") |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,8 @@ |
|||||||
|
module github.com/Unknwon/com |
||||||
|
|
||||||
|
require ( |
||||||
|
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e // indirect |
||||||
|
github.com/jtolds/gls v4.2.1+incompatible // indirect |
||||||
|
github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 // indirect |
||||||
|
github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c |
||||||
|
) |
@ -0,0 +1,8 @@ |
|||||||
|
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg= |
||||||
|
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= |
||||||
|
github.com/jtolds/gls v4.2.1+incompatible h1:fSuqC+Gmlu6l/ZYAoZzx2pyucC8Xza35fpRVWLVmUEE= |
||||||
|
github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= |
||||||
|
github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 h1:Jpy1PXuP99tXNrhbq2BaPz9B+jNAvH1JPQQpG/9GCXY= |
||||||
|
github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= |
||||||
|
github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c h1:Ho+uVpkel/udgjbwB5Lktg9BtvJSh2DT0Hi6LPSyI2w= |
||||||
|
github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= |
@ -0,0 +1,12 @@ |
|||||||
|
# Binaries for programs and plugins |
||||||
|
*.exe |
||||||
|
*.exe~ |
||||||
|
*.dll |
||||||
|
*.so |
||||||
|
*.dylib |
||||||
|
|
||||||
|
# Test binary, build with `go test -c` |
||||||
|
*.test |
||||||
|
|
||||||
|
# Output of the go coverage tool, specifically when used with LiteIDE |
||||||
|
*.out |
@ -0,0 +1,201 @@ |
|||||||
|
Apache License |
||||||
|
Version 2.0, January 2004 |
||||||
|
http://www.apache.org/licenses/ |
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION |
||||||
|
|
||||||
|
1. Definitions. |
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction, |
||||||
|
and distribution as defined by Sections 1 through 9 of this document. |
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by |
||||||
|
the copyright owner that is granting the License. |
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all |
||||||
|
other entities that control, are controlled by, or are under common |
||||||
|
control with that entity. For the purposes of this definition, |
||||||
|
"control" means (i) the power, direct or indirect, to cause the |
||||||
|
direction or management of such entity, whether by contract or |
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the |
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity. |
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity |
||||||
|
exercising permissions granted by this License. |
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications, |
||||||
|
including but not limited to software source code, documentation |
||||||
|
source, and configuration files. |
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical |
||||||
|
transformation or translation of a Source form, including but |
||||||
|
not limited to compiled object code, generated documentation, |
||||||
|
and conversions to other media types. |
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or |
||||||
|
Object form, made available under the License, as indicated by a |
||||||
|
copyright notice that is included in or attached to the work |
||||||
|
(an example is provided in the Appendix below). |
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object |
||||||
|
form, that is based on (or derived from) the Work and for which the |
||||||
|
editorial revisions, annotations, elaborations, or other modifications |
||||||
|
represent, as a whole, an original work of authorship. For the purposes |
||||||
|
of this License, Derivative Works shall not include works that remain |
||||||
|
separable from, or merely link (or bind by name) to the interfaces of, |
||||||
|
the Work and Derivative Works thereof. |
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including |
||||||
|
the original version of the Work and any modifications or additions |
||||||
|
to that Work or Derivative Works thereof, that is intentionally |
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner |
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of |
||||||
|
the copyright owner. For the purposes of this definition, "submitted" |
||||||
|
means any form of electronic, verbal, or written communication sent |
||||||
|
to the Licensor or its representatives, including but not limited to |
||||||
|
communication on electronic mailing lists, source code control systems, |
||||||
|
and issue tracking systems that are managed by, or on behalf of, the |
||||||
|
Licensor for the purpose of discussing and improving the Work, but |
||||||
|
excluding communication that is conspicuously marked or otherwise |
||||||
|
designated in writing by the copyright owner as "Not a Contribution." |
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity |
||||||
|
on behalf of whom a Contribution has been received by Licensor and |
||||||
|
subsequently incorporated within the Work. |
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of |
||||||
|
this License, each Contributor hereby grants to You a perpetual, |
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
||||||
|
copyright license to reproduce, prepare Derivative Works of, |
||||||
|
publicly display, publicly perform, sublicense, and distribute the |
||||||
|
Work and such Derivative Works in Source or Object form. |
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of |
||||||
|
this License, each Contributor hereby grants to You a perpetual, |
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
||||||
|
(except as stated in this section) patent license to make, have made, |
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work, |
||||||
|
where such license applies only to those patent claims licensable |
||||||
|
by such Contributor that are necessarily infringed by their |
||||||
|
Contribution(s) alone or by combination of their Contribution(s) |
||||||
|
with the Work to which such Contribution(s) was submitted. If You |
||||||
|
institute patent litigation against any entity (including a |
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work |
||||||
|
or a Contribution incorporated within the Work constitutes direct |
||||||
|
or contributory patent infringement, then any patent licenses |
||||||
|
granted to You under this License for that Work shall terminate |
||||||
|
as of the date such litigation is filed. |
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the |
||||||
|
Work or Derivative Works thereof in any medium, with or without |
||||||
|
modifications, and in Source or Object form, provided that You |
||||||
|
meet the following conditions: |
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or |
||||||
|
Derivative Works a copy of this License; and |
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices |
||||||
|
stating that You changed the files; and |
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works |
||||||
|
that You distribute, all copyright, patent, trademark, and |
||||||
|
attribution notices from the Source form of the Work, |
||||||
|
excluding those notices that do not pertain to any part of |
||||||
|
the Derivative Works; and |
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its |
||||||
|
distribution, then any Derivative Works that You distribute must |
||||||
|
include a readable copy of the attribution notices contained |
||||||
|
within such NOTICE file, excluding those notices that do not |
||||||
|
pertain to any part of the Derivative Works, in at least one |
||||||
|
of the following places: within a NOTICE text file distributed |
||||||
|
as part of the Derivative Works; within the Source form or |
||||||
|
documentation, if provided along with the Derivative Works; or, |
||||||
|
within a display generated by the Derivative Works, if and |
||||||
|
wherever such third-party notices normally appear. The contents |
||||||
|
of the NOTICE file are for informational purposes only and |
||||||
|
do not modify the License. You may add Your own attribution |
||||||
|
notices within Derivative Works that You distribute, alongside |
||||||
|
or as an addendum to the NOTICE text from the Work, provided |
||||||
|
that such additional attribution notices cannot be construed |
||||||
|
as modifying the License. |
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and |
||||||
|
may provide additional or different license terms and conditions |
||||||
|
for use, reproduction, or distribution of Your modifications, or |
||||||
|
for any such Derivative Works as a whole, provided Your use, |
||||||
|
reproduction, and distribution of the Work otherwise complies with |
||||||
|
the conditions stated in this License. |
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise, |
||||||
|
any Contribution intentionally submitted for inclusion in the Work |
||||||
|
by You to the Licensor shall be under the terms and conditions of |
||||||
|
this License, without any additional terms or conditions. |
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify |
||||||
|
the terms of any separate license agreement you may have executed |
||||||
|
with Licensor regarding such Contributions. |
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade |
||||||
|
names, trademarks, service marks, or product names of the Licensor, |
||||||
|
except as required for reasonable and customary use in describing the |
||||||
|
origin of the Work and reproducing the content of the NOTICE file. |
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or |
||||||
|
agreed to in writing, Licensor provides the Work (and each |
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS, |
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
||||||
|
implied, including, without limitation, any warranties or conditions |
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A |
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the |
||||||
|
appropriateness of using or redistributing the Work and assume any |
||||||
|
risks associated with Your exercise of permissions under this License. |
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory, |
||||||
|
whether in tort (including negligence), contract, or otherwise, |
||||||
|
unless required by applicable law (such as deliberate and grossly |
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be |
||||||
|
liable to You for damages, including any direct, indirect, special, |
||||||
|
incidental, or consequential damages of any character arising as a |
||||||
|
result of this License or out of the use or inability to use the |
||||||
|
Work (including but not limited to damages for loss of goodwill, |
||||||
|
work stoppage, computer failure or malfunction, or any and all |
||||||
|
other commercial damages or losses), even if such Contributor |
||||||
|
has been advised of the possibility of such damages. |
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing |
||||||
|
the Work or Derivative Works thereof, You may choose to offer, |
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity, |
||||||
|
or other liability obligations and/or rights consistent with this |
||||||
|
License. However, in accepting such obligations, You may act only |
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf |
||||||
|
of any other Contributor, and only if You agree to indemnify, |
||||||
|
defend, and hold each Contributor harmless for any liability |
||||||
|
incurred by, or claims asserted against, such Contributor by reason |
||||||
|
of your accepting any such warranty or additional liability. |
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS |
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work. |
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following |
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]" |
||||||
|
replaced with your own identifying information. (Don't include |
||||||
|
the brackets!) The text should be enclosed in the appropriate |
||||||
|
comment syntax for the file format. We also recommend that a |
||||||
|
file or class name and description of purpose be included on the |
||||||
|
same "printed page" as the copyright notice for easier |
||||||
|
identification within third-party archives. |
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner] |
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
you may not use this file except in compliance with the License. |
||||||
|
You may obtain a copy of the License at |
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0 |
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software |
||||||
|
distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
See the License for the specific language governing permissions and |
||||||
|
limitations under the License. |
@ -0,0 +1,2 @@ |
|||||||
|
# cors |
||||||
|
Package cors is a middleware that handles CORS requests & headers for Macaron. |
@ -0,0 +1,139 @@ |
|||||||
|
package cors |
||||||
|
|
||||||
|
import ( |
||||||
|
"fmt" |
||||||
|
"log" |
||||||
|
"net/http" |
||||||
|
"net/url" |
||||||
|
"strconv" |
||||||
|
"strings" |
||||||
|
|
||||||
|
macaron "gopkg.in/macaron.v1" |
||||||
|
) |
||||||
|
|
||||||
|
const _VERSION = "0.1.0" |
||||||
|
|
||||||
|
func Version() string { |
||||||
|
return _VERSION |
||||||
|
} |
||||||
|
|
||||||
|
// Options represents a struct for specifying configuration options for the CORS middleware.
|
||||||
|
type Options struct { |
||||||
|
Section string |
||||||
|
Scheme string |
||||||
|
AllowDomain string |
||||||
|
AllowSubdomain bool |
||||||
|
Methods []string |
||||||
|
MaxAgeSeconds int |
||||||
|
AllowCredentials bool |
||||||
|
} |
||||||
|
|
||||||
|
func prepareOptions(options []Options) Options { |
||||||
|
var opt Options |
||||||
|
if len(options) > 0 { |
||||||
|
opt = options[0] |
||||||
|
} |
||||||
|
|
||||||
|
if len(opt.Section) == 0 { |
||||||
|
opt.Section = "cors" |
||||||
|
} |
||||||
|
sec := macaron.Config().Section(opt.Section) |
||||||
|
|
||||||
|
if len(opt.Scheme) == 0 { |
||||||
|
opt.Scheme = sec.Key("SCHEME").MustString("http") |
||||||
|
} |
||||||
|
if len(opt.AllowDomain) == 0 { |
||||||
|
opt.AllowDomain = sec.Key("ALLOW_DOMAIN").MustString("*") |
||||||
|
} |
||||||
|
if !opt.AllowSubdomain { |
||||||
|
opt.AllowSubdomain = sec.Key("ALLOW_SUBDOMAIN").MustBool(false) |
||||||
|
} |
||||||
|
if len(opt.Methods) == 0 { |
||||||
|
opt.Methods = sec.Key("METHODS").Strings(",") |
||||||
|
if len(opt.Methods) == 0 { |
||||||
|
opt.Methods = []string{ |
||||||
|
http.MethodGet, |
||||||
|
http.MethodHead, |
||||||
|
http.MethodPost, |
||||||
|
http.MethodPut, |
||||||
|
http.MethodPatch, |
||||||
|
http.MethodDelete, |
||||||
|
http.MethodOptions, |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
if opt.MaxAgeSeconds <= 0 { |
||||||
|
// cache options response for 600 secs
|
||||||
|
// ref: https://stackoverflow.com/questions/54300997/is-it-possible-to-cache-http-options-response?noredirect=1#comment95790277_54300997
|
||||||
|
// ref: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age
|
||||||
|
opt.MaxAgeSeconds = sec.Key("MAX_AGE_SECONDS").MustInt(600) |
||||||
|
} |
||||||
|
if !opt.AllowCredentials { |
||||||
|
opt.AllowCredentials = sec.Key("ALLOW_CREDENTIALS").MustBool(true) |
||||||
|
} |
||||||
|
|
||||||
|
return opt |
||||||
|
} |
||||||
|
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
|
||||||
|
// https://fetch.spec.whatwg.org/#cors-protocol-and-credentials
|
||||||
|
// For requests without credentials, the server may specify "*" as a wildcard, thereby allowing any origin to access the resource.
|
||||||
|
func CORS(options ...Options) macaron.Handler { |
||||||
|
opt := prepareOptions(options) |
||||||
|
return func(ctx *macaron.Context, log *log.Logger) { |
||||||
|
reqOptions := ctx.Req.Method == http.MethodOptions |
||||||
|
|
||||||
|
headers := map[string]string{ |
||||||
|
"access-control-allow-methods": strings.Join(opt.Methods, ","), |
||||||
|
"access-control-allow-headers": ctx.Req.Header.Get("access-control-request-headers"), |
||||||
|
"access-control-max-age": strconv.Itoa(opt.MaxAgeSeconds), |
||||||
|
} |
||||||
|
if opt.AllowDomain == "*" { |
||||||
|
headers["access-control-allow-origin"] = "*" |
||||||
|
} else if opt.AllowDomain != "" { |
||||||
|
origin := ctx.Req.Header.Get("Origin") |
||||||
|
if reqOptions && origin == "" { |
||||||
|
respErrorf(ctx, log, http.StatusBadRequest, "missing origin header in CORS request") |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
u, err := url.Parse(origin) |
||||||
|
if err != nil { |
||||||
|
respErrorf(ctx, log, http.StatusBadRequest, "Failed to parse CORS origin header. Reason: %v", err) |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
ok := u.Hostname() == opt.AllowDomain || |
||||||
|
(opt.AllowSubdomain && strings.HasSuffix(u.Hostname(), "."+opt.AllowDomain)) |
||||||
|
if ok { |
||||||
|
u.Scheme = opt.Scheme |
||||||
|
headers["access-control-allow-origin"] = u.String() |
||||||
|
headers["access-control-allow-credentials"] = strconv.FormatBool(opt.AllowCredentials) |
||||||
|
headers["vary"] = "Origin" |
||||||
|
} |
||||||
|
if reqOptions && !ok { |
||||||
|
respErrorf(ctx, log, http.StatusBadRequest, "CORS request from prohibited domain %v", origin) |
||||||
|
return |
||||||
|
} |
||||||
|
} |
||||||
|
ctx.Resp.Before(func(w macaron.ResponseWriter) { |
||||||
|
for k, v := range headers { |
||||||
|
w.Header().Set(k, v) |
||||||
|
} |
||||||
|
}) |
||||||
|
if reqOptions { |
||||||
|
ctx.Status(200) // return response
|
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func respErrorf(ctx *macaron.Context, log *log.Logger, statusCode int, format string, a ...interface{}) { |
||||||
|
msg := fmt.Sprintf(format, a...) |
||||||
|
log.Println(msg) |
||||||
|
ctx.WriteHeader(statusCode) |
||||||
|
_, err := ctx.Write([]byte(msg)) |
||||||
|
if err != nil { |
||||||
|
panic(err) |
||||||
|
} |
||||||
|
return |
||||||
|
} |
@ -0,0 +1,11 @@ |
|||||||
|
module github.com/go-macaron/cors |
||||||
|
|
||||||
|
go 1.12 |
||||||
|
|
||||||
|
require ( |
||||||
|
github.com/Unknwon/com v0.0.0-20190321035513-0fed4efef755 // indirect |
||||||
|
github.com/go-macaron/inject v0.0.0-20160627170012-d8a0b8677191 // indirect |
||||||
|
golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480 // indirect |
||||||
|
gopkg.in/ini.v1 v1.42.0 // indirect |
||||||
|
gopkg.in/macaron.v1 v1.3.2 |
||||||
|
) |
@ -0,0 +1,19 @@ |
|||||||
|
github.com/Unknwon/com v0.0.0-20190321035513-0fed4efef755 h1:1B7wb36fHLSwZfHg6ngZhhtIEHQjiC5H4p7qQGBEffg= |
||||||
|
github.com/Unknwon/com v0.0.0-20190321035513-0fed4efef755/go.mod h1:voKvFVpXBJxdIPeqjoJuLK+UVcRlo/JLjeToGxPYu68= |
||||||
|
github.com/go-macaron/inject v0.0.0-20160627170012-d8a0b8677191 h1:NjHlg70DuOkcAMqgt0+XA+NHwtu66MkTVVgR4fFWbcI= |
||||||
|
github.com/go-macaron/inject v0.0.0-20160627170012-d8a0b8677191/go.mod h1:VFI2o2q9kYsC4o7VP1HrEVosiZZTd+MVT3YZx4gqvJw= |
||||||
|
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg= |
||||||
|
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= |
||||||
|
github.com/jtolds/gls v4.2.1+incompatible h1:fSuqC+Gmlu6l/ZYAoZzx2pyucC8Xza35fpRVWLVmUEE= |
||||||
|
github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= |
||||||
|
github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 h1:Jpy1PXuP99tXNrhbq2BaPz9B+jNAvH1JPQQpG/9GCXY= |
||||||
|
github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= |
||||||
|
github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c h1:Ho+uVpkel/udgjbwB5Lktg9BtvJSh2DT0Hi6LPSyI2w= |
||||||
|
github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= |
||||||
|
golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480 h1:O5YqonU5IWby+w98jVUG9h7zlCWCcH4RHyPVReBmhzk= |
||||||
|
golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= |
||||||
|
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
||||||
|
gopkg.in/ini.v1 v1.42.0 h1:7N3gPTt50s8GuLortA00n8AqRTk75qOP98+mTPpgzRk= |
||||||
|
gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= |
||||||
|
gopkg.in/macaron.v1 v1.3.2 h1:AvWIaPmwBUA87/OWzePkoxeaw6YJWDfBt1pDFPBnLf8= |
||||||
|
gopkg.in/macaron.v1 v1.3.2/go.mod h1:PrsiawTWAGZs6wFbT5hlr7SQ2Ns9h7cUVtcUu4lQOVo= |
@ -0,0 +1,308 @@ |
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved. |
||||||
|
// Use of this source code is governed by a BSD-style |
||||||
|
// license that can be found in the LICENSE file. |
||||||
|
|
||||||
|
// +build go1.11 |
||||||
|
// +build !gccgo,!appengine |
||||||
|
|
||||||
|
#include "textflag.h" |
||||||
|
|
||||||
|
#define NUM_ROUNDS 10 |
||||||
|
|
||||||
|
// func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32) |
||||||
|
TEXT ·xorKeyStreamVX(SB), NOSPLIT, $0 |
||||||
|
MOVD dst+0(FP), R1 |
||||||
|
MOVD src+24(FP), R2 |
||||||
|
MOVD src_len+32(FP), R3 |
||||||
|
MOVD key+48(FP), R4 |
||||||
|
MOVD nonce+56(FP), R6 |
||||||
|
MOVD counter+64(FP), R7 |
||||||
|
|
||||||
|
MOVD $·constants(SB), R10 |
||||||
|
MOVD $·incRotMatrix(SB), R11 |
||||||
|
|
||||||
|
MOVW (R7), R20 |
||||||
|
|
||||||
|
AND $~255, R3, R13 |
||||||
|
ADD R2, R13, R12 // R12 for block end |
||||||
|
AND $255, R3, R13 |
||||||
|
loop: |
||||||
|
MOVD $NUM_ROUNDS, R21 |
||||||
|
VLD1 (R11), [V30.S4, V31.S4] |
||||||
|
|
||||||
|
// load contants |
||||||
|
// VLD4R (R10), [V0.S4, V1.S4, V2.S4, V3.S4] |
||||||
|
WORD $0x4D60E940 |
||||||
|
|
||||||
|
// load keys |
||||||
|
// VLD4R 16(R4), [V4.S4, V5.S4, V6.S4, V7.S4] |
||||||
|
WORD $0x4DFFE884 |
||||||
|
// VLD4R 16(R4), [V8.S4, V9.S4, V10.S4, V11.S4] |
||||||
|
WORD $0x4DFFE888 |
||||||
|
SUB $32, R4 |
||||||
|
|
||||||
|
// load counter + nonce |
||||||
|
// VLD1R (R7), [V12.S4] |
||||||
|
WORD $0x4D40C8EC |
||||||
|
|
||||||
|
// VLD3R (R6), [V13.S4, V14.S4, V15.S4] |
||||||
|
WORD $0x4D40E8CD |
||||||
|
|
||||||
|
// update counter |
||||||
|
VADD V30.S4, V12.S4, V12.S4 |
||||||
|
|
||||||
|
chacha: |
||||||
|
// V0..V3 += V4..V7 |
||||||
|
// V12..V15 <<<= ((V12..V15 XOR V0..V3), 16) |
||||||
|
VADD V0.S4, V4.S4, V0.S4 |
||||||
|
VADD V1.S4, V5.S4, V1.S4 |
||||||
|
VADD V2.S4, V6.S4, V2.S4 |
||||||
|
VADD V3.S4, V7.S4, V3.S4 |
||||||
|
VEOR V12.B16, V0.B16, V12.B16 |
||||||
|
VEOR V13.B16, V1.B16, V13.B16 |
||||||
|
VEOR V14.B16, V2.B16, V14.B16 |
||||||
|
VEOR V15.B16, V3.B16, V15.B16 |
||||||
|
VREV32 V12.H8, V12.H8 |
||||||
|
VREV32 V13.H8, V13.H8 |
||||||
|
VREV32 V14.H8, V14.H8 |
||||||
|
VREV32 V15.H8, V15.H8 |
||||||
|
// V8..V11 += V12..V15 |
||||||
|
// V4..V7 <<<= ((V4..V7 XOR V8..V11), 12) |
||||||
|
VADD V8.S4, V12.S4, V8.S4 |
||||||
|
VADD V9.S4, V13.S4, V9.S4 |
||||||
|
VADD V10.S4, V14.S4, V10.S4 |
||||||
|
VADD V11.S4, V15.S4, V11.S4 |
||||||
|
VEOR V8.B16, V4.B16, V16.B16 |
||||||
|
VEOR V9.B16, V5.B16, V17.B16 |
||||||
|
VEOR V10.B16, V6.B16, V18.B16 |
||||||
|
VEOR V11.B16, V7.B16, V19.B16 |
||||||
|
VSHL $12, V16.S4, V4.S4 |
||||||
|
VSHL $12, V17.S4, V5.S4 |
||||||
|
VSHL $12, V18.S4, V6.S4 |
||||||
|
VSHL $12, V19.S4, V7.S4 |
||||||
|
VSRI $20, V16.S4, V4.S4 |
||||||
|
VSRI $20, V17.S4, V5.S4 |
||||||
|
VSRI $20, V18.S4, V6.S4 |
||||||
|
VSRI $20, V19.S4, V7.S4 |
||||||
|
|
||||||
|
// V0..V3 += V4..V7 |
||||||
|
// V12..V15 <<<= ((V12..V15 XOR V0..V3), 8) |
||||||
|
VADD V0.S4, V4.S4, V0.S4 |
||||||
|
VADD V1.S4, V5.S4, V1.S4 |
||||||
|
VADD V2.S4, V6.S4, V2.S4 |
||||||
|
VADD V3.S4, V7.S4, V3.S4 |
||||||
|
VEOR V12.B16, V0.B16, V12.B16 |
||||||
|
VEOR V13.B16, V1.B16, V13.B16 |
||||||
|
VEOR V14.B16, V2.B16, V14.B16 |
||||||
|
VEOR V15.B16, V3.B16, V15.B16 |
||||||
|
VTBL V31.B16, [V12.B16], V12.B16 |
||||||
|
VTBL V31.B16, [V13.B16], V13.B16 |
||||||
|
VTBL V31.B16, [V14.B16], V14.B16 |
||||||
|
VTBL V31.B16, [V15.B16], V15.B16 |
||||||
|
|
||||||
|
// V8..V11 += V12..V15 |
||||||
|
// V4..V7 <<<= ((V4..V7 XOR V8..V11), 7) |
||||||
|
VADD V12.S4, V8.S4, V8.S4 |
||||||
|
VADD V13.S4, V9.S4, V9.S4 |
||||||
|
VADD V14.S4, V10.S4, V10.S4 |
||||||
|
VADD V15.S4, V11.S4, V11.S4 |
||||||
|
VEOR V8.B16, V4.B16, V16.B16 |
||||||
|
VEOR V9.B16, V5.B16, V17.B16 |
||||||
|
VEOR V10.B16, V6.B16, V18.B16 |
||||||
|
VEOR V11.B16, V7.B16, V19.B16 |
||||||
|
VSHL $7, V16.S4, V4.S4 |
||||||
|
VSHL $7, V17.S4, V5.S4 |
||||||
|
VSHL $7, V18.S4, V6.S4 |
||||||
|
VSHL $7, V19.S4, V7.S4 |
||||||
|
VSRI $25, V16.S4, V4.S4 |
||||||
|
VSRI $25, V17.S4, V5.S4 |
||||||
|
VSRI $25, V18.S4, V6.S4 |
||||||
|
VSRI $25, V19.S4, V7.S4 |
||||||
|
|
||||||
|
// V0..V3 += V5..V7, V4 |
||||||
|
// V15,V12-V14 <<<= ((V15,V12-V14 XOR V0..V3), 16) |
||||||
|
VADD V0.S4, V5.S4, V0.S4 |
||||||
|
VADD V1.S4, V6.S4, V1.S4 |
||||||
|
VADD V2.S4, V7.S4, V2.S4 |
||||||
|
VADD V3.S4, V4.S4, V3.S4 |
||||||
|
VEOR V15.B16, V0.B16, V15.B16 |
||||||
|
VEOR V12.B16, V1.B16, V12.B16 |
||||||
|
VEOR V13.B16, V2.B16, V13.B16 |
||||||
|
VEOR V14.B16, V3.B16, V14.B16 |
||||||
|
VREV32 V12.H8, V12.H8 |
||||||
|
VREV32 V13.H8, V13.H8 |
||||||
|
VREV32 V14.H8, V14.H8 |
||||||
|
VREV32 V15.H8, V15.H8 |
||||||
|
|
||||||
|
// V10 += V15; V5 <<<= ((V10 XOR V5), 12)
|
||||||
|
// ... |
||||||
|
VADD V15.S4, V10.S4, V10.S4 |
||||||
|
VADD V12.S4, V11.S4, V11.S4 |
||||||
|
VADD V13.S4, V8.S4, V8.S4 |
||||||
|
VADD V14.S4, V9.S4, V9.S4 |
||||||
|
VEOR V10.B16, V5.B16, V16.B16 |
||||||
|
VEOR V11.B16, V6.B16, V17.B16 |
||||||
|
VEOR V8.B16, V7.B16, V18.B16 |
||||||
|
VEOR V9.B16, V4.B16, V19.B16 |
||||||
|
VSHL $12, V16.S4, V5.S4 |
||||||
|
VSHL $12, V17.S4, V6.S4 |
||||||
|
VSHL $12, V18.S4, V7.S4 |
||||||
|
VSHL $12, V19.S4, V4.S4 |
||||||
|
VSRI $20, V16.S4, V5.S4 |
||||||
|
VSRI $20, V17.S4, V6.S4 |
||||||
|
VSRI $20, V18.S4, V7.S4 |
||||||
|
VSRI $20, V19.S4, V4.S4 |
||||||
|
|
||||||
|
// V0 += V5; V15 <<<= ((V0 XOR V15), 8)
|
||||||
|
// ... |
||||||
|
VADD V5.S4, V0.S4, V0.S4 |
||||||
|
VADD V6.S4, V1.S4, V1.S4 |
||||||
|
VADD V7.S4, V2.S4, V2.S4 |
||||||
|
VADD V4.S4, V3.S4, V3.S4 |
||||||
|
VEOR V0.B16, V15.B16, V15.B16 |
||||||
|
VEOR V1.B16, V12.B16, V12.B16 |
||||||
|
VEOR V2.B16, V13.B16, V13.B16 |
||||||
|
VEOR V3.B16, V14.B16, V14.B16 |
||||||
|
VTBL V31.B16, [V12.B16], V12.B16 |
||||||
|
VTBL V31.B16, [V13.B16], V13.B16 |
||||||
|
VTBL V31.B16, [V14.B16], V14.B16 |
||||||
|
VTBL V31.B16, [V15.B16], V15.B16 |
||||||
|
|
||||||
|
// V10 += V15; V5 <<<= ((V10 XOR V5), 7)
|
||||||
|
// ... |
||||||
|
VADD V15.S4, V10.S4, V10.S4 |
||||||
|
VADD V12.S4, V11.S4, V11.S4 |
||||||
|
VADD V13.S4, V8.S4, V8.S4 |
||||||
|
VADD V14.S4, V9.S4, V9.S4 |
||||||
|
VEOR V10.B16, V5.B16, V16.B16 |
||||||
|
VEOR V11.B16, V6.B16, V17.B16 |
||||||
|
VEOR V8.B16, V7.B16, V18.B16 |
||||||
|
VEOR V9.B16, V4.B16, V19.B16 |
||||||
|
VSHL $7, V16.S4, V5.S4 |
||||||
|
VSHL $7, V17.S4, V6.S4 |
||||||
|
VSHL $7, V18.S4, V7.S4 |
||||||
|
VSHL $7, V19.S4, V4.S4 |
||||||
|
VSRI $25, V16.S4, V5.S4 |
||||||
|
VSRI $25, V17.S4, V6.S4 |
||||||
|
VSRI $25, V18.S4, V7.S4 |
||||||
|
VSRI $25, V19.S4, V4.S4 |
||||||
|
|
||||||
|
SUB $1, R21 |
||||||
|
CBNZ R21, chacha |
||||||
|
|
||||||
|
// VLD4R (R10), [V16.S4, V17.S4, V18.S4, V19.S4] |
||||||
|
WORD $0x4D60E950 |
||||||
|
|
||||||
|
// VLD4R 16(R4), [V20.S4, V21.S4, V22.S4, V23.S4] |
||||||
|
WORD $0x4DFFE894 |
||||||
|
VADD V30.S4, V12.S4, V12.S4 |
||||||
|
VADD V16.S4, V0.S4, V0.S4 |
||||||
|
VADD V17.S4, V1.S4, V1.S4 |
||||||
|
VADD V18.S4, V2.S4, V2.S4 |
||||||
|
VADD V19.S4, V3.S4, V3.S4 |
||||||
|
// VLD4R 16(R4), [V24.S4, V25.S4, V26.S4, V27.S4] |
||||||
|
WORD $0x4DFFE898 |
||||||
|
// restore R4 |
||||||
|
SUB $32, R4 |
||||||
|
|
||||||
|
// load counter + nonce |
||||||
|
// VLD1R (R7), [V28.S4] |
||||||
|
WORD $0x4D40C8FC |
||||||
|
// VLD3R (R6), [V29.S4, V30.S4, V31.S4] |
||||||
|
WORD $0x4D40E8DD |
||||||
|
|
||||||
|
VADD V20.S4, V4.S4, V4.S4 |
||||||
|
VADD V21.S4, V5.S4, V5.S4 |
||||||
|
VADD V22.S4, V6.S4, V6.S4 |
||||||
|
VADD V23.S4, V7.S4, V7.S4 |
||||||
|
VADD V24.S4, V8.S4, V8.S4 |
||||||
|
VADD V25.S4, V9.S4, V9.S4 |
||||||
|
VADD V26.S4, V10.S4, V10.S4 |
||||||
|
VADD V27.S4, V11.S4, V11.S4 |
||||||
|
VADD V28.S4, V12.S4, V12.S4 |
||||||
|
VADD V29.S4, V13.S4, V13.S4 |
||||||
|
VADD V30.S4, V14.S4, V14.S4 |
||||||
|
VADD V31.S4, V15.S4, V15.S4 |
||||||
|
|
||||||
|
VZIP1 V1.S4, V0.S4, V16.S4 |
||||||
|
VZIP2 V1.S4, V0.S4, V17.S4 |
||||||
|
VZIP1 V3.S4, V2.S4, V18.S4 |
||||||
|
VZIP2 V3.S4, V2.S4, V19.S4 |
||||||
|
VZIP1 V5.S4, V4.S4, V20.S4 |
||||||
|
VZIP2 V5.S4, V4.S4, V21.S4 |
||||||
|
VZIP1 V7.S4, V6.S4, V22.S4 |
||||||
|
VZIP2 V7.S4, V6.S4, V23.S4 |
||||||
|
VZIP1 V9.S4, V8.S4, V24.S4 |
||||||
|
VZIP2 V9.S4, V8.S4, V25.S4 |
||||||
|
VZIP1 V11.S4, V10.S4, V26.S4 |
||||||
|
VZIP2 V11.S4, V10.S4, V27.S4 |
||||||
|
VZIP1 V13.S4, V12.S4, V28.S4 |
||||||
|
VZIP2 V13.S4, V12.S4, V29.S4 |
||||||
|
VZIP1 V15.S4, V14.S4, V30.S4 |
||||||
|
VZIP2 V15.S4, V14.S4, V31.S4 |
||||||
|
VZIP1 V18.D2, V16.D2, V0.D2 |
||||||
|
VZIP2 V18.D2, V16.D2, V4.D2 |
||||||
|
VZIP1 V19.D2, V17.D2, V8.D2 |
||||||
|
VZIP2 V19.D2, V17.D2, V12.D2 |
||||||
|
VLD1.P 64(R2), [V16.B16, V17.B16, V18.B16, V19.B16] |
||||||
|
|
||||||
|
VZIP1 V22.D2, V20.D2, V1.D2 |
||||||
|
VZIP2 V22.D2, V20.D2, V5.D2 |
||||||
|
VZIP1 V23.D2, V21.D2, V9.D2 |
||||||
|
VZIP2 V23.D2, V21.D2, V13.D2 |
||||||
|
VLD1.P 64(R2), [V20.B16, V21.B16, V22.B16, V23.B16] |
||||||
|
VZIP1 V26.D2, V24.D2, V2.D2 |
||||||
|
VZIP2 V26.D2, V24.D2, V6.D2 |
||||||
|
VZIP1 V27.D2, V25.D2, V10.D2 |
||||||
|
VZIP2 V27.D2, V25.D2, V14.D2 |
||||||
|
VLD1.P 64(R2), [V24.B16, V25.B16, V26.B16, V27.B16] |
||||||
|
VZIP1 V30.D2, V28.D2, V3.D2 |
||||||
|
VZIP2 V30.D2, V28.D2, V7.D2 |
||||||
|
VZIP1 V31.D2, V29.D2, V11.D2 |
||||||
|
VZIP2 V31.D2, V29.D2, V15.D2 |
||||||
|
VLD1.P 64(R2), [V28.B16, V29.B16, V30.B16, V31.B16] |
||||||
|
VEOR V0.B16, V16.B16, V16.B16 |
||||||
|
VEOR V1.B16, V17.B16, V17.B16 |
||||||
|
VEOR V2.B16, V18.B16, V18.B16 |
||||||
|
VEOR V3.B16, V19.B16, V19.B16 |
||||||
|
VST1.P [V16.B16, V17.B16, V18.B16, V19.B16], 64(R1) |
||||||
|
VEOR V4.B16, V20.B16, V20.B16 |
||||||
|
VEOR V5.B16, V21.B16, V21.B16 |
||||||
|
VEOR V6.B16, V22.B16, V22.B16 |
||||||
|
VEOR V7.B16, V23.B16, V23.B16 |
||||||
|
VST1.P [V20.B16, V21.B16, V22.B16, V23.B16], 64(R1) |
||||||
|
VEOR V8.B16, V24.B16, V24.B16 |
||||||
|
VEOR V9.B16, V25.B16, V25.B16 |
||||||
|
VEOR V10.B16, V26.B16, V26.B16 |
||||||
|
VEOR V11.B16, V27.B16, V27.B16 |
||||||
|
VST1.P [V24.B16, V25.B16, V26.B16, V27.B16], 64(R1) |
||||||
|
VEOR V12.B16, V28.B16, V28.B16 |
||||||
|
VEOR V13.B16, V29.B16, V29.B16 |
||||||
|
VEOR V14.B16, V30.B16, V30.B16 |
||||||
|
VEOR V15.B16, V31.B16, V31.B16 |
||||||
|
VST1.P [V28.B16, V29.B16, V30.B16, V31.B16], 64(R1) |
||||||
|
|
||||||
|
ADD $4, R20 |
||||||
|
MOVW R20, (R7) // update counter |
||||||
|
|
||||||
|
CMP R2, R12 |
||||||
|
BGT loop |
||||||
|
|
||||||
|
RET |
||||||
|
|
||||||
|
|
||||||
|
DATA ·constants+0x00(SB)/4, $0x61707865 |
||||||
|
DATA ·constants+0x04(SB)/4, $0x3320646e |
||||||
|
DATA ·constants+0x08(SB)/4, $0x79622d32 |
||||||
|
DATA ·constants+0x0c(SB)/4, $0x6b206574 |
||||||
|
GLOBL ·constants(SB), NOPTR|RODATA, $32 |
||||||
|
|
||||||
|
DATA ·incRotMatrix+0x00(SB)/4, $0x00000000 |
||||||
|
DATA ·incRotMatrix+0x04(SB)/4, $0x00000001 |
||||||
|
DATA ·incRotMatrix+0x08(SB)/4, $0x00000002 |
||||||
|
DATA ·incRotMatrix+0x0c(SB)/4, $0x00000003 |
||||||
|
DATA ·incRotMatrix+0x10(SB)/4, $0x02010003 |
||||||
|
DATA ·incRotMatrix+0x14(SB)/4, $0x06050407 |
||||||
|
DATA ·incRotMatrix+0x18(SB)/4, $0x0A09080B |
||||||
|
DATA ·incRotMatrix+0x1c(SB)/4, $0x0E0D0C0F |
||||||
|
GLOBL ·incRotMatrix(SB), NOPTR|RODATA, $32 |
@ -0,0 +1,31 @@ |
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build go1.11
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
package chacha20 |
||||||
|
|
||||||
|
const ( |
||||||
|
haveAsm = true |
||||||
|
bufSize = 256 |
||||||
|
) |
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32) |
||||||
|
|
||||||
|
func (c *Cipher) xorKeyStreamAsm(dst, src []byte) { |
||||||
|
|
||||||
|
if len(src) >= bufSize { |
||||||
|
xorKeyStreamVX(dst, src, &c.key, &c.nonce, &c.counter) |
||||||
|
} |
||||||
|
|
||||||
|
if len(src)%bufSize != 0 { |
||||||
|
i := len(src) - len(src)%bufSize |
||||||
|
c.buf = [bufSize]byte{} |
||||||
|
copy(c.buf[:], src[i:]) |
||||||
|
xorKeyStreamVX(c.buf[:], c.buf[:], &c.key, &c.nonce, &c.counter) |
||||||
|
c.len = bufSize - copy(dst[i:], c.buf[:len(src)%bufSize]) |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,11 @@ |
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !amd64 gccgo appengine
|
||||||
|
|
||||||
|
package poly1305 |
||||||
|
|
||||||
|
type mac struct{ macGeneric } |
||||||
|
|
||||||
|
func newMAC(key *[32]byte) mac { return mac{newMACGeneric(key)} } |
@ -0,0 +1,30 @@ |
|||||||
|
// Copyright 2019 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 cpu |
||||||
|
|
||||||
|
import ( |
||||||
|
"encoding/binary" |
||||||
|
"runtime" |
||||||
|
) |
||||||
|
|
||||||
|
// hostByteOrder returns binary.LittleEndian on little-endian machines and
|
||||||
|
// binary.BigEndian on big-endian machines.
|
||||||
|
func hostByteOrder() binary.ByteOrder { |
||||||
|
switch runtime.GOARCH { |
||||||
|
case "386", "amd64", "amd64p32", |
||||||
|
"arm", "arm64", |
||||||
|
"mipsle", "mips64le", "mips64p32le", |
||||||
|
"ppc64le", |
||||||
|
"riscv", "riscv64": |
||||||
|
return binary.LittleEndian |
||||||
|
case "armbe", "arm64be", |
||||||
|
"mips", "mips64", "mips64p32", |
||||||
|
"ppc", "ppc64", |
||||||
|
"s390", "s390x", |
||||||
|
"sparc", "sparc64": |
||||||
|
return binary.BigEndian |
||||||
|
} |
||||||
|
panic("unknown architecture") |
||||||
|
} |
@ -0,0 +1,126 @@ |
|||||||
|
// Copyright 2018 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 cpu implements processor feature detection for
|
||||||
|
// various CPU architectures.
|
||||||
|
package cpu |
||||||
|
|
||||||
|
// Initialized reports whether the CPU features were initialized.
|
||||||
|
//
|
||||||
|
// For some GOOS/GOARCH combinations initialization of the CPU features depends
|
||||||
|
// on reading an operating specific file, e.g. /proc/self/auxv on linux/arm
|
||||||
|
// Initialized will report false if reading the file fails.
|
||||||
|
var Initialized bool |
||||||
|
|
||||||
|
// CacheLinePad is used to pad structs to avoid false sharing.
|
||||||
|
type CacheLinePad struct{ _ [cacheLineSize]byte } |
||||||
|
|
||||||
|
// X86 contains the supported CPU features of the
|
||||||
|
// current X86/AMD64 platform. If the current platform
|
||||||
|
// is not X86/AMD64 then all feature flags are false.
|
||||||
|
//
|
||||||
|
// X86 is padded to avoid false sharing. Further the HasAVX
|
||||||
|
// and HasAVX2 are only set if the OS supports XMM and YMM
|
||||||
|
// registers in addition to the CPUID feature bit being set.
|
||||||
|
var X86 struct { |
||||||
|
_ CacheLinePad |
||||||
|
HasAES bool // AES hardware implementation (AES NI)
|
||||||
|
HasADX bool // Multi-precision add-carry instruction extensions
|
||||||
|
HasAVX bool // Advanced vector extension
|
||||||
|
HasAVX2 bool // Advanced vector extension 2
|
||||||
|
HasBMI1 bool // Bit manipulation instruction set 1
|
||||||
|
HasBMI2 bool // Bit manipulation instruction set 2
|
||||||
|
HasERMS bool // Enhanced REP for MOVSB and STOSB
|
||||||
|
HasFMA bool // Fused-multiply-add instructions
|
||||||
|
HasOSXSAVE bool // OS supports XSAVE/XRESTOR for saving/restoring XMM registers.
|
||||||
|
HasPCLMULQDQ bool // PCLMULQDQ instruction - most often used for AES-GCM
|
||||||
|
HasPOPCNT bool // Hamming weight instruction POPCNT.
|
||||||
|
HasRDRAND bool // RDRAND instruction (on-chip random number generator)
|
||||||
|
HasRDSEED bool // RDSEED instruction (on-chip random number generator)
|
||||||
|
HasSSE2 bool // Streaming SIMD extension 2 (always available on amd64)
|
||||||
|
HasSSE3 bool // Streaming SIMD extension 3
|
||||||
|
HasSSSE3 bool // Supplemental streaming SIMD extension 3
|
||||||
|
HasSSE41 bool // Streaming SIMD extension 4 and 4.1
|
||||||
|
HasSSE42 bool // Streaming SIMD extension 4 and 4.2
|
||||||
|
_ CacheLinePad |
||||||
|
} |
||||||
|
|
||||||
|
// ARM64 contains the supported CPU features of the
|
||||||
|
// current ARMv8(aarch64) platform. If the current platform
|
||||||
|
// is not arm64 then all feature flags are false.
|
||||||
|
var ARM64 struct { |
||||||
|
_ CacheLinePad |
||||||
|
HasFP bool // Floating-point instruction set (always available)
|
||||||
|
HasASIMD bool // Advanced SIMD (always available)
|
||||||
|
HasEVTSTRM bool // Event stream support
|
||||||
|
HasAES bool // AES hardware implementation
|
||||||
|
HasPMULL bool // Polynomial multiplication instruction set
|
||||||
|
HasSHA1 bool // SHA1 hardware implementation
|
||||||
|
HasSHA2 bool // SHA2 hardware implementation
|
||||||
|
HasCRC32 bool // CRC32 hardware implementation
|
||||||
|
HasATOMICS bool // Atomic memory operation instruction set
|
||||||
|
HasFPHP bool // Half precision floating-point instruction set
|
||||||
|
HasASIMDHP bool // Advanced SIMD half precision instruction set
|
||||||
|
HasCPUID bool // CPUID identification scheme registers
|
||||||
|
HasASIMDRDM bool // Rounding double multiply add/subtract instruction set
|
||||||
|
HasJSCVT bool // Javascript conversion from floating-point to integer
|
||||||
|
HasFCMA bool // Floating-point multiplication and addition of complex numbers
|
||||||
|
HasLRCPC bool // Release Consistent processor consistent support
|
||||||
|
HasDCPOP bool // Persistent memory support
|
||||||
|
HasSHA3 bool // SHA3 hardware implementation
|
||||||
|
HasSM3 bool // SM3 hardware implementation
|
||||||
|
HasSM4 bool // SM4 hardware implementation
|
||||||
|
HasASIMDDP bool // Advanced SIMD double precision instruction set
|
||||||
|
HasSHA512 bool // SHA512 hardware implementation
|
||||||
|
HasSVE bool // Scalable Vector Extensions
|
||||||
|
HasASIMDFHM bool // Advanced SIMD multiplication FP16 to FP32
|
||||||
|
_ CacheLinePad |
||||||
|
} |
||||||
|
|
||||||
|
// PPC64 contains the supported CPU features of the current ppc64/ppc64le platforms.
|
||||||
|
// If the current platform is not ppc64/ppc64le then all feature flags are false.
|
||||||
|
//
|
||||||
|
// For ppc64/ppc64le, it is safe to check only for ISA level starting on ISA v3.00,
|
||||||
|
// since there are no optional categories. There are some exceptions that also
|
||||||
|
// require kernel support to work (DARN, SCV), so there are feature bits for
|
||||||
|
// those as well. The minimum processor requirement is POWER8 (ISA 2.07).
|
||||||
|
// The struct is padded to avoid false sharing.
|
||||||
|
var PPC64 struct { |
||||||
|
_ CacheLinePad |
||||||
|
HasDARN bool // Hardware random number generator (requires kernel enablement)
|
||||||
|
HasSCV bool // Syscall vectored (requires kernel enablement)
|
||||||
|
IsPOWER8 bool // ISA v2.07 (POWER8)
|
||||||
|
IsPOWER9 bool // ISA v3.00 (POWER9)
|
||||||
|
_ CacheLinePad |
||||||
|
} |
||||||
|
|
||||||
|
// S390X contains the supported CPU features of the current IBM Z
|
||||||
|
// (s390x) platform. If the current platform is not IBM Z then all
|
||||||
|
// feature flags are false.
|
||||||
|
//
|
||||||
|
// S390X is padded to avoid false sharing. Further HasVX is only set
|
||||||
|
// if the OS supports vector registers in addition to the STFLE
|
||||||
|
// feature bit being set.
|
||||||
|
var S390X struct { |
||||||
|
_ CacheLinePad |
||||||
|
HasZARCH bool // z/Architecture mode is active [mandatory]
|
||||||
|
HasSTFLE bool // store facility list extended
|
||||||
|
HasLDISP bool // long (20-bit) displacements
|
||||||
|
HasEIMM bool // 32-bit immediates
|
||||||
|
HasDFP bool // decimal floating point
|
||||||
|
HasETF3EH bool // ETF-3 enhanced
|
||||||
|
HasMSA bool // message security assist (CPACF)
|
||||||
|
HasAES bool // KM-AES{128,192,256} functions
|
||||||
|
HasAESCBC bool // KMC-AES{128,192,256} functions
|
||||||
|
HasAESCTR bool // KMCTR-AES{128,192,256} functions
|
||||||
|
HasAESGCM bool // KMA-GCM-AES{128,192,256} functions
|
||||||
|
HasGHASH bool // KIMD-GHASH function
|
||||||
|
HasSHA1 bool // K{I,L}MD-SHA-1 functions
|
||||||
|
HasSHA256 bool // K{I,L}MD-SHA-256 functions
|
||||||
|
HasSHA512 bool // K{I,L}MD-SHA-512 functions
|
||||||
|
HasSHA3 bool // K{I,L}MD-SHA3-{224,256,384,512} and K{I,L}MD-SHAKE-{128,256} functions
|
||||||
|
HasVX bool // vector facility
|
||||||
|
HasVXE bool // vector-enhancements facility 1
|
||||||
|
_ CacheLinePad |
||||||
|
} |
@ -0,0 +1,30 @@ |
|||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build aix,ppc64
|
||||||
|
|
||||||
|
package cpu |
||||||
|
|
||||||
|
import "golang.org/x/sys/unix" |
||||||
|
|
||||||
|
const cacheLineSize = 128 |
||||||
|
|
||||||
|
const ( |
||||||
|
// getsystemcfg constants
|
||||||
|
_SC_IMPL = 2 |
||||||
|
_IMPL_POWER8 = 0x10000 |
||||||
|
_IMPL_POWER9 = 0x20000 |
||||||
|
) |
||||||
|
|
||||||
|
func init() { |
||||||
|
impl := unix.Getsystemcfg(_SC_IMPL) |
||||||
|
if impl&_IMPL_POWER8 != 0 { |
||||||
|
PPC64.IsPOWER8 = true |
||||||
|
} |
||||||
|
if impl&_IMPL_POWER9 != 0 { |
||||||
|
PPC64.IsPOWER9 = true |
||||||
|
} |
||||||
|
|
||||||
|
Initialized = true |
||||||
|
} |
@ -0,0 +1,9 @@ |
|||||||
|
// Copyright 2018 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 cpu |
||||||
|
|
||||||
|
const cacheLineSize = 32 |
||||||
|
|
||||||
|
func doinit() {} |
@ -0,0 +1,21 @@ |
|||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
package cpu |
||||||
|
|
||||||
|
// haveAsmFunctions reports whether the other functions in this file can
|
||||||
|
// be safely called.
|
||||||
|
func haveAsmFunctions() bool { return true } |
||||||
|
|
||||||
|
// The following feature detection functions are defined in cpu_s390x.s.
|
||||||
|
// They are likely to be expensive to call so the results should be cached.
|
||||||
|
func stfle() facilityList |
||||||
|
func kmQuery() queryResult |
||||||
|
func kmcQuery() queryResult |
||||||
|
func kmctrQuery() queryResult |
||||||
|
func kmaQuery() queryResult |
||||||
|
func kimdQuery() queryResult |
||||||
|
func klmdQuery() queryResult |
@ -0,0 +1,16 @@ |
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build 386 amd64 amd64p32
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
package cpu |
||||||
|
|
||||||
|
// cpuid is implemented in cpu_x86.s for gc compiler
|
||||||
|
// and in cpu_gccgo.c for gccgo.
|
||||||
|
func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32) |
||||||
|
|
||||||
|
// xgetbv with ecx = 0 is implemented in cpu_x86.s for gc compiler
|
||||||
|
// and in cpu_gccgo.c for gccgo.
|
||||||
|
func xgetbv() (eax, edx uint32) |
@ -0,0 +1,43 @@ |
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build 386 amd64 amd64p32
|
||||||
|
// +build gccgo
|
||||||
|
|
||||||
|
#include <cpuid.h> |
||||||
|
#include <stdint.h> |
||||||
|
|
||||||
|
// Need to wrap __get_cpuid_count because it's declared as static.
|
||||||
|
int |
||||||
|
gccgoGetCpuidCount(uint32_t leaf, uint32_t subleaf, |
||||||
|
uint32_t *eax, uint32_t *ebx, |
||||||
|
uint32_t *ecx, uint32_t *edx) |
||||||
|
{ |
||||||
|
return __get_cpuid_count(leaf, subleaf, eax, ebx, ecx, edx); |
||||||
|
} |
||||||
|
|
||||||
|
// xgetbv reads the contents of an XCR (Extended Control Register)
|
||||||
|
// specified in the ECX register into registers EDX:EAX.
|
||||||
|
// Currently, the only supported value for XCR is 0.
|
||||||
|
//
|
||||||
|
// TODO: Replace with a better alternative:
|
||||||
|
//
|
||||||
|
// #include <xsaveintrin.h>
|
||||||
|
//
|
||||||
|
// #pragma GCC target("xsave")
|
||||||
|
//
|
||||||
|
// void gccgoXgetbv(uint32_t *eax, uint32_t *edx) {
|
||||||
|
// unsigned long long x = _xgetbv(0);
|
||||||
|
// *eax = x & 0xffffffff;
|
||||||
|
// *edx = (x >> 32) & 0xffffffff;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Note that _xgetbv is defined starting with GCC 8.
|
||||||
|
void |
||||||
|
gccgoXgetbv(uint32_t *eax, uint32_t *edx) |
||||||
|
{ |
||||||
|
__asm(" xorl %%ecx, %%ecx\n" |
||||||
|
" xgetbv" |
||||||
|
: "=a"(*eax), "=d"(*edx)); |
||||||
|
} |
@ -0,0 +1,26 @@ |
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build 386 amd64 amd64p32
|
||||||
|
// +build gccgo
|
||||||
|
|
||||||
|
package cpu |
||||||
|
|
||||||
|
//extern gccgoGetCpuidCount
|
||||||
|
func gccgoGetCpuidCount(eaxArg, ecxArg uint32, eax, ebx, ecx, edx *uint32) |
||||||
|
|
||||||
|
func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32) { |
||||||
|
var a, b, c, d uint32 |
||||||
|
gccgoGetCpuidCount(eaxArg, ecxArg, &a, &b, &c, &d) |
||||||
|
return a, b, c, d |
||||||
|
} |
||||||
|
|
||||||
|
//extern gccgoXgetbv
|
||||||
|
func gccgoXgetbv(eax, edx *uint32) |
||||||
|
|
||||||
|
func xgetbv() (eax, edx uint32) { |
||||||
|
var a, d uint32 |
||||||
|
gccgoXgetbv(&a, &d) |
||||||
|
return a, d |
||||||
|
} |
@ -0,0 +1,22 @@ |
|||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build gccgo
|
||||||
|
|
||||||
|
package cpu |
||||||
|
|
||||||
|
// haveAsmFunctions reports whether the other functions in this file can
|
||||||
|
// be safely called.
|
||||||
|
func haveAsmFunctions() bool { return false } |
||||||
|
|
||||||
|
// TODO(mundaym): the following feature detection functions are currently
|
||||||
|
// stubs. See https://golang.org/cl/162887 for how to fix this.
|
||||||
|
// They are likely to be expensive to call so the results should be cached.
|
||||||
|
func stfle() facilityList { panic("not implemented for gccgo") } |
||||||
|
func kmQuery() queryResult { panic("not implemented for gccgo") } |
||||||
|
func kmcQuery() queryResult { panic("not implemented for gccgo") } |
||||||
|
func kmctrQuery() queryResult { panic("not implemented for gccgo") } |
||||||
|
func kmaQuery() queryResult { panic("not implemented for gccgo") } |
||||||
|
func kimdQuery() queryResult { panic("not implemented for gccgo") } |
||||||
|
func klmdQuery() queryResult { panic("not implemented for gccgo") } |
@ -0,0 +1,59 @@ |
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//+build !amd64,!amd64p32,!386
|
||||||
|
|
||||||
|
package cpu |
||||||
|
|
||||||
|
import ( |
||||||
|
"io/ioutil" |
||||||
|
) |
||||||
|
|
||||||
|
const ( |
||||||
|
_AT_HWCAP = 16 |
||||||
|
_AT_HWCAP2 = 26 |
||||||
|
|
||||||
|
procAuxv = "/proc/self/auxv" |
||||||
|
|
||||||
|
uintSize = int(32 << (^uint(0) >> 63)) |
||||||
|
) |
||||||
|
|
||||||
|
// For those platforms don't have a 'cpuid' equivalent we use HWCAP/HWCAP2
|
||||||
|
// These are initialized in cpu_$GOARCH.go
|
||||||
|
// and should not be changed after they are initialized.
|
||||||
|
var hwCap uint |
||||||
|
var hwCap2 uint |
||||||
|
|
||||||
|
func init() { |
||||||
|
buf, err := ioutil.ReadFile(procAuxv) |
||||||
|
if err != nil { |
||||||
|
// e.g. on android /proc/self/auxv is not accessible, so silently
|
||||||
|
// ignore the error and leave Initialized = false
|
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
bo := hostByteOrder() |
||||||
|
for len(buf) >= 2*(uintSize/8) { |
||||||
|
var tag, val uint |
||||||
|
switch uintSize { |
||||||
|
case 32: |
||||||
|
tag = uint(bo.Uint32(buf[0:])) |
||||||
|
val = uint(bo.Uint32(buf[4:])) |
||||||
|
buf = buf[8:] |
||||||
|
case 64: |
||||||
|
tag = uint(bo.Uint64(buf[0:])) |
||||||
|
val = uint(bo.Uint64(buf[8:])) |
||||||
|
buf = buf[16:] |
||||||
|
} |
||||||
|
switch tag { |
||||||
|
case _AT_HWCAP: |
||||||
|
hwCap = val |
||||||
|
case _AT_HWCAP2: |
||||||
|
hwCap2 = val |
||||||
|
} |
||||||
|
} |
||||||
|
doinit() |
||||||
|
|
||||||
|
Initialized = true |
||||||
|
} |
@ -0,0 +1,67 @@ |
|||||||
|
// Copyright 2018 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 cpu |
||||||
|
|
||||||
|
const cacheLineSize = 64 |
||||||
|
|
||||||
|
// HWCAP/HWCAP2 bits. These are exposed by Linux.
|
||||||
|
const ( |
||||||
|
hwcap_FP = 1 << 0 |
||||||
|
hwcap_ASIMD = 1 << 1 |
||||||
|
hwcap_EVTSTRM = 1 << 2 |
||||||
|
hwcap_AES = 1 << 3 |
||||||
|
hwcap_PMULL = 1 << 4 |
||||||
|
hwcap_SHA1 = 1 << 5 |
||||||
|
hwcap_SHA2 = 1 << 6 |
||||||
|
hwcap_CRC32 = 1 << 7 |
||||||
|
hwcap_ATOMICS = 1 << 8 |
||||||
|
hwcap_FPHP = 1 << 9 |
||||||
|
hwcap_ASIMDHP = 1 << 10 |
||||||
|
hwcap_CPUID = 1 << 11 |
||||||
|
hwcap_ASIMDRDM = 1 << 12 |
||||||
|
hwcap_JSCVT = 1 << 13 |
||||||
|
hwcap_FCMA = 1 << 14 |
||||||
|
hwcap_LRCPC = 1 << 15 |
||||||
|
hwcap_DCPOP = 1 << 16 |
||||||
|
hwcap_SHA3 = 1 << 17 |
||||||
|
hwcap_SM3 = 1 << 18 |
||||||
|
hwcap_SM4 = 1 << 19 |
||||||
|
hwcap_ASIMDDP = 1 << 20 |
||||||
|
hwcap_SHA512 = 1 << 21 |
||||||
|
hwcap_SVE = 1 << 22 |
||||||
|
hwcap_ASIMDFHM = 1 << 23 |
||||||
|
) |
||||||
|
|
||||||
|
func doinit() { |
||||||
|
// HWCAP feature bits
|
||||||
|
ARM64.HasFP = isSet(hwCap, hwcap_FP) |
||||||
|
ARM64.HasASIMD = isSet(hwCap, hwcap_ASIMD) |
||||||
|
ARM64.HasEVTSTRM = isSet(hwCap, hwcap_EVTSTRM) |
||||||
|
ARM64.HasAES = isSet(hwCap, hwcap_AES) |
||||||
|
ARM64.HasPMULL = isSet(hwCap, hwcap_PMULL) |
||||||
|
ARM64.HasSHA1 = isSet(hwCap, hwcap_SHA1) |
||||||
|
ARM64.HasSHA2 = isSet(hwCap, hwcap_SHA2) |
||||||
|
ARM64.HasCRC32 = isSet(hwCap, hwcap_CRC32) |
||||||
|
ARM64.HasATOMICS = isSet(hwCap, hwcap_ATOMICS) |
||||||
|
ARM64.HasFPHP = isSet(hwCap, hwcap_FPHP) |
||||||
|
ARM64.HasASIMDHP = isSet(hwCap, hwcap_ASIMDHP) |
||||||
|
ARM64.HasCPUID = isSet(hwCap, hwcap_CPUID) |
||||||
|
ARM64.HasASIMDRDM = isSet(hwCap, hwcap_ASIMDRDM) |
||||||
|
ARM64.HasJSCVT = isSet(hwCap, hwcap_JSCVT) |
||||||
|
ARM64.HasFCMA = isSet(hwCap, hwcap_FCMA) |
||||||
|
ARM64.HasLRCPC = isSet(hwCap, hwcap_LRCPC) |
||||||
|
ARM64.HasDCPOP = isSet(hwCap, hwcap_DCPOP) |
||||||
|
ARM64.HasSHA3 = isSet(hwCap, hwcap_SHA3) |
||||||
|
ARM64.HasSM3 = isSet(hwCap, hwcap_SM3) |
||||||
|
ARM64.HasSM4 = isSet(hwCap, hwcap_SM4) |
||||||
|
ARM64.HasASIMDDP = isSet(hwCap, hwcap_ASIMDDP) |
||||||
|
ARM64.HasSHA512 = isSet(hwCap, hwcap_SHA512) |
||||||
|
ARM64.HasSVE = isSet(hwCap, hwcap_SVE) |
||||||
|
ARM64.HasASIMDFHM = isSet(hwCap, hwcap_ASIMDFHM) |
||||||
|
} |
||||||
|
|
||||||
|
func isSet(hwc uint, value uint) bool { |
||||||
|
return hwc&value != 0 |
||||||
|
} |
@ -0,0 +1,33 @@ |
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build linux
|
||||||
|
// +build ppc64 ppc64le
|
||||||
|
|
||||||
|
package cpu |
||||||
|
|
||||||
|
const cacheLineSize = 128 |
||||||
|
|
||||||
|
// HWCAP/HWCAP2 bits. These are exposed by the kernel.
|
||||||
|
const ( |
||||||
|
// ISA Level
|
||||||
|
_PPC_FEATURE2_ARCH_2_07 = 0x80000000 |
||||||
|
_PPC_FEATURE2_ARCH_3_00 = 0x00800000 |
||||||
|
|
||||||
|
// CPU features
|
||||||
|
_PPC_FEATURE2_DARN = 0x00200000 |
||||||
|
_PPC_FEATURE2_SCV = 0x00100000 |
||||||
|
) |
||||||
|
|
||||||
|
func doinit() { |
||||||
|
// HWCAP2 feature bits
|
||||||
|
PPC64.IsPOWER8 = isSet(hwCap2, _PPC_FEATURE2_ARCH_2_07) |
||||||
|
PPC64.IsPOWER9 = isSet(hwCap2, _PPC_FEATURE2_ARCH_3_00) |
||||||
|
PPC64.HasDARN = isSet(hwCap2, _PPC_FEATURE2_DARN) |
||||||
|
PPC64.HasSCV = isSet(hwCap2, _PPC_FEATURE2_SCV) |
||||||
|
} |
||||||
|
|
||||||
|
func isSet(hwc uint, value uint) bool { |
||||||
|
return hwc&value != 0 |
||||||
|
} |
@ -0,0 +1,161 @@ |
|||||||
|
// Copyright 2019 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 cpu |
||||||
|
|
||||||
|
const cacheLineSize = 256 |
||||||
|
|
||||||
|
const ( |
||||||
|
// bit mask values from /usr/include/bits/hwcap.h
|
||||||
|
hwcap_ZARCH = 2 |
||||||
|
hwcap_STFLE = 4 |
||||||
|
hwcap_MSA = 8 |
||||||
|
hwcap_LDISP = 16 |
||||||
|
hwcap_EIMM = 32 |
||||||
|
hwcap_DFP = 64 |
||||||
|
hwcap_ETF3EH = 256 |
||||||
|
hwcap_VX = 2048 |
||||||
|
hwcap_VXE = 8192 |
||||||
|
) |
||||||
|
|
||||||
|
// bitIsSet reports whether the bit at index is set. The bit index
|
||||||
|
// is in big endian order, so bit index 0 is the leftmost bit.
|
||||||
|
func bitIsSet(bits []uint64, index uint) bool { |
||||||
|
return bits[index/64]&((1<<63)>>(index%64)) != 0 |
||||||
|
} |
||||||
|
|
||||||
|
// function is the code for the named cryptographic function.
|
||||||
|
type function uint8 |
||||||
|
|
||||||
|
const ( |
||||||
|
// KM{,A,C,CTR} function codes
|
||||||
|
aes128 function = 18 // AES-128
|
||||||
|
aes192 function = 19 // AES-192
|
||||||
|
aes256 function = 20 // AES-256
|
||||||
|
|
||||||
|
// K{I,L}MD function codes
|
||||||
|
sha1 function = 1 // SHA-1
|
||||||
|
sha256 function = 2 // SHA-256
|
||||||
|
sha512 function = 3 // SHA-512
|
||||||
|
sha3_224 function = 32 // SHA3-224
|
||||||
|
sha3_256 function = 33 // SHA3-256
|
||||||
|
sha3_384 function = 34 // SHA3-384
|
||||||
|
sha3_512 function = 35 // SHA3-512
|
||||||
|
shake128 function = 36 // SHAKE-128
|
||||||
|
shake256 function = 37 // SHAKE-256
|
||||||
|
|
||||||
|
// KLMD function codes
|
||||||
|
ghash function = 65 // GHASH
|
||||||
|
) |
||||||
|
|
||||||
|
// queryResult contains the result of a Query function
|
||||||
|
// call. Bits are numbered in big endian order so the
|
||||||
|
// leftmost bit (the MSB) is at index 0.
|
||||||
|
type queryResult struct { |
||||||
|
bits [2]uint64 |
||||||
|
} |
||||||
|
|
||||||
|
// Has reports whether the given functions are present.
|
||||||
|
func (q *queryResult) Has(fns ...function) bool { |
||||||
|
if len(fns) == 0 { |
||||||
|
panic("no function codes provided") |
||||||
|
} |
||||||
|
for _, f := range fns { |
||||||
|
if !bitIsSet(q.bits[:], uint(f)) { |
||||||
|
return false |
||||||
|
} |
||||||
|
} |
||||||
|
return true |
||||||
|
} |
||||||
|
|
||||||
|
// facility is a bit index for the named facility.
|
||||||
|
type facility uint8 |
||||||
|
|
||||||
|
const ( |
||||||
|
// cryptography facilities
|
||||||
|
msa4 facility = 77 // message-security-assist extension 4
|
||||||
|
msa8 facility = 146 // message-security-assist extension 8
|
||||||
|
) |
||||||
|
|
||||||
|
// facilityList contains the result of an STFLE call.
|
||||||
|
// Bits are numbered in big endian order so the
|
||||||
|
// leftmost bit (the MSB) is at index 0.
|
||||||
|
type facilityList struct { |
||||||
|
bits [4]uint64 |
||||||
|
} |
||||||
|
|
||||||
|
// Has reports whether the given facilities are present.
|
||||||
|
func (s *facilityList) Has(fs ...facility) bool { |
||||||
|
if len(fs) == 0 { |
||||||
|
panic("no facility bits provided") |
||||||
|
} |
||||||
|
for _, f := range fs { |
||||||
|
if !bitIsSet(s.bits[:], uint(f)) { |
||||||
|
return false |
||||||
|
} |
||||||
|
} |
||||||
|
return true |
||||||
|
} |
||||||
|
|
||||||
|
func doinit() { |
||||||
|
// test HWCAP bit vector
|
||||||
|
has := func(featureMask uint) bool { |
||||||
|
return hwCap&featureMask == featureMask |
||||||
|
} |
||||||
|
|
||||||
|
// mandatory
|
||||||
|
S390X.HasZARCH = has(hwcap_ZARCH) |
||||||
|
|
||||||
|
// optional
|
||||||
|
S390X.HasSTFLE = has(hwcap_STFLE) |
||||||
|
S390X.HasLDISP = has(hwcap_LDISP) |
||||||
|
S390X.HasEIMM = has(hwcap_EIMM) |
||||||
|
S390X.HasETF3EH = has(hwcap_ETF3EH) |
||||||
|
S390X.HasDFP = has(hwcap_DFP) |
||||||
|
S390X.HasMSA = has(hwcap_MSA) |
||||||
|
S390X.HasVX = has(hwcap_VX) |
||||||
|
if S390X.HasVX { |
||||||
|
S390X.HasVXE = has(hwcap_VXE) |
||||||
|
} |
||||||
|
|
||||||
|
// We need implementations of stfle, km and so on
|
||||||
|
// to detect cryptographic features.
|
||||||
|
if !haveAsmFunctions() { |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
// optional cryptographic functions
|
||||||
|
if S390X.HasMSA { |
||||||
|
aes := []function{aes128, aes192, aes256} |
||||||
|
|
||||||
|
// cipher message
|
||||||
|
km, kmc := kmQuery(), kmcQuery() |
||||||
|
S390X.HasAES = km.Has(aes...) |
||||||
|
S390X.HasAESCBC = kmc.Has(aes...) |
||||||
|
if S390X.HasSTFLE { |
||||||
|
facilities := stfle() |
||||||
|
if facilities.Has(msa4) { |
||||||
|
kmctr := kmctrQuery() |
||||||
|
S390X.HasAESCTR = kmctr.Has(aes...) |
||||||
|
} |
||||||
|
if facilities.Has(msa8) { |
||||||
|
kma := kmaQuery() |
||||||
|
S390X.HasAESGCM = kma.Has(aes...) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// compute message digest
|
||||||
|
kimd := kimdQuery() // intermediate (no padding)
|
||||||
|
klmd := klmdQuery() // last (padding)
|
||||||
|
S390X.HasSHA1 = kimd.Has(sha1) && klmd.Has(sha1) |
||||||
|
S390X.HasSHA256 = kimd.Has(sha256) && klmd.Has(sha256) |
||||||
|
S390X.HasSHA512 = kimd.Has(sha512) && klmd.Has(sha512) |
||||||
|
S390X.HasGHASH = kimd.Has(ghash) // KLMD-GHASH does not exist
|
||||||
|
sha3 := []function{ |
||||||
|
sha3_224, sha3_256, sha3_384, sha3_512, |
||||||
|
shake128, shake256, |
||||||
|
} |
||||||
|
S390X.HasSHA3 = kimd.Has(sha3...) && klmd.Has(sha3...) |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,11 @@ |
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build mips64 mips64le
|
||||||
|
|
||||||
|
package cpu |
||||||
|
|
||||||
|
const cacheLineSize = 32 |
||||||
|
|
||||||
|
func doinit() {} |
@ -0,0 +1,11 @@ |
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build mips mipsle
|
||||||
|
|
||||||
|
package cpu |
||||||
|
|
||||||
|
const cacheLineSize = 32 |
||||||
|
|
||||||
|
func doinit() {} |
@ -0,0 +1,11 @@ |
|||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !linux,arm64
|
||||||
|
|
||||||
|
package cpu |
||||||
|
|
||||||
|
const cacheLineSize = 64 |
||||||
|
|
||||||
|
func doinit() {} |
@ -0,0 +1,57 @@ |
|||||||
|
// Copyright 2019 The Go Authors. All rights reserved. |
||||||
|
// Use of this source code is governed by a BSD-style |
||||||
|
// license that can be found in the LICENSE file. |
||||||
|
|
||||||
|
// +build !gccgo |
||||||
|
|
||||||
|
#include "textflag.h" |
||||||
|
|
||||||
|
// func stfle() facilityList |
||||||
|
TEXT ·stfle(SB), NOSPLIT|NOFRAME, $0-32 |
||||||
|
MOVD $ret+0(FP), R1 |
||||||
|
MOVD $3, R0 // last doubleword index to store |
||||||
|
XC $32, (R1), (R1) // clear 4 doublewords (32 bytes) |
||||||
|
WORD $0xb2b01000 // store facility list extended (STFLE) |
||||||
|
RET |
||||||
|
|
||||||
|
// func kmQuery() queryResult |
||||||
|
TEXT ·kmQuery(SB), NOSPLIT|NOFRAME, $0-16 |
||||||
|
MOVD $0, R0 // set function code to 0 (KM-Query) |
||||||
|
MOVD $ret+0(FP), R1 // address of 16-byte return value |
||||||
|
WORD $0xB92E0024 // cipher message (KM) |
||||||
|
RET |
||||||
|
|
||||||
|
// func kmcQuery() queryResult |
||||||
|
TEXT ·kmcQuery(SB), NOSPLIT|NOFRAME, $0-16 |
||||||
|
MOVD $0, R0 // set function code to 0 (KMC-Query) |
||||||
|
MOVD $ret+0(FP), R1 // address of 16-byte return value |
||||||
|
WORD $0xB92F0024 // cipher message with chaining (KMC) |
||||||
|
RET |
||||||
|
|
||||||
|
// func kmctrQuery() queryResult |
||||||
|
TEXT ·kmctrQuery(SB), NOSPLIT|NOFRAME, $0-16 |
||||||
|
MOVD $0, R0 // set function code to 0 (KMCTR-Query) |
||||||
|
MOVD $ret+0(FP), R1 // address of 16-byte return value |
||||||
|
WORD $0xB92D4024 // cipher message with counter (KMCTR) |
||||||
|
RET |
||||||
|
|
||||||
|
// func kmaQuery() queryResult |
||||||
|
TEXT ·kmaQuery(SB), NOSPLIT|NOFRAME, $0-16 |
||||||
|
MOVD $0, R0 // set function code to 0 (KMA-Query) |
||||||
|
MOVD $ret+0(FP), R1 // address of 16-byte return value |
||||||
|
WORD $0xb9296024 // cipher message with authentication (KMA) |
||||||
|
RET |
||||||
|
|
||||||
|
// func kimdQuery() queryResult |
||||||
|
TEXT ·kimdQuery(SB), NOSPLIT|NOFRAME, $0-16 |
||||||
|
MOVD $0, R0 // set function code to 0 (KIMD-Query) |
||||||
|
MOVD $ret+0(FP), R1 // address of 16-byte return value |
||||||
|
WORD $0xB93E0024 // compute intermediate message digest (KIMD) |
||||||
|
RET |
||||||
|
|
||||||
|
// func klmdQuery() queryResult |
||||||
|
TEXT ·klmdQuery(SB), NOSPLIT|NOFRAME, $0-16 |
||||||
|
MOVD $0, R0 // set function code to 0 (KLMD-Query) |
||||||
|
MOVD $ret+0(FP), R1 // address of 16-byte return value |
||||||
|
WORD $0xB93F0024 // compute last message digest (KLMD) |
||||||
|
RET |
@ -0,0 +1,15 @@ |
|||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build wasm
|
||||||
|
|
||||||
|
package cpu |
||||||
|
|
||||||
|
// We're compiling the cpu package for an unknown (software-abstracted) CPU.
|
||||||
|
// Make CacheLinePad an empty struct and hope that the usual struct alignment
|
||||||
|
// rules are good enough.
|
||||||
|
|
||||||
|
const cacheLineSize = 0 |
||||||
|
|
||||||
|
func doinit() {} |
@ -0,0 +1,59 @@ |
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build 386 amd64 amd64p32
|
||||||
|
|
||||||
|
package cpu |
||||||
|
|
||||||
|
const cacheLineSize = 64 |
||||||
|
|
||||||
|
func init() { |
||||||
|
Initialized = true |
||||||
|
|
||||||
|
maxID, _, _, _ := cpuid(0, 0) |
||||||
|
|
||||||
|
if maxID < 1 { |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
_, _, ecx1, edx1 := cpuid(1, 0) |
||||||
|
X86.HasSSE2 = isSet(26, edx1) |
||||||
|
|
||||||
|
X86.HasSSE3 = isSet(0, ecx1) |
||||||
|
X86.HasPCLMULQDQ = isSet(1, ecx1) |
||||||
|
X86.HasSSSE3 = isSet(9, ecx1) |
||||||
|
X86.HasFMA = isSet(12, ecx1) |
||||||
|
X86.HasSSE41 = isSet(19, ecx1) |
||||||
|
X86.HasSSE42 = isSet(20, ecx1) |
||||||
|
X86.HasPOPCNT = isSet(23, ecx1) |
||||||
|
X86.HasAES = isSet(25, ecx1) |
||||||
|
X86.HasOSXSAVE = isSet(27, ecx1) |
||||||
|
X86.HasRDRAND = isSet(30, ecx1) |
||||||
|
|
||||||
|
osSupportsAVX := false |
||||||
|
// For XGETBV, OSXSAVE bit is required and sufficient.
|
||||||
|
if X86.HasOSXSAVE { |
||||||
|
eax, _ := xgetbv() |
||||||
|
// Check if XMM and YMM registers have OS support.
|
||||||
|
osSupportsAVX = isSet(1, eax) && isSet(2, eax) |
||||||
|
} |
||||||
|
|
||||||
|
X86.HasAVX = isSet(28, ecx1) && osSupportsAVX |
||||||
|
|
||||||
|
if maxID < 7 { |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
_, ebx7, _, _ := cpuid(7, 0) |
||||||
|
X86.HasBMI1 = isSet(3, ebx7) |
||||||
|
X86.HasAVX2 = isSet(5, ebx7) && osSupportsAVX |
||||||
|
X86.HasBMI2 = isSet(8, ebx7) |
||||||
|
X86.HasERMS = isSet(9, ebx7) |
||||||
|
X86.HasRDSEED = isSet(18, ebx7) |
||||||
|
X86.HasADX = isSet(19, ebx7) |
||||||
|
} |
||||||
|
|
||||||
|
func isSet(bitpos uint, value uint32) bool { |
||||||
|
return value&(1<<bitpos) != 0 |
||||||
|
} |
@ -0,0 +1,27 @@ |
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved. |
||||||
|
// Use of this source code is governed by a BSD-style |
||||||
|
// license that can be found in the LICENSE file. |
||||||
|
|
||||||
|
// +build 386 amd64 amd64p32 |
||||||
|
// +build !gccgo |
||||||
|
|
||||||
|
#include "textflag.h" |
||||||
|
|
||||||
|
// func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32) |
||||||
|
TEXT ·cpuid(SB), NOSPLIT, $0-24 |
||||||
|
MOVL eaxArg+0(FP), AX |
||||||
|
MOVL ecxArg+4(FP), CX |
||||||
|
CPUID |
||||||
|
MOVL AX, eax+8(FP) |
||||||
|
MOVL BX, ebx+12(FP) |
||||||
|
MOVL CX, ecx+16(FP) |
||||||
|
MOVL DX, edx+20(FP) |
||||||
|
RET |
||||||
|
|
||||||
|
// func xgetbv() (eax, edx uint32) |
||||||
|
TEXT ·xgetbv(SB),NOSPLIT,$0-8 |
||||||
|
MOVL $0, CX |
||||||
|
XGETBV |
||||||
|
MOVL AX, eax+0(FP) |
||||||
|
MOVL DX, edx+4(FP) |
||||||
|
RET |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue