mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
Bye bye openapi (#1081)
* add DateTime sans mgo * change all uses of strfmt.DateTime to common.DateTime, remove test strfmt usage * remove api tests, system-test dep on api test multiple reasons to remove the api tests: * awkward dependency with fn_go meant generating bindings on a branched fn to vendor those to test new stuff. this is at a minimum not at all intuitive, worth it, nor a fun way to spend the finite amount of time we have to live. * api tests only tested a subset of functionality that the server/ api tests already test, and we risk having tests where one tests some thing and the other doesn't. let's not. we have too many test suites as it is, and these pretty much only test that we updated the fn_go bindings, which is actually a hassle as noted above and the cli will pretty quickly figure out anyway. * fn_go relies on openapi, which relies on mgo, which is deprecated and we'd like to remove as a dependency. openapi is a _huge_ dep built in a NIH fashion, that cannot simply remove the mgo dep as users may be using it. we've now stolen their date time and otherwise killed usage of it in fn core, for fn_go it still exists but that's less of a problem. * update deps removals: * easyjson * mgo * go-openapi * mapstructure * fn_go * purell * go-validator also, had to lock docker. we shouldn't use docker on master anyway, they strongly advise against that. had no luck with latest version rev, so i locked it to what we were using before. until next time. the rest is just playing dep roulette, those end up removing a ton tho * fix exec test to work * account for john le cache
This commit is contained in:
422
vendor/golang.org/x/crypto/acme/acme.go
generated
vendored
422
vendor/golang.org/x/crypto/acme/acme.go
generated
vendored
@@ -14,7 +14,6 @@
|
||||
package acme
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
@@ -23,6 +22,8 @@ import (
|
||||
"crypto/sha256"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/asn1"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
@@ -33,7 +34,6 @@ import (
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -42,6 +42,9 @@ import (
|
||||
// LetsEncryptURL is the Directory endpoint of Let's Encrypt CA.
|
||||
const LetsEncryptURL = "https://acme-v01.api.letsencrypt.org/directory"
|
||||
|
||||
// idPeACMEIdentifierV1 is the OID for the ACME extension for the TLS-ALPN challenge.
|
||||
var idPeACMEIdentifierV1 = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 30, 1}
|
||||
|
||||
const (
|
||||
maxChainLen = 5 // max depth and breadth of a certificate chain
|
||||
maxCertSize = 1 << 20 // max size of a certificate, in bytes
|
||||
@@ -76,6 +79,22 @@ type Client struct {
|
||||
// will have no effect.
|
||||
DirectoryURL string
|
||||
|
||||
// RetryBackoff computes the duration after which the nth retry of a failed request
|
||||
// should occur. The value of n for the first call on failure is 1.
|
||||
// The values of r and resp are the request and response of the last failed attempt.
|
||||
// If the returned value is negative or zero, no more retries are done and an error
|
||||
// is returned to the caller of the original method.
|
||||
//
|
||||
// Requests which result in a 4xx client error are not retried,
|
||||
// except for 400 Bad Request due to "bad nonce" errors and 429 Too Many Requests.
|
||||
//
|
||||
// If RetryBackoff is nil, a truncated exponential backoff algorithm
|
||||
// with the ceiling of 10 seconds is used, where each subsequent retry n
|
||||
// is done after either ("Retry-After" + jitter) or (2^n seconds + jitter),
|
||||
// preferring the former if "Retry-After" header is found in the resp.
|
||||
// The jitter is a random value up to 1 second.
|
||||
RetryBackoff func(n int, r *http.Request, resp *http.Response) time.Duration
|
||||
|
||||
dirMu sync.Mutex // guards writes to dir
|
||||
dir *Directory // cached result of Client's Discover method
|
||||
|
||||
@@ -99,15 +118,12 @@ func (c *Client) Discover(ctx context.Context) (Directory, error) {
|
||||
if dirURL == "" {
|
||||
dirURL = LetsEncryptURL
|
||||
}
|
||||
res, err := c.get(ctx, dirURL)
|
||||
res, err := c.get(ctx, dirURL, wantStatus(http.StatusOK))
|
||||
if err != nil {
|
||||
return Directory{}, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
c.addNonce(res.Header)
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return Directory{}, responseError(res)
|
||||
}
|
||||
|
||||
var v struct {
|
||||
Reg string `json:"new-reg"`
|
||||
@@ -166,14 +182,11 @@ func (c *Client) CreateCert(ctx context.Context, csr []byte, exp time.Duration,
|
||||
req.NotAfter = now.Add(exp).Format(time.RFC3339)
|
||||
}
|
||||
|
||||
res, err := c.retryPostJWS(ctx, c.Key, c.dir.CertURL, req)
|
||||
res, err := c.post(ctx, c.Key, c.dir.CertURL, req, wantStatus(http.StatusCreated))
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != http.StatusCreated {
|
||||
return nil, "", responseError(res)
|
||||
}
|
||||
|
||||
curl := res.Header.Get("Location") // cert permanent URL
|
||||
if res.ContentLength == 0 {
|
||||
@@ -196,26 +209,11 @@ func (c *Client) CreateCert(ctx context.Context, csr []byte, exp time.Duration,
|
||||
// Callers are encouraged to parse the returned value to ensure the certificate is valid
|
||||
// and has expected features.
|
||||
func (c *Client) FetchCert(ctx context.Context, url string, bundle bool) ([][]byte, error) {
|
||||
for {
|
||||
res, err := c.get(ctx, url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode == http.StatusOK {
|
||||
return c.responseCert(ctx, res, bundle)
|
||||
}
|
||||
if res.StatusCode > 299 {
|
||||
return nil, responseError(res)
|
||||
}
|
||||
d := retryAfter(res.Header.Get("Retry-After"), 3*time.Second)
|
||||
select {
|
||||
case <-time.After(d):
|
||||
// retry
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
}
|
||||
res, err := c.get(ctx, url, wantStatus(http.StatusOK))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c.responseCert(ctx, res, bundle)
|
||||
}
|
||||
|
||||
// RevokeCert revokes a previously issued certificate cert, provided in DER format.
|
||||
@@ -241,14 +239,11 @@ func (c *Client) RevokeCert(ctx context.Context, key crypto.Signer, cert []byte,
|
||||
if key == nil {
|
||||
key = c.Key
|
||||
}
|
||||
res, err := c.retryPostJWS(ctx, key, c.dir.RevokeURL, body)
|
||||
res, err := c.post(ctx, key, c.dir.RevokeURL, body, wantStatus(http.StatusOK))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return responseError(res)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -329,14 +324,11 @@ func (c *Client) Authorize(ctx context.Context, domain string) (*Authorization,
|
||||
Resource: "new-authz",
|
||||
Identifier: authzID{Type: "dns", Value: domain},
|
||||
}
|
||||
res, err := c.retryPostJWS(ctx, c.Key, c.dir.AuthzURL, req)
|
||||
res, err := c.post(ctx, c.Key, c.dir.AuthzURL, req, wantStatus(http.StatusCreated))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != http.StatusCreated {
|
||||
return nil, responseError(res)
|
||||
}
|
||||
|
||||
var v wireAuthz
|
||||
if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
|
||||
@@ -353,14 +345,11 @@ func (c *Client) Authorize(ctx context.Context, domain string) (*Authorization,
|
||||
// If a caller needs to poll an authorization until its status is final,
|
||||
// see the WaitAuthorization method.
|
||||
func (c *Client) GetAuthorization(ctx context.Context, url string) (*Authorization, error) {
|
||||
res, err := c.get(ctx, url)
|
||||
res, err := c.get(ctx, url, wantStatus(http.StatusOK, http.StatusAccepted))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusAccepted {
|
||||
return nil, responseError(res)
|
||||
}
|
||||
var v wireAuthz
|
||||
if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
|
||||
return nil, fmt.Errorf("acme: invalid response: %v", err)
|
||||
@@ -387,14 +376,11 @@ func (c *Client) RevokeAuthorization(ctx context.Context, url string) error {
|
||||
Status: "deactivated",
|
||||
Delete: true,
|
||||
}
|
||||
res, err := c.retryPostJWS(ctx, c.Key, url, req)
|
||||
res, err := c.post(ctx, c.Key, url, req, wantStatus(http.StatusOK))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return responseError(res)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -406,44 +392,42 @@ func (c *Client) RevokeAuthorization(ctx context.Context, url string) error {
|
||||
// In all other cases WaitAuthorization returns an error.
|
||||
// If the Status is StatusInvalid, the returned error is of type *AuthorizationError.
|
||||
func (c *Client) WaitAuthorization(ctx context.Context, url string) (*Authorization, error) {
|
||||
sleep := sleeper(ctx)
|
||||
for {
|
||||
res, err := c.get(ctx, url)
|
||||
res, err := c.get(ctx, url, wantStatus(http.StatusOK, http.StatusAccepted))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if res.StatusCode >= 400 && res.StatusCode <= 499 {
|
||||
// Non-retriable error. For instance, Let's Encrypt may return 404 Not Found
|
||||
// when requesting an expired authorization.
|
||||
defer res.Body.Close()
|
||||
return nil, responseError(res)
|
||||
}
|
||||
|
||||
retry := res.Header.Get("Retry-After")
|
||||
if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusAccepted {
|
||||
res.Body.Close()
|
||||
if err := sleep(retry, 1); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
continue
|
||||
}
|
||||
var raw wireAuthz
|
||||
err = json.NewDecoder(res.Body).Decode(&raw)
|
||||
res.Body.Close()
|
||||
if err != nil {
|
||||
if err := sleep(retry, 0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
continue
|
||||
}
|
||||
if raw.Status == StatusValid {
|
||||
switch {
|
||||
case err != nil:
|
||||
// Skip and retry.
|
||||
case raw.Status == StatusValid:
|
||||
return raw.authorization(url), nil
|
||||
}
|
||||
if raw.Status == StatusInvalid {
|
||||
case raw.Status == StatusInvalid:
|
||||
return nil, raw.error(url)
|
||||
}
|
||||
if err := sleep(retry, 0); err != nil {
|
||||
return nil, err
|
||||
|
||||
// Exponential backoff is implemented in c.get above.
|
||||
// This is just to prevent continuously hitting the CA
|
||||
// while waiting for a final authorization status.
|
||||
d := retryAfter(res.Header.Get("Retry-After"))
|
||||
if d == 0 {
|
||||
// Given that the fastest challenges TLS-SNI and HTTP-01
|
||||
// require a CA to make at least 1 network round trip
|
||||
// and most likely persist a challenge state,
|
||||
// this default delay seems reasonable.
|
||||
d = time.Second
|
||||
}
|
||||
t := time.NewTimer(d)
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
t.Stop()
|
||||
return nil, ctx.Err()
|
||||
case <-t.C:
|
||||
// Retry.
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -452,14 +436,11 @@ func (c *Client) WaitAuthorization(ctx context.Context, url string) (*Authorizat
|
||||
//
|
||||
// A client typically polls a challenge status using this method.
|
||||
func (c *Client) GetChallenge(ctx context.Context, url string) (*Challenge, error) {
|
||||
res, err := c.get(ctx, url)
|
||||
res, err := c.get(ctx, url, wantStatus(http.StatusOK, http.StatusAccepted))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusAccepted {
|
||||
return nil, responseError(res)
|
||||
}
|
||||
v := wireChallenge{URI: url}
|
||||
if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
|
||||
return nil, fmt.Errorf("acme: invalid response: %v", err)
|
||||
@@ -486,16 +467,14 @@ func (c *Client) Accept(ctx context.Context, chal *Challenge) (*Challenge, error
|
||||
Type: chal.Type,
|
||||
Auth: auth,
|
||||
}
|
||||
res, err := c.retryPostJWS(ctx, c.Key, chal.URI, req)
|
||||
res, err := c.post(ctx, c.Key, chal.URI, req, wantStatus(
|
||||
http.StatusOK, // according to the spec
|
||||
http.StatusAccepted, // Let's Encrypt: see https://goo.gl/WsJ7VT (acme-divergences.md)
|
||||
))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
// Note: the protocol specifies 200 as the expected response code, but
|
||||
// letsencrypt seems to be returning 202.
|
||||
if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusAccepted {
|
||||
return nil, responseError(res)
|
||||
}
|
||||
|
||||
var v wireChallenge
|
||||
if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
|
||||
@@ -552,7 +531,7 @@ func (c *Client) HTTP01ChallengePath(token string) string {
|
||||
// If no WithKey option is provided, a new ECDSA key is generated using P-256 curve.
|
||||
//
|
||||
// The returned certificate is valid for the next 24 hours and must be presented only when
|
||||
// the server name of the client hello matches exactly the returned name value.
|
||||
// the server name of the TLS ClientHello matches exactly the returned name value.
|
||||
func (c *Client) TLSSNI01ChallengeCert(token string, opt ...CertOption) (cert tls.Certificate, name string, err error) {
|
||||
ka, err := keyAuth(c.Key.Public(), token)
|
||||
if err != nil {
|
||||
@@ -579,7 +558,7 @@ func (c *Client) TLSSNI01ChallengeCert(token string, opt ...CertOption) (cert tl
|
||||
// If no WithKey option is provided, a new ECDSA key is generated using P-256 curve.
|
||||
//
|
||||
// The returned certificate is valid for the next 24 hours and must be presented only when
|
||||
// the server name in the client hello matches exactly the returned name value.
|
||||
// the server name in the TLS ClientHello matches exactly the returned name value.
|
||||
func (c *Client) TLSSNI02ChallengeCert(token string, opt ...CertOption) (cert tls.Certificate, name string, err error) {
|
||||
b := sha256.Sum256([]byte(token))
|
||||
h := hex.EncodeToString(b[:])
|
||||
@@ -600,6 +579,52 @@ func (c *Client) TLSSNI02ChallengeCert(token string, opt ...CertOption) (cert tl
|
||||
return cert, sanA, nil
|
||||
}
|
||||
|
||||
// TLSALPN01ChallengeCert creates a certificate for TLS-ALPN-01 challenge response.
|
||||
// Servers can present the certificate to validate the challenge and prove control
|
||||
// over a domain name. For more details on TLS-ALPN-01 see
|
||||
// https://tools.ietf.org/html/draft-shoemaker-acme-tls-alpn-00#section-3
|
||||
//
|
||||
// The token argument is a Challenge.Token value.
|
||||
// If a WithKey option is provided, its private part signs the returned cert,
|
||||
// and the public part is used to specify the signee.
|
||||
// If no WithKey option is provided, a new ECDSA key is generated using P-256 curve.
|
||||
//
|
||||
// The returned certificate is valid for the next 24 hours and must be presented only when
|
||||
// the server name in the TLS ClientHello matches the domain, and the special acme-tls/1 ALPN protocol
|
||||
// has been specified.
|
||||
func (c *Client) TLSALPN01ChallengeCert(token, domain string, opt ...CertOption) (cert tls.Certificate, err error) {
|
||||
ka, err := keyAuth(c.Key.Public(), token)
|
||||
if err != nil {
|
||||
return tls.Certificate{}, err
|
||||
}
|
||||
shasum := sha256.Sum256([]byte(ka))
|
||||
extValue, err := asn1.Marshal(shasum[:])
|
||||
if err != nil {
|
||||
return tls.Certificate{}, err
|
||||
}
|
||||
acmeExtension := pkix.Extension{
|
||||
Id: idPeACMEIdentifierV1,
|
||||
Critical: true,
|
||||
Value: extValue,
|
||||
}
|
||||
|
||||
tmpl := defaultTLSChallengeCertTemplate()
|
||||
|
||||
var newOpt []CertOption
|
||||
for _, o := range opt {
|
||||
switch o := o.(type) {
|
||||
case *certOptTemplate:
|
||||
t := *(*x509.Certificate)(o) // shallow copy is ok
|
||||
tmpl = &t
|
||||
default:
|
||||
newOpt = append(newOpt, o)
|
||||
}
|
||||
}
|
||||
tmpl.ExtraExtensions = append(tmpl.ExtraExtensions, acmeExtension)
|
||||
newOpt = append(newOpt, WithTemplate(tmpl))
|
||||
return tlsChallengeCert([]string{domain}, newOpt)
|
||||
}
|
||||
|
||||
// doReg sends all types of registration requests.
|
||||
// The type of request is identified by typ argument, which is a "resource"
|
||||
// in the ACME spec terms.
|
||||
@@ -619,14 +644,14 @@ func (c *Client) doReg(ctx context.Context, url string, typ string, acct *Accoun
|
||||
req.Contact = acct.Contact
|
||||
req.Agreement = acct.AgreedTerms
|
||||
}
|
||||
res, err := c.retryPostJWS(ctx, c.Key, url, req)
|
||||
res, err := c.post(ctx, c.Key, url, req, wantStatus(
|
||||
http.StatusOK, // updates and deletes
|
||||
http.StatusCreated, // new account creation
|
||||
))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode < 200 || res.StatusCode > 299 {
|
||||
return nil, responseError(res)
|
||||
}
|
||||
|
||||
var v struct {
|
||||
Contact []string
|
||||
@@ -656,59 +681,6 @@ func (c *Client) doReg(ctx context.Context, url string, typ string, acct *Accoun
|
||||
}, nil
|
||||
}
|
||||
|
||||
// retryPostJWS will retry calls to postJWS if there is a badNonce error,
|
||||
// clearing the stored nonces after each error.
|
||||
// If the response was 4XX-5XX, then responseError is called on the body,
|
||||
// the body is closed, and the error returned.
|
||||
func (c *Client) retryPostJWS(ctx context.Context, key crypto.Signer, url string, body interface{}) (*http.Response, error) {
|
||||
sleep := sleeper(ctx)
|
||||
for {
|
||||
res, err := c.postJWS(ctx, key, url, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// handle errors 4XX-5XX with responseError
|
||||
if res.StatusCode >= 400 && res.StatusCode <= 599 {
|
||||
err := responseError(res)
|
||||
res.Body.Close()
|
||||
// according to spec badNonce is urn:ietf:params:acme:error:badNonce
|
||||
// however, acme servers in the wild return their version of the error
|
||||
// https://tools.ietf.org/html/draft-ietf-acme-acme-02#section-5.4
|
||||
if ae, ok := err.(*Error); ok && strings.HasSuffix(strings.ToLower(ae.ProblemType), ":badnonce") {
|
||||
// clear any nonces that we might've stored that might now be
|
||||
// considered bad
|
||||
c.clearNonces()
|
||||
retry := res.Header.Get("Retry-After")
|
||||
if err := sleep(retry, 1); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
continue
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
}
|
||||
|
||||
// postJWS signs the body with the given key and POSTs it to the provided url.
|
||||
// The body argument must be JSON-serializable.
|
||||
func (c *Client) postJWS(ctx context.Context, key crypto.Signer, url string, body interface{}) (*http.Response, error) {
|
||||
nonce, err := c.popNonce(ctx, url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b, err := jwsEncodeJSON(body, key, nonce)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res, err := c.post(ctx, url, "application/jose+json", bytes.NewReader(b))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.addNonce(res.Header)
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// popNonce returns a nonce value previously stored with c.addNonce
|
||||
// or fetches a fresh one from the given URL.
|
||||
func (c *Client) popNonce(ctx context.Context, url string) (string, error) {
|
||||
@@ -749,58 +721,12 @@ func (c *Client) addNonce(h http.Header) {
|
||||
c.nonces[v] = struct{}{}
|
||||
}
|
||||
|
||||
func (c *Client) httpClient() *http.Client {
|
||||
if c.HTTPClient != nil {
|
||||
return c.HTTPClient
|
||||
}
|
||||
return http.DefaultClient
|
||||
}
|
||||
|
||||
func (c *Client) get(ctx context.Context, urlStr string) (*http.Response, error) {
|
||||
req, err := http.NewRequest("GET", urlStr, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c.do(ctx, req)
|
||||
}
|
||||
|
||||
func (c *Client) head(ctx context.Context, urlStr string) (*http.Response, error) {
|
||||
req, err := http.NewRequest("HEAD", urlStr, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c.do(ctx, req)
|
||||
}
|
||||
|
||||
func (c *Client) post(ctx context.Context, urlStr, contentType string, body io.Reader) (*http.Response, error) {
|
||||
req, err := http.NewRequest("POST", urlStr, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("Content-Type", contentType)
|
||||
return c.do(ctx, req)
|
||||
}
|
||||
|
||||
func (c *Client) do(ctx context.Context, req *http.Request) (*http.Response, error) {
|
||||
res, err := c.httpClient().Do(req.WithContext(ctx))
|
||||
if err != nil {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
// Prefer the unadorned context error.
|
||||
// (The acme package had tests assuming this, previously from ctxhttp's
|
||||
// behavior, predating net/http supporting contexts natively)
|
||||
// TODO(bradfitz): reconsider this in the future. But for now this
|
||||
// requires no test updates.
|
||||
return nil, ctx.Err()
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (c *Client) fetchNonce(ctx context.Context, url string) (string, error) {
|
||||
resp, err := c.head(ctx, url)
|
||||
r, err := http.NewRequest("HEAD", url, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
resp, err := c.doNoRetry(ctx, r)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -852,24 +778,6 @@ func (c *Client) responseCert(ctx context.Context, res *http.Response, bundle bo
|
||||
return cert, nil
|
||||
}
|
||||
|
||||
// responseError creates an error of Error type from resp.
|
||||
func responseError(resp *http.Response) error {
|
||||
// don't care if ReadAll returns an error:
|
||||
// json.Unmarshal will fail in that case anyway
|
||||
b, _ := ioutil.ReadAll(resp.Body)
|
||||
e := &wireError{Status: resp.StatusCode}
|
||||
if err := json.Unmarshal(b, e); err != nil {
|
||||
// this is not a regular error response:
|
||||
// populate detail with anything we received,
|
||||
// e.Status will already contain HTTP response code value
|
||||
e.Detail = string(b)
|
||||
if e.Detail == "" {
|
||||
e.Detail = resp.Status
|
||||
}
|
||||
}
|
||||
return e.error(resp.Header)
|
||||
}
|
||||
|
||||
// chainCert fetches CA certificate chain recursively by following "up" links.
|
||||
// Each recursive call increments the depth by 1, resulting in an error
|
||||
// if the recursion level reaches maxChainLen.
|
||||
@@ -880,14 +788,11 @@ func (c *Client) chainCert(ctx context.Context, url string, depth int) ([][]byte
|
||||
return nil, errors.New("acme: certificate chain is too deep")
|
||||
}
|
||||
|
||||
res, err := c.get(ctx, url)
|
||||
res, err := c.get(ctx, url, wantStatus(http.StatusOK))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return nil, responseError(res)
|
||||
}
|
||||
b, err := ioutil.ReadAll(io.LimitReader(res.Body, maxCertSize+1))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -932,65 +837,6 @@ func linkHeader(h http.Header, rel string) []string {
|
||||
return links
|
||||
}
|
||||
|
||||
// sleeper returns a function that accepts the Retry-After HTTP header value
|
||||
// and an increment that's used with backoff to increasingly sleep on
|
||||
// consecutive calls until the context is done. If the Retry-After header
|
||||
// cannot be parsed, then backoff is used with a maximum sleep time of 10
|
||||
// seconds.
|
||||
func sleeper(ctx context.Context) func(ra string, inc int) error {
|
||||
var count int
|
||||
return func(ra string, inc int) error {
|
||||
count += inc
|
||||
d := backoff(count, 10*time.Second)
|
||||
d = retryAfter(ra, d)
|
||||
wakeup := time.NewTimer(d)
|
||||
defer wakeup.Stop()
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case <-wakeup.C:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// retryAfter parses a Retry-After HTTP header value,
|
||||
// trying to convert v into an int (seconds) or use http.ParseTime otherwise.
|
||||
// It returns d if v cannot be parsed.
|
||||
func retryAfter(v string, d time.Duration) time.Duration {
|
||||
if i, err := strconv.Atoi(v); err == nil {
|
||||
return time.Duration(i) * time.Second
|
||||
}
|
||||
t, err := http.ParseTime(v)
|
||||
if err != nil {
|
||||
return d
|
||||
}
|
||||
return t.Sub(timeNow())
|
||||
}
|
||||
|
||||
// backoff computes a duration after which an n+1 retry iteration should occur
|
||||
// using truncated exponential backoff algorithm.
|
||||
//
|
||||
// The n argument is always bounded between 0 and 30.
|
||||
// The max argument defines upper bound for the returned value.
|
||||
func backoff(n int, max time.Duration) time.Duration {
|
||||
if n < 0 {
|
||||
n = 0
|
||||
}
|
||||
if n > 30 {
|
||||
n = 30
|
||||
}
|
||||
var d time.Duration
|
||||
if x, err := rand.Int(rand.Reader, big.NewInt(1000)); err == nil {
|
||||
d = time.Duration(x.Int64()) * time.Millisecond
|
||||
}
|
||||
d += time.Duration(1<<uint(n)) * time.Second
|
||||
if d > max {
|
||||
return max
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
// keyAuth generates a key authorization string for a given token.
|
||||
func keyAuth(pub crypto.PublicKey, token string) (string, error) {
|
||||
th, err := JWKThumbprint(pub)
|
||||
@@ -1000,15 +846,25 @@ func keyAuth(pub crypto.PublicKey, token string) (string, error) {
|
||||
return fmt.Sprintf("%s.%s", token, th), nil
|
||||
}
|
||||
|
||||
// defaultTLSChallengeCertTemplate is a template used to create challenge certs for TLS challenges.
|
||||
func defaultTLSChallengeCertTemplate() *x509.Certificate {
|
||||
return &x509.Certificate{
|
||||
SerialNumber: big.NewInt(1),
|
||||
NotBefore: time.Now(),
|
||||
NotAfter: time.Now().Add(24 * time.Hour),
|
||||
BasicConstraintsValid: true,
|
||||
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||
}
|
||||
}
|
||||
|
||||
// tlsChallengeCert creates a temporary certificate for TLS-SNI challenges
|
||||
// with the given SANs and auto-generated public/private key pair.
|
||||
// The Subject Common Name is set to the first SAN to aid debugging.
|
||||
// To create a cert with a custom key pair, specify WithKey option.
|
||||
func tlsChallengeCert(san []string, opt []CertOption) (tls.Certificate, error) {
|
||||
var (
|
||||
key crypto.Signer
|
||||
tmpl *x509.Certificate
|
||||
)
|
||||
var key crypto.Signer
|
||||
tmpl := defaultTLSChallengeCertTemplate()
|
||||
for _, o := range opt {
|
||||
switch o := o.(type) {
|
||||
case *certOptKey:
|
||||
@@ -1017,7 +873,7 @@ func tlsChallengeCert(san []string, opt []CertOption) (tls.Certificate, error) {
|
||||
}
|
||||
key = o.key
|
||||
case *certOptTemplate:
|
||||
var t = *(*x509.Certificate)(o) // shallow copy is ok
|
||||
t := *(*x509.Certificate)(o) // shallow copy is ok
|
||||
tmpl = &t
|
||||
default:
|
||||
// package's fault, if we let this happen:
|
||||
@@ -1030,16 +886,6 @@ func tlsChallengeCert(san []string, opt []CertOption) (tls.Certificate, error) {
|
||||
return tls.Certificate{}, err
|
||||
}
|
||||
}
|
||||
if tmpl == nil {
|
||||
tmpl = &x509.Certificate{
|
||||
SerialNumber: big.NewInt(1),
|
||||
NotBefore: time.Now(),
|
||||
NotAfter: time.Now().Add(24 * time.Hour),
|
||||
BasicConstraintsValid: true,
|
||||
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||
}
|
||||
}
|
||||
tmpl.DNSNames = san
|
||||
if len(san) > 0 {
|
||||
tmpl.Subject.CommonName = san[0]
|
||||
|
||||
325
vendor/golang.org/x/crypto/acme/acme_test.go
generated
vendored
325
vendor/golang.org/x/crypto/acme/acme_test.go
generated
vendored
@@ -13,9 +13,9 @@ import (
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
@@ -485,88 +485,37 @@ func TestGetAuthorization(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestWaitAuthorization(t *testing.T) {
|
||||
var count int
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
count++
|
||||
w.Header().Set("Retry-After", "0")
|
||||
if count > 1 {
|
||||
fmt.Fprintf(w, `{"status":"valid"}`)
|
||||
return
|
||||
t.Run("wait loop", func(t *testing.T) {
|
||||
var count int
|
||||
authz, err := runWaitAuthorization(context.Background(), t, func(w http.ResponseWriter, r *http.Request) {
|
||||
count++
|
||||
w.Header().Set("Retry-After", "0")
|
||||
if count > 1 {
|
||||
fmt.Fprintf(w, `{"status":"valid"}`)
|
||||
return
|
||||
}
|
||||
fmt.Fprintf(w, `{"status":"pending"}`)
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("non-nil error: %v", err)
|
||||
}
|
||||
fmt.Fprintf(w, `{"status":"pending"}`)
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
type res struct {
|
||||
authz *Authorization
|
||||
err error
|
||||
}
|
||||
done := make(chan res)
|
||||
defer close(done)
|
||||
go func() {
|
||||
var client Client
|
||||
a, err := client.WaitAuthorization(context.Background(), ts.URL)
|
||||
done <- res{a, err}
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-time.After(5 * time.Second):
|
||||
t.Fatal("WaitAuthz took too long to return")
|
||||
case res := <-done:
|
||||
if res.err != nil {
|
||||
t.Fatalf("res.err = %v", res.err)
|
||||
}
|
||||
if res.authz == nil {
|
||||
t.Fatal("res.authz is nil")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestWaitAuthorizationInvalid(t *testing.T) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintf(w, `{"status":"invalid"}`)
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
res := make(chan error)
|
||||
defer close(res)
|
||||
go func() {
|
||||
var client Client
|
||||
_, err := client.WaitAuthorization(context.Background(), ts.URL)
|
||||
res <- err
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-time.After(3 * time.Second):
|
||||
t.Fatal("WaitAuthz took too long to return")
|
||||
case err := <-res:
|
||||
if err == nil {
|
||||
t.Error("err is nil")
|
||||
if authz == nil {
|
||||
t.Fatal("authz is nil")
|
||||
}
|
||||
})
|
||||
t.Run("invalid status", func(t *testing.T) {
|
||||
_, err := runWaitAuthorization(context.Background(), t, func(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintf(w, `{"status":"invalid"}`)
|
||||
})
|
||||
if _, ok := err.(*AuthorizationError); !ok {
|
||||
t.Errorf("err is %T; want *AuthorizationError", err)
|
||||
t.Errorf("err is %v (%T); want non-nil *AuthorizationError", err, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestWaitAuthorizationClientError(t *testing.T) {
|
||||
const code = http.StatusBadRequest
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(code)
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
ch := make(chan error, 1)
|
||||
go func() {
|
||||
var client Client
|
||||
_, err := client.WaitAuthorization(context.Background(), ts.URL)
|
||||
ch <- err
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-time.After(3 * time.Second):
|
||||
t.Fatal("WaitAuthz took too long to return")
|
||||
case err := <-ch:
|
||||
})
|
||||
t.Run("non-retriable error", func(t *testing.T) {
|
||||
const code = http.StatusBadRequest
|
||||
_, err := runWaitAuthorization(context.Background(), t, func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(code)
|
||||
})
|
||||
res, ok := err.(*Error)
|
||||
if !ok {
|
||||
t.Fatalf("err is %v (%T); want a non-nil *Error", err, err)
|
||||
@@ -574,34 +523,60 @@ func TestWaitAuthorizationClientError(t *testing.T) {
|
||||
if res.StatusCode != code {
|
||||
t.Errorf("res.StatusCode = %d; want %d", res.StatusCode, code)
|
||||
}
|
||||
})
|
||||
for _, code := range []int{http.StatusTooManyRequests, http.StatusInternalServerError} {
|
||||
t.Run(fmt.Sprintf("retriable %d error", code), func(t *testing.T) {
|
||||
var count int
|
||||
authz, err := runWaitAuthorization(context.Background(), t, func(w http.ResponseWriter, r *http.Request) {
|
||||
count++
|
||||
w.Header().Set("Retry-After", "0")
|
||||
if count > 1 {
|
||||
fmt.Fprintf(w, `{"status":"valid"}`)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(code)
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("non-nil error: %v", err)
|
||||
}
|
||||
if authz == nil {
|
||||
t.Fatal("authz is nil")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestWaitAuthorizationCancel(t *testing.T) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Retry-After", "60")
|
||||
fmt.Fprintf(w, `{"status":"pending"}`)
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
res := make(chan error)
|
||||
defer close(res)
|
||||
go func() {
|
||||
var client Client
|
||||
t.Run("context cancel", func(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond)
|
||||
defer cancel()
|
||||
_, err := client.WaitAuthorization(ctx, ts.URL)
|
||||
res <- err
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-time.After(time.Second):
|
||||
t.Fatal("WaitAuthz took too long to return")
|
||||
case err := <-res:
|
||||
_, err := runWaitAuthorization(ctx, t, func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Retry-After", "60")
|
||||
fmt.Fprintf(w, `{"status":"pending"}`)
|
||||
})
|
||||
if err == nil {
|
||||
t.Error("err is nil")
|
||||
}
|
||||
})
|
||||
}
|
||||
func runWaitAuthorization(ctx context.Context, t *testing.T, h http.HandlerFunc) (*Authorization, error) {
|
||||
t.Helper()
|
||||
ts := httptest.NewServer(h)
|
||||
defer ts.Close()
|
||||
type res struct {
|
||||
authz *Authorization
|
||||
err error
|
||||
}
|
||||
ch := make(chan res, 1)
|
||||
go func() {
|
||||
var client Client
|
||||
a, err := client.WaitAuthorization(ctx, ts.URL)
|
||||
ch <- res{a, err}
|
||||
}()
|
||||
select {
|
||||
case <-time.After(3 * time.Second):
|
||||
t.Fatal("WaitAuthorization took too long to return")
|
||||
case v := <-ch:
|
||||
return v.authz, v.err
|
||||
}
|
||||
panic("runWaitAuthorization: out of select")
|
||||
}
|
||||
|
||||
func TestRevokeAuthorization(t *testing.T) {
|
||||
@@ -628,7 +603,7 @@ func TestRevokeAuthorization(t *testing.T) {
|
||||
t.Errorf("req.Delete is false")
|
||||
}
|
||||
case "/2":
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
}
|
||||
}))
|
||||
defer ts.Close()
|
||||
@@ -849,7 +824,7 @@ func TestFetchCertRetry(t *testing.T) {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if count < 1 {
|
||||
w.Header().Set("Retry-After", "0")
|
||||
w.WriteHeader(http.StatusAccepted)
|
||||
w.WriteHeader(http.StatusTooManyRequests)
|
||||
count++
|
||||
return
|
||||
}
|
||||
@@ -1096,44 +1071,6 @@ func TestNonce_postJWS(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRetryPostJWS(t *testing.T) {
|
||||
var count int
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
count++
|
||||
w.Header().Set("Replay-Nonce", fmt.Sprintf("nonce%d", count))
|
||||
if r.Method == "HEAD" {
|
||||
// We expect the client to do 2 head requests to fetch
|
||||
// nonces, one to start and another after getting badNonce
|
||||
return
|
||||
}
|
||||
|
||||
head, err := decodeJWSHead(r)
|
||||
if err != nil {
|
||||
t.Errorf("decodeJWSHead: %v", err)
|
||||
} else if head.Nonce == "" {
|
||||
t.Error("head.Nonce is empty")
|
||||
} else if head.Nonce == "nonce1" {
|
||||
// return a badNonce error to force the call to retry
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(`{"type":"urn:ietf:params:acme:error:badNonce"}`))
|
||||
return
|
||||
}
|
||||
// Make client.Authorize happy; we're not testing its result.
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
w.Write([]byte(`{"status":"valid"}`))
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
client := Client{Key: testKey, dir: &Directory{AuthzURL: ts.URL}}
|
||||
// This call will fail with badNonce, causing a retry
|
||||
if _, err := client.Authorize(context.Background(), "example.com"); err != nil {
|
||||
t.Errorf("client.Authorize 1: %v", err)
|
||||
}
|
||||
if count != 4 {
|
||||
t.Errorf("total requests count: %d; want 4", count)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLinkHeader(t *testing.T) {
|
||||
h := http.Header{"Link": {
|
||||
`<https://example.com/acme/new-authz>;rel="next"`,
|
||||
@@ -1157,37 +1094,6 @@ func TestLinkHeader(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestErrorResponse(t *testing.T) {
|
||||
s := `{
|
||||
"status": 400,
|
||||
"type": "urn:acme:error:xxx",
|
||||
"detail": "text"
|
||||
}`
|
||||
res := &http.Response{
|
||||
StatusCode: 400,
|
||||
Status: "400 Bad Request",
|
||||
Body: ioutil.NopCloser(strings.NewReader(s)),
|
||||
Header: http.Header{"X-Foo": {"bar"}},
|
||||
}
|
||||
err := responseError(res)
|
||||
v, ok := err.(*Error)
|
||||
if !ok {
|
||||
t.Fatalf("err = %+v (%T); want *Error type", err, err)
|
||||
}
|
||||
if v.StatusCode != 400 {
|
||||
t.Errorf("v.StatusCode = %v; want 400", v.StatusCode)
|
||||
}
|
||||
if v.ProblemType != "urn:acme:error:xxx" {
|
||||
t.Errorf("v.ProblemType = %q; want urn:acme:error:xxx", v.ProblemType)
|
||||
}
|
||||
if v.Detail != "text" {
|
||||
t.Errorf("v.Detail = %q; want text", v.Detail)
|
||||
}
|
||||
if !reflect.DeepEqual(v.Header, res.Header) {
|
||||
t.Errorf("v.Header = %+v; want %+v", v.Header, res.Header)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTLSSNI01ChallengeCert(t *testing.T) {
|
||||
const (
|
||||
token = "evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA"
|
||||
@@ -1255,6 +1161,58 @@ func TestTLSSNI02ChallengeCert(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTLSALPN01ChallengeCert(t *testing.T) {
|
||||
const (
|
||||
token = "evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA"
|
||||
keyAuth = "evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ-PCt92wr-oA." + testKeyECThumbprint
|
||||
// echo -n <token.testKeyECThumbprint> | shasum -a 256
|
||||
h = "0420dbbd5eefe7b4d06eb9d1d9f5acb4c7cda27d320e4b30332f0b6cb441734ad7b0"
|
||||
domain = "example.com"
|
||||
)
|
||||
|
||||
extValue, err := hex.DecodeString(h)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
client := &Client{Key: testKeyEC}
|
||||
tlscert, err := client.TLSALPN01ChallengeCert(token, domain)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if n := len(tlscert.Certificate); n != 1 {
|
||||
t.Fatalf("len(tlscert.Certificate) = %d; want 1", n)
|
||||
}
|
||||
cert, err := x509.ParseCertificate(tlscert.Certificate[0])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
names := []string{domain}
|
||||
if !reflect.DeepEqual(cert.DNSNames, names) {
|
||||
t.Fatalf("cert.DNSNames = %v;\nwant %v", cert.DNSNames, names)
|
||||
}
|
||||
if cn := cert.Subject.CommonName; cn != domain {
|
||||
t.Errorf("CommonName = %q; want %q", cn, domain)
|
||||
}
|
||||
acmeExts := []pkix.Extension{}
|
||||
for _, ext := range cert.Extensions {
|
||||
if idPeACMEIdentifierV1.Equal(ext.Id) {
|
||||
acmeExts = append(acmeExts, ext)
|
||||
}
|
||||
}
|
||||
if len(acmeExts) != 1 {
|
||||
t.Errorf("acmeExts = %v; want exactly one", acmeExts)
|
||||
}
|
||||
if !acmeExts[0].Critical {
|
||||
t.Errorf("acmeExt.Critical = %v; want true", acmeExts[0].Critical)
|
||||
}
|
||||
if bytes.Compare(acmeExts[0].Value, extValue) != 0 {
|
||||
t.Errorf("acmeExt.Value = %v; want %v", acmeExts[0].Value, extValue)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestTLSChallengeCertOpt(t *testing.T) {
|
||||
key, err := rsa.GenerateKey(rand.Reader, 512)
|
||||
if err != nil {
|
||||
@@ -1353,28 +1311,3 @@ func TestDNS01ChallengeRecord(t *testing.T) {
|
||||
t.Errorf("val = %q; want %q", val, value)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBackoff(t *testing.T) {
|
||||
tt := []struct{ min, max time.Duration }{
|
||||
{time.Second, 2 * time.Second},
|
||||
{2 * time.Second, 3 * time.Second},
|
||||
{4 * time.Second, 5 * time.Second},
|
||||
{8 * time.Second, 9 * time.Second},
|
||||
}
|
||||
for i, test := range tt {
|
||||
d := backoff(i, time.Minute)
|
||||
if d < test.min || test.max < d {
|
||||
t.Errorf("%d: d = %v; want between %v and %v", i, d, test.min, test.max)
|
||||
}
|
||||
}
|
||||
|
||||
min, max := time.Second, 2*time.Second
|
||||
if d := backoff(-1, time.Minute); d < min || max < d {
|
||||
t.Errorf("d = %v; want between %v and %v", d, min, max)
|
||||
}
|
||||
|
||||
bound := 10 * time.Second
|
||||
if d := backoff(100, bound); d != bound {
|
||||
t.Errorf("d = %v; want %v", d, bound)
|
||||
}
|
||||
}
|
||||
|
||||
278
vendor/golang.org/x/crypto/acme/autocert/autocert.go
generated
vendored
278
vendor/golang.org/x/crypto/acme/autocert/autocert.go
generated
vendored
@@ -98,11 +98,11 @@ type Manager struct {
|
||||
// To always accept the terms, the callers can use AcceptTOS.
|
||||
Prompt func(tosURL string) bool
|
||||
|
||||
// Cache optionally stores and retrieves previously-obtained certificates.
|
||||
// If nil, certs will only be cached for the lifetime of the Manager.
|
||||
// Cache optionally stores and retrieves previously-obtained certificates
|
||||
// and other state. If nil, certs will only be cached for the lifetime of
|
||||
// the Manager. Multiple Managers can share the same Cache.
|
||||
//
|
||||
// Manager passes the Cache certificates data encoded in PEM, with private/public
|
||||
// parts combined in a single Cache.Put call, private key first.
|
||||
// Using a persistent Cache, such as DirCache, is strongly recommended.
|
||||
Cache Cache
|
||||
|
||||
// HostPolicy controls which domains the Manager will attempt
|
||||
@@ -127,8 +127,10 @@ type Manager struct {
|
||||
|
||||
// Client is used to perform low-level operations, such as account registration
|
||||
// and requesting new certificates.
|
||||
//
|
||||
// If Client is nil, a zero-value acme.Client is used with acme.LetsEncryptURL
|
||||
// directory endpoint and a newly-generated ECDSA P-256 key.
|
||||
// as directory endpoint. If the Client.Key is nil, a new ECDSA P-256 key is
|
||||
// generated and, if Cache is not nil, stored in cache.
|
||||
//
|
||||
// Mutating the field after the first call of GetCertificate method will have no effect.
|
||||
Client *acme.Client
|
||||
@@ -140,22 +142,30 @@ type Manager struct {
|
||||
// If the Client's account key is already registered, Email is not used.
|
||||
Email string
|
||||
|
||||
// ForceRSA makes the Manager generate certificates with 2048-bit RSA keys.
|
||||
// ForceRSA used to make the Manager generate RSA certificates. It is now ignored.
|
||||
//
|
||||
// If false, a default is used. Currently the default
|
||||
// is EC-based keys using the P-256 curve.
|
||||
// Deprecated: the Manager will request the correct type of certificate based
|
||||
// on what each client supports.
|
||||
ForceRSA bool
|
||||
|
||||
// ExtraExtensions are used when generating a new CSR (Certificate Request),
|
||||
// thus allowing customization of the resulting certificate.
|
||||
// For instance, TLS Feature Extension (RFC 7633) can be used
|
||||
// to prevent an OCSP downgrade attack.
|
||||
//
|
||||
// The field value is passed to crypto/x509.CreateCertificateRequest
|
||||
// in the template's ExtraExtensions field as is.
|
||||
ExtraExtensions []pkix.Extension
|
||||
|
||||
clientMu sync.Mutex
|
||||
client *acme.Client // initialized by acmeClient method
|
||||
|
||||
stateMu sync.Mutex
|
||||
state map[string]*certState // keyed by domain name
|
||||
state map[certKey]*certState
|
||||
|
||||
// renewal tracks the set of domains currently running renewal timers.
|
||||
// It is keyed by domain name.
|
||||
renewalMu sync.Mutex
|
||||
renewal map[string]*domainRenewal
|
||||
renewal map[certKey]*domainRenewal
|
||||
|
||||
// tokensMu guards the rest of the fields: tryHTTP01, certTokens and httpTokens.
|
||||
tokensMu sync.RWMutex
|
||||
@@ -174,6 +184,23 @@ type Manager struct {
|
||||
certTokens map[string]*tls.Certificate
|
||||
}
|
||||
|
||||
// certKey is the key by which certificates are tracked in state, renewal and cache.
|
||||
type certKey struct {
|
||||
domain string // without trailing dot
|
||||
isRSA bool // RSA cert for legacy clients (as opposed to default ECDSA)
|
||||
isToken bool // tls-sni challenge token cert; key type is undefined regardless of isRSA
|
||||
}
|
||||
|
||||
func (c certKey) String() string {
|
||||
if c.isToken {
|
||||
return c.domain + "+token"
|
||||
}
|
||||
if c.isRSA {
|
||||
return c.domain + "+rsa"
|
||||
}
|
||||
return c.domain
|
||||
}
|
||||
|
||||
// GetCertificate implements the tls.Config.GetCertificate hook.
|
||||
// It provides a TLS certificate for hello.ServerName host, including answering
|
||||
// *.acme.invalid (TLS-SNI) challenges. All other fields of hello are ignored.
|
||||
@@ -194,7 +221,7 @@ func (m *Manager) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate,
|
||||
if !strings.Contains(strings.Trim(name, "."), ".") {
|
||||
return nil, errors.New("acme/autocert: server name component count invalid")
|
||||
}
|
||||
if strings.ContainsAny(name, `/\`) {
|
||||
if strings.ContainsAny(name, `+/\`) {
|
||||
return nil, errors.New("acme/autocert: server name contains invalid character")
|
||||
}
|
||||
|
||||
@@ -210,7 +237,7 @@ func (m *Manager) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate,
|
||||
if cert := m.certTokens[name]; cert != nil {
|
||||
return cert, nil
|
||||
}
|
||||
if cert, err := m.cacheGet(ctx, name); err == nil {
|
||||
if cert, err := m.cacheGet(ctx, certKey{domain: name, isToken: true}); err == nil {
|
||||
return cert, nil
|
||||
}
|
||||
// TODO: cache error results?
|
||||
@@ -218,8 +245,11 @@ func (m *Manager) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate,
|
||||
}
|
||||
|
||||
// regular domain
|
||||
name = strings.TrimSuffix(name, ".") // golang.org/issue/18114
|
||||
cert, err := m.cert(ctx, name)
|
||||
ck := certKey{
|
||||
domain: strings.TrimSuffix(name, "."), // golang.org/issue/18114
|
||||
isRSA: !supportsECDSA(hello),
|
||||
}
|
||||
cert, err := m.cert(ctx, ck)
|
||||
if err == nil {
|
||||
return cert, nil
|
||||
}
|
||||
@@ -231,14 +261,60 @@ func (m *Manager) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate,
|
||||
if err := m.hostPolicy()(ctx, name); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cert, err = m.createCert(ctx, name)
|
||||
cert, err = m.createCert(ctx, ck)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m.cachePut(ctx, name, cert)
|
||||
m.cachePut(ctx, ck, cert)
|
||||
return cert, nil
|
||||
}
|
||||
|
||||
func supportsECDSA(hello *tls.ClientHelloInfo) bool {
|
||||
// The "signature_algorithms" extension, if present, limits the key exchange
|
||||
// algorithms allowed by the cipher suites. See RFC 5246, section 7.4.1.4.1.
|
||||
if hello.SignatureSchemes != nil {
|
||||
ecdsaOK := false
|
||||
schemeLoop:
|
||||
for _, scheme := range hello.SignatureSchemes {
|
||||
const tlsECDSAWithSHA1 tls.SignatureScheme = 0x0203 // constant added in Go 1.10
|
||||
switch scheme {
|
||||
case tlsECDSAWithSHA1, tls.ECDSAWithP256AndSHA256,
|
||||
tls.ECDSAWithP384AndSHA384, tls.ECDSAWithP521AndSHA512:
|
||||
ecdsaOK = true
|
||||
break schemeLoop
|
||||
}
|
||||
}
|
||||
if !ecdsaOK {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if hello.SupportedCurves != nil {
|
||||
ecdsaOK := false
|
||||
for _, curve := range hello.SupportedCurves {
|
||||
if curve == tls.CurveP256 {
|
||||
ecdsaOK = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !ecdsaOK {
|
||||
return false
|
||||
}
|
||||
}
|
||||
for _, suite := range hello.CipherSuites {
|
||||
switch suite {
|
||||
case tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305:
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// HTTPHandler configures the Manager to provision ACME "http-01" challenge responses.
|
||||
// It returns an http.Handler that responds to the challenges and must be
|
||||
// running on port 80. If it receives a request that is not an ACME challenge,
|
||||
@@ -304,16 +380,16 @@ func stripPort(hostport string) string {
|
||||
// cert returns an existing certificate either from m.state or cache.
|
||||
// If a certificate is found in cache but not in m.state, the latter will be filled
|
||||
// with the cached value.
|
||||
func (m *Manager) cert(ctx context.Context, name string) (*tls.Certificate, error) {
|
||||
func (m *Manager) cert(ctx context.Context, ck certKey) (*tls.Certificate, error) {
|
||||
m.stateMu.Lock()
|
||||
if s, ok := m.state[name]; ok {
|
||||
if s, ok := m.state[ck]; ok {
|
||||
m.stateMu.Unlock()
|
||||
s.RLock()
|
||||
defer s.RUnlock()
|
||||
return s.tlscert()
|
||||
}
|
||||
defer m.stateMu.Unlock()
|
||||
cert, err := m.cacheGet(ctx, name)
|
||||
cert, err := m.cacheGet(ctx, ck)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -322,25 +398,25 @@ func (m *Manager) cert(ctx context.Context, name string) (*tls.Certificate, erro
|
||||
return nil, errors.New("acme/autocert: private key cannot sign")
|
||||
}
|
||||
if m.state == nil {
|
||||
m.state = make(map[string]*certState)
|
||||
m.state = make(map[certKey]*certState)
|
||||
}
|
||||
s := &certState{
|
||||
key: signer,
|
||||
cert: cert.Certificate,
|
||||
leaf: cert.Leaf,
|
||||
}
|
||||
m.state[name] = s
|
||||
go m.renew(name, s.key, s.leaf.NotAfter)
|
||||
m.state[ck] = s
|
||||
go m.renew(ck, s.key, s.leaf.NotAfter)
|
||||
return cert, nil
|
||||
}
|
||||
|
||||
// cacheGet always returns a valid certificate, or an error otherwise.
|
||||
// If a cached certficate exists but is not valid, ErrCacheMiss is returned.
|
||||
func (m *Manager) cacheGet(ctx context.Context, domain string) (*tls.Certificate, error) {
|
||||
// If a cached certificate exists but is not valid, ErrCacheMiss is returned.
|
||||
func (m *Manager) cacheGet(ctx context.Context, ck certKey) (*tls.Certificate, error) {
|
||||
if m.Cache == nil {
|
||||
return nil, ErrCacheMiss
|
||||
}
|
||||
data, err := m.Cache.Get(ctx, domain)
|
||||
data, err := m.Cache.Get(ctx, ck.String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -371,7 +447,7 @@ func (m *Manager) cacheGet(ctx context.Context, domain string) (*tls.Certificate
|
||||
}
|
||||
|
||||
// verify and create TLS cert
|
||||
leaf, err := validCert(domain, pubDER, privKey)
|
||||
leaf, err := validCert(ck, pubDER, privKey)
|
||||
if err != nil {
|
||||
return nil, ErrCacheMiss
|
||||
}
|
||||
@@ -383,7 +459,7 @@ func (m *Manager) cacheGet(ctx context.Context, domain string) (*tls.Certificate
|
||||
return tlscert, nil
|
||||
}
|
||||
|
||||
func (m *Manager) cachePut(ctx context.Context, domain string, tlscert *tls.Certificate) error {
|
||||
func (m *Manager) cachePut(ctx context.Context, ck certKey, tlscert *tls.Certificate) error {
|
||||
if m.Cache == nil {
|
||||
return nil
|
||||
}
|
||||
@@ -415,7 +491,7 @@ func (m *Manager) cachePut(ctx context.Context, domain string, tlscert *tls.Cert
|
||||
}
|
||||
}
|
||||
|
||||
return m.Cache.Put(ctx, domain, buf.Bytes())
|
||||
return m.Cache.Put(ctx, ck.String(), buf.Bytes())
|
||||
}
|
||||
|
||||
func encodeECDSAKey(w io.Writer, key *ecdsa.PrivateKey) error {
|
||||
@@ -432,9 +508,9 @@ func encodeECDSAKey(w io.Writer, key *ecdsa.PrivateKey) error {
|
||||
//
|
||||
// If the domain is already being verified, it waits for the existing verification to complete.
|
||||
// Either way, createCert blocks for the duration of the whole process.
|
||||
func (m *Manager) createCert(ctx context.Context, domain string) (*tls.Certificate, error) {
|
||||
func (m *Manager) createCert(ctx context.Context, ck certKey) (*tls.Certificate, error) {
|
||||
// TODO: maybe rewrite this whole piece using sync.Once
|
||||
state, err := m.certState(domain)
|
||||
state, err := m.certState(ck)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -452,44 +528,44 @@ func (m *Manager) createCert(ctx context.Context, domain string) (*tls.Certifica
|
||||
defer state.Unlock()
|
||||
state.locked = false
|
||||
|
||||
der, leaf, err := m.authorizedCert(ctx, state.key, domain)
|
||||
der, leaf, err := m.authorizedCert(ctx, state.key, ck)
|
||||
if err != nil {
|
||||
// Remove the failed state after some time,
|
||||
// making the manager call createCert again on the following TLS hello.
|
||||
time.AfterFunc(createCertRetryAfter, func() {
|
||||
defer testDidRemoveState(domain)
|
||||
defer testDidRemoveState(ck)
|
||||
m.stateMu.Lock()
|
||||
defer m.stateMu.Unlock()
|
||||
// Verify the state hasn't changed and it's still invalid
|
||||
// before deleting.
|
||||
s, ok := m.state[domain]
|
||||
s, ok := m.state[ck]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if _, err := validCert(domain, s.cert, s.key); err == nil {
|
||||
if _, err := validCert(ck, s.cert, s.key); err == nil {
|
||||
return
|
||||
}
|
||||
delete(m.state, domain)
|
||||
delete(m.state, ck)
|
||||
})
|
||||
return nil, err
|
||||
}
|
||||
state.cert = der
|
||||
state.leaf = leaf
|
||||
go m.renew(domain, state.key, state.leaf.NotAfter)
|
||||
go m.renew(ck, state.key, state.leaf.NotAfter)
|
||||
return state.tlscert()
|
||||
}
|
||||
|
||||
// certState returns a new or existing certState.
|
||||
// If a new certState is returned, state.exist is false and the state is locked.
|
||||
// The returned error is non-nil only in the case where a new state could not be created.
|
||||
func (m *Manager) certState(domain string) (*certState, error) {
|
||||
func (m *Manager) certState(ck certKey) (*certState, error) {
|
||||
m.stateMu.Lock()
|
||||
defer m.stateMu.Unlock()
|
||||
if m.state == nil {
|
||||
m.state = make(map[string]*certState)
|
||||
m.state = make(map[certKey]*certState)
|
||||
}
|
||||
// existing state
|
||||
if state, ok := m.state[domain]; ok {
|
||||
if state, ok := m.state[ck]; ok {
|
||||
return state, nil
|
||||
}
|
||||
|
||||
@@ -498,7 +574,7 @@ func (m *Manager) certState(domain string) (*certState, error) {
|
||||
err error
|
||||
key crypto.Signer
|
||||
)
|
||||
if m.ForceRSA {
|
||||
if ck.isRSA {
|
||||
key, err = rsa.GenerateKey(rand.Reader, 2048)
|
||||
} else {
|
||||
key, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
@@ -512,22 +588,22 @@ func (m *Manager) certState(domain string) (*certState, error) {
|
||||
locked: true,
|
||||
}
|
||||
state.Lock() // will be unlocked by m.certState caller
|
||||
m.state[domain] = state
|
||||
m.state[ck] = state
|
||||
return state, nil
|
||||
}
|
||||
|
||||
// authorizedCert starts the domain ownership verification process and requests a new cert upon success.
|
||||
// The key argument is the certificate private key.
|
||||
func (m *Manager) authorizedCert(ctx context.Context, key crypto.Signer, domain string) (der [][]byte, leaf *x509.Certificate, err error) {
|
||||
func (m *Manager) authorizedCert(ctx context.Context, key crypto.Signer, ck certKey) (der [][]byte, leaf *x509.Certificate, err error) {
|
||||
client, err := m.acmeClient(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if err := m.verify(ctx, client, domain); err != nil {
|
||||
if err := m.verify(ctx, client, ck.domain); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
csr, err := certRequest(key, domain)
|
||||
csr, err := certRequest(key, ck.domain, m.ExtraExtensions)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -535,13 +611,25 @@ func (m *Manager) authorizedCert(ctx context.Context, key crypto.Signer, domain
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
leaf, err = validCert(domain, der, key)
|
||||
leaf, err = validCert(ck, der, key)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return der, leaf, nil
|
||||
}
|
||||
|
||||
// revokePendingAuthz revokes all authorizations idenfied by the elements of uri slice.
|
||||
// It ignores revocation errors.
|
||||
func (m *Manager) revokePendingAuthz(ctx context.Context, uri []string) {
|
||||
client, err := m.acmeClient(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, u := range uri {
|
||||
client.RevokeAuthorization(ctx, u)
|
||||
}
|
||||
}
|
||||
|
||||
// verify runs the identifier (domain) authorization flow
|
||||
// using each applicable ACME challenge type.
|
||||
func (m *Manager) verify(ctx context.Context, client *acme.Client, domain string) error {
|
||||
@@ -554,6 +642,24 @@ func (m *Manager) verify(ctx context.Context, client *acme.Client, domain string
|
||||
}
|
||||
m.tokensMu.RUnlock()
|
||||
|
||||
// Keep track of pending authzs and revoke the ones that did not validate.
|
||||
pendingAuthzs := make(map[string]bool)
|
||||
defer func() {
|
||||
var uri []string
|
||||
for k, pending := range pendingAuthzs {
|
||||
if pending {
|
||||
uri = append(uri, k)
|
||||
}
|
||||
}
|
||||
if len(uri) > 0 {
|
||||
// Use "detached" background context.
|
||||
// The revocations need not happen in the current verification flow.
|
||||
go m.revokePendingAuthz(context.Background(), uri)
|
||||
}
|
||||
}()
|
||||
|
||||
// errs accumulates challenge failure errors, printed if all fail
|
||||
errs := make(map[*acme.Challenge]error)
|
||||
var nextTyp int // challengeType index of the next challenge type to try
|
||||
for {
|
||||
// Start domain authorization and get the challenge.
|
||||
@@ -570,6 +676,8 @@ func (m *Manager) verify(ctx context.Context, client *acme.Client, domain string
|
||||
return fmt.Errorf("acme/autocert: invalid authorization %q", authz.URI)
|
||||
}
|
||||
|
||||
pendingAuthzs[authz.URI] = true
|
||||
|
||||
// Pick the next preferred challenge.
|
||||
var chal *acme.Challenge
|
||||
for chal == nil && nextTyp < len(challengeTypes) {
|
||||
@@ -577,21 +685,30 @@ func (m *Manager) verify(ctx context.Context, client *acme.Client, domain string
|
||||
nextTyp++
|
||||
}
|
||||
if chal == nil {
|
||||
return fmt.Errorf("acme/autocert: unable to authorize %q; tried %q", domain, challengeTypes)
|
||||
errorMsg := fmt.Sprintf("acme/autocert: unable to authorize %q", domain)
|
||||
for chal, err := range errs {
|
||||
errorMsg += fmt.Sprintf("; challenge %q failed with error: %v", chal.Type, err)
|
||||
}
|
||||
return errors.New(errorMsg)
|
||||
}
|
||||
cleanup, err := m.fulfill(ctx, client, chal)
|
||||
if err != nil {
|
||||
errs[chal] = err
|
||||
continue
|
||||
}
|
||||
defer cleanup()
|
||||
if _, err := client.Accept(ctx, chal); err != nil {
|
||||
errs[chal] = err
|
||||
continue
|
||||
}
|
||||
|
||||
// A challenge is fulfilled and accepted: wait for the CA to validate.
|
||||
if _, err := client.WaitAuthorization(ctx, authz.URI); err == nil {
|
||||
return nil
|
||||
if _, err := client.WaitAuthorization(ctx, authz.URI); err != nil {
|
||||
errs[chal] = err
|
||||
continue
|
||||
}
|
||||
delete(pendingAuthzs, authz.URI)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -634,8 +751,8 @@ func pickChallenge(typ string, chal []*acme.Challenge) *acme.Challenge {
|
||||
return nil
|
||||
}
|
||||
|
||||
// putCertToken stores the cert under the named key in both m.certTokens map
|
||||
// and m.Cache.
|
||||
// putCertToken stores the token certificate with the specified name
|
||||
// in both m.certTokens map and m.Cache.
|
||||
func (m *Manager) putCertToken(ctx context.Context, name string, cert *tls.Certificate) {
|
||||
m.tokensMu.Lock()
|
||||
defer m.tokensMu.Unlock()
|
||||
@@ -643,17 +760,18 @@ func (m *Manager) putCertToken(ctx context.Context, name string, cert *tls.Certi
|
||||
m.certTokens = make(map[string]*tls.Certificate)
|
||||
}
|
||||
m.certTokens[name] = cert
|
||||
m.cachePut(ctx, name, cert)
|
||||
m.cachePut(ctx, certKey{domain: name, isToken: true}, cert)
|
||||
}
|
||||
|
||||
// deleteCertToken removes the token certificate for the specified domain name
|
||||
// deleteCertToken removes the token certificate with the specified name
|
||||
// from both m.certTokens map and m.Cache.
|
||||
func (m *Manager) deleteCertToken(name string) {
|
||||
m.tokensMu.Lock()
|
||||
defer m.tokensMu.Unlock()
|
||||
delete(m.certTokens, name)
|
||||
if m.Cache != nil {
|
||||
m.Cache.Delete(context.Background(), name)
|
||||
ck := certKey{domain: name, isToken: true}
|
||||
m.Cache.Delete(context.Background(), ck.String())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -704,7 +822,7 @@ func (m *Manager) deleteHTTPToken(tokenPath string) {
|
||||
// httpTokenCacheKey returns a key at which an http-01 token value may be stored
|
||||
// in the Manager's optional Cache.
|
||||
func httpTokenCacheKey(tokenPath string) string {
|
||||
return "http-01-" + path.Base(tokenPath)
|
||||
return path.Base(tokenPath) + "+http-01"
|
||||
}
|
||||
|
||||
// renew starts a cert renewal timer loop, one per domain.
|
||||
@@ -715,18 +833,18 @@ func httpTokenCacheKey(tokenPath string) string {
|
||||
//
|
||||
// The key argument is a certificate private key.
|
||||
// The exp argument is the cert expiration time (NotAfter).
|
||||
func (m *Manager) renew(domain string, key crypto.Signer, exp time.Time) {
|
||||
func (m *Manager) renew(ck certKey, key crypto.Signer, exp time.Time) {
|
||||
m.renewalMu.Lock()
|
||||
defer m.renewalMu.Unlock()
|
||||
if m.renewal[domain] != nil {
|
||||
if m.renewal[ck] != nil {
|
||||
// another goroutine is already on it
|
||||
return
|
||||
}
|
||||
if m.renewal == nil {
|
||||
m.renewal = make(map[string]*domainRenewal)
|
||||
m.renewal = make(map[certKey]*domainRenewal)
|
||||
}
|
||||
dr := &domainRenewal{m: m, domain: domain, key: key}
|
||||
m.renewal[domain] = dr
|
||||
dr := &domainRenewal{m: m, ck: ck, key: key}
|
||||
m.renewal[ck] = dr
|
||||
dr.start(exp)
|
||||
}
|
||||
|
||||
@@ -742,7 +860,10 @@ func (m *Manager) stopRenew() {
|
||||
}
|
||||
|
||||
func (m *Manager) accountKey(ctx context.Context) (crypto.Signer, error) {
|
||||
const keyName = "acme_account.key"
|
||||
const keyName = "acme_account+key"
|
||||
|
||||
// Previous versions of autocert stored the value under a different key.
|
||||
const legacyKeyName = "acme_account.key"
|
||||
|
||||
genKey := func() (*ecdsa.PrivateKey, error) {
|
||||
return ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
@@ -753,6 +874,9 @@ func (m *Manager) accountKey(ctx context.Context) (crypto.Signer, error) {
|
||||
}
|
||||
|
||||
data, err := m.Cache.Get(ctx, keyName)
|
||||
if err == ErrCacheMiss {
|
||||
data, err = m.Cache.Get(ctx, legacyKeyName)
|
||||
}
|
||||
if err == ErrCacheMiss {
|
||||
key, err := genKey()
|
||||
if err != nil {
|
||||
@@ -849,12 +973,12 @@ func (s *certState) tlscert() (*tls.Certificate, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
// certRequest creates a certificate request for the given common name cn
|
||||
// and optional SANs.
|
||||
func certRequest(key crypto.Signer, cn string, san ...string) ([]byte, error) {
|
||||
// certRequest generates a CSR for the given common name cn and optional SANs.
|
||||
func certRequest(key crypto.Signer, cn string, ext []pkix.Extension, san ...string) ([]byte, error) {
|
||||
req := &x509.CertificateRequest{
|
||||
Subject: pkix.Name{CommonName: cn},
|
||||
DNSNames: san,
|
||||
Subject: pkix.Name{CommonName: cn},
|
||||
DNSNames: san,
|
||||
ExtraExtensions: ext,
|
||||
}
|
||||
return x509.CreateCertificateRequest(rand.Reader, req, key)
|
||||
}
|
||||
@@ -885,12 +1009,12 @@ func parsePrivateKey(der []byte) (crypto.Signer, error) {
|
||||
return nil, errors.New("acme/autocert: failed to parse private key")
|
||||
}
|
||||
|
||||
// validCert parses a cert chain provided as der argument and verifies the leaf, der[0],
|
||||
// corresponds to the private key, as well as the domain match and expiration dates.
|
||||
// It doesn't do any revocation checking.
|
||||
// validCert parses a cert chain provided as der argument and verifies the leaf and der[0]
|
||||
// correspond to the private key, the domain and key type match, and expiration dates
|
||||
// are valid. It doesn't do any revocation checking.
|
||||
//
|
||||
// The returned value is the verified leaf cert.
|
||||
func validCert(domain string, der [][]byte, key crypto.Signer) (leaf *x509.Certificate, err error) {
|
||||
func validCert(ck certKey, der [][]byte, key crypto.Signer) (leaf *x509.Certificate, err error) {
|
||||
// parse public part(s)
|
||||
var n int
|
||||
for _, b := range der {
|
||||
@@ -902,7 +1026,7 @@ func validCert(domain string, der [][]byte, key crypto.Signer) (leaf *x509.Certi
|
||||
n += copy(pub[n:], b)
|
||||
}
|
||||
x509Cert, err := x509.ParseCertificates(pub)
|
||||
if len(x509Cert) == 0 {
|
||||
if err != nil || len(x509Cert) == 0 {
|
||||
return nil, errors.New("acme/autocert: no public key found")
|
||||
}
|
||||
// verify the leaf is not expired and matches the domain name
|
||||
@@ -914,10 +1038,10 @@ func validCert(domain string, der [][]byte, key crypto.Signer) (leaf *x509.Certi
|
||||
if now.After(leaf.NotAfter) {
|
||||
return nil, errors.New("acme/autocert: expired certificate")
|
||||
}
|
||||
if err := leaf.VerifyHostname(domain); err != nil {
|
||||
if err := leaf.VerifyHostname(ck.domain); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// ensure the leaf corresponds to the private key
|
||||
// ensure the leaf corresponds to the private key and matches the certKey type
|
||||
switch pub := leaf.PublicKey.(type) {
|
||||
case *rsa.PublicKey:
|
||||
prv, ok := key.(*rsa.PrivateKey)
|
||||
@@ -927,6 +1051,9 @@ func validCert(domain string, der [][]byte, key crypto.Signer) (leaf *x509.Certi
|
||||
if pub.N.Cmp(prv.N) != 0 {
|
||||
return nil, errors.New("acme/autocert: private key does not match public key")
|
||||
}
|
||||
if !ck.isRSA && !ck.isToken {
|
||||
return nil, errors.New("acme/autocert: key type does not match expected value")
|
||||
}
|
||||
case *ecdsa.PublicKey:
|
||||
prv, ok := key.(*ecdsa.PrivateKey)
|
||||
if !ok {
|
||||
@@ -935,6 +1062,9 @@ func validCert(domain string, der [][]byte, key crypto.Signer) (leaf *x509.Certi
|
||||
if pub.X.Cmp(prv.X) != 0 || pub.Y.Cmp(prv.Y) != 0 {
|
||||
return nil, errors.New("acme/autocert: private key does not match public key")
|
||||
}
|
||||
if ck.isRSA && !ck.isToken {
|
||||
return nil, errors.New("acme/autocert: key type does not match expected value")
|
||||
}
|
||||
default:
|
||||
return nil, errors.New("acme/autocert: unknown public key algorithm")
|
||||
}
|
||||
@@ -958,5 +1088,5 @@ var (
|
||||
timeNow = time.Now
|
||||
|
||||
// Called when a state is removed.
|
||||
testDidRemoveState = func(domain string) {}
|
||||
testDidRemoveState = func(certKey) {}
|
||||
)
|
||||
|
||||
563
vendor/golang.org/x/crypto/acme/autocert/autocert_test.go
generated
vendored
563
vendor/golang.org/x/crypto/acme/autocert/autocert_test.go
generated
vendored
@@ -5,6 +5,7 @@
|
||||
package autocert
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
@@ -14,6 +15,7 @@ import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/asn1"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
@@ -31,6 +33,12 @@ import (
|
||||
"golang.org/x/crypto/acme"
|
||||
)
|
||||
|
||||
var (
|
||||
exampleDomain = "example.org"
|
||||
exampleCertKey = certKey{domain: exampleDomain}
|
||||
exampleCertKeyRSA = certKey{domain: exampleDomain, isRSA: true}
|
||||
)
|
||||
|
||||
var discoTmpl = template.Must(template.New("disco").Parse(`{
|
||||
"new-reg": "{{.}}/new-reg",
|
||||
"new-authz": "{{.}}/new-authz",
|
||||
@@ -64,6 +72,7 @@ var authzTmpl = template.Must(template.New("authz").Parse(`{
|
||||
}`))
|
||||
|
||||
type memCache struct {
|
||||
t *testing.T
|
||||
mu sync.Mutex
|
||||
keyData map[string][]byte
|
||||
}
|
||||
@@ -79,7 +88,26 @@ func (m *memCache) Get(ctx context.Context, key string) ([]byte, error) {
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// filenameSafe returns whether all characters in s are printable ASCII
|
||||
// and safe to use in a filename on most filesystems.
|
||||
func filenameSafe(s string) bool {
|
||||
for _, c := range s {
|
||||
if c < 0x20 || c > 0x7E {
|
||||
return false
|
||||
}
|
||||
switch c {
|
||||
case '\\', '/', ':', '*', '?', '"', '<', '>', '|':
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (m *memCache) Put(ctx context.Context, key string, data []byte) error {
|
||||
if !filenameSafe(key) {
|
||||
m.t.Errorf("invalid characters in cache key %q", key)
|
||||
}
|
||||
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
@@ -95,12 +123,29 @@ func (m *memCache) Delete(ctx context.Context, key string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func newMemCache() *memCache {
|
||||
func newMemCache(t *testing.T) *memCache {
|
||||
return &memCache{
|
||||
t: t,
|
||||
keyData: make(map[string][]byte),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *memCache) numCerts() int {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
res := 0
|
||||
for key := range m.keyData {
|
||||
if strings.HasSuffix(key, "+token") ||
|
||||
strings.HasSuffix(key, "+key") ||
|
||||
strings.HasSuffix(key, "+http-01") {
|
||||
continue
|
||||
}
|
||||
res++
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func dummyCert(pub interface{}, san ...string) ([]byte, error) {
|
||||
return dateDummyCert(pub, time.Now(), time.Now().Add(90*24*time.Hour), san...)
|
||||
}
|
||||
@@ -137,53 +182,58 @@ func decodePayload(v interface{}, r io.Reader) error {
|
||||
return json.Unmarshal(payload, v)
|
||||
}
|
||||
|
||||
func clientHelloInfo(sni string, ecdsaSupport bool) *tls.ClientHelloInfo {
|
||||
hello := &tls.ClientHelloInfo{
|
||||
ServerName: sni,
|
||||
CipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305},
|
||||
}
|
||||
if ecdsaSupport {
|
||||
hello.CipherSuites = append(hello.CipherSuites, tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305)
|
||||
}
|
||||
return hello
|
||||
}
|
||||
|
||||
func TestGetCertificate(t *testing.T) {
|
||||
man := &Manager{Prompt: AcceptTOS}
|
||||
defer man.stopRenew()
|
||||
hello := &tls.ClientHelloInfo{ServerName: "example.org"}
|
||||
hello := clientHelloInfo("example.org", true)
|
||||
testGetCertificate(t, man, "example.org", hello)
|
||||
}
|
||||
|
||||
func TestGetCertificate_trailingDot(t *testing.T) {
|
||||
man := &Manager{Prompt: AcceptTOS}
|
||||
defer man.stopRenew()
|
||||
hello := &tls.ClientHelloInfo{ServerName: "example.org."}
|
||||
hello := clientHelloInfo("example.org.", true)
|
||||
testGetCertificate(t, man, "example.org", hello)
|
||||
}
|
||||
|
||||
func TestGetCertificate_ForceRSA(t *testing.T) {
|
||||
man := &Manager{
|
||||
Prompt: AcceptTOS,
|
||||
Cache: newMemCache(),
|
||||
Cache: newMemCache(t),
|
||||
ForceRSA: true,
|
||||
}
|
||||
defer man.stopRenew()
|
||||
hello := &tls.ClientHelloInfo{ServerName: "example.org"}
|
||||
testGetCertificate(t, man, "example.org", hello)
|
||||
hello := clientHelloInfo(exampleDomain, true)
|
||||
testGetCertificate(t, man, exampleDomain, hello)
|
||||
|
||||
cert, err := man.cacheGet(context.Background(), "example.org")
|
||||
// ForceRSA was deprecated and is now ignored.
|
||||
cert, err := man.cacheGet(context.Background(), exampleCertKey)
|
||||
if err != nil {
|
||||
t.Fatalf("man.cacheGet: %v", err)
|
||||
}
|
||||
if _, ok := cert.PrivateKey.(*rsa.PrivateKey); !ok {
|
||||
t.Errorf("cert.PrivateKey is %T; want *rsa.PrivateKey", cert.PrivateKey)
|
||||
if _, ok := cert.PrivateKey.(*ecdsa.PrivateKey); !ok {
|
||||
t.Errorf("cert.PrivateKey is %T; want *ecdsa.PrivateKey", cert.PrivateKey)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetCertificate_nilPrompt(t *testing.T) {
|
||||
man := &Manager{}
|
||||
defer man.stopRenew()
|
||||
url, finish := startACMEServerStub(t, man, "example.org")
|
||||
url, finish := startACMEServerStub(t, getCertificateFromManager(man, true), "example.org")
|
||||
defer finish()
|
||||
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
man.Client = &acme.Client{
|
||||
Key: key,
|
||||
DirectoryURL: url,
|
||||
}
|
||||
hello := &tls.ClientHelloInfo{ServerName: "example.org"}
|
||||
man.Client = &acme.Client{DirectoryURL: url}
|
||||
hello := clientHelloInfo("example.org", true)
|
||||
if _, err := man.GetCertificate(hello); err == nil {
|
||||
t.Error("got certificate for example.org; wanted error")
|
||||
}
|
||||
@@ -197,7 +247,7 @@ func TestGetCertificate_expiredCache(t *testing.T) {
|
||||
}
|
||||
tmpl := &x509.Certificate{
|
||||
SerialNumber: big.NewInt(1),
|
||||
Subject: pkix.Name{CommonName: "example.org"},
|
||||
Subject: pkix.Name{CommonName: exampleDomain},
|
||||
NotAfter: time.Now(),
|
||||
}
|
||||
pub, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, &pk.PublicKey, pk)
|
||||
@@ -209,16 +259,16 @@ func TestGetCertificate_expiredCache(t *testing.T) {
|
||||
PrivateKey: pk,
|
||||
}
|
||||
|
||||
man := &Manager{Prompt: AcceptTOS, Cache: newMemCache()}
|
||||
man := &Manager{Prompt: AcceptTOS, Cache: newMemCache(t)}
|
||||
defer man.stopRenew()
|
||||
if err := man.cachePut(context.Background(), "example.org", tlscert); err != nil {
|
||||
if err := man.cachePut(context.Background(), exampleCertKey, tlscert); err != nil {
|
||||
t.Fatalf("man.cachePut: %v", err)
|
||||
}
|
||||
|
||||
// The expired cached cert should trigger a new cert issuance
|
||||
// and return without an error.
|
||||
hello := &tls.ClientHelloInfo{ServerName: "example.org"}
|
||||
testGetCertificate(t, man, "example.org", hello)
|
||||
hello := clientHelloInfo(exampleDomain, true)
|
||||
testGetCertificate(t, man, exampleDomain, hello)
|
||||
}
|
||||
|
||||
func TestGetCertificate_failedAttempt(t *testing.T) {
|
||||
@@ -227,7 +277,6 @@ func TestGetCertificate_failedAttempt(t *testing.T) {
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
const example = "example.org"
|
||||
d := createCertRetryAfter
|
||||
f := testDidRemoveState
|
||||
defer func() {
|
||||
@@ -236,51 +285,167 @@ func TestGetCertificate_failedAttempt(t *testing.T) {
|
||||
}()
|
||||
createCertRetryAfter = 0
|
||||
done := make(chan struct{})
|
||||
testDidRemoveState = func(domain string) {
|
||||
if domain != example {
|
||||
t.Errorf("testDidRemoveState: domain = %q; want %q", domain, example)
|
||||
testDidRemoveState = func(ck certKey) {
|
||||
if ck != exampleCertKey {
|
||||
t.Errorf("testDidRemoveState: domain = %v; want %v", ck, exampleCertKey)
|
||||
}
|
||||
close(done)
|
||||
}
|
||||
|
||||
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
man := &Manager{
|
||||
Prompt: AcceptTOS,
|
||||
Client: &acme.Client{
|
||||
Key: key,
|
||||
DirectoryURL: ts.URL,
|
||||
},
|
||||
}
|
||||
defer man.stopRenew()
|
||||
hello := &tls.ClientHelloInfo{ServerName: example}
|
||||
hello := clientHelloInfo(exampleDomain, true)
|
||||
if _, err := man.GetCertificate(hello); err == nil {
|
||||
t.Error("GetCertificate: err is nil")
|
||||
}
|
||||
select {
|
||||
case <-time.After(5 * time.Second):
|
||||
t.Errorf("took too long to remove the %q state", example)
|
||||
t.Errorf("took too long to remove the %q state", exampleCertKey)
|
||||
case <-done:
|
||||
man.stateMu.Lock()
|
||||
defer man.stateMu.Unlock()
|
||||
if v, exist := man.state[example]; exist {
|
||||
t.Errorf("state exists for %q: %+v", example, v)
|
||||
if v, exist := man.state[exampleCertKey]; exist {
|
||||
t.Errorf("state exists for %v: %+v", exampleCertKey, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// testGetCertificate_tokenCache tests the fallback of token certificate fetches
|
||||
// to cache when Manager.certTokens misses. ecdsaSupport refers to the CA when
|
||||
// verifying the certificate token.
|
||||
func testGetCertificate_tokenCache(t *testing.T, ecdsaSupport bool) {
|
||||
man1 := &Manager{
|
||||
Cache: newMemCache(t),
|
||||
Prompt: AcceptTOS,
|
||||
}
|
||||
defer man1.stopRenew()
|
||||
man2 := &Manager{
|
||||
Cache: man1.Cache,
|
||||
Prompt: AcceptTOS,
|
||||
}
|
||||
defer man2.stopRenew()
|
||||
|
||||
// Send the verification request to a different Manager from the one that
|
||||
// initiated the authorization, when they share caches.
|
||||
url, finish := startACMEServerStub(t, getCertificateFromManager(man2, ecdsaSupport), "example.org")
|
||||
defer finish()
|
||||
man1.Client = &acme.Client{DirectoryURL: url}
|
||||
hello := clientHelloInfo("example.org", true)
|
||||
if _, err := man1.GetCertificate(hello); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if _, err := man2.GetCertificate(hello); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetCertificate_tokenCache(t *testing.T) {
|
||||
t.Run("ecdsaSupport=true", func(t *testing.T) {
|
||||
testGetCertificate_tokenCache(t, true)
|
||||
})
|
||||
t.Run("ecdsaSupport=false", func(t *testing.T) {
|
||||
testGetCertificate_tokenCache(t, false)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetCertificate_ecdsaVsRSA(t *testing.T) {
|
||||
cache := newMemCache(t)
|
||||
man := &Manager{Prompt: AcceptTOS, Cache: cache}
|
||||
defer man.stopRenew()
|
||||
url, finish := startACMEServerStub(t, getCertificateFromManager(man, true), "example.org")
|
||||
defer finish()
|
||||
man.Client = &acme.Client{DirectoryURL: url}
|
||||
|
||||
cert, err := man.GetCertificate(clientHelloInfo("example.org", true))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if _, ok := cert.Leaf.PublicKey.(*ecdsa.PublicKey); !ok {
|
||||
t.Error("an ECDSA client was served a non-ECDSA certificate")
|
||||
}
|
||||
|
||||
cert, err = man.GetCertificate(clientHelloInfo("example.org", false))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if _, ok := cert.Leaf.PublicKey.(*rsa.PublicKey); !ok {
|
||||
t.Error("a RSA client was served a non-RSA certificate")
|
||||
}
|
||||
|
||||
if _, err := man.GetCertificate(clientHelloInfo("example.org", true)); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if _, err := man.GetCertificate(clientHelloInfo("example.org", false)); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if numCerts := cache.numCerts(); numCerts != 2 {
|
||||
t.Errorf("found %d certificates in cache; want %d", numCerts, 2)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetCertificate_wrongCacheKeyType(t *testing.T) {
|
||||
cache := newMemCache(t)
|
||||
man := &Manager{Prompt: AcceptTOS, Cache: cache}
|
||||
defer man.stopRenew()
|
||||
url, finish := startACMEServerStub(t, getCertificateFromManager(man, true), exampleDomain)
|
||||
defer finish()
|
||||
man.Client = &acme.Client{DirectoryURL: url}
|
||||
|
||||
// Make an RSA cert and cache it without suffix.
|
||||
pk, err := rsa.GenerateKey(rand.Reader, 512)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tmpl := &x509.Certificate{
|
||||
SerialNumber: big.NewInt(1),
|
||||
Subject: pkix.Name{CommonName: exampleDomain},
|
||||
NotAfter: time.Now().Add(90 * 24 * time.Hour),
|
||||
}
|
||||
pub, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, &pk.PublicKey, pk)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rsaCert := &tls.Certificate{
|
||||
Certificate: [][]byte{pub},
|
||||
PrivateKey: pk,
|
||||
}
|
||||
if err := man.cachePut(context.Background(), exampleCertKey, rsaCert); err != nil {
|
||||
t.Fatalf("man.cachePut: %v", err)
|
||||
}
|
||||
|
||||
// The RSA cached cert should be silently ignored and replaced.
|
||||
cert, err := man.GetCertificate(clientHelloInfo(exampleDomain, true))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if _, ok := cert.Leaf.PublicKey.(*ecdsa.PublicKey); !ok {
|
||||
t.Error("an ECDSA client was served a non-ECDSA certificate")
|
||||
}
|
||||
if numCerts := cache.numCerts(); numCerts != 1 {
|
||||
t.Errorf("found %d certificates in cache; want %d", numCerts, 1)
|
||||
}
|
||||
}
|
||||
|
||||
func getCertificateFromManager(man *Manager, ecdsaSupport bool) func(string) error {
|
||||
return func(sni string) error {
|
||||
_, err := man.GetCertificate(clientHelloInfo(sni, ecdsaSupport))
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// startACMEServerStub runs an ACME server
|
||||
// The domain argument is the expected domain name of a certificate request.
|
||||
func startACMEServerStub(t *testing.T, man *Manager, domain string) (url string, finish func()) {
|
||||
func startACMEServerStub(t *testing.T, getCertificate func(string) error, domain string) (url string, finish func()) {
|
||||
// echo token-02 | shasum -a 256
|
||||
// then divide result in 2 parts separated by dot
|
||||
tokenCertName := "4e8eb87631187e9ff2153b56b13a4dec.13a35d002e485d60ff37354b32f665d9.token.acme.invalid"
|
||||
verifyTokenCert := func() {
|
||||
hello := &tls.ClientHelloInfo{ServerName: tokenCertName}
|
||||
_, err := man.GetCertificate(hello)
|
||||
if err != nil {
|
||||
if err := getCertificate(tokenCertName); err != nil {
|
||||
t.Errorf("verifyTokenCert: GetCertificate(%q): %v", tokenCertName, err)
|
||||
return
|
||||
}
|
||||
@@ -362,8 +527,7 @@ func startACMEServerStub(t *testing.T, man *Manager, domain string) (url string,
|
||||
tick := time.NewTicker(100 * time.Millisecond)
|
||||
defer tick.Stop()
|
||||
for {
|
||||
hello := &tls.ClientHelloInfo{ServerName: tokenCertName}
|
||||
if _, err := man.GetCertificate(hello); err != nil {
|
||||
if err := getCertificate(tokenCertName); err != nil {
|
||||
return
|
||||
}
|
||||
select {
|
||||
@@ -387,21 +551,13 @@ func startACMEServerStub(t *testing.T, man *Manager, domain string) (url string,
|
||||
// tests man.GetCertificate flow using the provided hello argument.
|
||||
// The domain argument is the expected domain name of a certificate request.
|
||||
func testGetCertificate(t *testing.T, man *Manager, domain string, hello *tls.ClientHelloInfo) {
|
||||
url, finish := startACMEServerStub(t, man, domain)
|
||||
url, finish := startACMEServerStub(t, getCertificateFromManager(man, true), domain)
|
||||
defer finish()
|
||||
|
||||
// use EC key to run faster on 386
|
||||
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
man.Client = &acme.Client{
|
||||
Key: key,
|
||||
DirectoryURL: url,
|
||||
}
|
||||
man.Client = &acme.Client{DirectoryURL: url}
|
||||
|
||||
// simulate tls.Config.GetCertificate
|
||||
var tlscert *tls.Certificate
|
||||
var err error
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
tlscert, err = man.GetCertificate(hello)
|
||||
@@ -445,7 +601,7 @@ func TestVerifyHTTP01(t *testing.T) {
|
||||
if w.Code != http.StatusOK {
|
||||
t.Errorf("http token: w.Code = %d; want %d", w.Code, http.StatusOK)
|
||||
}
|
||||
if v := string(w.Body.Bytes()); !strings.HasPrefix(v, "token-http-01.") {
|
||||
if v := w.Body.String(); !strings.HasPrefix(v, "token-http-01.") {
|
||||
t.Errorf("http token value = %q; want 'token-http-01.' prefix", v)
|
||||
}
|
||||
}
|
||||
@@ -505,18 +661,18 @@ func TestVerifyHTTP01(t *testing.T) {
|
||||
}))
|
||||
defer ca.Close()
|
||||
|
||||
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
m := &Manager{
|
||||
Client: &acme.Client{
|
||||
Key: key,
|
||||
DirectoryURL: ca.URL,
|
||||
},
|
||||
}
|
||||
http01 = m.HTTPHandler(nil)
|
||||
if err := m.verify(context.Background(), m.Client, "example.org"); err != nil {
|
||||
ctx := context.Background()
|
||||
client, err := m.acmeClient(ctx)
|
||||
if err != nil {
|
||||
t.Fatalf("m.acmeClient: %v", err)
|
||||
}
|
||||
if err := m.verify(ctx, client, "example.org"); err != nil {
|
||||
t.Errorf("m.verify: %v", err)
|
||||
}
|
||||
// Only tls-sni-01, tls-sni-02 and http-01 must be accepted
|
||||
@@ -529,6 +685,111 @@ func TestVerifyHTTP01(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRevokeFailedAuthz(t *testing.T) {
|
||||
// Prefill authorization URIs expected to be revoked.
|
||||
// The challenges are selected in a specific order,
|
||||
// each tried within a newly created authorization.
|
||||
// This means each authorization URI corresponds to a different challenge type.
|
||||
revokedAuthz := map[string]bool{
|
||||
"/authz/0": false, // tls-sni-02
|
||||
"/authz/1": false, // tls-sni-01
|
||||
"/authz/2": false, // no viable challenge, but authz is created
|
||||
}
|
||||
|
||||
var authzCount int // num. of created authorizations
|
||||
var revokeCount int // num. of revoked authorizations
|
||||
done := make(chan struct{}) // closed when revokeCount is 3
|
||||
|
||||
// ACME CA server stub, only the needed bits.
|
||||
// TODO: Merge this with startACMEServerStub, making it a configurable CA for testing.
|
||||
var ca *httptest.Server
|
||||
ca = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Replay-Nonce", "nonce")
|
||||
if r.Method == "HEAD" {
|
||||
// a nonce request
|
||||
return
|
||||
}
|
||||
|
||||
switch r.URL.Path {
|
||||
// Discovery.
|
||||
case "/":
|
||||
if err := discoTmpl.Execute(w, ca.URL); err != nil {
|
||||
t.Errorf("discoTmpl: %v", err)
|
||||
}
|
||||
// Client key registration.
|
||||
case "/new-reg":
|
||||
w.Write([]byte("{}"))
|
||||
// New domain authorization.
|
||||
case "/new-authz":
|
||||
w.Header().Set("Location", fmt.Sprintf("%s/authz/%d", ca.URL, authzCount))
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
if err := authzTmpl.Execute(w, ca.URL); err != nil {
|
||||
t.Errorf("authzTmpl: %v", err)
|
||||
}
|
||||
authzCount++
|
||||
// tls-sni-02 challenge "accept" request.
|
||||
case "/challenge/2":
|
||||
// Refuse.
|
||||
http.Error(w, "won't accept tls-sni-02 challenge", http.StatusBadRequest)
|
||||
// tls-sni-01 challenge "accept" request.
|
||||
case "/challenge/1":
|
||||
// Accept but the authorization will be "expired".
|
||||
w.Write([]byte("{}"))
|
||||
// Authorization requests.
|
||||
case "/authz/0", "/authz/1", "/authz/2":
|
||||
// Revocation requests.
|
||||
if r.Method == "POST" {
|
||||
var req struct{ Status string }
|
||||
if err := decodePayload(&req, r.Body); err != nil {
|
||||
t.Errorf("%s: decodePayload: %v", r.URL, err)
|
||||
}
|
||||
switch req.Status {
|
||||
case "deactivated":
|
||||
revokedAuthz[r.URL.Path] = true
|
||||
revokeCount++
|
||||
if revokeCount >= 3 {
|
||||
// Last authorization is revoked.
|
||||
defer close(done)
|
||||
}
|
||||
default:
|
||||
t.Errorf("%s: req.Status = %q; want 'deactivated'", r.URL, req.Status)
|
||||
}
|
||||
w.Write([]byte(`{"status": "invalid"}`))
|
||||
return
|
||||
}
|
||||
// Authorization status requests.
|
||||
// Simulate abandoned authorization, deleted by the CA.
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
t.Errorf("unrecognized r.URL.Path: %s", r.URL.Path)
|
||||
}
|
||||
}))
|
||||
defer ca.Close()
|
||||
|
||||
m := &Manager{
|
||||
Client: &acme.Client{DirectoryURL: ca.URL},
|
||||
}
|
||||
// Should fail and revoke 3 authorizations.
|
||||
// The first 2 are tsl-sni-02 and tls-sni-01 challenges.
|
||||
// The third time an authorization is created but no viable challenge is found.
|
||||
// See revokedAuthz above for more explanation.
|
||||
if _, err := m.createCert(context.Background(), exampleCertKey); err == nil {
|
||||
t.Errorf("m.createCert returned nil error")
|
||||
}
|
||||
select {
|
||||
case <-time.After(3 * time.Second):
|
||||
t.Error("revocations took too long")
|
||||
case <-done:
|
||||
// revokeCount is at least 3.
|
||||
}
|
||||
for uri, ok := range revokedAuthz {
|
||||
if !ok {
|
||||
t.Errorf("%q authorization was not revoked", uri)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHTTPHandlerDefaultFallback(t *testing.T) {
|
||||
tt := []struct {
|
||||
method, url string
|
||||
@@ -571,7 +832,7 @@ func TestHTTPHandlerDefaultFallback(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAccountKeyCache(t *testing.T) {
|
||||
m := Manager{Cache: newMemCache()}
|
||||
m := Manager{Cache: newMemCache(t)}
|
||||
ctx := context.Background()
|
||||
k1, err := m.accountKey(ctx)
|
||||
if err != nil {
|
||||
@@ -587,36 +848,57 @@ func TestAccountKeyCache(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCache(t *testing.T) {
|
||||
privKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
ecdsaKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tmpl := &x509.Certificate{
|
||||
SerialNumber: big.NewInt(1),
|
||||
Subject: pkix.Name{CommonName: "example.org"},
|
||||
NotAfter: time.Now().Add(time.Hour),
|
||||
}
|
||||
pub, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, &privKey.PublicKey, privKey)
|
||||
cert, err := dummyCert(ecdsaKey.Public(), exampleDomain)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tlscert := &tls.Certificate{
|
||||
Certificate: [][]byte{pub},
|
||||
PrivateKey: privKey,
|
||||
ecdsaCert := &tls.Certificate{
|
||||
Certificate: [][]byte{cert},
|
||||
PrivateKey: ecdsaKey,
|
||||
}
|
||||
|
||||
man := &Manager{Cache: newMemCache()}
|
||||
rsaKey, err := rsa.GenerateKey(rand.Reader, 512)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cert, err = dummyCert(rsaKey.Public(), exampleDomain)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rsaCert := &tls.Certificate{
|
||||
Certificate: [][]byte{cert},
|
||||
PrivateKey: rsaKey,
|
||||
}
|
||||
|
||||
man := &Manager{Cache: newMemCache(t)}
|
||||
defer man.stopRenew()
|
||||
ctx := context.Background()
|
||||
if err := man.cachePut(ctx, "example.org", tlscert); err != nil {
|
||||
|
||||
if err := man.cachePut(ctx, exampleCertKey, ecdsaCert); err != nil {
|
||||
t.Fatalf("man.cachePut: %v", err)
|
||||
}
|
||||
res, err := man.cacheGet(ctx, "example.org")
|
||||
if err := man.cachePut(ctx, exampleCertKeyRSA, rsaCert); err != nil {
|
||||
t.Fatalf("man.cachePut: %v", err)
|
||||
}
|
||||
|
||||
res, err := man.cacheGet(ctx, exampleCertKey)
|
||||
if err != nil {
|
||||
t.Fatalf("man.cacheGet: %v", err)
|
||||
}
|
||||
if res == nil {
|
||||
t.Fatal("res is nil")
|
||||
if res == nil || !bytes.Equal(res.Certificate[0], ecdsaCert.Certificate[0]) {
|
||||
t.Errorf("man.cacheGet = %+v; want %+v", res, ecdsaCert)
|
||||
}
|
||||
|
||||
res, err = man.cacheGet(ctx, exampleCertKeyRSA)
|
||||
if err != nil {
|
||||
t.Fatalf("man.cacheGet: %v", err)
|
||||
}
|
||||
if res == nil || !bytes.Equal(res.Certificate[0], rsaCert.Certificate[0]) {
|
||||
t.Errorf("man.cacheGet = %+v; want %+v", res, rsaCert)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -680,26 +962,28 @@ func TestValidCert(t *testing.T) {
|
||||
}
|
||||
|
||||
tt := []struct {
|
||||
domain string
|
||||
key crypto.Signer
|
||||
cert [][]byte
|
||||
ok bool
|
||||
ck certKey
|
||||
key crypto.Signer
|
||||
cert [][]byte
|
||||
ok bool
|
||||
}{
|
||||
{"example.org", key1, [][]byte{cert1}, true},
|
||||
{"example.org", key3, [][]byte{cert3}, true},
|
||||
{"example.org", key1, [][]byte{cert1, cert2, cert3}, true},
|
||||
{"example.org", key1, [][]byte{cert1, {1}}, false},
|
||||
{"example.org", key1, [][]byte{{1}}, false},
|
||||
{"example.org", key1, [][]byte{cert2}, false},
|
||||
{"example.org", key2, [][]byte{cert1}, false},
|
||||
{"example.org", key1, [][]byte{cert3}, false},
|
||||
{"example.org", key3, [][]byte{cert1}, false},
|
||||
{"example.net", key1, [][]byte{cert1}, false},
|
||||
{"example.org", key1, [][]byte{early}, false},
|
||||
{"example.org", key1, [][]byte{expired}, false},
|
||||
{certKey{domain: "example.org"}, key1, [][]byte{cert1}, true},
|
||||
{certKey{domain: "example.org", isRSA: true}, key3, [][]byte{cert3}, true},
|
||||
{certKey{domain: "example.org"}, key1, [][]byte{cert1, cert2, cert3}, true},
|
||||
{certKey{domain: "example.org"}, key1, [][]byte{cert1, {1}}, false},
|
||||
{certKey{domain: "example.org"}, key1, [][]byte{{1}}, false},
|
||||
{certKey{domain: "example.org"}, key1, [][]byte{cert2}, false},
|
||||
{certKey{domain: "example.org"}, key2, [][]byte{cert1}, false},
|
||||
{certKey{domain: "example.org"}, key1, [][]byte{cert3}, false},
|
||||
{certKey{domain: "example.org"}, key3, [][]byte{cert1}, false},
|
||||
{certKey{domain: "example.net"}, key1, [][]byte{cert1}, false},
|
||||
{certKey{domain: "example.org"}, key1, [][]byte{early}, false},
|
||||
{certKey{domain: "example.org"}, key1, [][]byte{expired}, false},
|
||||
{certKey{domain: "example.org", isRSA: true}, key1, [][]byte{cert1}, false},
|
||||
{certKey{domain: "example.org"}, key3, [][]byte{cert3}, false},
|
||||
}
|
||||
for i, test := range tt {
|
||||
leaf, err := validCert(test.domain, test.cert, test.key)
|
||||
leaf, err := validCert(test.ck, test.cert, test.key)
|
||||
if err != nil && test.ok {
|
||||
t.Errorf("%d: err = %v", i, err)
|
||||
}
|
||||
@@ -748,10 +1032,99 @@ func TestManagerGetCertificateBogusSNI(t *testing.T) {
|
||||
{"fo.o", "cache.Get of fo.o"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
_, err := m.GetCertificate(&tls.ClientHelloInfo{ServerName: tt.name})
|
||||
_, err := m.GetCertificate(clientHelloInfo(tt.name, true))
|
||||
got := fmt.Sprint(err)
|
||||
if got != tt.wantErr {
|
||||
t.Errorf("GetCertificate(SNI = %q) = %q; want %q", tt.name, got, tt.wantErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCertRequest(t *testing.T) {
|
||||
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// An extension from RFC7633. Any will do.
|
||||
ext := pkix.Extension{
|
||||
Id: asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1},
|
||||
Value: []byte("dummy"),
|
||||
}
|
||||
b, err := certRequest(key, "example.org", []pkix.Extension{ext}, "san.example.org")
|
||||
if err != nil {
|
||||
t.Fatalf("certRequest: %v", err)
|
||||
}
|
||||
r, err := x509.ParseCertificateRequest(b)
|
||||
if err != nil {
|
||||
t.Fatalf("ParseCertificateRequest: %v", err)
|
||||
}
|
||||
var found bool
|
||||
for _, v := range r.Extensions {
|
||||
if v.Id.Equal(ext.Id) {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Errorf("want %v in Extensions: %v", ext, r.Extensions)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSupportsECDSA(t *testing.T) {
|
||||
tests := []struct {
|
||||
CipherSuites []uint16
|
||||
SignatureSchemes []tls.SignatureScheme
|
||||
SupportedCurves []tls.CurveID
|
||||
ecdsaOk bool
|
||||
}{
|
||||
{[]uint16{
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
}, nil, nil, false},
|
||||
{[]uint16{
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
}, nil, nil, true},
|
||||
|
||||
// SignatureSchemes limits, not extends, CipherSuites
|
||||
{[]uint16{
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
}, []tls.SignatureScheme{
|
||||
tls.PKCS1WithSHA256, tls.ECDSAWithP256AndSHA256,
|
||||
}, nil, false},
|
||||
{[]uint16{
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
}, []tls.SignatureScheme{
|
||||
tls.PKCS1WithSHA256,
|
||||
}, nil, false},
|
||||
{[]uint16{
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
}, []tls.SignatureScheme{
|
||||
tls.PKCS1WithSHA256, tls.ECDSAWithP256AndSHA256,
|
||||
}, nil, true},
|
||||
|
||||
{[]uint16{
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
}, []tls.SignatureScheme{
|
||||
tls.PKCS1WithSHA256, tls.ECDSAWithP256AndSHA256,
|
||||
}, []tls.CurveID{
|
||||
tls.CurveP521,
|
||||
}, false},
|
||||
{[]uint16{
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
}, []tls.SignatureScheme{
|
||||
tls.PKCS1WithSHA256, tls.ECDSAWithP256AndSHA256,
|
||||
}, []tls.CurveID{
|
||||
tls.CurveP256,
|
||||
tls.CurveP521,
|
||||
}, true},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
result := supportsECDSA(&tls.ClientHelloInfo{
|
||||
CipherSuites: tt.CipherSuites,
|
||||
SignatureSchemes: tt.SignatureSchemes,
|
||||
SupportedCurves: tt.SupportedCurves,
|
||||
})
|
||||
if result != tt.ecdsaOk {
|
||||
t.Errorf("%d: supportsECDSA = %v; want %v", i, result, tt.ecdsaOk)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
6
vendor/golang.org/x/crypto/acme/autocert/cache.go
generated
vendored
6
vendor/golang.org/x/crypto/acme/autocert/cache.go
generated
vendored
@@ -16,10 +16,10 @@ import (
|
||||
var ErrCacheMiss = errors.New("acme/autocert: certificate cache miss")
|
||||
|
||||
// Cache is used by Manager to store and retrieve previously obtained certificates
|
||||
// as opaque data.
|
||||
// and other account data as opaque blobs.
|
||||
//
|
||||
// The key argument of the methods refers to a domain name but need not be an FQDN.
|
||||
// Cache implementations should not rely on the key naming pattern.
|
||||
// Cache implementations should not rely on the key naming pattern. Keys can
|
||||
// include any printable ASCII characters, except the following: \/:*?"<>|
|
||||
type Cache interface {
|
||||
// Get returns a certificate data for the specified key.
|
||||
// If there's no such key, Get returns ErrCacheMiss.
|
||||
|
||||
14
vendor/golang.org/x/crypto/acme/autocert/renewal.go
generated
vendored
14
vendor/golang.org/x/crypto/acme/autocert/renewal.go
generated
vendored
@@ -17,9 +17,9 @@ const renewJitter = time.Hour
|
||||
// domainRenewal tracks the state used by the periodic timers
|
||||
// renewing a single domain's cert.
|
||||
type domainRenewal struct {
|
||||
m *Manager
|
||||
domain string
|
||||
key crypto.Signer
|
||||
m *Manager
|
||||
ck certKey
|
||||
key crypto.Signer
|
||||
|
||||
timerMu sync.Mutex
|
||||
timer *time.Timer
|
||||
@@ -77,7 +77,7 @@ func (dr *domainRenewal) updateState(state *certState) {
|
||||
dr.m.stateMu.Lock()
|
||||
defer dr.m.stateMu.Unlock()
|
||||
dr.key = state.key
|
||||
dr.m.state[dr.domain] = state
|
||||
dr.m.state[dr.ck] = state
|
||||
}
|
||||
|
||||
// do is similar to Manager.createCert but it doesn't lock a Manager.state item.
|
||||
@@ -91,7 +91,7 @@ func (dr *domainRenewal) updateState(state *certState) {
|
||||
func (dr *domainRenewal) do(ctx context.Context) (time.Duration, error) {
|
||||
// a race is likely unavoidable in a distributed environment
|
||||
// but we try nonetheless
|
||||
if tlscert, err := dr.m.cacheGet(ctx, dr.domain); err == nil {
|
||||
if tlscert, err := dr.m.cacheGet(ctx, dr.ck); err == nil {
|
||||
next := dr.next(tlscert.Leaf.NotAfter)
|
||||
if next > dr.m.renewBefore()+renewJitter {
|
||||
signer, ok := tlscert.PrivateKey.(crypto.Signer)
|
||||
@@ -107,7 +107,7 @@ func (dr *domainRenewal) do(ctx context.Context) (time.Duration, error) {
|
||||
}
|
||||
}
|
||||
|
||||
der, leaf, err := dr.m.authorizedCert(ctx, dr.key, dr.domain)
|
||||
der, leaf, err := dr.m.authorizedCert(ctx, dr.key, dr.ck)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -120,7 +120,7 @@ func (dr *domainRenewal) do(ctx context.Context) (time.Duration, error) {
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if err := dr.m.cachePut(ctx, dr.domain, tlscert); err != nil {
|
||||
if err := dr.m.cachePut(ctx, dr.ck, tlscert); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
dr.updateState(state)
|
||||
|
||||
72
vendor/golang.org/x/crypto/acme/autocert/renewal_test.go
generated
vendored
72
vendor/golang.org/x/crypto/acme/autocert/renewal_test.go
generated
vendored
@@ -48,8 +48,6 @@ func TestRenewalNext(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRenewFromCache(t *testing.T) {
|
||||
const domain = "example.org"
|
||||
|
||||
// ACME CA server stub
|
||||
var ca *httptest.Server
|
||||
ca = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -84,7 +82,7 @@ func TestRenewFromCache(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("new-cert: CSR: %v", err)
|
||||
}
|
||||
der, err := dummyCert(csr.PublicKey, domain)
|
||||
der, err := dummyCert(csr.PublicKey, exampleDomain)
|
||||
if err != nil {
|
||||
t.Fatalf("new-cert: dummyCert: %v", err)
|
||||
}
|
||||
@@ -105,30 +103,28 @@ func TestRenewFromCache(t *testing.T) {
|
||||
}))
|
||||
defer ca.Close()
|
||||
|
||||
// use EC key to run faster on 386
|
||||
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
man := &Manager{
|
||||
Prompt: AcceptTOS,
|
||||
Cache: newMemCache(),
|
||||
Cache: newMemCache(t),
|
||||
RenewBefore: 24 * time.Hour,
|
||||
Client: &acme.Client{
|
||||
Key: key,
|
||||
DirectoryURL: ca.URL,
|
||||
},
|
||||
}
|
||||
defer man.stopRenew()
|
||||
|
||||
// cache an almost expired cert
|
||||
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
now := time.Now()
|
||||
cert, err := dateDummyCert(key.Public(), now.Add(-2*time.Hour), now.Add(time.Minute), domain)
|
||||
cert, err := dateDummyCert(key.Public(), now.Add(-2*time.Hour), now.Add(time.Minute), exampleDomain)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tlscert := &tls.Certificate{PrivateKey: key, Certificate: [][]byte{cert}}
|
||||
if err := man.cachePut(context.Background(), domain, tlscert); err != nil {
|
||||
if err := man.cachePut(context.Background(), exampleCertKey, tlscert); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -152,7 +148,7 @@ func TestRenewFromCache(t *testing.T) {
|
||||
|
||||
// ensure the new cert is cached
|
||||
after := time.Now().Add(future)
|
||||
tlscert, err := man.cacheGet(context.Background(), domain)
|
||||
tlscert, err := man.cacheGet(context.Background(), exampleCertKey)
|
||||
if err != nil {
|
||||
t.Fatalf("man.cacheGet: %v", err)
|
||||
}
|
||||
@@ -163,9 +159,9 @@ func TestRenewFromCache(t *testing.T) {
|
||||
// verify the old cert is also replaced in memory
|
||||
man.stateMu.Lock()
|
||||
defer man.stateMu.Unlock()
|
||||
s := man.state[domain]
|
||||
s := man.state[exampleCertKey]
|
||||
if s == nil {
|
||||
t.Fatalf("m.state[%q] is nil", domain)
|
||||
t.Fatalf("m.state[%q] is nil", exampleCertKey)
|
||||
}
|
||||
tlscert, err = s.tlscert()
|
||||
if err != nil {
|
||||
@@ -177,7 +173,7 @@ func TestRenewFromCache(t *testing.T) {
|
||||
}
|
||||
|
||||
// trigger renew
|
||||
hello := &tls.ClientHelloInfo{ServerName: domain}
|
||||
hello := clientHelloInfo(exampleDomain, true)
|
||||
if _, err := man.GetCertificate(hello); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -191,19 +187,11 @@ func TestRenewFromCache(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRenewFromCacheAlreadyRenewed(t *testing.T) {
|
||||
const domain = "example.org"
|
||||
|
||||
// use EC key to run faster on 386
|
||||
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
man := &Manager{
|
||||
Prompt: AcceptTOS,
|
||||
Cache: newMemCache(),
|
||||
Cache: newMemCache(t),
|
||||
RenewBefore: 24 * time.Hour,
|
||||
Client: &acme.Client{
|
||||
Key: key,
|
||||
DirectoryURL: "invalid",
|
||||
},
|
||||
}
|
||||
@@ -215,38 +203,42 @@ func TestRenewFromCacheAlreadyRenewed(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
now := time.Now()
|
||||
newCert, err := dateDummyCert(newKey.Public(), now.Add(-2*time.Hour), now.Add(time.Hour*24*90), domain)
|
||||
newCert, err := dateDummyCert(newKey.Public(), now.Add(-2*time.Hour), now.Add(time.Hour*24*90), exampleDomain)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
newLeaf, err := validCert(domain, [][]byte{newCert}, newKey)
|
||||
newLeaf, err := validCert(exampleCertKey, [][]byte{newCert}, newKey)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
newTLSCert := &tls.Certificate{PrivateKey: newKey, Certificate: [][]byte{newCert}, Leaf: newLeaf}
|
||||
if err := man.cachePut(context.Background(), domain, newTLSCert); err != nil {
|
||||
if err := man.cachePut(context.Background(), exampleCertKey, newTLSCert); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// set internal state to an almost expired cert
|
||||
oldCert, err := dateDummyCert(key.Public(), now.Add(-2*time.Hour), now.Add(time.Minute), domain)
|
||||
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
oldLeaf, err := validCert(domain, [][]byte{oldCert}, key)
|
||||
oldCert, err := dateDummyCert(key.Public(), now.Add(-2*time.Hour), now.Add(time.Minute), exampleDomain)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
oldLeaf, err := validCert(exampleCertKey, [][]byte{oldCert}, key)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
man.stateMu.Lock()
|
||||
if man.state == nil {
|
||||
man.state = make(map[string]*certState)
|
||||
man.state = make(map[certKey]*certState)
|
||||
}
|
||||
s := &certState{
|
||||
key: key,
|
||||
cert: [][]byte{oldCert},
|
||||
leaf: oldLeaf,
|
||||
}
|
||||
man.state[domain] = s
|
||||
man.state[exampleCertKey] = s
|
||||
man.stateMu.Unlock()
|
||||
|
||||
// veriy the renewal accepted the newer cached cert
|
||||
@@ -267,7 +259,7 @@ func TestRenewFromCacheAlreadyRenewed(t *testing.T) {
|
||||
}
|
||||
|
||||
// ensure the cached cert was not modified
|
||||
tlscert, err := man.cacheGet(context.Background(), domain)
|
||||
tlscert, err := man.cacheGet(context.Background(), exampleCertKey)
|
||||
if err != nil {
|
||||
t.Fatalf("man.cacheGet: %v", err)
|
||||
}
|
||||
@@ -278,9 +270,9 @@ func TestRenewFromCacheAlreadyRenewed(t *testing.T) {
|
||||
// verify the old cert is also replaced in memory
|
||||
man.stateMu.Lock()
|
||||
defer man.stateMu.Unlock()
|
||||
s := man.state[domain]
|
||||
s := man.state[exampleCertKey]
|
||||
if s == nil {
|
||||
t.Fatalf("m.state[%q] is nil", domain)
|
||||
t.Fatalf("m.state[%q] is nil", exampleCertKey)
|
||||
}
|
||||
stateKey := s.key.Public().(*ecdsa.PublicKey)
|
||||
if stateKey.X.Cmp(newKey.X) != 0 || stateKey.Y.Cmp(newKey.Y) != 0 {
|
||||
@@ -295,9 +287,9 @@ func TestRenewFromCacheAlreadyRenewed(t *testing.T) {
|
||||
}
|
||||
|
||||
// verify the private key is replaced in the renewal state
|
||||
r := man.renewal[domain]
|
||||
r := man.renewal[exampleCertKey]
|
||||
if r == nil {
|
||||
t.Fatalf("m.renewal[%q] is nil", domain)
|
||||
t.Fatalf("m.renewal[%q] is nil", exampleCertKey)
|
||||
}
|
||||
renewalKey := r.key.Public().(*ecdsa.PublicKey)
|
||||
if renewalKey.X.Cmp(newKey.X) != 0 || renewalKey.Y.Cmp(newKey.Y) != 0 {
|
||||
@@ -307,7 +299,7 @@ func TestRenewFromCacheAlreadyRenewed(t *testing.T) {
|
||||
}
|
||||
|
||||
// assert the expiring cert is returned from state
|
||||
hello := &tls.ClientHelloInfo{ServerName: domain}
|
||||
hello := clientHelloInfo(exampleDomain, true)
|
||||
tlscert, err := man.GetCertificate(hello)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -317,7 +309,7 @@ func TestRenewFromCacheAlreadyRenewed(t *testing.T) {
|
||||
}
|
||||
|
||||
// trigger renew
|
||||
go man.renew(domain, s.key, s.leaf.NotAfter)
|
||||
go man.renew(exampleCertKey, s.key, s.leaf.NotAfter)
|
||||
|
||||
// wait for renew loop
|
||||
select {
|
||||
@@ -325,7 +317,7 @@ func TestRenewFromCacheAlreadyRenewed(t *testing.T) {
|
||||
t.Fatal("renew took too long to occur")
|
||||
case <-done:
|
||||
// assert the new cert is returned from state after renew
|
||||
hello := &tls.ClientHelloInfo{ServerName: domain}
|
||||
hello := clientHelloInfo(exampleDomain, true)
|
||||
tlscert, err := man.GetCertificate(hello)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
||||
276
vendor/golang.org/x/crypto/acme/http.go
generated
vendored
Normal file
276
vendor/golang.org/x/crypto/acme/http.go
generated
vendored
Normal file
@@ -0,0 +1,276 @@
|
||||
// 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 acme
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto"
|
||||
"crypto/rand"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// retryTimer encapsulates common logic for retrying unsuccessful requests.
|
||||
// It is not safe for concurrent use.
|
||||
type retryTimer struct {
|
||||
// backoffFn provides backoff delay sequence for retries.
|
||||
// See Client.RetryBackoff doc comment.
|
||||
backoffFn func(n int, r *http.Request, res *http.Response) time.Duration
|
||||
// n is the current retry attempt.
|
||||
n int
|
||||
}
|
||||
|
||||
func (t *retryTimer) inc() {
|
||||
t.n++
|
||||
}
|
||||
|
||||
// backoff pauses the current goroutine as described in Client.RetryBackoff.
|
||||
func (t *retryTimer) backoff(ctx context.Context, r *http.Request, res *http.Response) error {
|
||||
d := t.backoffFn(t.n, r, res)
|
||||
if d <= 0 {
|
||||
return fmt.Errorf("acme: no more retries for %s; tried %d time(s)", r.URL, t.n)
|
||||
}
|
||||
wakeup := time.NewTimer(d)
|
||||
defer wakeup.Stop()
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case <-wakeup.C:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) retryTimer() *retryTimer {
|
||||
f := c.RetryBackoff
|
||||
if f == nil {
|
||||
f = defaultBackoff
|
||||
}
|
||||
return &retryTimer{backoffFn: f}
|
||||
}
|
||||
|
||||
// defaultBackoff provides default Client.RetryBackoff implementation
|
||||
// using a truncated exponential backoff algorithm,
|
||||
// as described in Client.RetryBackoff.
|
||||
//
|
||||
// The n argument is always bounded between 1 and 30.
|
||||
// The returned value is always greater than 0.
|
||||
func defaultBackoff(n int, r *http.Request, res *http.Response) time.Duration {
|
||||
const max = 10 * time.Second
|
||||
var jitter time.Duration
|
||||
if x, err := rand.Int(rand.Reader, big.NewInt(1000)); err == nil {
|
||||
// Set the minimum to 1ms to avoid a case where
|
||||
// an invalid Retry-After value is parsed into 0 below,
|
||||
// resulting in the 0 returned value which would unintentionally
|
||||
// stop the retries.
|
||||
jitter = (1 + time.Duration(x.Int64())) * time.Millisecond
|
||||
}
|
||||
if v, ok := res.Header["Retry-After"]; ok {
|
||||
return retryAfter(v[0]) + jitter
|
||||
}
|
||||
|
||||
if n < 1 {
|
||||
n = 1
|
||||
}
|
||||
if n > 30 {
|
||||
n = 30
|
||||
}
|
||||
d := time.Duration(1<<uint(n-1))*time.Second + jitter
|
||||
if d > max {
|
||||
return max
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
// retryAfter parses a Retry-After HTTP header value,
|
||||
// trying to convert v into an int (seconds) or use http.ParseTime otherwise.
|
||||
// It returns zero value if v cannot be parsed.
|
||||
func retryAfter(v string) time.Duration {
|
||||
if i, err := strconv.Atoi(v); err == nil {
|
||||
return time.Duration(i) * time.Second
|
||||
}
|
||||
t, err := http.ParseTime(v)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return t.Sub(timeNow())
|
||||
}
|
||||
|
||||
// resOkay is a function that reports whether the provided response is okay.
|
||||
// It is expected to keep the response body unread.
|
||||
type resOkay func(*http.Response) bool
|
||||
|
||||
// wantStatus returns a function which reports whether the code
|
||||
// matches the status code of a response.
|
||||
func wantStatus(codes ...int) resOkay {
|
||||
return func(res *http.Response) bool {
|
||||
for _, code := range codes {
|
||||
if code == res.StatusCode {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// get issues an unsigned GET request to the specified URL.
|
||||
// It returns a non-error value only when ok reports true.
|
||||
//
|
||||
// get retries unsuccessful attempts according to c.RetryBackoff
|
||||
// until the context is done or a non-retriable error is received.
|
||||
func (c *Client) get(ctx context.Context, url string, ok resOkay) (*http.Response, error) {
|
||||
retry := c.retryTimer()
|
||||
for {
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res, err := c.doNoRetry(ctx, req)
|
||||
switch {
|
||||
case err != nil:
|
||||
return nil, err
|
||||
case ok(res):
|
||||
return res, nil
|
||||
case isRetriable(res.StatusCode):
|
||||
res.Body.Close()
|
||||
retry.inc()
|
||||
if err := retry.backoff(ctx, req, res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
default:
|
||||
defer res.Body.Close()
|
||||
return nil, responseError(res)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// post issues a signed POST request in JWS format using the provided key
|
||||
// to the specified URL.
|
||||
// It returns a non-error value only when ok reports true.
|
||||
//
|
||||
// post retries unsuccessful attempts according to c.RetryBackoff
|
||||
// until the context is done or a non-retriable error is received.
|
||||
// It uses postNoRetry to make individual requests.
|
||||
func (c *Client) post(ctx context.Context, key crypto.Signer, url string, body interface{}, ok resOkay) (*http.Response, error) {
|
||||
retry := c.retryTimer()
|
||||
for {
|
||||
res, req, err := c.postNoRetry(ctx, key, url, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if ok(res) {
|
||||
return res, nil
|
||||
}
|
||||
err = responseError(res)
|
||||
res.Body.Close()
|
||||
switch {
|
||||
// Check for bad nonce before isRetriable because it may have been returned
|
||||
// with an unretriable response code such as 400 Bad Request.
|
||||
case isBadNonce(err):
|
||||
// Consider any previously stored nonce values to be invalid.
|
||||
c.clearNonces()
|
||||
case !isRetriable(res.StatusCode):
|
||||
return nil, err
|
||||
}
|
||||
retry.inc()
|
||||
if err := retry.backoff(ctx, req, res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// postNoRetry signs the body with the given key and POSTs it to the provided url.
|
||||
// The body argument must be JSON-serializable.
|
||||
// It is used by c.post to retry unsuccessful attempts.
|
||||
func (c *Client) postNoRetry(ctx context.Context, key crypto.Signer, url string, body interface{}) (*http.Response, *http.Request, error) {
|
||||
nonce, err := c.popNonce(ctx, url)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
b, err := jwsEncodeJSON(body, key, nonce)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
req, err := http.NewRequest("POST", url, bytes.NewReader(b))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/jose+json")
|
||||
res, err := c.doNoRetry(ctx, req)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
c.addNonce(res.Header)
|
||||
return res, req, nil
|
||||
}
|
||||
|
||||
// doNoRetry issues a request req, replacing its context (if any) with ctx.
|
||||
func (c *Client) doNoRetry(ctx context.Context, req *http.Request) (*http.Response, error) {
|
||||
res, err := c.httpClient().Do(req.WithContext(ctx))
|
||||
if err != nil {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
// Prefer the unadorned context error.
|
||||
// (The acme package had tests assuming this, previously from ctxhttp's
|
||||
// behavior, predating net/http supporting contexts natively)
|
||||
// TODO(bradfitz): reconsider this in the future. But for now this
|
||||
// requires no test updates.
|
||||
return nil, ctx.Err()
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (c *Client) httpClient() *http.Client {
|
||||
if c.HTTPClient != nil {
|
||||
return c.HTTPClient
|
||||
}
|
||||
return http.DefaultClient
|
||||
}
|
||||
|
||||
// isBadNonce reports whether err is an ACME "badnonce" error.
|
||||
func isBadNonce(err error) bool {
|
||||
// According to the spec badNonce is urn:ietf:params:acme:error:badNonce.
|
||||
// However, ACME servers in the wild return their versions of the error.
|
||||
// See https://tools.ietf.org/html/draft-ietf-acme-acme-02#section-5.4
|
||||
// and https://github.com/letsencrypt/boulder/blob/0e07eacb/docs/acme-divergences.md#section-66.
|
||||
ae, ok := err.(*Error)
|
||||
return ok && strings.HasSuffix(strings.ToLower(ae.ProblemType), ":badnonce")
|
||||
}
|
||||
|
||||
// isRetriable reports whether a request can be retried
|
||||
// based on the response status code.
|
||||
//
|
||||
// Note that a "bad nonce" error is returned with a non-retriable 400 Bad Request code.
|
||||
// Callers should parse the response and check with isBadNonce.
|
||||
func isRetriable(code int) bool {
|
||||
return code <= 399 || code >= 500 || code == http.StatusTooManyRequests
|
||||
}
|
||||
|
||||
// responseError creates an error of Error type from resp.
|
||||
func responseError(resp *http.Response) error {
|
||||
// don't care if ReadAll returns an error:
|
||||
// json.Unmarshal will fail in that case anyway
|
||||
b, _ := ioutil.ReadAll(resp.Body)
|
||||
e := &wireError{Status: resp.StatusCode}
|
||||
if err := json.Unmarshal(b, e); err != nil {
|
||||
// this is not a regular error response:
|
||||
// populate detail with anything we received,
|
||||
// e.Status will already contain HTTP response code value
|
||||
e.Detail = string(b)
|
||||
if e.Detail == "" {
|
||||
e.Detail = resp.Status
|
||||
}
|
||||
}
|
||||
return e.error(resp.Header)
|
||||
}
|
||||
158
vendor/golang.org/x/crypto/acme/http_test.go
generated
vendored
Normal file
158
vendor/golang.org/x/crypto/acme/http_test.go
generated
vendored
Normal file
@@ -0,0 +1,158 @@
|
||||
// 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 acme
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestDefaultBackoff(t *testing.T) {
|
||||
tt := []struct {
|
||||
nretry int
|
||||
retryAfter string // Retry-After header
|
||||
out time.Duration // expected min; max = min + jitter
|
||||
}{
|
||||
{-1, "", time.Second}, // verify the lower bound is 1
|
||||
{0, "", time.Second}, // verify the lower bound is 1
|
||||
{100, "", 10 * time.Second}, // verify the ceiling
|
||||
{1, "3600", time.Hour}, // verify the header value is used
|
||||
{1, "", 1 * time.Second},
|
||||
{2, "", 2 * time.Second},
|
||||
{3, "", 4 * time.Second},
|
||||
{4, "", 8 * time.Second},
|
||||
}
|
||||
for i, test := range tt {
|
||||
r := httptest.NewRequest("GET", "/", nil)
|
||||
resp := &http.Response{Header: http.Header{}}
|
||||
if test.retryAfter != "" {
|
||||
resp.Header.Set("Retry-After", test.retryAfter)
|
||||
}
|
||||
d := defaultBackoff(test.nretry, r, resp)
|
||||
max := test.out + time.Second // + max jitter
|
||||
if d < test.out || max < d {
|
||||
t.Errorf("%d: defaultBackoff(%v) = %v; want between %v and %v", i, test.nretry, d, test.out, max)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestErrorResponse(t *testing.T) {
|
||||
s := `{
|
||||
"status": 400,
|
||||
"type": "urn:acme:error:xxx",
|
||||
"detail": "text"
|
||||
}`
|
||||
res := &http.Response{
|
||||
StatusCode: 400,
|
||||
Status: "400 Bad Request",
|
||||
Body: ioutil.NopCloser(strings.NewReader(s)),
|
||||
Header: http.Header{"X-Foo": {"bar"}},
|
||||
}
|
||||
err := responseError(res)
|
||||
v, ok := err.(*Error)
|
||||
if !ok {
|
||||
t.Fatalf("err = %+v (%T); want *Error type", err, err)
|
||||
}
|
||||
if v.StatusCode != 400 {
|
||||
t.Errorf("v.StatusCode = %v; want 400", v.StatusCode)
|
||||
}
|
||||
if v.ProblemType != "urn:acme:error:xxx" {
|
||||
t.Errorf("v.ProblemType = %q; want urn:acme:error:xxx", v.ProblemType)
|
||||
}
|
||||
if v.Detail != "text" {
|
||||
t.Errorf("v.Detail = %q; want text", v.Detail)
|
||||
}
|
||||
if !reflect.DeepEqual(v.Header, res.Header) {
|
||||
t.Errorf("v.Header = %+v; want %+v", v.Header, res.Header)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPostWithRetries(t *testing.T) {
|
||||
var count int
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
count++
|
||||
w.Header().Set("Replay-Nonce", fmt.Sprintf("nonce%d", count))
|
||||
if r.Method == "HEAD" {
|
||||
// We expect the client to do 2 head requests to fetch
|
||||
// nonces, one to start and another after getting badNonce
|
||||
return
|
||||
}
|
||||
|
||||
head, err := decodeJWSHead(r)
|
||||
if err != nil {
|
||||
t.Errorf("decodeJWSHead: %v", err)
|
||||
} else if head.Nonce == "" {
|
||||
t.Error("head.Nonce is empty")
|
||||
} else if head.Nonce == "nonce1" {
|
||||
// return a badNonce error to force the call to retry
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(`{"type":"urn:ietf:params:acme:error:badNonce"}`))
|
||||
return
|
||||
}
|
||||
// Make client.Authorize happy; we're not testing its result.
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
w.Write([]byte(`{"status":"valid"}`))
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
client := &Client{Key: testKey, dir: &Directory{AuthzURL: ts.URL}}
|
||||
// This call will fail with badNonce, causing a retry
|
||||
if _, err := client.Authorize(context.Background(), "example.com"); err != nil {
|
||||
t.Errorf("client.Authorize 1: %v", err)
|
||||
}
|
||||
if count != 4 {
|
||||
t.Errorf("total requests count: %d; want 4", count)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRetryBackoffArgs(t *testing.T) {
|
||||
const resCode = http.StatusInternalServerError
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Replay-Nonce", "test-nonce")
|
||||
w.WriteHeader(resCode)
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
// Canceled in backoff.
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
var nretry int
|
||||
backoff := func(n int, r *http.Request, res *http.Response) time.Duration {
|
||||
nretry++
|
||||
if n != nretry {
|
||||
t.Errorf("n = %d; want %d", n, nretry)
|
||||
}
|
||||
if nretry == 3 {
|
||||
cancel()
|
||||
}
|
||||
|
||||
if r == nil {
|
||||
t.Error("r is nil")
|
||||
}
|
||||
if res.StatusCode != resCode {
|
||||
t.Errorf("res.StatusCode = %d; want %d", res.StatusCode, resCode)
|
||||
}
|
||||
return time.Millisecond
|
||||
}
|
||||
|
||||
client := &Client{
|
||||
Key: testKey,
|
||||
RetryBackoff: backoff,
|
||||
dir: &Directory{AuthzURL: ts.URL},
|
||||
}
|
||||
if _, err := client.Authorize(ctx, "example.com"); err == nil {
|
||||
t.Error("err is nil")
|
||||
}
|
||||
if nretry != 3 {
|
||||
t.Errorf("nretry = %d; want 3", nretry)
|
||||
}
|
||||
}
|
||||
8
vendor/golang.org/x/crypto/acme/types.go
generated
vendored
8
vendor/golang.org/x/crypto/acme/types.go
generated
vendored
@@ -104,7 +104,7 @@ func RateLimit(err error) (time.Duration, bool) {
|
||||
if e.Header == nil {
|
||||
return 0, true
|
||||
}
|
||||
return retryAfter(e.Header.Get("Retry-After"), 0), true
|
||||
return retryAfter(e.Header.Get("Retry-After")), true
|
||||
}
|
||||
|
||||
// Account is a user account. It is associated with a private key.
|
||||
@@ -296,8 +296,8 @@ func (e *wireError) error(h http.Header) *Error {
|
||||
}
|
||||
}
|
||||
|
||||
// CertOption is an optional argument type for the TLSSNIxChallengeCert methods for
|
||||
// customizing a temporary certificate for TLS-SNI challenges.
|
||||
// CertOption is an optional argument type for the TLS ChallengeCert methods for
|
||||
// customizing a temporary certificate for TLS-based challenges.
|
||||
type CertOption interface {
|
||||
privateCertOpt()
|
||||
}
|
||||
@@ -317,7 +317,7 @@ func (*certOptKey) privateCertOpt() {}
|
||||
// WithTemplate creates an option for specifying a certificate template.
|
||||
// See x509.CreateCertificate for template usage details.
|
||||
//
|
||||
// In TLSSNIxChallengeCert methods, the template is also used as parent,
|
||||
// In TLS ChallengeCert methods, the template is also used as parent,
|
||||
// resulting in a self-signed certificate.
|
||||
// The DNSNames field of t is always overwritten for tls-sni challenge certs.
|
||||
func WithTemplate(t *x509.Certificate) CertOption {
|
||||
|
||||
9
vendor/golang.org/x/crypto/argon2/blamka_amd64.go
generated
vendored
9
vendor/golang.org/x/crypto/argon2/blamka_amd64.go
generated
vendored
@@ -6,12 +6,11 @@
|
||||
|
||||
package argon2
|
||||
|
||||
func init() {
|
||||
useSSE4 = supportsSSE4()
|
||||
}
|
||||
import "golang.org/x/sys/cpu"
|
||||
|
||||
//go:noescape
|
||||
func supportsSSE4() bool
|
||||
func init() {
|
||||
useSSE4 = cpu.X86.HasSSE41
|
||||
}
|
||||
|
||||
//go:noescape
|
||||
func mixBlocksSSE2(out, a, b, c *block)
|
||||
|
||||
9
vendor/golang.org/x/crypto/argon2/blamka_amd64.s
generated
vendored
9
vendor/golang.org/x/crypto/argon2/blamka_amd64.s
generated
vendored
@@ -241,12 +241,3 @@ loop:
|
||||
SUBQ $2, BP
|
||||
JA loop
|
||||
RET
|
||||
|
||||
// func supportsSSE4() bool
|
||||
TEXT ·supportsSSE4(SB), 4, $0-1
|
||||
MOVL $1, AX
|
||||
CPUID
|
||||
SHRL $19, CX // Bit 19 indicates SSE4 support
|
||||
ANDL $1, CX // CX != 0 if support SSE4
|
||||
MOVB CX, ret+0(FP)
|
||||
RET
|
||||
|
||||
68
vendor/golang.org/x/crypto/blake2b/blake2b.go
generated
vendored
68
vendor/golang.org/x/crypto/blake2b/blake2b.go
generated
vendored
@@ -92,6 +92,8 @@ func New256(key []byte) (hash.Hash, error) { return newDigest(Size256, key) }
|
||||
// values equal or greater than:
|
||||
// - 32 if BLAKE2b is used as a hash function (The key is zero bytes long).
|
||||
// - 16 if BLAKE2b is used as a MAC function (The key is at least 16 bytes long).
|
||||
// When the key is nil, the returned hash.Hash implements BinaryMarshaler
|
||||
// and BinaryUnmarshaler for state (de)serialization as documented by hash.Hash.
|
||||
func New(size int, key []byte) (hash.Hash, error) { return newDigest(size, key) }
|
||||
|
||||
func newDigest(hashSize int, key []byte) (*digest, error) {
|
||||
@@ -150,6 +152,50 @@ type digest struct {
|
||||
keyLen int
|
||||
}
|
||||
|
||||
const (
|
||||
magic = "b2b"
|
||||
marshaledSize = len(magic) + 8*8 + 2*8 + 1 + BlockSize + 1
|
||||
)
|
||||
|
||||
func (d *digest) MarshalBinary() ([]byte, error) {
|
||||
if d.keyLen != 0 {
|
||||
return nil, errors.New("crypto/blake2b: cannot marshal MACs")
|
||||
}
|
||||
b := make([]byte, 0, marshaledSize)
|
||||
b = append(b, magic...)
|
||||
for i := 0; i < 8; i++ {
|
||||
b = appendUint64(b, d.h[i])
|
||||
}
|
||||
b = appendUint64(b, d.c[0])
|
||||
b = appendUint64(b, d.c[1])
|
||||
// Maximum value for size is 64
|
||||
b = append(b, byte(d.size))
|
||||
b = append(b, d.block[:]...)
|
||||
b = append(b, byte(d.offset))
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func (d *digest) UnmarshalBinary(b []byte) error {
|
||||
if len(b) < len(magic) || string(b[:len(magic)]) != magic {
|
||||
return errors.New("crypto/blake2b: invalid hash state identifier")
|
||||
}
|
||||
if len(b) != marshaledSize {
|
||||
return errors.New("crypto/blake2b: invalid hash state size")
|
||||
}
|
||||
b = b[len(magic):]
|
||||
for i := 0; i < 8; i++ {
|
||||
b, d.h[i] = consumeUint64(b)
|
||||
}
|
||||
b, d.c[0] = consumeUint64(b)
|
||||
b, d.c[1] = consumeUint64(b)
|
||||
d.size = int(b[0])
|
||||
b = b[1:]
|
||||
copy(d.block[:], b[:BlockSize])
|
||||
b = b[BlockSize:]
|
||||
d.offset = int(b[0])
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *digest) BlockSize() int { return BlockSize }
|
||||
|
||||
func (d *digest) Size() int { return d.size }
|
||||
@@ -219,3 +265,25 @@ func (d *digest) finalize(hash *[Size]byte) {
|
||||
binary.LittleEndian.PutUint64(hash[8*i:], v)
|
||||
}
|
||||
}
|
||||
|
||||
func appendUint64(b []byte, x uint64) []byte {
|
||||
var a [8]byte
|
||||
binary.BigEndian.PutUint64(a[:], x)
|
||||
return append(b, a[:]...)
|
||||
}
|
||||
|
||||
func appendUint32(b []byte, x uint32) []byte {
|
||||
var a [4]byte
|
||||
binary.BigEndian.PutUint32(a[:], x)
|
||||
return append(b, a[:]...)
|
||||
}
|
||||
|
||||
func consumeUint64(b []byte) ([]byte, uint64) {
|
||||
x := binary.BigEndian.Uint64(b)
|
||||
return b[8:], x
|
||||
}
|
||||
|
||||
func consumeUint32(b []byte) ([]byte, uint32) {
|
||||
x := binary.BigEndian.Uint32(b)
|
||||
return b[4:], x
|
||||
}
|
||||
|
||||
26
vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.go
generated
vendored
26
vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.go
generated
vendored
@@ -6,21 +6,14 @@
|
||||
|
||||
package blake2b
|
||||
|
||||
import "golang.org/x/sys/cpu"
|
||||
|
||||
func init() {
|
||||
useAVX2 = supportsAVX2()
|
||||
useAVX = supportsAVX()
|
||||
useSSE4 = supportsSSE4()
|
||||
useAVX2 = cpu.X86.HasAVX2
|
||||
useAVX = cpu.X86.HasAVX
|
||||
useSSE4 = cpu.X86.HasSSE41
|
||||
}
|
||||
|
||||
//go:noescape
|
||||
func supportsSSE4() bool
|
||||
|
||||
//go:noescape
|
||||
func supportsAVX() bool
|
||||
|
||||
//go:noescape
|
||||
func supportsAVX2() bool
|
||||
|
||||
//go:noescape
|
||||
func hashBlocksAVX2(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
|
||||
|
||||
@@ -31,13 +24,14 @@ func hashBlocksAVX(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
|
||||
func hashBlocksSSE4(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
|
||||
|
||||
func hashBlocks(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) {
|
||||
if useAVX2 {
|
||||
switch {
|
||||
case useAVX2:
|
||||
hashBlocksAVX2(h, c, flag, blocks)
|
||||
} else if useAVX {
|
||||
case useAVX:
|
||||
hashBlocksAVX(h, c, flag, blocks)
|
||||
} else if useSSE4 {
|
||||
case useSSE4:
|
||||
hashBlocksSSE4(h, c, flag, blocks)
|
||||
} else {
|
||||
default:
|
||||
hashBlocksGeneric(h, c, flag, blocks)
|
||||
}
|
||||
}
|
||||
|
||||
12
vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.s
generated
vendored
12
vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.s
generated
vendored
@@ -748,15 +748,3 @@ noinc:
|
||||
|
||||
MOVQ BP, SP
|
||||
RET
|
||||
|
||||
// func supportsAVX2() bool
|
||||
TEXT ·supportsAVX2(SB), 4, $0-1
|
||||
MOVQ runtime·support_avx2(SB), AX
|
||||
MOVB AX, ret+0(FP)
|
||||
RET
|
||||
|
||||
// func supportsAVX() bool
|
||||
TEXT ·supportsAVX(SB), 4, $0-1
|
||||
MOVQ runtime·support_avx(SB), AX
|
||||
MOVB AX, ret+0(FP)
|
||||
RET
|
||||
|
||||
9
vendor/golang.org/x/crypto/blake2b/blake2b_amd64.go
generated
vendored
9
vendor/golang.org/x/crypto/blake2b/blake2b_amd64.go
generated
vendored
@@ -6,12 +6,11 @@
|
||||
|
||||
package blake2b
|
||||
|
||||
func init() {
|
||||
useSSE4 = supportsSSE4()
|
||||
}
|
||||
import "golang.org/x/sys/cpu"
|
||||
|
||||
//go:noescape
|
||||
func supportsSSE4() bool
|
||||
func init() {
|
||||
useSSE4 = cpu.X86.HasSSE41
|
||||
}
|
||||
|
||||
//go:noescape
|
||||
func hashBlocksSSE4(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
|
||||
|
||||
9
vendor/golang.org/x/crypto/blake2b/blake2b_amd64.s
generated
vendored
9
vendor/golang.org/x/crypto/blake2b/blake2b_amd64.s
generated
vendored
@@ -279,12 +279,3 @@ noinc:
|
||||
|
||||
MOVQ BP, SP
|
||||
RET
|
||||
|
||||
// func supportsSSE4() bool
|
||||
TEXT ·supportsSSE4(SB), 4, $0-1
|
||||
MOVL $1, AX
|
||||
CPUID
|
||||
SHRL $19, CX // Bit 19 indicates SSE4 support
|
||||
ANDL $1, CX // CX != 0 if support SSE4
|
||||
MOVB CX, ret+0(FP)
|
||||
RET
|
||||
|
||||
49
vendor/golang.org/x/crypto/blake2b/blake2b_test.go
generated
vendored
49
vendor/golang.org/x/crypto/blake2b/blake2b_test.go
generated
vendored
@@ -6,6 +6,7 @@ package blake2b
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"hash"
|
||||
@@ -69,6 +70,54 @@ func TestHashes2X(t *testing.T) {
|
||||
testHashes2X(t)
|
||||
}
|
||||
|
||||
func TestMarshal(t *testing.T) {
|
||||
input := make([]byte, 255)
|
||||
for i := range input {
|
||||
input[i] = byte(i)
|
||||
}
|
||||
for _, size := range []int{Size, Size256, Size384, 12, 25, 63} {
|
||||
for i := 0; i < 256; i++ {
|
||||
h, err := New(size, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("size=%d, len(input)=%d: error from New(%v, nil): %v", size, i, size, err)
|
||||
}
|
||||
h2, err := New(size, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("size=%d, len(input)=%d: error from New(%v, nil): %v", size, i, size, err)
|
||||
}
|
||||
|
||||
h.Write(input[:i/2])
|
||||
halfstate, err := h.(encoding.BinaryMarshaler).MarshalBinary()
|
||||
if err != nil {
|
||||
t.Fatalf("size=%d, len(input)=%d: could not marshal: %v", size, i, err)
|
||||
}
|
||||
err = h2.(encoding.BinaryUnmarshaler).UnmarshalBinary(halfstate)
|
||||
if err != nil {
|
||||
t.Fatalf("size=%d, len(input)=%d: could not unmarshal: %v", size, i, err)
|
||||
}
|
||||
|
||||
h.Write(input[i/2 : i])
|
||||
sum := h.Sum(nil)
|
||||
h2.Write(input[i/2 : i])
|
||||
sum2 := h2.Sum(nil)
|
||||
|
||||
if !bytes.Equal(sum, sum2) {
|
||||
t.Fatalf("size=%d, len(input)=%d: results do not match; sum = %v, sum2 = %v", size, i, sum, sum2)
|
||||
}
|
||||
|
||||
h3, err := New(size, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("size=%d, len(input)=%d: error from New(%v, nil): %v", size, i, size, err)
|
||||
}
|
||||
h3.Write(input[:i])
|
||||
sum3 := h3.Sum(nil)
|
||||
if !bytes.Equal(sum, sum3) {
|
||||
t.Fatalf("size=%d, len(input)=%d: sum = %v, want %v", size, i, sum, sum3)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testHashes(t *testing.T) {
|
||||
key, _ := hex.DecodeString("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f")
|
||||
|
||||
|
||||
57
vendor/golang.org/x/crypto/blake2s/blake2s.go
generated
vendored
57
vendor/golang.org/x/crypto/blake2s/blake2s.go
generated
vendored
@@ -49,6 +49,8 @@ func Sum256(data []byte) [Size]byte {
|
||||
|
||||
// New256 returns a new hash.Hash computing the BLAKE2s-256 checksum. A non-nil
|
||||
// key turns the hash into a MAC. The key must between zero and 32 bytes long.
|
||||
// When the key is nil, the returned hash.Hash implements BinaryMarshaler
|
||||
// and BinaryUnmarshaler for state (de)serialization as documented by hash.Hash.
|
||||
func New256(key []byte) (hash.Hash, error) { return newDigest(Size, key) }
|
||||
|
||||
// New128 returns a new hash.Hash computing the BLAKE2s-128 checksum given a
|
||||
@@ -120,6 +122,50 @@ type digest struct {
|
||||
keyLen int
|
||||
}
|
||||
|
||||
const (
|
||||
magic = "b2s"
|
||||
marshaledSize = len(magic) + 8*4 + 2*4 + 1 + BlockSize + 1
|
||||
)
|
||||
|
||||
func (d *digest) MarshalBinary() ([]byte, error) {
|
||||
if d.keyLen != 0 {
|
||||
return nil, errors.New("crypto/blake2s: cannot marshal MACs")
|
||||
}
|
||||
b := make([]byte, 0, marshaledSize)
|
||||
b = append(b, magic...)
|
||||
for i := 0; i < 8; i++ {
|
||||
b = appendUint32(b, d.h[i])
|
||||
}
|
||||
b = appendUint32(b, d.c[0])
|
||||
b = appendUint32(b, d.c[1])
|
||||
// Maximum value for size is 32
|
||||
b = append(b, byte(d.size))
|
||||
b = append(b, d.block[:]...)
|
||||
b = append(b, byte(d.offset))
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func (d *digest) UnmarshalBinary(b []byte) error {
|
||||
if len(b) < len(magic) || string(b[:len(magic)]) != magic {
|
||||
return errors.New("crypto/blake2s: invalid hash state identifier")
|
||||
}
|
||||
if len(b) != marshaledSize {
|
||||
return errors.New("crypto/blake2s: invalid hash state size")
|
||||
}
|
||||
b = b[len(magic):]
|
||||
for i := 0; i < 8; i++ {
|
||||
b, d.h[i] = consumeUint32(b)
|
||||
}
|
||||
b, d.c[0] = consumeUint32(b)
|
||||
b, d.c[1] = consumeUint32(b)
|
||||
d.size = int(b[0])
|
||||
b = b[1:]
|
||||
copy(d.block[:], b[:BlockSize])
|
||||
b = b[BlockSize:]
|
||||
d.offset = int(b[0])
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *digest) BlockSize() int { return BlockSize }
|
||||
|
||||
func (d *digest) Size() int { return d.size }
|
||||
@@ -185,3 +231,14 @@ func (d *digest) finalize(hash *[Size]byte) {
|
||||
binary.LittleEndian.PutUint32(hash[4*i:], v)
|
||||
}
|
||||
}
|
||||
|
||||
func appendUint32(b []byte, x uint32) []byte {
|
||||
var a [4]byte
|
||||
binary.BigEndian.PutUint32(a[:], x)
|
||||
return append(b, a[:]...)
|
||||
}
|
||||
|
||||
func consumeUint32(b []byte) ([]byte, uint32) {
|
||||
x := binary.BigEndian.Uint32(b)
|
||||
return b[4:], x
|
||||
}
|
||||
|
||||
19
vendor/golang.org/x/crypto/blake2s/blake2s_386.go
generated
vendored
19
vendor/golang.org/x/crypto/blake2s/blake2s_386.go
generated
vendored
@@ -6,18 +6,14 @@
|
||||
|
||||
package blake2s
|
||||
|
||||
import "golang.org/x/sys/cpu"
|
||||
|
||||
var (
|
||||
useSSE4 = false
|
||||
useSSSE3 = supportSSSE3()
|
||||
useSSE2 = supportSSE2()
|
||||
useSSSE3 = cpu.X86.HasSSSE3
|
||||
useSSE2 = cpu.X86.HasSSE2
|
||||
)
|
||||
|
||||
//go:noescape
|
||||
func supportSSE2() bool
|
||||
|
||||
//go:noescape
|
||||
func supportSSSE3() bool
|
||||
|
||||
//go:noescape
|
||||
func hashBlocksSSE2(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
|
||||
|
||||
@@ -25,11 +21,12 @@ func hashBlocksSSE2(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
|
||||
func hashBlocksSSSE3(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
|
||||
|
||||
func hashBlocks(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte) {
|
||||
if useSSSE3 {
|
||||
switch {
|
||||
case useSSSE3:
|
||||
hashBlocksSSSE3(h, c, flag, blocks)
|
||||
} else if useSSE2 {
|
||||
case useSSE2:
|
||||
hashBlocksSSE2(h, c, flag, blocks)
|
||||
} else {
|
||||
default:
|
||||
hashBlocksGeneric(h, c, flag, blocks)
|
||||
}
|
||||
}
|
||||
|
||||
25
vendor/golang.org/x/crypto/blake2s/blake2s_386.s
generated
vendored
25
vendor/golang.org/x/crypto/blake2s/blake2s_386.s
generated
vendored
@@ -433,28 +433,3 @@ loop:
|
||||
|
||||
MOVL BP, SP
|
||||
RET
|
||||
|
||||
// func supportSSSE3() bool
|
||||
TEXT ·supportSSSE3(SB), 4, $0-1
|
||||
MOVL $1, AX
|
||||
CPUID
|
||||
MOVL CX, BX
|
||||
ANDL $0x1, BX // supports SSE3
|
||||
JZ FALSE
|
||||
ANDL $0x200, CX // supports SSSE3
|
||||
JZ FALSE
|
||||
MOVB $1, ret+0(FP)
|
||||
RET
|
||||
|
||||
FALSE:
|
||||
MOVB $0, ret+0(FP)
|
||||
RET
|
||||
|
||||
// func supportSSE2() bool
|
||||
TEXT ·supportSSE2(SB), 4, $0-1
|
||||
MOVL $1, AX
|
||||
CPUID
|
||||
SHRL $26, DX
|
||||
ANDL $1, DX // DX != 0 if support SSE2
|
||||
MOVB DX, ret+0(FP)
|
||||
RET
|
||||
|
||||
23
vendor/golang.org/x/crypto/blake2s/blake2s_amd64.go
generated
vendored
23
vendor/golang.org/x/crypto/blake2s/blake2s_amd64.go
generated
vendored
@@ -6,18 +6,14 @@
|
||||
|
||||
package blake2s
|
||||
|
||||
import "golang.org/x/sys/cpu"
|
||||
|
||||
var (
|
||||
useSSE4 = supportSSE4()
|
||||
useSSSE3 = supportSSSE3()
|
||||
useSSE2 = true // Always available on amd64
|
||||
useSSE4 = cpu.X86.HasSSE41
|
||||
useSSSE3 = cpu.X86.HasSSSE3
|
||||
useSSE2 = cpu.X86.HasSSE2
|
||||
)
|
||||
|
||||
//go:noescape
|
||||
func supportSSSE3() bool
|
||||
|
||||
//go:noescape
|
||||
func supportSSE4() bool
|
||||
|
||||
//go:noescape
|
||||
func hashBlocksSSE2(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
|
||||
|
||||
@@ -28,13 +24,14 @@ func hashBlocksSSSE3(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
|
||||
func hashBlocksSSE4(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
|
||||
|
||||
func hashBlocks(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte) {
|
||||
if useSSE4 {
|
||||
switch {
|
||||
case useSSE4:
|
||||
hashBlocksSSE4(h, c, flag, blocks)
|
||||
} else if useSSSE3 {
|
||||
case useSSSE3:
|
||||
hashBlocksSSSE3(h, c, flag, blocks)
|
||||
} else if useSSE2 {
|
||||
case useSSE2:
|
||||
hashBlocksSSE2(h, c, flag, blocks)
|
||||
} else {
|
||||
default:
|
||||
hashBlocksGeneric(h, c, flag, blocks)
|
||||
}
|
||||
}
|
||||
|
||||
25
vendor/golang.org/x/crypto/blake2s/blake2s_amd64.s
generated
vendored
25
vendor/golang.org/x/crypto/blake2s/blake2s_amd64.s
generated
vendored
@@ -436,28 +436,3 @@ TEXT ·hashBlocksSSSE3(SB), 0, $672-48 // frame = 656 + 16 byte alignment
|
||||
TEXT ·hashBlocksSSE4(SB), 0, $32-48 // frame = 16 + 16 byte alignment
|
||||
HASH_BLOCKS(h+0(FP), c+8(FP), flag+16(FP), blocks_base+24(FP), blocks_len+32(FP), BLAKE2s_SSE4)
|
||||
RET
|
||||
|
||||
// func supportSSE4() bool
|
||||
TEXT ·supportSSE4(SB), 4, $0-1
|
||||
MOVL $1, AX
|
||||
CPUID
|
||||
SHRL $19, CX // Bit 19 indicates SSE4.1.
|
||||
ANDL $1, CX
|
||||
MOVB CX, ret+0(FP)
|
||||
RET
|
||||
|
||||
// func supportSSSE3() bool
|
||||
TEXT ·supportSSSE3(SB), 4, $0-1
|
||||
MOVL $1, AX
|
||||
CPUID
|
||||
MOVL CX, BX
|
||||
ANDL $0x1, BX // Bit zero indicates SSE3 support.
|
||||
JZ FALSE
|
||||
ANDL $0x200, CX // Bit nine indicates SSSE3 support.
|
||||
JZ FALSE
|
||||
MOVB $1, ret+0(FP)
|
||||
RET
|
||||
|
||||
FALSE:
|
||||
MOVB $0, ret+0(FP)
|
||||
RET
|
||||
|
||||
48
vendor/golang.org/x/crypto/blake2s/blake2s_test.go
generated
vendored
48
vendor/golang.org/x/crypto/blake2s/blake2s_test.go
generated
vendored
@@ -5,6 +5,8 @@
|
||||
package blake2s
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"testing"
|
||||
@@ -64,6 +66,52 @@ func TestHashes2X(t *testing.T) {
|
||||
testHashes2X(t)
|
||||
}
|
||||
|
||||
func TestMarshal(t *testing.T) {
|
||||
input := make([]byte, 255)
|
||||
for i := range input {
|
||||
input[i] = byte(i)
|
||||
}
|
||||
for i := 0; i < 256; i++ {
|
||||
h, err := New256(nil)
|
||||
if err != nil {
|
||||
t.Fatalf("len(input)=%d: error from New256(nil): %v", i, err)
|
||||
}
|
||||
h2, err := New256(nil)
|
||||
if err != nil {
|
||||
t.Fatalf("len(input)=%d: error from New256(nil): %v", i, err)
|
||||
}
|
||||
|
||||
h.Write(input[:i/2])
|
||||
halfstate, err := h.(encoding.BinaryMarshaler).MarshalBinary()
|
||||
if err != nil {
|
||||
t.Fatalf("len(input)=%d: could not marshal: %v", i, err)
|
||||
}
|
||||
err = h2.(encoding.BinaryUnmarshaler).UnmarshalBinary(halfstate)
|
||||
if err != nil {
|
||||
t.Fatalf("len(input)=%d: could not unmarshal: %v", i, err)
|
||||
}
|
||||
|
||||
h.Write(input[i/2 : i])
|
||||
sum := h.Sum(nil)
|
||||
h2.Write(input[i/2 : i])
|
||||
sum2 := h2.Sum(nil)
|
||||
|
||||
if !bytes.Equal(sum, sum2) {
|
||||
t.Fatalf("len(input)=%d: results do not match; sum = %v, sum2 = %v", i, sum, sum2)
|
||||
}
|
||||
|
||||
h3, err := New256(nil)
|
||||
if err != nil {
|
||||
t.Fatalf("len(input)=%d: error from New256(nil): %v", i, err)
|
||||
}
|
||||
h3.Write(input[:i])
|
||||
sum3 := h3.Sum(nil)
|
||||
if !bytes.Equal(sum, sum3) {
|
||||
t.Fatalf("len(input)=%d: sum = %v, want %v", i, sum, sum3)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testHashes(t *testing.T) {
|
||||
key, _ := hex.DecodeString("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")
|
||||
|
||||
|
||||
20
vendor/golang.org/x/crypto/bn256/bn256.go
generated
vendored
20
vendor/golang.org/x/crypto/bn256/bn256.go
generated
vendored
@@ -97,14 +97,18 @@ func (e *G1) Neg(a *G1) *G1 {
|
||||
|
||||
// Marshal converts n to a byte slice.
|
||||
func (e *G1) Marshal() []byte {
|
||||
// Each value is a 256-bit number.
|
||||
const numBytes = 256 / 8
|
||||
|
||||
if e.p.IsInfinity() {
|
||||
return make([]byte, numBytes*2)
|
||||
}
|
||||
|
||||
e.p.MakeAffine(nil)
|
||||
|
||||
xBytes := new(big.Int).Mod(e.p.x, p).Bytes()
|
||||
yBytes := new(big.Int).Mod(e.p.y, p).Bytes()
|
||||
|
||||
// Each value is a 256-bit number.
|
||||
const numBytes = 256 / 8
|
||||
|
||||
ret := make([]byte, numBytes*2)
|
||||
copy(ret[1*numBytes-len(xBytes):], xBytes)
|
||||
copy(ret[2*numBytes-len(yBytes):], yBytes)
|
||||
@@ -205,6 +209,13 @@ func (e *G2) Add(a, b *G2) *G2 {
|
||||
|
||||
// Marshal converts n into a byte slice.
|
||||
func (n *G2) Marshal() []byte {
|
||||
// Each value is a 256-bit number.
|
||||
const numBytes = 256 / 8
|
||||
|
||||
if n.p.IsInfinity() {
|
||||
return make([]byte, numBytes*4)
|
||||
}
|
||||
|
||||
n.p.MakeAffine(nil)
|
||||
|
||||
xxBytes := new(big.Int).Mod(n.p.x.x, p).Bytes()
|
||||
@@ -212,9 +223,6 @@ func (n *G2) Marshal() []byte {
|
||||
yxBytes := new(big.Int).Mod(n.p.y.x, p).Bytes()
|
||||
yyBytes := new(big.Int).Mod(n.p.y.y, p).Bytes()
|
||||
|
||||
// Each value is a 256-bit number.
|
||||
const numBytes = 256 / 8
|
||||
|
||||
ret := make([]byte, numBytes*4)
|
||||
copy(ret[1*numBytes-len(xxBytes):], xxBytes)
|
||||
copy(ret[2*numBytes-len(xyBytes):], xyBytes)
|
||||
|
||||
9
vendor/golang.org/x/crypto/bn256/curve.go
generated
vendored
9
vendor/golang.org/x/crypto/bn256/curve.go
generated
vendored
@@ -245,10 +245,19 @@ func (c *curvePoint) Mul(a *curvePoint, scalar *big.Int, pool *bnPool) *curvePoi
|
||||
return c
|
||||
}
|
||||
|
||||
// MakeAffine converts c to affine form and returns c. If c is ∞, then it sets
|
||||
// c to 0 : 1 : 0.
|
||||
func (c *curvePoint) MakeAffine(pool *bnPool) *curvePoint {
|
||||
if words := c.z.Bits(); len(words) == 1 && words[0] == 1 {
|
||||
return c
|
||||
}
|
||||
if c.IsInfinity() {
|
||||
c.x.SetInt64(0)
|
||||
c.y.SetInt64(1)
|
||||
c.z.SetInt64(0)
|
||||
c.t.SetInt64(0)
|
||||
return c
|
||||
}
|
||||
|
||||
zInv := pool.Get().ModInverse(c.z, p)
|
||||
t := pool.Get().Mul(c.y, zInv)
|
||||
|
||||
9
vendor/golang.org/x/crypto/bn256/twist.go
generated
vendored
9
vendor/golang.org/x/crypto/bn256/twist.go
generated
vendored
@@ -219,10 +219,19 @@ func (c *twistPoint) Mul(a *twistPoint, scalar *big.Int, pool *bnPool) *twistPoi
|
||||
return c
|
||||
}
|
||||
|
||||
// MakeAffine converts c to affine form and returns c. If c is ∞, then it sets
|
||||
// c to 0 : 1 : 0.
|
||||
func (c *twistPoint) MakeAffine(pool *bnPool) *twistPoint {
|
||||
if c.z.IsOne() {
|
||||
return c
|
||||
}
|
||||
if c.IsInfinity() {
|
||||
c.x.SetZero()
|
||||
c.y.SetOne()
|
||||
c.z.SetZero()
|
||||
c.t.SetZero()
|
||||
return c
|
||||
}
|
||||
|
||||
zInv := newGFp2(pool).Invert(c.z, pool)
|
||||
t := newGFp2(pool).Mul(c.y, zInv, pool)
|
||||
|
||||
12
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305.go
generated
vendored
12
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305.go
generated
vendored
@@ -7,6 +7,7 @@ package chacha20poly1305 // import "golang.org/x/crypto/chacha20poly1305"
|
||||
|
||||
import (
|
||||
"crypto/cipher"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
)
|
||||
|
||||
@@ -18,7 +19,7 @@ const (
|
||||
)
|
||||
|
||||
type chacha20poly1305 struct {
|
||||
key [32]byte
|
||||
key [8]uint32
|
||||
}
|
||||
|
||||
// New returns a ChaCha20-Poly1305 AEAD that uses the given, 256-bit key.
|
||||
@@ -27,7 +28,14 @@ func New(key []byte) (cipher.AEAD, error) {
|
||||
return nil, errors.New("chacha20poly1305: bad key length")
|
||||
}
|
||||
ret := new(chacha20poly1305)
|
||||
copy(ret.key[:], key)
|
||||
ret.key[0] = binary.LittleEndian.Uint32(key[0:4])
|
||||
ret.key[1] = binary.LittleEndian.Uint32(key[4:8])
|
||||
ret.key[2] = binary.LittleEndian.Uint32(key[8:12])
|
||||
ret.key[3] = binary.LittleEndian.Uint32(key[12:16])
|
||||
ret.key[4] = binary.LittleEndian.Uint32(key[16:20])
|
||||
ret.key[5] = binary.LittleEndian.Uint32(key[20:24])
|
||||
ret.key[6] = binary.LittleEndian.Uint32(key[24:28])
|
||||
ret.key[7] = binary.LittleEndian.Uint32(key[28:32])
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
|
||||
86
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go
generated
vendored
86
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go
generated
vendored
@@ -6,7 +6,12 @@
|
||||
|
||||
package chacha20poly1305
|
||||
|
||||
import "encoding/binary"
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"golang.org/x/crypto/internal/subtle"
|
||||
"golang.org/x/sys/cpu"
|
||||
)
|
||||
|
||||
//go:noescape
|
||||
func chacha20Poly1305Open(dst []byte, key []uint32, src, ad []byte) bool
|
||||
@@ -14,78 +19,27 @@ func chacha20Poly1305Open(dst []byte, key []uint32, src, ad []byte) bool
|
||||
//go:noescape
|
||||
func chacha20Poly1305Seal(dst []byte, key []uint32, src, ad []byte)
|
||||
|
||||
// cpuid is implemented in chacha20poly1305_amd64.s.
|
||||
func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32)
|
||||
|
||||
// xgetbv with ecx = 0 is implemented in chacha20poly1305_amd64.s.
|
||||
func xgetbv() (eax, edx uint32)
|
||||
|
||||
var (
|
||||
useASM bool
|
||||
useAVX2 bool
|
||||
useASM = cpu.X86.HasSSSE3
|
||||
useAVX2 = cpu.X86.HasAVX2 && cpu.X86.HasBMI2
|
||||
)
|
||||
|
||||
func init() {
|
||||
detectCPUFeatures()
|
||||
}
|
||||
|
||||
// detectCPUFeatures is used to detect if cpu instructions
|
||||
// used by the functions implemented in assembler in
|
||||
// chacha20poly1305_amd64.s are supported.
|
||||
func detectCPUFeatures() {
|
||||
maxID, _, _, _ := cpuid(0, 0)
|
||||
if maxID < 1 {
|
||||
return
|
||||
}
|
||||
|
||||
_, _, ecx1, _ := cpuid(1, 0)
|
||||
|
||||
haveSSSE3 := isSet(9, ecx1)
|
||||
useASM = haveSSSE3
|
||||
|
||||
haveOSXSAVE := isSet(27, ecx1)
|
||||
|
||||
osSupportsAVX := false
|
||||
// For XGETBV, OSXSAVE bit is required and sufficient.
|
||||
if haveOSXSAVE {
|
||||
eax, _ := xgetbv()
|
||||
// Check if XMM and YMM registers have OS support.
|
||||
osSupportsAVX = isSet(1, eax) && isSet(2, eax)
|
||||
}
|
||||
haveAVX := isSet(28, ecx1) && osSupportsAVX
|
||||
|
||||
if maxID < 7 {
|
||||
return
|
||||
}
|
||||
|
||||
_, ebx7, _, _ := cpuid(7, 0)
|
||||
haveAVX2 := isSet(5, ebx7) && haveAVX
|
||||
haveBMI2 := isSet(8, ebx7)
|
||||
|
||||
useAVX2 = haveAVX2 && haveBMI2
|
||||
}
|
||||
|
||||
// isSet checks if bit at bitpos is set in value.
|
||||
func isSet(bitpos uint, value uint32) bool {
|
||||
return value&(1<<bitpos) != 0
|
||||
}
|
||||
|
||||
// setupState writes a ChaCha20 input matrix to state. See
|
||||
// https://tools.ietf.org/html/rfc7539#section-2.3.
|
||||
func setupState(state *[16]uint32, key *[32]byte, nonce []byte) {
|
||||
func setupState(state *[16]uint32, key *[8]uint32, nonce []byte) {
|
||||
state[0] = 0x61707865
|
||||
state[1] = 0x3320646e
|
||||
state[2] = 0x79622d32
|
||||
state[3] = 0x6b206574
|
||||
|
||||
state[4] = binary.LittleEndian.Uint32(key[:4])
|
||||
state[5] = binary.LittleEndian.Uint32(key[4:8])
|
||||
state[6] = binary.LittleEndian.Uint32(key[8:12])
|
||||
state[7] = binary.LittleEndian.Uint32(key[12:16])
|
||||
state[8] = binary.LittleEndian.Uint32(key[16:20])
|
||||
state[9] = binary.LittleEndian.Uint32(key[20:24])
|
||||
state[10] = binary.LittleEndian.Uint32(key[24:28])
|
||||
state[11] = binary.LittleEndian.Uint32(key[28:32])
|
||||
state[4] = key[0]
|
||||
state[5] = key[1]
|
||||
state[6] = key[2]
|
||||
state[7] = key[3]
|
||||
state[8] = key[4]
|
||||
state[9] = key[5]
|
||||
state[10] = key[6]
|
||||
state[11] = key[7]
|
||||
|
||||
state[12] = 0
|
||||
state[13] = binary.LittleEndian.Uint32(nonce[:4])
|
||||
@@ -102,6 +56,9 @@ func (c *chacha20poly1305) seal(dst, nonce, plaintext, additionalData []byte) []
|
||||
setupState(&state, &c.key, nonce)
|
||||
|
||||
ret, out := sliceForAppend(dst, len(plaintext)+16)
|
||||
if subtle.InexactOverlap(out, plaintext) {
|
||||
panic("chacha20poly1305: invalid buffer overlap")
|
||||
}
|
||||
chacha20Poly1305Seal(out[:], state[:], plaintext, additionalData)
|
||||
return ret
|
||||
}
|
||||
@@ -116,6 +73,9 @@ func (c *chacha20poly1305) open(dst, nonce, ciphertext, additionalData []byte) (
|
||||
|
||||
ciphertext = ciphertext[:len(ciphertext)-16]
|
||||
ret, out := sliceForAppend(dst, len(ciphertext))
|
||||
if subtle.InexactOverlap(out, ciphertext) {
|
||||
panic("chacha20poly1305: invalid buffer overlap")
|
||||
}
|
||||
if !chacha20Poly1305Open(out, state[:], ciphertext, additionalData) {
|
||||
for i := range out {
|
||||
out[i] = 0
|
||||
|
||||
19
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.s
generated
vendored
19
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.s
generated
vendored
@@ -2693,22 +2693,3 @@ sealAVX2Tail512LoopB:
|
||||
VPERM2I128 $0x13, tmpStoreAVX2, DD3, DD0
|
||||
|
||||
JMP sealAVX2SealHash
|
||||
|
||||
// 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
|
||||
|
||||
37
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go
generated
vendored
37
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go
generated
vendored
@@ -8,6 +8,7 @@ import (
|
||||
"encoding/binary"
|
||||
|
||||
"golang.org/x/crypto/internal/chacha20"
|
||||
"golang.org/x/crypto/internal/subtle"
|
||||
"golang.org/x/crypto/poly1305"
|
||||
)
|
||||
|
||||
@@ -16,15 +17,20 @@ func roundTo16(n int) int {
|
||||
}
|
||||
|
||||
func (c *chacha20poly1305) sealGeneric(dst, nonce, plaintext, additionalData []byte) []byte {
|
||||
var counter [16]byte
|
||||
copy(counter[4:], nonce)
|
||||
ret, out := sliceForAppend(dst, len(plaintext)+poly1305.TagSize)
|
||||
if subtle.InexactOverlap(out, plaintext) {
|
||||
panic("chacha20poly1305: invalid buffer overlap")
|
||||
}
|
||||
|
||||
var polyKey [32]byte
|
||||
chacha20.XORKeyStream(polyKey[:], polyKey[:], &counter, &c.key)
|
||||
|
||||
ret, out := sliceForAppend(dst, len(plaintext)+poly1305.TagSize)
|
||||
counter[0] = 1
|
||||
chacha20.XORKeyStream(out, plaintext, &counter, &c.key)
|
||||
s := chacha20.New(c.key, [3]uint32{
|
||||
binary.LittleEndian.Uint32(nonce[0:4]),
|
||||
binary.LittleEndian.Uint32(nonce[4:8]),
|
||||
binary.LittleEndian.Uint32(nonce[8:12]),
|
||||
})
|
||||
s.XORKeyStream(polyKey[:], polyKey[:])
|
||||
s.Advance() // skip the next 32 bytes
|
||||
s.XORKeyStream(out, plaintext)
|
||||
|
||||
polyInput := make([]byte, roundTo16(len(additionalData))+roundTo16(len(plaintext))+8+8)
|
||||
copy(polyInput, additionalData)
|
||||
@@ -44,11 +50,14 @@ func (c *chacha20poly1305) openGeneric(dst, nonce, ciphertext, additionalData []
|
||||
copy(tag[:], ciphertext[len(ciphertext)-16:])
|
||||
ciphertext = ciphertext[:len(ciphertext)-16]
|
||||
|
||||
var counter [16]byte
|
||||
copy(counter[4:], nonce)
|
||||
|
||||
var polyKey [32]byte
|
||||
chacha20.XORKeyStream(polyKey[:], polyKey[:], &counter, &c.key)
|
||||
s := chacha20.New(c.key, [3]uint32{
|
||||
binary.LittleEndian.Uint32(nonce[0:4]),
|
||||
binary.LittleEndian.Uint32(nonce[4:8]),
|
||||
binary.LittleEndian.Uint32(nonce[8:12]),
|
||||
})
|
||||
s.XORKeyStream(polyKey[:], polyKey[:])
|
||||
s.Advance() // skip the next 32 bytes
|
||||
|
||||
polyInput := make([]byte, roundTo16(len(additionalData))+roundTo16(len(ciphertext))+8+8)
|
||||
copy(polyInput, additionalData)
|
||||
@@ -57,6 +66,9 @@ func (c *chacha20poly1305) openGeneric(dst, nonce, ciphertext, additionalData []
|
||||
binary.LittleEndian.PutUint64(polyInput[len(polyInput)-8:], uint64(len(ciphertext)))
|
||||
|
||||
ret, out := sliceForAppend(dst, len(ciphertext))
|
||||
if subtle.InexactOverlap(out, ciphertext) {
|
||||
panic("chacha20poly1305: invalid buffer overlap")
|
||||
}
|
||||
if !poly1305.Verify(&tag, polyInput, &polyKey) {
|
||||
for i := range out {
|
||||
out[i] = 0
|
||||
@@ -64,7 +76,6 @@ func (c *chacha20poly1305) openGeneric(dst, nonce, ciphertext, additionalData []
|
||||
return nil, errOpen
|
||||
}
|
||||
|
||||
counter[0] = 1
|
||||
chacha20.XORKeyStream(out, ciphertext, &counter, &c.key)
|
||||
s.XORKeyStream(out, ciphertext)
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
7
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_vectors_test.go
generated
vendored
7
vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_vectors_test.go
generated
vendored
@@ -7,6 +7,13 @@ package chacha20poly1305
|
||||
var chacha20Poly1305Tests = []struct {
|
||||
plaintext, aad, key, nonce, out string
|
||||
}{
|
||||
{
|
||||
"",
|
||||
"",
|
||||
"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
|
||||
"070000004041424344454647",
|
||||
"a0784d7a4716f3feb4f64e7f4b39bf04",
|
||||
},
|
||||
{
|
||||
"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e",
|
||||
"50515253c0c1c2c3c4c5c6c7",
|
||||
|
||||
67
vendor/golang.org/x/crypto/cryptobyte/asn1.go
generated
vendored
67
vendor/golang.org/x/crypto/cryptobyte/asn1.go
generated
vendored
@@ -23,6 +23,12 @@ func (b *Builder) AddASN1Int64(v int64) {
|
||||
b.addASN1Signed(asn1.INTEGER, v)
|
||||
}
|
||||
|
||||
// AddASN1Int64WithTag appends a DER-encoded ASN.1 INTEGER with the
|
||||
// given tag.
|
||||
func (b *Builder) AddASN1Int64WithTag(v int64, tag asn1.Tag) {
|
||||
b.addASN1Signed(tag, v)
|
||||
}
|
||||
|
||||
// AddASN1Enum appends a DER-encoded ASN.1 ENUMERATION.
|
||||
func (b *Builder) AddASN1Enum(v int64) {
|
||||
b.addASN1Signed(asn1.ENUM, v)
|
||||
@@ -224,6 +230,9 @@ func (b *Builder) AddASN1(tag asn1.Tag, f BuilderContinuation) {
|
||||
|
||||
// String
|
||||
|
||||
// ReadASN1Boolean decodes an ASN.1 INTEGER and converts it to a boolean
|
||||
// representation into out and advances. It reports whether the read
|
||||
// was successful.
|
||||
func (s *String) ReadASN1Boolean(out *bool) bool {
|
||||
var bytes String
|
||||
if !s.ReadASN1(&bytes, asn1.INTEGER) || len(bytes) != 1 {
|
||||
@@ -245,8 +254,8 @@ func (s *String) ReadASN1Boolean(out *bool) bool {
|
||||
var bigIntType = reflect.TypeOf((*big.Int)(nil)).Elem()
|
||||
|
||||
// ReadASN1Integer decodes an ASN.1 INTEGER into out and advances. If out does
|
||||
// not point to an integer or to a big.Int, it panics. It returns true on
|
||||
// success and false on error.
|
||||
// not point to an integer or to a big.Int, it panics. It reports whether the
|
||||
// read was successful.
|
||||
func (s *String) ReadASN1Integer(out interface{}) bool {
|
||||
if reflect.TypeOf(out).Kind() != reflect.Ptr {
|
||||
panic("out is not a pointer")
|
||||
@@ -359,8 +368,16 @@ func asn1Unsigned(out *uint64, n []byte) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// ReadASN1Enum decodes an ASN.1 ENUMERATION into out and advances. It returns
|
||||
// true on success and false on error.
|
||||
// ReadASN1Int64WithTag decodes an ASN.1 INTEGER with the given tag into out
|
||||
// and advances. It reports whether the read was successful and resulted in a
|
||||
// value that can be represented in an int64.
|
||||
func (s *String) ReadASN1Int64WithTag(out *int64, tag asn1.Tag) bool {
|
||||
var bytes String
|
||||
return s.ReadASN1(&bytes, tag) && checkASN1Integer(bytes) && asn1Signed(out, bytes)
|
||||
}
|
||||
|
||||
// ReadASN1Enum decodes an ASN.1 ENUMERATION into out and advances. It reports
|
||||
// whether the read was successful.
|
||||
func (s *String) ReadASN1Enum(out *int) bool {
|
||||
var bytes String
|
||||
var i int64
|
||||
@@ -392,7 +409,7 @@ func (s *String) readBase128Int(out *int) bool {
|
||||
}
|
||||
|
||||
// ReadASN1ObjectIdentifier decodes an ASN.1 OBJECT IDENTIFIER into out and
|
||||
// advances. It returns true on success and false on error.
|
||||
// advances. It reports whether the read was successful.
|
||||
func (s *String) ReadASN1ObjectIdentifier(out *encoding_asn1.ObjectIdentifier) bool {
|
||||
var bytes String
|
||||
if !s.ReadASN1(&bytes, asn1.OBJECT_IDENTIFIER) || len(bytes) == 0 {
|
||||
@@ -431,7 +448,7 @@ func (s *String) ReadASN1ObjectIdentifier(out *encoding_asn1.ObjectIdentifier) b
|
||||
}
|
||||
|
||||
// ReadASN1GeneralizedTime decodes an ASN.1 GENERALIZEDTIME into out and
|
||||
// advances. It returns true on success and false on error.
|
||||
// advances. It reports whether the read was successful.
|
||||
func (s *String) ReadASN1GeneralizedTime(out *time.Time) bool {
|
||||
var bytes String
|
||||
if !s.ReadASN1(&bytes, asn1.GeneralizedTime) {
|
||||
@@ -449,8 +466,8 @@ func (s *String) ReadASN1GeneralizedTime(out *time.Time) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// ReadASN1BitString decodes an ASN.1 BIT STRING into out and advances. It
|
||||
// returns true on success and false on error.
|
||||
// ReadASN1BitString decodes an ASN.1 BIT STRING into out and advances.
|
||||
// It reports whether the read was successful.
|
||||
func (s *String) ReadASN1BitString(out *encoding_asn1.BitString) bool {
|
||||
var bytes String
|
||||
if !s.ReadASN1(&bytes, asn1.BIT_STRING) || len(bytes) == 0 {
|
||||
@@ -471,8 +488,8 @@ func (s *String) ReadASN1BitString(out *encoding_asn1.BitString) bool {
|
||||
}
|
||||
|
||||
// ReadASN1BitString decodes an ASN.1 BIT STRING into out and advances. It is
|
||||
// an error if the BIT STRING is not a whole number of bytes. This function
|
||||
// returns true on success and false on error.
|
||||
// an error if the BIT STRING is not a whole number of bytes. It reports
|
||||
// whether the read was successful.
|
||||
func (s *String) ReadASN1BitStringAsBytes(out *[]byte) bool {
|
||||
var bytes String
|
||||
if !s.ReadASN1(&bytes, asn1.BIT_STRING) || len(bytes) == 0 {
|
||||
@@ -489,14 +506,14 @@ func (s *String) ReadASN1BitStringAsBytes(out *[]byte) bool {
|
||||
|
||||
// ReadASN1Bytes reads the contents of a DER-encoded ASN.1 element (not including
|
||||
// tag and length bytes) into out, and advances. The element must match the
|
||||
// given tag. It returns true on success and false on error.
|
||||
// given tag. It reports whether the read was successful.
|
||||
func (s *String) ReadASN1Bytes(out *[]byte, tag asn1.Tag) bool {
|
||||
return s.ReadASN1((*String)(out), tag)
|
||||
}
|
||||
|
||||
// ReadASN1 reads the contents of a DER-encoded ASN.1 element (not including
|
||||
// tag and length bytes) into out, and advances. The element must match the
|
||||
// given tag. It returns true on success and false on error.
|
||||
// given tag. It reports whether the read was successful.
|
||||
//
|
||||
// Tags greater than 30 are not supported (i.e. low-tag-number format only).
|
||||
func (s *String) ReadASN1(out *String, tag asn1.Tag) bool {
|
||||
@@ -509,7 +526,7 @@ func (s *String) ReadASN1(out *String, tag asn1.Tag) bool {
|
||||
|
||||
// ReadASN1Element reads the contents of a DER-encoded ASN.1 element (including
|
||||
// tag and length bytes) into out, and advances. The element must match the
|
||||
// given tag. It returns true on success and false on error.
|
||||
// given tag. It reports whether the read was successful.
|
||||
//
|
||||
// Tags greater than 30 are not supported (i.e. low-tag-number format only).
|
||||
func (s *String) ReadASN1Element(out *String, tag asn1.Tag) bool {
|
||||
@@ -521,8 +538,8 @@ func (s *String) ReadASN1Element(out *String, tag asn1.Tag) bool {
|
||||
}
|
||||
|
||||
// ReadAnyASN1 reads the contents of a DER-encoded ASN.1 element (not including
|
||||
// tag and length bytes) into out, sets outTag to its tag, and advances. It
|
||||
// returns true on success and false on error.
|
||||
// tag and length bytes) into out, sets outTag to its tag, and advances.
|
||||
// It reports whether the read was successful.
|
||||
//
|
||||
// Tags greater than 30 are not supported (i.e. low-tag-number format only).
|
||||
func (s *String) ReadAnyASN1(out *String, outTag *asn1.Tag) bool {
|
||||
@@ -531,14 +548,14 @@ func (s *String) ReadAnyASN1(out *String, outTag *asn1.Tag) bool {
|
||||
|
||||
// ReadAnyASN1Element reads the contents of a DER-encoded ASN.1 element
|
||||
// (including tag and length bytes) into out, sets outTag to is tag, and
|
||||
// advances. It returns true on success and false on error.
|
||||
// advances. It reports whether the read was successful.
|
||||
//
|
||||
// Tags greater than 30 are not supported (i.e. low-tag-number format only).
|
||||
func (s *String) ReadAnyASN1Element(out *String, outTag *asn1.Tag) bool {
|
||||
return s.readASN1(out, outTag, false /* include header */)
|
||||
}
|
||||
|
||||
// PeekASN1Tag returns true if the next ASN.1 value on the string starts with
|
||||
// PeekASN1Tag reports whether the next ASN.1 value on the string starts with
|
||||
// the given tag.
|
||||
func (s String) PeekASN1Tag(tag asn1.Tag) bool {
|
||||
if len(s) == 0 {
|
||||
@@ -547,7 +564,8 @@ func (s String) PeekASN1Tag(tag asn1.Tag) bool {
|
||||
return asn1.Tag(s[0]) == tag
|
||||
}
|
||||
|
||||
// SkipASN1 reads and discards an ASN.1 element with the given tag.
|
||||
// SkipASN1 reads and discards an ASN.1 element with the given tag. It
|
||||
// reports whether the operation was successful.
|
||||
func (s *String) SkipASN1(tag asn1.Tag) bool {
|
||||
var unused String
|
||||
return s.ReadASN1(&unused, tag)
|
||||
@@ -556,7 +574,7 @@ func (s *String) SkipASN1(tag asn1.Tag) bool {
|
||||
// ReadOptionalASN1 attempts to read the contents of a DER-encoded ASN.1
|
||||
// element (not including tag and length bytes) tagged with the given tag into
|
||||
// out. It stores whether an element with the tag was found in outPresent,
|
||||
// unless outPresent is nil. It returns true on success and false on error.
|
||||
// unless outPresent is nil. It reports whether the read was successful.
|
||||
func (s *String) ReadOptionalASN1(out *String, outPresent *bool, tag asn1.Tag) bool {
|
||||
present := s.PeekASN1Tag(tag)
|
||||
if outPresent != nil {
|
||||
@@ -569,7 +587,7 @@ func (s *String) ReadOptionalASN1(out *String, outPresent *bool, tag asn1.Tag) b
|
||||
}
|
||||
|
||||
// SkipOptionalASN1 advances s over an ASN.1 element with the given tag, or
|
||||
// else leaves s unchanged.
|
||||
// else leaves s unchanged. It reports whether the operation was successful.
|
||||
func (s *String) SkipOptionalASN1(tag asn1.Tag) bool {
|
||||
if !s.PeekASN1Tag(tag) {
|
||||
return true
|
||||
@@ -581,8 +599,8 @@ func (s *String) SkipOptionalASN1(tag asn1.Tag) bool {
|
||||
// ReadOptionalASN1Integer attempts to read an optional ASN.1 INTEGER
|
||||
// explicitly tagged with tag into out and advances. If no element with a
|
||||
// matching tag is present, it writes defaultValue into out instead. If out
|
||||
// does not point to an integer or to a big.Int, it panics. It returns true on
|
||||
// success and false on error.
|
||||
// does not point to an integer or to a big.Int, it panics. It reports
|
||||
// whether the read was successful.
|
||||
func (s *String) ReadOptionalASN1Integer(out interface{}, tag asn1.Tag, defaultValue interface{}) bool {
|
||||
if reflect.TypeOf(out).Kind() != reflect.Ptr {
|
||||
panic("out is not a pointer")
|
||||
@@ -619,8 +637,8 @@ func (s *String) ReadOptionalASN1Integer(out interface{}, tag asn1.Tag, defaultV
|
||||
|
||||
// ReadOptionalASN1OctetString attempts to read an optional ASN.1 OCTET STRING
|
||||
// explicitly tagged with tag into out and advances. If no element with a
|
||||
// matching tag is present, it writes defaultValue into out instead. It returns
|
||||
// true on success and false on error.
|
||||
// matching tag is present, it sets "out" to nil instead. It reports
|
||||
// whether the read was successful.
|
||||
func (s *String) ReadOptionalASN1OctetString(out *[]byte, outPresent *bool, tag asn1.Tag) bool {
|
||||
var present bool
|
||||
var child String
|
||||
@@ -644,6 +662,7 @@ func (s *String) ReadOptionalASN1OctetString(out *[]byte, outPresent *bool, tag
|
||||
|
||||
// ReadOptionalASN1Boolean sets *out to the value of the next ASN.1 BOOLEAN or,
|
||||
// if the next bytes are not an ASN.1 BOOLEAN, to the value of defaultValue.
|
||||
// It reports whether the operation was successful.
|
||||
func (s *String) ReadOptionalASN1Boolean(out *bool, defaultValue bool) bool {
|
||||
var present bool
|
||||
var child String
|
||||
|
||||
33
vendor/golang.org/x/crypto/cryptobyte/asn1_test.go
generated
vendored
33
vendor/golang.org/x/crypto/cryptobyte/asn1_test.go
generated
vendored
@@ -149,6 +149,39 @@ func TestReadASN1IntegerSigned(t *testing.T) {
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// Repeat with the implicit-tagging functions
|
||||
t.Run("WithTag", func(t *testing.T) {
|
||||
for i, test := range testData64 {
|
||||
tag := asn1.Tag((i * 3) % 32).ContextSpecific()
|
||||
|
||||
testData := make([]byte, len(test.in))
|
||||
copy(testData, test.in)
|
||||
|
||||
// Alter the tag of the test case.
|
||||
testData[0] = uint8(tag)
|
||||
|
||||
in := String(testData)
|
||||
var out int64
|
||||
ok := in.ReadASN1Int64WithTag(&out, tag)
|
||||
if !ok || out != test.out {
|
||||
t.Errorf("#%d: in.ReadASN1Int64WithTag() = %v, want true; out = %d, want %d", i, ok, out, test.out)
|
||||
}
|
||||
|
||||
var b Builder
|
||||
b.AddASN1Int64WithTag(test.out, tag)
|
||||
result, err := b.Bytes()
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("#%d: AddASN1Int64WithTag failed: %s", i, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if !bytes.Equal(result, testData) {
|
||||
t.Errorf("#%d: AddASN1Int64WithTag: got %x, want %x", i, result, testData)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestReadASN1IntegerUnsigned(t *testing.T) {
|
||||
|
||||
29
vendor/golang.org/x/crypto/cryptobyte/string.go
generated
vendored
29
vendor/golang.org/x/crypto/cryptobyte/string.go
generated
vendored
@@ -37,8 +37,8 @@ func (s *String) Skip(n int) bool {
|
||||
return s.read(n) != nil
|
||||
}
|
||||
|
||||
// ReadUint8 decodes an 8-bit value into out and advances over it. It
|
||||
// returns true on success and false on error.
|
||||
// ReadUint8 decodes an 8-bit value into out and advances over it.
|
||||
// It reports whether the read was successful.
|
||||
func (s *String) ReadUint8(out *uint8) bool {
|
||||
v := s.read(1)
|
||||
if v == nil {
|
||||
@@ -49,7 +49,7 @@ func (s *String) ReadUint8(out *uint8) bool {
|
||||
}
|
||||
|
||||
// ReadUint16 decodes a big-endian, 16-bit value into out and advances over it.
|
||||
// It returns true on success and false on error.
|
||||
// It reports whether the read was successful.
|
||||
func (s *String) ReadUint16(out *uint16) bool {
|
||||
v := s.read(2)
|
||||
if v == nil {
|
||||
@@ -60,7 +60,7 @@ func (s *String) ReadUint16(out *uint16) bool {
|
||||
}
|
||||
|
||||
// ReadUint24 decodes a big-endian, 24-bit value into out and advances over it.
|
||||
// It returns true on success and false on error.
|
||||
// It reports whether the read was successful.
|
||||
func (s *String) ReadUint24(out *uint32) bool {
|
||||
v := s.read(3)
|
||||
if v == nil {
|
||||
@@ -71,7 +71,7 @@ func (s *String) ReadUint24(out *uint32) bool {
|
||||
}
|
||||
|
||||
// ReadUint32 decodes a big-endian, 32-bit value into out and advances over it.
|
||||
// It returns true on success and false on error.
|
||||
// It reports whether the read was successful.
|
||||
func (s *String) ReadUint32(out *uint32) bool {
|
||||
v := s.read(4)
|
||||
if v == nil {
|
||||
@@ -119,28 +119,27 @@ func (s *String) readLengthPrefixed(lenLen int, outChild *String) bool {
|
||||
}
|
||||
|
||||
// ReadUint8LengthPrefixed reads the content of an 8-bit length-prefixed value
|
||||
// into out and advances over it. It returns true on success and false on
|
||||
// error.
|
||||
// into out and advances over it. It reports whether the read was successful.
|
||||
func (s *String) ReadUint8LengthPrefixed(out *String) bool {
|
||||
return s.readLengthPrefixed(1, out)
|
||||
}
|
||||
|
||||
// ReadUint16LengthPrefixed reads the content of a big-endian, 16-bit
|
||||
// length-prefixed value into out and advances over it. It returns true on
|
||||
// success and false on error.
|
||||
// length-prefixed value into out and advances over it. It reports whether the
|
||||
// read was successful.
|
||||
func (s *String) ReadUint16LengthPrefixed(out *String) bool {
|
||||
return s.readLengthPrefixed(2, out)
|
||||
}
|
||||
|
||||
// ReadUint24LengthPrefixed reads the content of a big-endian, 24-bit
|
||||
// length-prefixed value into out and advances over it. It returns true on
|
||||
// success and false on error.
|
||||
// length-prefixed value into out and advances over it. It reports whether
|
||||
// the read was successful.
|
||||
func (s *String) ReadUint24LengthPrefixed(out *String) bool {
|
||||
return s.readLengthPrefixed(3, out)
|
||||
}
|
||||
|
||||
// ReadBytes reads n bytes into out and advances over them. It returns true on
|
||||
// success and false and error.
|
||||
// ReadBytes reads n bytes into out and advances over them. It reports
|
||||
// whether the read was successful.
|
||||
func (s *String) ReadBytes(out *[]byte, n int) bool {
|
||||
v := s.read(n)
|
||||
if v == nil {
|
||||
@@ -150,8 +149,8 @@ func (s *String) ReadBytes(out *[]byte, n int) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// CopyBytes copies len(out) bytes into out and advances over them. It returns
|
||||
// true on success and false on error.
|
||||
// CopyBytes copies len(out) bytes into out and advances over them. It reports
|
||||
// whether the copy operation was successful
|
||||
func (s *String) CopyBytes(out []byte) bool {
|
||||
n := len(out)
|
||||
v := s.read(n)
|
||||
|
||||
47
vendor/golang.org/x/crypto/ed25519/ed25519.go
generated
vendored
47
vendor/golang.org/x/crypto/ed25519/ed25519.go
generated
vendored
@@ -6,7 +6,10 @@
|
||||
// https://ed25519.cr.yp.to/.
|
||||
//
|
||||
// These functions are also compatible with the “Ed25519” function defined in
|
||||
// RFC 8032.
|
||||
// RFC 8032. However, unlike RFC 8032's formulation, this package's private key
|
||||
// representation includes a public key suffix to make multiple signing
|
||||
// operations with the same key more efficient. This package refers to the RFC
|
||||
// 8032 private key as the “seed”.
|
||||
package ed25519
|
||||
|
||||
// This code is a port of the public domain, “ref10” implementation of ed25519
|
||||
@@ -31,6 +34,8 @@ const (
|
||||
PrivateKeySize = 64
|
||||
// SignatureSize is the size, in bytes, of signatures generated and verified by this package.
|
||||
SignatureSize = 64
|
||||
// SeedSize is the size, in bytes, of private key seeds. These are the private key representations used by RFC 8032.
|
||||
SeedSize = 32
|
||||
)
|
||||
|
||||
// PublicKey is the type of Ed25519 public keys.
|
||||
@@ -46,6 +51,15 @@ func (priv PrivateKey) Public() crypto.PublicKey {
|
||||
return PublicKey(publicKey)
|
||||
}
|
||||
|
||||
// Seed returns the private key seed corresponding to priv. It is provided for
|
||||
// interoperability with RFC 8032. RFC 8032's private keys correspond to seeds
|
||||
// in this package.
|
||||
func (priv PrivateKey) Seed() []byte {
|
||||
seed := make([]byte, SeedSize)
|
||||
copy(seed, priv[:32])
|
||||
return seed
|
||||
}
|
||||
|
||||
// Sign signs the given message with priv.
|
||||
// Ed25519 performs two passes over messages to be signed and therefore cannot
|
||||
// handle pre-hashed messages. Thus opts.HashFunc() must return zero to
|
||||
@@ -61,19 +75,33 @@ func (priv PrivateKey) Sign(rand io.Reader, message []byte, opts crypto.SignerOp
|
||||
|
||||
// GenerateKey generates a public/private key pair using entropy from rand.
|
||||
// If rand is nil, crypto/rand.Reader will be used.
|
||||
func GenerateKey(rand io.Reader) (publicKey PublicKey, privateKey PrivateKey, err error) {
|
||||
func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) {
|
||||
if rand == nil {
|
||||
rand = cryptorand.Reader
|
||||
}
|
||||
|
||||
privateKey = make([]byte, PrivateKeySize)
|
||||
publicKey = make([]byte, PublicKeySize)
|
||||
_, err = io.ReadFull(rand, privateKey[:32])
|
||||
if err != nil {
|
||||
seed := make([]byte, SeedSize)
|
||||
if _, err := io.ReadFull(rand, seed); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
digest := sha512.Sum512(privateKey[:32])
|
||||
privateKey := NewKeyFromSeed(seed)
|
||||
publicKey := make([]byte, PublicKeySize)
|
||||
copy(publicKey, privateKey[32:])
|
||||
|
||||
return publicKey, privateKey, nil
|
||||
}
|
||||
|
||||
// NewKeyFromSeed calculates a private key from a seed. It will panic if
|
||||
// len(seed) is not SeedSize. This function is provided for interoperability
|
||||
// with RFC 8032. RFC 8032's private keys correspond to seeds in this
|
||||
// package.
|
||||
func NewKeyFromSeed(seed []byte) PrivateKey {
|
||||
if l := len(seed); l != SeedSize {
|
||||
panic("ed25519: bad seed length: " + strconv.Itoa(l))
|
||||
}
|
||||
|
||||
digest := sha512.Sum512(seed)
|
||||
digest[0] &= 248
|
||||
digest[31] &= 127
|
||||
digest[31] |= 64
|
||||
@@ -85,10 +113,11 @@ func GenerateKey(rand io.Reader) (publicKey PublicKey, privateKey PrivateKey, er
|
||||
var publicKeyBytes [32]byte
|
||||
A.ToBytes(&publicKeyBytes)
|
||||
|
||||
privateKey := make([]byte, PrivateKeySize)
|
||||
copy(privateKey, seed)
|
||||
copy(privateKey[32:], publicKeyBytes[:])
|
||||
copy(publicKey, publicKeyBytes[:])
|
||||
|
||||
return publicKey, privateKey, nil
|
||||
return privateKey
|
||||
}
|
||||
|
||||
// Sign signs the message with privateKey and returns a signature. It will
|
||||
|
||||
13
vendor/golang.org/x/crypto/ed25519/ed25519_test.go
generated
vendored
13
vendor/golang.org/x/crypto/ed25519/ed25519_test.go
generated
vendored
@@ -139,6 +139,19 @@ func TestGolden(t *testing.T) {
|
||||
if !Verify(pubKey, msg, sig2) {
|
||||
t.Errorf("signature failed to verify on line %d", lineNo)
|
||||
}
|
||||
|
||||
priv2 := NewKeyFromSeed(priv[:32])
|
||||
if !bytes.Equal(priv[:], priv2) {
|
||||
t.Errorf("recreating key pair gave different private key on line %d: %x vs %x", lineNo, priv[:], priv2)
|
||||
}
|
||||
|
||||
if pubKey2 := priv2.Public().(PublicKey); !bytes.Equal(pubKey, pubKey2) {
|
||||
t.Errorf("recreating key pair gave different public key on line %d: %x vs %x", lineNo, pubKey, pubKey2)
|
||||
}
|
||||
|
||||
if seed := priv2.Seed(); !bytes.Equal(priv[:32], seed) {
|
||||
t.Errorf("recreating key pair gave different seed on line %d: %x vs %x", lineNo, priv[:32], seed)
|
||||
}
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
|
||||
283
vendor/golang.org/x/crypto/internal/chacha20/asm_s390x.s
generated
vendored
Normal file
283
vendor/golang.org/x/crypto/internal/chacha20/asm_s390x.s
generated
vendored
Normal file
@@ -0,0 +1,283 @@
|
||||
// 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 s390x,!gccgo,!appengine
|
||||
|
||||
#include "go_asm.h"
|
||||
#include "textflag.h"
|
||||
|
||||
// This is an implementation of the ChaCha20 encryption algorithm as
|
||||
// specified in RFC 7539. It uses vector instructions to compute
|
||||
// 4 keystream blocks in parallel (256 bytes) which are then XORed
|
||||
// with the bytes in the input slice.
|
||||
|
||||
GLOBL ·constants<>(SB), RODATA|NOPTR, $32
|
||||
// BSWAP: swap bytes in each 4-byte element
|
||||
DATA ·constants<>+0x00(SB)/4, $0x03020100
|
||||
DATA ·constants<>+0x04(SB)/4, $0x07060504
|
||||
DATA ·constants<>+0x08(SB)/4, $0x0b0a0908
|
||||
DATA ·constants<>+0x0c(SB)/4, $0x0f0e0d0c
|
||||
// J0: [j0, j1, j2, j3]
|
||||
DATA ·constants<>+0x10(SB)/4, $0x61707865
|
||||
DATA ·constants<>+0x14(SB)/4, $0x3320646e
|
||||
DATA ·constants<>+0x18(SB)/4, $0x79622d32
|
||||
DATA ·constants<>+0x1c(SB)/4, $0x6b206574
|
||||
|
||||
// EXRL targets:
|
||||
TEXT ·mvcSrcToBuf(SB), NOFRAME|NOSPLIT, $0
|
||||
MVC $1, (R1), (R8)
|
||||
RET
|
||||
|
||||
TEXT ·mvcBufToDst(SB), NOFRAME|NOSPLIT, $0
|
||||
MVC $1, (R8), (R9)
|
||||
RET
|
||||
|
||||
#define BSWAP V5
|
||||
#define J0 V6
|
||||
#define KEY0 V7
|
||||
#define KEY1 V8
|
||||
#define NONCE V9
|
||||
#define CTR V10
|
||||
#define M0 V11
|
||||
#define M1 V12
|
||||
#define M2 V13
|
||||
#define M3 V14
|
||||
#define INC V15
|
||||
#define X0 V16
|
||||
#define X1 V17
|
||||
#define X2 V18
|
||||
#define X3 V19
|
||||
#define X4 V20
|
||||
#define X5 V21
|
||||
#define X6 V22
|
||||
#define X7 V23
|
||||
#define X8 V24
|
||||
#define X9 V25
|
||||
#define X10 V26
|
||||
#define X11 V27
|
||||
#define X12 V28
|
||||
#define X13 V29
|
||||
#define X14 V30
|
||||
#define X15 V31
|
||||
|
||||
#define NUM_ROUNDS 20
|
||||
|
||||
#define ROUND4(a0, a1, a2, a3, b0, b1, b2, b3, c0, c1, c2, c3, d0, d1, d2, d3) \
|
||||
VAF a1, a0, a0 \
|
||||
VAF b1, b0, b0 \
|
||||
VAF c1, c0, c0 \
|
||||
VAF d1, d0, d0 \
|
||||
VX a0, a2, a2 \
|
||||
VX b0, b2, b2 \
|
||||
VX c0, c2, c2 \
|
||||
VX d0, d2, d2 \
|
||||
VERLLF $16, a2, a2 \
|
||||
VERLLF $16, b2, b2 \
|
||||
VERLLF $16, c2, c2 \
|
||||
VERLLF $16, d2, d2 \
|
||||
VAF a2, a3, a3 \
|
||||
VAF b2, b3, b3 \
|
||||
VAF c2, c3, c3 \
|
||||
VAF d2, d3, d3 \
|
||||
VX a3, a1, a1 \
|
||||
VX b3, b1, b1 \
|
||||
VX c3, c1, c1 \
|
||||
VX d3, d1, d1 \
|
||||
VERLLF $12, a1, a1 \
|
||||
VERLLF $12, b1, b1 \
|
||||
VERLLF $12, c1, c1 \
|
||||
VERLLF $12, d1, d1 \
|
||||
VAF a1, a0, a0 \
|
||||
VAF b1, b0, b0 \
|
||||
VAF c1, c0, c0 \
|
||||
VAF d1, d0, d0 \
|
||||
VX a0, a2, a2 \
|
||||
VX b0, b2, b2 \
|
||||
VX c0, c2, c2 \
|
||||
VX d0, d2, d2 \
|
||||
VERLLF $8, a2, a2 \
|
||||
VERLLF $8, b2, b2 \
|
||||
VERLLF $8, c2, c2 \
|
||||
VERLLF $8, d2, d2 \
|
||||
VAF a2, a3, a3 \
|
||||
VAF b2, b3, b3 \
|
||||
VAF c2, c3, c3 \
|
||||
VAF d2, d3, d3 \
|
||||
VX a3, a1, a1 \
|
||||
VX b3, b1, b1 \
|
||||
VX c3, c1, c1 \
|
||||
VX d3, d1, d1 \
|
||||
VERLLF $7, a1, a1 \
|
||||
VERLLF $7, b1, b1 \
|
||||
VERLLF $7, c1, c1 \
|
||||
VERLLF $7, d1, d1
|
||||
|
||||
#define PERMUTE(mask, v0, v1, v2, v3) \
|
||||
VPERM v0, v0, mask, v0 \
|
||||
VPERM v1, v1, mask, v1 \
|
||||
VPERM v2, v2, mask, v2 \
|
||||
VPERM v3, v3, mask, v3
|
||||
|
||||
#define ADDV(x, v0, v1, v2, v3) \
|
||||
VAF x, v0, v0 \
|
||||
VAF x, v1, v1 \
|
||||
VAF x, v2, v2 \
|
||||
VAF x, v3, v3
|
||||
|
||||
#define XORV(off, dst, src, v0, v1, v2, v3) \
|
||||
VLM off(src), M0, M3 \
|
||||
PERMUTE(BSWAP, v0, v1, v2, v3) \
|
||||
VX v0, M0, M0 \
|
||||
VX v1, M1, M1 \
|
||||
VX v2, M2, M2 \
|
||||
VX v3, M3, M3 \
|
||||
VSTM M0, M3, off(dst)
|
||||
|
||||
#define SHUFFLE(a, b, c, d, t, u, v, w) \
|
||||
VMRHF a, c, t \ // t = {a[0], c[0], a[1], c[1]}
|
||||
VMRHF b, d, u \ // u = {b[0], d[0], b[1], d[1]}
|
||||
VMRLF a, c, v \ // v = {a[2], c[2], a[3], c[3]}
|
||||
VMRLF b, d, w \ // w = {b[2], d[2], b[3], d[3]}
|
||||
VMRHF t, u, a \ // a = {a[0], b[0], c[0], d[0]}
|
||||
VMRLF t, u, b \ // b = {a[1], b[1], c[1], d[1]}
|
||||
VMRHF v, w, c \ // c = {a[2], b[2], c[2], d[2]}
|
||||
VMRLF v, w, d // d = {a[3], b[3], c[3], d[3]}
|
||||
|
||||
// func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32, buf *[256]byte, len *int)
|
||||
TEXT ·xorKeyStreamVX(SB), NOSPLIT, $0
|
||||
MOVD $·constants<>(SB), R1
|
||||
MOVD dst+0(FP), R2 // R2=&dst[0]
|
||||
LMG src+24(FP), R3, R4 // R3=&src[0] R4=len(src)
|
||||
MOVD key+48(FP), R5 // R5=key
|
||||
MOVD nonce+56(FP), R6 // R6=nonce
|
||||
MOVD counter+64(FP), R7 // R7=counter
|
||||
MOVD buf+72(FP), R8 // R8=buf
|
||||
MOVD len+80(FP), R9 // R9=len
|
||||
|
||||
// load BSWAP and J0
|
||||
VLM (R1), BSWAP, J0
|
||||
|
||||
// set up tail buffer
|
||||
ADD $-1, R4, R12
|
||||
MOVBZ R12, R12
|
||||
CMPUBEQ R12, $255, aligned
|
||||
MOVD R4, R1
|
||||
AND $~255, R1
|
||||
MOVD $(R3)(R1*1), R1
|
||||
EXRL $·mvcSrcToBuf(SB), R12
|
||||
MOVD $255, R0
|
||||
SUB R12, R0
|
||||
MOVD R0, (R9) // update len
|
||||
|
||||
aligned:
|
||||
// setup
|
||||
MOVD $95, R0
|
||||
VLM (R5), KEY0, KEY1
|
||||
VLL R0, (R6), NONCE
|
||||
VZERO M0
|
||||
VLEIB $7, $32, M0
|
||||
VSRLB M0, NONCE, NONCE
|
||||
|
||||
// initialize counter values
|
||||
VLREPF (R7), CTR
|
||||
VZERO INC
|
||||
VLEIF $1, $1, INC
|
||||
VLEIF $2, $2, INC
|
||||
VLEIF $3, $3, INC
|
||||
VAF INC, CTR, CTR
|
||||
VREPIF $4, INC
|
||||
|
||||
chacha:
|
||||
VREPF $0, J0, X0
|
||||
VREPF $1, J0, X1
|
||||
VREPF $2, J0, X2
|
||||
VREPF $3, J0, X3
|
||||
VREPF $0, KEY0, X4
|
||||
VREPF $1, KEY0, X5
|
||||
VREPF $2, KEY0, X6
|
||||
VREPF $3, KEY0, X7
|
||||
VREPF $0, KEY1, X8
|
||||
VREPF $1, KEY1, X9
|
||||
VREPF $2, KEY1, X10
|
||||
VREPF $3, KEY1, X11
|
||||
VLR CTR, X12
|
||||
VREPF $1, NONCE, X13
|
||||
VREPF $2, NONCE, X14
|
||||
VREPF $3, NONCE, X15
|
||||
|
||||
MOVD $(NUM_ROUNDS/2), R1
|
||||
|
||||
loop:
|
||||
ROUND4(X0, X4, X12, X8, X1, X5, X13, X9, X2, X6, X14, X10, X3, X7, X15, X11)
|
||||
ROUND4(X0, X5, X15, X10, X1, X6, X12, X11, X2, X7, X13, X8, X3, X4, X14, X9)
|
||||
|
||||
ADD $-1, R1
|
||||
BNE loop
|
||||
|
||||
// decrement length
|
||||
ADD $-256, R4
|
||||
BLT tail
|
||||
|
||||
continue:
|
||||
// rearrange vectors
|
||||
SHUFFLE(X0, X1, X2, X3, M0, M1, M2, M3)
|
||||
ADDV(J0, X0, X1, X2, X3)
|
||||
SHUFFLE(X4, X5, X6, X7, M0, M1, M2, M3)
|
||||
ADDV(KEY0, X4, X5, X6, X7)
|
||||
SHUFFLE(X8, X9, X10, X11, M0, M1, M2, M3)
|
||||
ADDV(KEY1, X8, X9, X10, X11)
|
||||
VAF CTR, X12, X12
|
||||
SHUFFLE(X12, X13, X14, X15, M0, M1, M2, M3)
|
||||
ADDV(NONCE, X12, X13, X14, X15)
|
||||
|
||||
// increment counters
|
||||
VAF INC, CTR, CTR
|
||||
|
||||
// xor keystream with plaintext
|
||||
XORV(0*64, R2, R3, X0, X4, X8, X12)
|
||||
XORV(1*64, R2, R3, X1, X5, X9, X13)
|
||||
XORV(2*64, R2, R3, X2, X6, X10, X14)
|
||||
XORV(3*64, R2, R3, X3, X7, X11, X15)
|
||||
|
||||
// increment pointers
|
||||
MOVD $256(R2), R2
|
||||
MOVD $256(R3), R3
|
||||
|
||||
CMPBNE R4, $0, chacha
|
||||
CMPUBEQ R12, $255, return
|
||||
EXRL $·mvcBufToDst(SB), R12 // len was updated during setup
|
||||
|
||||
return:
|
||||
VSTEF $0, CTR, (R7)
|
||||
RET
|
||||
|
||||
tail:
|
||||
MOVD R2, R9
|
||||
MOVD R8, R2
|
||||
MOVD R8, R3
|
||||
MOVD $0, R4
|
||||
JMP continue
|
||||
|
||||
// func hasVectorFacility() bool
|
||||
TEXT ·hasVectorFacility(SB), NOSPLIT, $24-1
|
||||
MOVD $x-24(SP), R1
|
||||
XC $24, 0(R1), 0(R1) // clear the storage
|
||||
MOVD $2, R0 // R0 is the number of double words stored -1
|
||||
WORD $0xB2B01000 // STFLE 0(R1)
|
||||
XOR R0, R0 // reset the value of R0
|
||||
MOVBZ z-8(SP), R1
|
||||
AND $0x40, R1
|
||||
BEQ novector
|
||||
|
||||
vectorinstalled:
|
||||
// check if the vector instruction has been enabled
|
||||
VLEIB $0, $0xF, V16
|
||||
VLGVB $0, V16, R1
|
||||
CMPBNE R1, $0xF, novector
|
||||
MOVB $1, ret+0(FP) // have vx
|
||||
RET
|
||||
|
||||
novector:
|
||||
MOVB $0, ret+0(FP) // no vx
|
||||
RET
|
||||
392
vendor/golang.org/x/crypto/internal/chacha20/chacha_generic.go
generated
vendored
392
vendor/golang.org/x/crypto/internal/chacha20/chacha_generic.go
generated
vendored
@@ -2,197 +2,235 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package ChaCha20 implements the core ChaCha20 function as specified in https://tools.ietf.org/html/rfc7539#section-2.3.
|
||||
// Package ChaCha20 implements the core ChaCha20 function as specified
|
||||
// in https://tools.ietf.org/html/rfc7539#section-2.3.
|
||||
package chacha20
|
||||
|
||||
import "encoding/binary"
|
||||
import (
|
||||
"crypto/cipher"
|
||||
"encoding/binary"
|
||||
|
||||
const rounds = 20
|
||||
"golang.org/x/crypto/internal/subtle"
|
||||
)
|
||||
|
||||
// core applies the ChaCha20 core function to 16-byte input in, 32-byte key k,
|
||||
// and 16-byte constant c, and puts the result into 64-byte array out.
|
||||
func core(out *[64]byte, in *[16]byte, k *[32]byte) {
|
||||
j0 := uint32(0x61707865)
|
||||
j1 := uint32(0x3320646e)
|
||||
j2 := uint32(0x79622d32)
|
||||
j3 := uint32(0x6b206574)
|
||||
j4 := binary.LittleEndian.Uint32(k[0:4])
|
||||
j5 := binary.LittleEndian.Uint32(k[4:8])
|
||||
j6 := binary.LittleEndian.Uint32(k[8:12])
|
||||
j7 := binary.LittleEndian.Uint32(k[12:16])
|
||||
j8 := binary.LittleEndian.Uint32(k[16:20])
|
||||
j9 := binary.LittleEndian.Uint32(k[20:24])
|
||||
j10 := binary.LittleEndian.Uint32(k[24:28])
|
||||
j11 := binary.LittleEndian.Uint32(k[28:32])
|
||||
j12 := binary.LittleEndian.Uint32(in[0:4])
|
||||
j13 := binary.LittleEndian.Uint32(in[4:8])
|
||||
j14 := binary.LittleEndian.Uint32(in[8:12])
|
||||
j15 := binary.LittleEndian.Uint32(in[12:16])
|
||||
// assert that *Cipher implements cipher.Stream
|
||||
var _ cipher.Stream = (*Cipher)(nil)
|
||||
|
||||
x0, x1, x2, x3, x4, x5, x6, x7 := j0, j1, j2, j3, j4, j5, j6, j7
|
||||
x8, x9, x10, x11, x12, x13, x14, x15 := j8, j9, j10, j11, j12, j13, j14, j15
|
||||
// Cipher is a stateful instance of ChaCha20 using a particular key
|
||||
// and nonce. A *Cipher implements the cipher.Stream interface.
|
||||
type Cipher struct {
|
||||
key [8]uint32
|
||||
counter uint32 // incremented after each block
|
||||
nonce [3]uint32
|
||||
buf [bufSize]byte // buffer for unused keystream bytes
|
||||
len int // number of unused keystream bytes at end of buf
|
||||
}
|
||||
|
||||
for i := 0; i < rounds; i += 2 {
|
||||
x0 += x4
|
||||
x12 ^= x0
|
||||
x12 = (x12 << 16) | (x12 >> (16))
|
||||
x8 += x12
|
||||
x4 ^= x8
|
||||
x4 = (x4 << 12) | (x4 >> (20))
|
||||
x0 += x4
|
||||
x12 ^= x0
|
||||
x12 = (x12 << 8) | (x12 >> (24))
|
||||
x8 += x12
|
||||
x4 ^= x8
|
||||
x4 = (x4 << 7) | (x4 >> (25))
|
||||
x1 += x5
|
||||
x13 ^= x1
|
||||
x13 = (x13 << 16) | (x13 >> 16)
|
||||
x9 += x13
|
||||
x5 ^= x9
|
||||
x5 = (x5 << 12) | (x5 >> 20)
|
||||
x1 += x5
|
||||
x13 ^= x1
|
||||
x13 = (x13 << 8) | (x13 >> 24)
|
||||
x9 += x13
|
||||
x5 ^= x9
|
||||
x5 = (x5 << 7) | (x5 >> 25)
|
||||
x2 += x6
|
||||
x14 ^= x2
|
||||
x14 = (x14 << 16) | (x14 >> 16)
|
||||
x10 += x14
|
||||
x6 ^= x10
|
||||
x6 = (x6 << 12) | (x6 >> 20)
|
||||
x2 += x6
|
||||
x14 ^= x2
|
||||
x14 = (x14 << 8) | (x14 >> 24)
|
||||
x10 += x14
|
||||
x6 ^= x10
|
||||
x6 = (x6 << 7) | (x6 >> 25)
|
||||
x3 += x7
|
||||
x15 ^= x3
|
||||
x15 = (x15 << 16) | (x15 >> 16)
|
||||
x11 += x15
|
||||
x7 ^= x11
|
||||
x7 = (x7 << 12) | (x7 >> 20)
|
||||
x3 += x7
|
||||
x15 ^= x3
|
||||
x15 = (x15 << 8) | (x15 >> 24)
|
||||
x11 += x15
|
||||
x7 ^= x11
|
||||
x7 = (x7 << 7) | (x7 >> 25)
|
||||
x0 += x5
|
||||
x15 ^= x0
|
||||
x15 = (x15 << 16) | (x15 >> 16)
|
||||
x10 += x15
|
||||
x5 ^= x10
|
||||
x5 = (x5 << 12) | (x5 >> 20)
|
||||
x0 += x5
|
||||
x15 ^= x0
|
||||
x15 = (x15 << 8) | (x15 >> 24)
|
||||
x10 += x15
|
||||
x5 ^= x10
|
||||
x5 = (x5 << 7) | (x5 >> 25)
|
||||
x1 += x6
|
||||
x12 ^= x1
|
||||
x12 = (x12 << 16) | (x12 >> 16)
|
||||
x11 += x12
|
||||
x6 ^= x11
|
||||
x6 = (x6 << 12) | (x6 >> 20)
|
||||
x1 += x6
|
||||
x12 ^= x1
|
||||
x12 = (x12 << 8) | (x12 >> 24)
|
||||
x11 += x12
|
||||
x6 ^= x11
|
||||
x6 = (x6 << 7) | (x6 >> 25)
|
||||
x2 += x7
|
||||
x13 ^= x2
|
||||
x13 = (x13 << 16) | (x13 >> 16)
|
||||
x8 += x13
|
||||
x7 ^= x8
|
||||
x7 = (x7 << 12) | (x7 >> 20)
|
||||
x2 += x7
|
||||
x13 ^= x2
|
||||
x13 = (x13 << 8) | (x13 >> 24)
|
||||
x8 += x13
|
||||
x7 ^= x8
|
||||
x7 = (x7 << 7) | (x7 >> 25)
|
||||
x3 += x4
|
||||
x14 ^= x3
|
||||
x14 = (x14 << 16) | (x14 >> 16)
|
||||
x9 += x14
|
||||
x4 ^= x9
|
||||
x4 = (x4 << 12) | (x4 >> 20)
|
||||
x3 += x4
|
||||
x14 ^= x3
|
||||
x14 = (x14 << 8) | (x14 >> 24)
|
||||
x9 += x14
|
||||
x4 ^= x9
|
||||
x4 = (x4 << 7) | (x4 >> 25)
|
||||
// New creates a new ChaCha20 stream cipher with the given key and nonce.
|
||||
// The initial counter value is set to 0.
|
||||
func New(key [8]uint32, nonce [3]uint32) *Cipher {
|
||||
return &Cipher{key: key, nonce: nonce}
|
||||
}
|
||||
|
||||
// XORKeyStream XORs each byte in the given slice with a byte from the
|
||||
// cipher's key stream. Dst and src must overlap entirely or not at all.
|
||||
//
|
||||
// If len(dst) < len(src), XORKeyStream will panic. It is acceptable
|
||||
// to pass a dst bigger than src, and in that case, XORKeyStream will
|
||||
// only update dst[:len(src)] and will not touch the rest of dst.
|
||||
//
|
||||
// Multiple calls to XORKeyStream behave as if the concatenation of
|
||||
// the src buffers was passed in a single run. That is, Cipher
|
||||
// maintains state and does not reset at each XORKeyStream call.
|
||||
func (s *Cipher) XORKeyStream(dst, src []byte) {
|
||||
if len(dst) < len(src) {
|
||||
panic("chacha20: output smaller than input")
|
||||
}
|
||||
if subtle.InexactOverlap(dst[:len(src)], src) {
|
||||
panic("chacha20: invalid buffer overlap")
|
||||
}
|
||||
|
||||
x0 += j0
|
||||
x1 += j1
|
||||
x2 += j2
|
||||
x3 += j3
|
||||
x4 += j4
|
||||
x5 += j5
|
||||
x6 += j6
|
||||
x7 += j7
|
||||
x8 += j8
|
||||
x9 += j9
|
||||
x10 += j10
|
||||
x11 += j11
|
||||
x12 += j12
|
||||
x13 += j13
|
||||
x14 += j14
|
||||
x15 += j15
|
||||
// xor src with buffered keystream first
|
||||
if s.len != 0 {
|
||||
buf := s.buf[len(s.buf)-s.len:]
|
||||
if len(src) < len(buf) {
|
||||
buf = buf[:len(src)]
|
||||
}
|
||||
td, ts := dst[:len(buf)], src[:len(buf)] // BCE hint
|
||||
for i, b := range buf {
|
||||
td[i] = ts[i] ^ b
|
||||
}
|
||||
s.len -= len(buf)
|
||||
if s.len != 0 {
|
||||
return
|
||||
}
|
||||
s.buf = [len(s.buf)]byte{} // zero the empty buffer
|
||||
src = src[len(buf):]
|
||||
dst = dst[len(buf):]
|
||||
}
|
||||
|
||||
binary.LittleEndian.PutUint32(out[0:4], x0)
|
||||
binary.LittleEndian.PutUint32(out[4:8], x1)
|
||||
binary.LittleEndian.PutUint32(out[8:12], x2)
|
||||
binary.LittleEndian.PutUint32(out[12:16], x3)
|
||||
binary.LittleEndian.PutUint32(out[16:20], x4)
|
||||
binary.LittleEndian.PutUint32(out[20:24], x5)
|
||||
binary.LittleEndian.PutUint32(out[24:28], x6)
|
||||
binary.LittleEndian.PutUint32(out[28:32], x7)
|
||||
binary.LittleEndian.PutUint32(out[32:36], x8)
|
||||
binary.LittleEndian.PutUint32(out[36:40], x9)
|
||||
binary.LittleEndian.PutUint32(out[40:44], x10)
|
||||
binary.LittleEndian.PutUint32(out[44:48], x11)
|
||||
binary.LittleEndian.PutUint32(out[48:52], x12)
|
||||
binary.LittleEndian.PutUint32(out[52:56], x13)
|
||||
binary.LittleEndian.PutUint32(out[56:60], x14)
|
||||
binary.LittleEndian.PutUint32(out[60:64], x15)
|
||||
if len(src) == 0 {
|
||||
return
|
||||
}
|
||||
if haveAsm {
|
||||
s.xorKeyStreamAsm(dst, src)
|
||||
return
|
||||
}
|
||||
|
||||
// set up a 64-byte buffer to pad out the final block if needed
|
||||
// (hoisted out of the main loop to avoid spills)
|
||||
rem := len(src) % 64 // length of final block
|
||||
fin := len(src) - rem // index of final block
|
||||
if rem > 0 {
|
||||
copy(s.buf[len(s.buf)-64:], src[fin:])
|
||||
}
|
||||
|
||||
// qr calculates a quarter round
|
||||
qr := func(a, b, c, d uint32) (uint32, uint32, uint32, uint32) {
|
||||
a += b
|
||||
d ^= a
|
||||
d = (d << 16) | (d >> 16)
|
||||
c += d
|
||||
b ^= c
|
||||
b = (b << 12) | (b >> 20)
|
||||
a += b
|
||||
d ^= a
|
||||
d = (d << 8) | (d >> 24)
|
||||
c += d
|
||||
b ^= c
|
||||
b = (b << 7) | (b >> 25)
|
||||
return a, b, c, d
|
||||
}
|
||||
|
||||
// ChaCha20 constants
|
||||
const (
|
||||
j0 = 0x61707865
|
||||
j1 = 0x3320646e
|
||||
j2 = 0x79622d32
|
||||
j3 = 0x6b206574
|
||||
)
|
||||
|
||||
// pre-calculate most of the first round
|
||||
s1, s5, s9, s13 := qr(j1, s.key[1], s.key[5], s.nonce[0])
|
||||
s2, s6, s10, s14 := qr(j2, s.key[2], s.key[6], s.nonce[1])
|
||||
s3, s7, s11, s15 := qr(j3, s.key[3], s.key[7], s.nonce[2])
|
||||
|
||||
n := len(src)
|
||||
src, dst = src[:n:n], dst[:n:n] // BCE hint
|
||||
for i := 0; i < n; i += 64 {
|
||||
// calculate the remainder of the first round
|
||||
s0, s4, s8, s12 := qr(j0, s.key[0], s.key[4], s.counter)
|
||||
|
||||
// execute the second round
|
||||
x0, x5, x10, x15 := qr(s0, s5, s10, s15)
|
||||
x1, x6, x11, x12 := qr(s1, s6, s11, s12)
|
||||
x2, x7, x8, x13 := qr(s2, s7, s8, s13)
|
||||
x3, x4, x9, x14 := qr(s3, s4, s9, s14)
|
||||
|
||||
// execute the remaining 18 rounds
|
||||
for i := 0; i < 9; i++ {
|
||||
x0, x4, x8, x12 = qr(x0, x4, x8, x12)
|
||||
x1, x5, x9, x13 = qr(x1, x5, x9, x13)
|
||||
x2, x6, x10, x14 = qr(x2, x6, x10, x14)
|
||||
x3, x7, x11, x15 = qr(x3, x7, x11, x15)
|
||||
|
||||
x0, x5, x10, x15 = qr(x0, x5, x10, x15)
|
||||
x1, x6, x11, x12 = qr(x1, x6, x11, x12)
|
||||
x2, x7, x8, x13 = qr(x2, x7, x8, x13)
|
||||
x3, x4, x9, x14 = qr(x3, x4, x9, x14)
|
||||
}
|
||||
|
||||
x0 += j0
|
||||
x1 += j1
|
||||
x2 += j2
|
||||
x3 += j3
|
||||
|
||||
x4 += s.key[0]
|
||||
x5 += s.key[1]
|
||||
x6 += s.key[2]
|
||||
x7 += s.key[3]
|
||||
x8 += s.key[4]
|
||||
x9 += s.key[5]
|
||||
x10 += s.key[6]
|
||||
x11 += s.key[7]
|
||||
|
||||
x12 += s.counter
|
||||
x13 += s.nonce[0]
|
||||
x14 += s.nonce[1]
|
||||
x15 += s.nonce[2]
|
||||
|
||||
// increment the counter
|
||||
s.counter += 1
|
||||
if s.counter == 0 {
|
||||
panic("chacha20: counter overflow")
|
||||
}
|
||||
|
||||
// pad to 64 bytes if needed
|
||||
in, out := src[i:], dst[i:]
|
||||
if i == fin {
|
||||
// src[fin:] has already been copied into s.buf before
|
||||
// the main loop
|
||||
in, out = s.buf[len(s.buf)-64:], s.buf[len(s.buf)-64:]
|
||||
}
|
||||
in, out = in[:64], out[:64] // BCE hint
|
||||
|
||||
// XOR the key stream with the source and write out the result
|
||||
xor(out[0:], in[0:], x0)
|
||||
xor(out[4:], in[4:], x1)
|
||||
xor(out[8:], in[8:], x2)
|
||||
xor(out[12:], in[12:], x3)
|
||||
xor(out[16:], in[16:], x4)
|
||||
xor(out[20:], in[20:], x5)
|
||||
xor(out[24:], in[24:], x6)
|
||||
xor(out[28:], in[28:], x7)
|
||||
xor(out[32:], in[32:], x8)
|
||||
xor(out[36:], in[36:], x9)
|
||||
xor(out[40:], in[40:], x10)
|
||||
xor(out[44:], in[44:], x11)
|
||||
xor(out[48:], in[48:], x12)
|
||||
xor(out[52:], in[52:], x13)
|
||||
xor(out[56:], in[56:], x14)
|
||||
xor(out[60:], in[60:], x15)
|
||||
}
|
||||
// copy any trailing bytes out of the buffer and into dst
|
||||
if rem != 0 {
|
||||
s.len = 64 - rem
|
||||
copy(dst[fin:], s.buf[len(s.buf)-64:])
|
||||
}
|
||||
}
|
||||
|
||||
// Advance discards bytes in the key stream until the next 64 byte block
|
||||
// boundary is reached and updates the counter accordingly. If the key
|
||||
// stream is already at a block boundary no bytes will be discarded and
|
||||
// the counter will be unchanged.
|
||||
func (s *Cipher) Advance() {
|
||||
s.len -= s.len % 64
|
||||
if s.len == 0 {
|
||||
s.buf = [len(s.buf)]byte{}
|
||||
}
|
||||
}
|
||||
|
||||
// XORKeyStream crypts bytes from in to out using the given key and counters.
|
||||
// In and out must overlap entirely or not at all. Counter contains the raw
|
||||
// ChaCha20 counter bytes (i.e. block counter followed by nonce).
|
||||
func XORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) {
|
||||
var block [64]byte
|
||||
var counterCopy [16]byte
|
||||
copy(counterCopy[:], counter[:])
|
||||
|
||||
for len(in) >= 64 {
|
||||
core(&block, &counterCopy, key)
|
||||
for i, x := range block {
|
||||
out[i] = in[i] ^ x
|
||||
}
|
||||
u := uint32(1)
|
||||
for i := 0; i < 4; i++ {
|
||||
u += uint32(counterCopy[i])
|
||||
counterCopy[i] = byte(u)
|
||||
u >>= 8
|
||||
}
|
||||
in = in[64:]
|
||||
out = out[64:]
|
||||
}
|
||||
|
||||
if len(in) > 0 {
|
||||
core(&block, &counterCopy, key)
|
||||
for i, v := range in {
|
||||
out[i] = v ^ block[i]
|
||||
}
|
||||
s := Cipher{
|
||||
key: [8]uint32{
|
||||
binary.LittleEndian.Uint32(key[0:4]),
|
||||
binary.LittleEndian.Uint32(key[4:8]),
|
||||
binary.LittleEndian.Uint32(key[8:12]),
|
||||
binary.LittleEndian.Uint32(key[12:16]),
|
||||
binary.LittleEndian.Uint32(key[16:20]),
|
||||
binary.LittleEndian.Uint32(key[20:24]),
|
||||
binary.LittleEndian.Uint32(key[24:28]),
|
||||
binary.LittleEndian.Uint32(key[28:32]),
|
||||
},
|
||||
nonce: [3]uint32{
|
||||
binary.LittleEndian.Uint32(counter[4:8]),
|
||||
binary.LittleEndian.Uint32(counter[8:12]),
|
||||
binary.LittleEndian.Uint32(counter[12:16]),
|
||||
},
|
||||
counter: binary.LittleEndian.Uint32(counter[0:4]),
|
||||
}
|
||||
s.XORKeyStream(out, in)
|
||||
}
|
||||
|
||||
16
vendor/golang.org/x/crypto/internal/chacha20/chacha_noasm.go
generated
vendored
Normal file
16
vendor/golang.org/x/crypto/internal/chacha20/chacha_noasm.go
generated
vendored
Normal file
@@ -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 !s390x gccgo appengine
|
||||
|
||||
package chacha20
|
||||
|
||||
const (
|
||||
bufSize = 64
|
||||
haveAsm = false
|
||||
)
|
||||
|
||||
func (*Cipher) xorKeyStreamAsm(dst, src []byte) {
|
||||
panic("not implemented")
|
||||
}
|
||||
30
vendor/golang.org/x/crypto/internal/chacha20/chacha_s390x.go
generated
vendored
Normal file
30
vendor/golang.org/x/crypto/internal/chacha20/chacha_s390x.go
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
// 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 s390x,!gccgo,!appengine
|
||||
|
||||
package chacha20
|
||||
|
||||
var haveAsm = hasVectorFacility()
|
||||
|
||||
const bufSize = 256
|
||||
|
||||
// hasVectorFacility reports whether the machine supports the vector
|
||||
// facility (vx).
|
||||
// Implementation in asm_s390x.s.
|
||||
func hasVectorFacility() bool
|
||||
|
||||
// xorKeyStreamVX is an assembly implementation of XORKeyStream. It must only
|
||||
// be called when the vector facility is available.
|
||||
// Implementation in asm_s390x.s.
|
||||
//go:noescape
|
||||
func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32, buf *[256]byte, len *int)
|
||||
|
||||
func (c *Cipher) xorKeyStreamAsm(dst, src []byte) {
|
||||
xorKeyStreamVX(dst, src, &c.key, &c.nonce, &c.counter, &c.buf, &c.len)
|
||||
}
|
||||
|
||||
// EXRL targets, DO NOT CALL!
|
||||
func mvcSrcToBuf()
|
||||
func mvcBufToDst()
|
||||
155
vendor/golang.org/x/crypto/internal/chacha20/chacha_test.go
generated
vendored
155
vendor/golang.org/x/crypto/internal/chacha20/chacha_test.go
generated
vendored
@@ -6,6 +6,8 @@ package chacha20
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@@ -31,3 +33,156 @@ func TestCore(t *testing.T) {
|
||||
t.Errorf("wanted %x but got %x", expected, result)
|
||||
}
|
||||
}
|
||||
|
||||
// Run the test cases with the input and output in different buffers.
|
||||
func TestNoOverlap(t *testing.T) {
|
||||
for _, c := range testVectors {
|
||||
s := New(c.key, c.nonce)
|
||||
input, err := hex.DecodeString(c.input)
|
||||
if err != nil {
|
||||
t.Fatalf("cannot decode input %#v: %v", c.input, err)
|
||||
}
|
||||
output := make([]byte, c.length)
|
||||
s.XORKeyStream(output, input)
|
||||
got := hex.EncodeToString(output)
|
||||
if got != c.output {
|
||||
t.Errorf("length=%v: got %#v, want %#v", c.length, got, c.output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Run the test cases with the input and output overlapping entirely.
|
||||
func TestOverlap(t *testing.T) {
|
||||
for _, c := range testVectors {
|
||||
s := New(c.key, c.nonce)
|
||||
data, err := hex.DecodeString(c.input)
|
||||
if err != nil {
|
||||
t.Fatalf("cannot decode input %#v: %v", c.input, err)
|
||||
}
|
||||
s.XORKeyStream(data, data)
|
||||
got := hex.EncodeToString(data)
|
||||
if got != c.output {
|
||||
t.Errorf("length=%v: got %#v, want %#v", c.length, got, c.output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Run the test cases with various source and destination offsets.
|
||||
func TestUnaligned(t *testing.T) {
|
||||
const max = 8 // max offset (+1) to test
|
||||
for _, c := range testVectors {
|
||||
input := make([]byte, c.length+max)
|
||||
output := make([]byte, c.length+max)
|
||||
for i := 0; i < max; i++ { // input offsets
|
||||
for j := 0; j < max; j++ { // output offsets
|
||||
s := New(c.key, c.nonce)
|
||||
|
||||
input := input[i : i+c.length]
|
||||
output := output[j : j+c.length]
|
||||
|
||||
data, err := hex.DecodeString(c.input)
|
||||
if err != nil {
|
||||
t.Fatalf("cannot decode input %#v: %v", c.input, err)
|
||||
}
|
||||
copy(input, data)
|
||||
s.XORKeyStream(output, input)
|
||||
got := hex.EncodeToString(output)
|
||||
if got != c.output {
|
||||
t.Errorf("length=%v: got %#v, want %#v", c.length, got, c.output)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Run the test cases by calling XORKeyStream multiple times.
|
||||
func TestStep(t *testing.T) {
|
||||
// wide range of step sizes to try and hit edge cases
|
||||
steps := [...]int{1, 3, 4, 7, 8, 17, 24, 30, 64, 256}
|
||||
rnd := rand.New(rand.NewSource(123))
|
||||
for _, c := range testVectors {
|
||||
s := New(c.key, c.nonce)
|
||||
input, err := hex.DecodeString(c.input)
|
||||
if err != nil {
|
||||
t.Fatalf("cannot decode input %#v: %v", c.input, err)
|
||||
}
|
||||
output := make([]byte, c.length)
|
||||
|
||||
// step through the buffers
|
||||
i, step := 0, steps[rnd.Intn(len(steps))]
|
||||
for i+step < c.length {
|
||||
s.XORKeyStream(output[i:i+step], input[i:i+step])
|
||||
if i+step < c.length && output[i+step] != 0 {
|
||||
t.Errorf("length=%v, i=%v, step=%v: output overwritten", c.length, i, step)
|
||||
}
|
||||
i += step
|
||||
step = steps[rnd.Intn(len(steps))]
|
||||
}
|
||||
// finish the encryption
|
||||
s.XORKeyStream(output[i:], input[i:])
|
||||
|
||||
got := hex.EncodeToString(output)
|
||||
if got != c.output {
|
||||
t.Errorf("length=%v: got %#v, want %#v", c.length, got, c.output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test that Advance() discards bytes until a block boundary is hit.
|
||||
func TestAdvance(t *testing.T) {
|
||||
for _, c := range testVectors {
|
||||
for i := 0; i < 63; i++ {
|
||||
s := New(c.key, c.nonce)
|
||||
z := New(c.key, c.nonce)
|
||||
input, err := hex.DecodeString(c.input)
|
||||
if err != nil {
|
||||
t.Fatalf("cannot decode input %#v: %v", c.input, err)
|
||||
}
|
||||
zeros, discard := make([]byte, 64), make([]byte, 64)
|
||||
so, zo := make([]byte, c.length), make([]byte, c.length)
|
||||
for j := 0; j < c.length; j += 64 {
|
||||
lim := j + i
|
||||
if lim > c.length {
|
||||
lim = c.length
|
||||
}
|
||||
s.XORKeyStream(so[j:lim], input[j:lim])
|
||||
// calling s.Advance() multiple times should have no effect
|
||||
for k := 0; k < i%3+1; k++ {
|
||||
s.Advance()
|
||||
}
|
||||
z.XORKeyStream(zo[j:lim], input[j:lim])
|
||||
if lim < c.length {
|
||||
end := 64 - i
|
||||
if c.length-lim < end {
|
||||
end = c.length - lim
|
||||
}
|
||||
z.XORKeyStream(discard[:], zeros[:end])
|
||||
}
|
||||
}
|
||||
|
||||
got := hex.EncodeToString(so)
|
||||
want := hex.EncodeToString(zo)
|
||||
if got != want {
|
||||
t.Errorf("length=%v: got %#v, want %#v", c.length, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkChaCha20(b *testing.B) {
|
||||
sizes := []int{32, 63, 64, 256, 1024, 1350, 65536}
|
||||
for _, size := range sizes {
|
||||
s := size
|
||||
b.Run(fmt.Sprint(s), func(b *testing.B) {
|
||||
k := [32]byte{}
|
||||
c := [16]byte{}
|
||||
src := make([]byte, s)
|
||||
dst := make([]byte, s)
|
||||
b.SetBytes(int64(s))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
XORKeyStream(dst, src, &c, &k)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
578
vendor/golang.org/x/crypto/internal/chacha20/vectors_test.go
generated
vendored
Normal file
578
vendor/golang.org/x/crypto/internal/chacha20/vectors_test.go
generated
vendored
Normal file
@@ -0,0 +1,578 @@
|
||||
// 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 chacha20
|
||||
|
||||
// Test vectors for ChaCha20 implementations.
|
||||
|
||||
type testCase struct {
|
||||
length int
|
||||
nonce [3]uint32
|
||||
key [8]uint32
|
||||
input string
|
||||
output string
|
||||
}
|
||||
|
||||
var testVectors = [...]testCase{
|
||||
{
|
||||
length: 0,
|
||||
nonce: [3]uint32{0x94d13317, 0x6b6a2b3, 0x3ffe0036},
|
||||
key: [8]uint32{0x9da8a3b6, 0x3abf4ae6, 0xa2f19cae, 0x1068c707, 0x72e4801e, 0xce165d92, 0x61e7028f, 0x82ac3d57},
|
||||
input: "",
|
||||
output: "",
|
||||
},
|
||||
{
|
||||
length: 5,
|
||||
nonce: [3]uint32{0x469fadd, 0xee3fcc1e, 0x45cf77b0},
|
||||
key: [8]uint32{0x3477e02b, 0x45bf809f, 0x27f4a1fa, 0xdb901de8, 0xd8a190dc, 0x1d2c21d4, 0x87bdf2ac, 0xdfbf0000},
|
||||
input: "23dbad0780",
|
||||
output: "415a3e498d",
|
||||
},
|
||||
{
|
||||
length: 9,
|
||||
nonce: [3]uint32{0x512a6b49, 0x8df9af6d, 0x5336a2a5},
|
||||
key: [8]uint32{0xe9124c25, 0x4fd1a373, 0x7945f7bb, 0xeed5f064, 0x29c4185d, 0x3c9acf13, 0x4c94a367, 0x7c2c2c53},
|
||||
input: "f518831fab69c054a6",
|
||||
output: "cfe40f63f81391484b",
|
||||
},
|
||||
{
|
||||
length: 12,
|
||||
nonce: [3]uint32{0xca697a9e, 0x6b2f6717, 0xb7859220},
|
||||
key: [8]uint32{0xfc825020, 0x5ca4410b, 0x7d5285d0, 0x160a1c9d, 0x15470b41, 0x3634742a, 0xe64aa7fa, 0xca0be67a},
|
||||
input: "805fad1d62951537aeed9859",
|
||||
output: "47bd303f93c3ce04bce44710",
|
||||
},
|
||||
{
|
||||
length: 14,
|
||||
nonce: [3]uint32{0xcded3db3, 0x35770a7f, 0x6aede9b},
|
||||
key: [8]uint32{0x44632def, 0xa5e420a7, 0xfc12a8f, 0x63b79a15, 0x337de314, 0xb82fbf16, 0x3104bc57, 0x677c9227},
|
||||
input: "f4e8a7577affb841cf48392cf5df",
|
||||
output: "f445c0fb7e3d5bfdab47090ddee6",
|
||||
},
|
||||
{
|
||||
length: 15,
|
||||
nonce: [3]uint32{0x348a50b1, 0x4acc9280, 0x8d6014ce},
|
||||
key: [8]uint32{0x34bd31a8, 0x2808f47e, 0x9d8b19f9, 0x4df59683, 0x31584348, 0x34a74a45, 0xde174a2, 0x29d4c7dc},
|
||||
input: "1179b71ec4dc34bd812f742b5a0b27",
|
||||
output: "cc7f80f333c647d6e592e4f7ecc834",
|
||||
},
|
||||
{
|
||||
length: 20,
|
||||
nonce: [3]uint32{0xc8754703, 0x9188c521, 0xac8ce8a6},
|
||||
key: [8]uint32{0xe93c79ed, 0xce89162b, 0x116a8366, 0xecdc657f, 0x5bc81d98, 0xff5d2f52, 0x171f3ebb, 0x50773f2f},
|
||||
input: "7bd94943d55392d0311c413ac755ce0347872ba3",
|
||||
output: "c43665de15136af232675d9d5dbbeca77f3c542a",
|
||||
},
|
||||
{
|
||||
length: 21,
|
||||
nonce: [3]uint32{0x9a8655cb, 0x6e9d6ea5, 0x5dad705e},
|
||||
key: [8]uint32{0x3542d5b3, 0x1f7bfd8f, 0x1038abf8, 0x7214e8ec, 0xedd05693, 0x60e663bd, 0xe8e5d506, 0xeea923a2},
|
||||
input: "1505f669acc5ad9aaa0e993ba8c24e744d13655e1f",
|
||||
output: "26cad1ccf4cf4c49b267ab7be10bc2ffa3ba66bc86",
|
||||
},
|
||||
{
|
||||
length: 25,
|
||||
nonce: [3]uint32{0x3f202ca4, 0x63fc86, 0x7260a10e},
|
||||
key: [8]uint32{0xe28ab1d6, 0xe83b3d47, 0x671271ca, 0xb977bcff, 0xa2f64476, 0x311d79b4, 0x180d91d0, 0xec1a6e0c},
|
||||
input: "20070523ddb4ebf0d5f20fd95aacf47fb269ebadda6879638a",
|
||||
output: "5ce972624cb2b7e7c28f5b865ba08c887911b4f5e361830a4b",
|
||||
},
|
||||
{
|
||||
length: 31,
|
||||
nonce: [3]uint32{0xcf8671ea, 0x8d72df2f, 0x8b5a538a},
|
||||
key: [8]uint32{0xe46ca2bb, 0xd06ab5ef, 0xb0e2966b, 0x54dd0c2d, 0x8815d89a, 0x426c30a9, 0x15b0f1e, 0x254bae75},
|
||||
input: "d10f8050c1186f92e26f351db36490d82ea677498562d8d4f487a0a4058adf",
|
||||
output: "f30c11bc553b2baf6870760d735680897c9fee168f976b2a33ef395fdbd4fc",
|
||||
},
|
||||
{
|
||||
length: 34,
|
||||
nonce: [3]uint32{0xd1be983a, 0xf5aa389, 0xfa26c7e1},
|
||||
key: [8]uint32{0x795c6da7, 0x8cb1aadc, 0xa042359a, 0x95ea2e27, 0x128253c4, 0xaabc592f, 0x391e810, 0xf641d971},
|
||||
input: "e88dc380b7d45a4a762c34f310199587867516fac4a2634022b96a9f862e17714d17",
|
||||
output: "aac98ba3821399e55a5eab5862f7f1bfc63637d700125878c2b17151f306c9aec80e",
|
||||
},
|
||||
{
|
||||
length: 34,
|
||||
nonce: [3]uint32{0x98f5f4b8, 0x3f181d73, 0x5bf4572e},
|
||||
key: [8]uint32{0xa86f8cf7, 0x8db41a2b, 0xe0e03156, 0x3dad8a59, 0xb3e4d1ba, 0x75f6fb38, 0xdb94709d, 0xc3db34f3},
|
||||
input: "b0fcf0a731e2902787309697db2384e1cda07b60002c95355a4e261fb601f034b2b3",
|
||||
output: "b6c8c40ddda029a70a21c25f724cc90c43f6edc407055683572a9f5e9690a1d571bb",
|
||||
},
|
||||
{
|
||||
length: 40,
|
||||
nonce: [3]uint32{0x7289ae18, 0x7ebe7e50, 0x7d819176},
|
||||
key: [8]uint32{0x336c07a0, 0x4a2ea22b, 0xa8872f46, 0xa47b5e28, 0xbe645e3f, 0x371c6591, 0xd2dc237a, 0x92c59580},
|
||||
input: "cf9ec6fa3f0a67488adb5598a48ed916729a1e416d206f9675dfa9fd6585793f274f363bbca348b3",
|
||||
output: "bb7ed8a199aa329dcd18736ce705804ffae8c3e2ba341ae907f94f4672d57175df25d28e16962fd6",
|
||||
},
|
||||
{
|
||||
length: 47,
|
||||
nonce: [3]uint32{0xfd3181de, 0x8b193e26, 0xbebc799},
|
||||
key: [8]uint32{0x781a4c2e, 0x27ab55e2, 0x814aaf43, 0xa0bab01, 0x9de62ce0, 0x472b03d2, 0xdfee18e8, 0x8b855b93},
|
||||
input: "be9a8211d68642310724eda3dd02f63fcc03a101d9564b0ecee6f4ecececcb0099bb26aabee46b1a2c0416b4ac269e",
|
||||
output: "3152f317cf3626e26d02cff9392619ea02e22115b6d43d6dd2e1177c6bb3cb71c4a90c3d13b63c43e03605ec98d9a1",
|
||||
},
|
||||
{
|
||||
length: 51,
|
||||
nonce: [3]uint32{0x27b02ff6, 0xa510613e, 0x218b22d8},
|
||||
key: [8]uint32{0x62fc7732, 0xcef06cf4, 0xa4f45ed5, 0x2f96654f, 0x9f2b956e, 0x42b572f4, 0x5bb59c86, 0x35e4784f},
|
||||
input: "495343a257250f8970f791f493b89d10edba89806b88aaaeb3b5aefd078ba7b765746164bce653f5e6c096dd8499fb76d97d77",
|
||||
output: "62c01f426581551b5b16e8b1a3a23c86bcdd189ab695dbea4bf811a14741e6ebbb0261ef8ae47778a6be7e0ef11697b891412c",
|
||||
},
|
||||
{
|
||||
length: 52,
|
||||
nonce: [3]uint32{0x9db97a63, 0xff50248, 0xf2b6df56},
|
||||
key: [8]uint32{0x2b657a8f, 0xfe67575d, 0xaa56d261, 0x30179a97, 0xaefcfff1, 0x9b8eb698, 0x1efe3756, 0xb4ea450c},
|
||||
input: "e37fbbd3fe37ce5a99d18e5dcb0dafe7adf8b596528708f7d310569ab44c251377f7363a390c653965e0cb8dd217464b3d8f79c1",
|
||||
output: "b07d4c56fb83a49e8d9fc992e1230bb5086fecbd828cdbc7353f61b1a3cec0baf9c5bf67c9da06b49469a999ba3b37916ec125be",
|
||||
},
|
||||
{
|
||||
length: 56,
|
||||
nonce: [3]uint32{0xc1dfec38, 0x7d7503d3, 0x9a3e3c66},
|
||||
key: [8]uint32{0x8614d8e7, 0xde9b0413, 0x2a48b4fa, 0xcbbde744, 0xad5ddc5e, 0x9144d83e, 0x74d9d617, 0x230bdb45},
|
||||
input: "9efab614388a7d99102bcc901e3623d31fd9dd9d3c3338d086f69c13e7aa8653f9ce76e722e5a6a8cbbbee067a6cb9c59aa9b4b4c518bbed",
|
||||
output: "829d9fe74b7a4b3aeb04580b41d38a156ffbebba5d49ad55d1b0370f25abcd41221304941ad8e0d5095e15fbd839295bf1e7a509a807c005",
|
||||
},
|
||||
{
|
||||
length: 63,
|
||||
nonce: [3]uint32{0xc7e2521c, 0x795499b4, 0xc7946cd7},
|
||||
key: [8]uint32{0x53fce774, 0x9a4b53bf, 0x5f614134, 0xa3c39414, 0xa8a07c72, 0x93242311, 0x43aeec99, 0x216deb5a},
|
||||
input: "03b5d7ab4bd8c9a4f47ec122cbeb595bd1a0d58de3bb3dcc66c4e288f29622d6863e846fdfb27a90740feb03a4761c6017250bc0f129cc65d19680ab9d6970",
|
||||
output: "83db55d9eb441a909268311da67d432c732ad6bda0a0dae710d1bce040b91269deb558a68ced4aa5760ca0b9c5efc84e725f297bdbdadbc368bea4e20261c5",
|
||||
},
|
||||
{
|
||||
length: 66,
|
||||
nonce: [3]uint32{0x1d41f0a1, 0x7c3b7778, 0x6991eea5},
|
||||
key: [8]uint32{0x1f213e39, 0x56261d14, 0x15fc7c2c, 0x21feccc5, 0xa95684c5, 0x26600506, 0xdadcc06b, 0xf2c810b0},
|
||||
input: "2f4da518578a2a82c8c855155645838ca431cdf35d9f8562f256746150580ca1c74f79b3e9ae78224573da8b47a4b3cc63fbed8d4e831a6b4d796c124d87c78a66e5",
|
||||
output: "6fc086ded3d1d5566577ccd9971e713c1126ec52d3894f09ab701116c7b5abda959cbb207f4468eb7b6a6b7e1b6d2bc6047f337499d63522f256ee751b91f84f70b6",
|
||||
},
|
||||
{
|
||||
length: 72,
|
||||
nonce: [3]uint32{0x749f022c, 0xa021dab0, 0x648c2252},
|
||||
key: [8]uint32{0xa1ace7b0, 0x567a0ea1, 0x52af13b9, 0xcba30c08, 0xe07a6d74, 0x5c3bca39, 0x85b2ac07, 0x3b5afc0},
|
||||
input: "55739a1738b4a4028021b21549e2661b050e3d830ad9a56f57bfcaca3e0f72051b9ca92411840061083e5e45124d8425061ab26c632ac7852118411ac80026da946357c630f27225",
|
||||
output: "8051bf98f8f2617e159ba205a9342ab700973dd045e09321805eed89e419f37f3211c5aa82666b9a097270babc26d3bfe0c990fe245ae982a31f23cfbf6156b5c8cfb77f340e2bf5",
|
||||
},
|
||||
{
|
||||
length: 74,
|
||||
nonce: [3]uint32{0x23c16ba8, 0x9fd1cd4e, 0xcb224ecb},
|
||||
key: [8]uint32{0xb694404a, 0x86b5f198, 0x10fd1bff, 0x13a84e54, 0xab21e509, 0x7443d764, 0x931b3f1, 0x686e87f2},
|
||||
input: "7ffd8d5970fdee613eeae531d1c673fd379d64b0b6bfedd010433b080b561038f7f266fa7e15d7d8e10d23f21b9d7724bb200b0f58b9250483e784f4a6555d09c234e8d1c549ebb76a8e",
|
||||
output: "c173617e36ea20ce04c490803b2098bd4f1ff4b31fdca1c51c6475ade83892c5f12731652d5774631d55ae2938617a5e9462bb6083328a23a4fba52de50ca9075586f2efc22aae56e3a8",
|
||||
},
|
||||
{
|
||||
length: 81,
|
||||
nonce: [3]uint32{0xd65f6f29, 0xf3f76219, 0x9a033c9e},
|
||||
key: [8]uint32{0xeba017c4, 0x69e0421a, 0x449e2317, 0x29858a11, 0xd0c8523a, 0xa8b0c9a2, 0xab2ca84, 0xaf011a45},
|
||||
input: "7a5766097562361cfaeac5b8a6175e1ceeeda30aec5e354df4302e7700ea48c505da9fdc57874da879480ecfea9c6c8904f330cbac5e27f296b33b667fea483348f031bef761d0b8e318a8132caa7a5943",
|
||||
output: "5e9fbf427c4f0fcf44db3180ea47d923f52bee933a985543622eff70e2b3f5c673be8e05cd7acbcadd8593da454c60d5f19131e61730a73b9c0f87e3921ee5a591a086446b2a0fadd8a4bc7b49a8e83764",
|
||||
},
|
||||
{
|
||||
length: 88,
|
||||
nonce: [3]uint32{0xc70ee56e, 0xe58ec41, 0xafd96f61},
|
||||
key: [8]uint32{0x172af2bb, 0x9085d27c, 0x8ca2c44d, 0x8aa148da, 0x290c88b0, 0x88187439, 0x18d54781, 0x633f2cce},
|
||||
input: "0777c02a2900052d9b79f38387d2c234108a2ad066cbf7df6ea6acc5a3f86b3d6156abb5b18ad4ecf79e171383a1897e64a95ecdbba6aa3f1c7c12fe31283629ff547cb113a826cb348a7c10507cc645fa2eb97b5f22e44d",
|
||||
output: "368c90db3464ba488340b1960e9f75d2c3b5b392bdd5622ff70e85e6d00b1e6a996ba3978ce64f8f2b5a9a90576c8f32b908233e15d2f443cccc98af87745c93c8056603407a3fb37ce0c1f8ab6384cc37c69c98bfecf337",
|
||||
},
|
||||
{
|
||||
length: 92,
|
||||
nonce: [3]uint32{0x3006da79, 0x2748051d, 0x72c17cdc},
|
||||
key: [8]uint32{0x60cdb7e8, 0xcecbe928, 0xe19b7ab9, 0x30d61537, 0xa0fbc199, 0x897738bf, 0xdd7705a9, 0x3e5c1763},
|
||||
input: "cf2dccbcfd781c030376f9019d841ca701cb54a1791f50f50bee0c2bf178182603a4712b5916eebd5001595c3f48283f1ba097ce2e7bf94f2b7fa957ce776e14a7a570093be2de386ececbd6525e72c5970c3e7d35974b8f0b831fbc",
|
||||
output: "7c92b8c75e6eb8675229660cedcb10334965a7737cde7336512d9eff846c670d1fa8f8a427ea4f43e66be609466711fd241ccff7d3f049bda3a2394e5aa2108abc80e859611dbd3c7ba2d044a3ececa4980dd65e823dd110fea7a548",
|
||||
},
|
||||
{
|
||||
length: 96,
|
||||
nonce: [3]uint32{0xfc0fb1ee, 0x414cc60a, 0x4144bd67},
|
||||
key: [8]uint32{0x103291c6, 0x822b03b6, 0xd29ab548, 0xc88f3efe, 0x6936056a, 0x28aaa61f, 0xa0df7858, 0xdaa23519},
|
||||
input: "e08a8949a1bfd6a8c1186b431b6ad59b106ae5552821db69b66dc03fbc4a2b970dcf9c7da4f5082572bc978f8ee27c554c8884b5a450b36d70453348cd6cac9b80c9900cf98a4088803f564bb1281d24507b2f61ba737c8145c71b50eb0f6dfc",
|
||||
output: "73d043acf9dcd758c7299bd1fd1f4100d61ff77d339e279bfbe6f9233b0d9afa24992a9c1c7a19545d469fdfb369c201322f6fe8c633fcdcffef31032bfb41b9fb55506e301d049fd447d61f974a713debeaed886f486a98efd3d6c3f25fbb30",
|
||||
},
|
||||
{
|
||||
length: 103,
|
||||
nonce: [3]uint32{0xc2030c57, 0x1e3b59e1, 0x607ede1a},
|
||||
key: [8]uint32{0xd1bac2b5, 0x56a94583, 0x628b479b, 0x3056a51e, 0x69bf8f8f, 0x2df1e03d, 0x4b9d48d2, 0x7df5c379},
|
||||
input: "a0c302120111f00c99cff7d839cdf43207a7e2f73d5dd888daa00d84254db0e621a72493480420c9c61ce1cfc54188ff525bb7a0e6c1cd298f598973a1de9fd2d79a21401588775b0adbe261ba4e4f79a894d1bd5835b5924d09ba32ef03cb4bc0bd6eb4ee4274",
|
||||
output: "bc714bd7d8399beedc238f7ddeb0b99d94ad6bf8bf54548a3e4b90a76aa5673c91db6482591e8ff9126e1412bce56d52a4c2d89f22c29858e24482f177abacef428d0ae1779f0ae0778c44f9f02fe474da93c35c615b5fad29eca697978891f426714441317f2b",
|
||||
},
|
||||
{
|
||||
length: 109,
|
||||
nonce: [3]uint32{0xf44dc81f, 0xcf6e03e7, 0xf4966796},
|
||||
key: [8]uint32{0xd7b12f4, 0x683f4789, 0xc7828fb4, 0x820fc6a0, 0xc51231eb, 0xe46716d7, 0x4036ef93, 0x26afb96c},
|
||||
input: "ebce290c03c7cb65d053918ba2da0256dc700b337b8c124c43d5da4746888ca78387feea1a3a72c5e249d3d93a1907977dd4009699a15be5da2ca89c60e971c8df5d4553b61b710d92d3453dea595a0e45ae1e093f02ea70608b7b32f9c6aadc661a052f9b14c03ea0117a3192",
|
||||
output: "cbb8c4ec827a1123c1141327c594d4a8b0b4a74b0008115bb9ec4275db3a8e5529a4f145551af29c473764cbaa0794b2d1eb1066f32a07fd39f5f3fe51498c46fba5310ae7c3664571d6a851e673ded3badc25e426f9c6038724779aa6d2d8ec3f54865f7df612e25575635ab5",
|
||||
},
|
||||
{
|
||||
length: 115,
|
||||
nonce: [3]uint32{0x8d3e461b, 0x7e05c360, 0x3bbbafdd},
|
||||
key: [8]uint32{0xf9b917c9, 0x9af89bf7, 0x7decbbc9, 0xe7e5ea7b, 0x9b4aab55, 0x90eff6be, 0xa19b6d90, 0xb9f69b1a},
|
||||
input: "275c97de985aa265332065ccce437770b110737a77dea62137a5d6cb62e9cb8b504d34334a58a71aba153d9b86f21377467b2fafaf54829331bf2ce0009acb37842b7a4b5f152aab650a393153f1ed479abc21f7a6fe205b9852ff2f7f3a0e3bfe76ca9770efada4e29e06db0569a99d08648e",
|
||||
output: "b225aa01d5c438d572deaea51ac12c0c694e0f9dc0ed2884a98e5e2943d52bb4692d7d8f12486de12d0559087e8c09e4f2d5b74e350838aa2bd36023032ccbcae56be75c6a17c59583d81a1fd60e305af5053ac89f753c9347f3040e48405232dc8428c49dcb3d9b899145f5b3bc955f34dbbe",
|
||||
},
|
||||
{
|
||||
length: 119,
|
||||
nonce: [3]uint32{0x871f33f5, 0xe4fee3ba, 0xcb8c1e93},
|
||||
key: [8]uint32{0x33124903, 0x7e0287e5, 0xe9d6988f, 0x1962405f, 0x5f21c1b5, 0x2ac695e6, 0x46b200c9, 0x9fda98ba},
|
||||
input: "ceda15cfffd53ccebe31b5886facd863f6166e02ec65f46f54148860a5c2702e34fd204d881af6055952690cd1ffa8ba4d0e297cc165d981b371932adb935398c987baff335108c5e77f2e5dd5e1ca9a017bc376cbdbe3c0f45e079c212e8986b438444e79cd37927c1479f45c9e75b0076cc9f8679011",
|
||||
output: "a3f1c3f885583b999c85cd118e2ababfa5a2de0c8eb28aacc161b1efee89d8de36ddeb584174c0e92011b8d667cb64009049976082072e6262933dbf7b14839805e1face375b7cbb54f9828ba1ed8aa55634ec5d72b6351feff4d77a3a22b34203b02e096f5e5f9ae9ad6a9dd16c57ce6d94dcc8873d18",
|
||||
},
|
||||
{
|
||||
length: 120,
|
||||
nonce: [3]uint32{0xef553ce8, 0xdfe120ea, 0x9a047e3a},
|
||||
key: [8]uint32{0xbef479c1, 0x59554f8b, 0xbf97f089, 0x52316f1e, 0x141e428, 0xff26dc04, 0xe10c8f57, 0xa7568a59},
|
||||
input: "799bb2d634406753416b3a2b67513293a0b3496ef5b2d019758dedaaac2edd72502fc4a375b3f0d4237bc16b0e3d47e7ddc315c6aef3a23fcae2eb3a6083bc7ac4fd1b5bf0025cc1cb266b40234b77db762c747d3a7b27956cf3a4cf72320fb60c0d0713fa60b37a6cb5b21a599e79d0f06a5b7201aeb5d2",
|
||||
output: "e84dfb3dbaac364085497aeabd197db852d3140c0c07f5f10e5c144c1fe26a50a9877649e88c6fe04283f4b7590a8d0d042ef577693f76f706e31c4979437590fe0ab03d89afb089d1be50ae173ea5458810372838eceac53bf4bac792735d8149e548efb432e236da92bf3168bbcf36f644c23efb478a4e",
|
||||
},
|
||||
{
|
||||
length: 123,
|
||||
nonce: [3]uint32{0xd98124a0, 0x78cd80aa, 0x3dc55cfc},
|
||||
key: [8]uint32{0x2286e41, 0xf13e38e3, 0xf735476b, 0x33c44bfc, 0xd7978797, 0x4a9c4595, 0x6080413, 0x1299fdd8},
|
||||
input: "b2d060bd173955f44ee01b8bfcf0a6fad017c3517e4e8c8da728379f6d54471c955615e2b1effe4ce3d0139df225223c361be1cac416ade10a749c5da324563696dae8272577e44e8588cd5306bff0bfbdb32af3ac7cbc78be24b51baf4d5e47cf8f1d6b0a63ed9359da45c3e7297b2314028848f5816feab885e2",
|
||||
output: "ffa4aa66dd5d39694ae64696bfa96f771accef68f195456ad815751e25c47ed4f27b436f1b3e3fcaa3e0d04133b53559c100cd633ced3d4321fc56225c85d2443727bce40434455aa4c1f3e6768c0fe58ad88b3a928313d41a7629f1ce874d2c8bcf822ebdaebfd9d95a31bb62daab5385eb8eefe026e8cbf1ff7a",
|
||||
},
|
||||
{
|
||||
length: 127,
|
||||
nonce: [3]uint32{0x53106b0f, 0xdf11fd81, 0x69d1b6f3},
|
||||
key: [8]uint32{0x736b138, 0x55cde194, 0xf8273c1, 0xf7c268e6, 0x61362bd5, 0xbb3cb455, 0x44d3c9fc, 0x7d56d3fd},
|
||||
input: "4f0171d7309493a349530940feece3c6200693f9cff38924114d53f723d090fffa3c80731b5ca989d3e924d1fa14266632cb9ab879e1a36df22dc9f8d1dadea229db72fded0c42187c38b9fa263c20e5fb5b4aa80eb90e8616e36d9b8c613b371c402343823184ecad3532058a46cf9e7ea5a9ecad043ac3028cbcc3f36d32",
|
||||
output: "88c773ff34b23e691e14018ba1b2bd48a4a6979b377eb0d68336ce6192dcd5177e6b4f1c4bea2df90af56b35fe2a1d6279d253c0194dcbca9bf136f92d69165b216e4c9d1ce6b3fbe40c71e32c3f4088de352732d0e2bad9c16fd0bb9bde3d6c30257ce063432d09f19da79d49aa7641124a6c9e3f09449e911edbae11a053",
|
||||
},
|
||||
{
|
||||
length: 130,
|
||||
nonce: [3]uint32{0x5e90ffbd, 0xa898f173, 0x269f9a88},
|
||||
key: [8]uint32{0x5244e05f, 0xf9adbe9b, 0x9e9f54ac, 0x23460046, 0x6782cdea, 0xba982c96, 0xc721506b, 0xed10f7e3},
|
||||
input: "8f8d9e18d3212bd20b96d75c06d1a63622fd83d13f79d542e45996135368772ea81511302a0d87e246dd346314cfe019bae8a5c97f567f12d82aca98dfea397c6a47dd0c419f1c609d9c52dcfcbe7eee68b2635954206ed592b7081442ce9ce3187d10ccd41cc856fb924b011f817c676c9419f52a2938c7af5f76755a75eb065411",
|
||||
output: "4e130c5df384b9c3c84aa38a744260735e93783da0337ade99f777e692c5ea276ac4cc65880b4ae9c3b96888760fdddb74bc2e2694bedf1ee6f14619c8015f951ba81b274b466e318d09defe80bdbed57bc213ac4631d2eb14c8e348181d60f6295ceee1e9231ae047830ef4778ff66146621b76974773b5d11c8e17a476450f46ef",
|
||||
},
|
||||
{
|
||||
length: 130,
|
||||
nonce: [3]uint32{0x308e39e8, 0x9aa4f14f, 0xf511db96},
|
||||
key: [8]uint32{0x833b5219, 0x4b82e588, 0x4b2d652c, 0x7c8f6ed7, 0xfe4be863, 0x9d3a50e5, 0xb888099b, 0x9f8d1968},
|
||||
input: "30d2379dd3ceae612182576f9acf6de505ab5a9445fe1a86ae75c5c29429e11c50fd9ec657b29b173a3763b1e171b5a7da1803ba5d64fccb2d32cb7788be194dbca00c3c91774c4c4c8ede48c1027d7cc8b387101a4fe5e44a1d9693b2f627626025072806083aadbced91c9711a0171f52ffb8ed5596cf34130022398c8a1da99c7",
|
||||
output: "b1e8da34ad0189038ee24673979b405ef73fdbdd6f376f800031d64005a4ebed51a37f2180571223848decbea6dd22b198ab9560d7edc047c5d69183dc69b5fca346911d25cb2a1a9f830dc6382ad0024e8c3eef3aa2d155abcfe43bff01956a5e20a862fbed5c5e8df8eed0601a120caac634b068314e221f175baa11ae29002bb9",
|
||||
},
|
||||
{
|
||||
length: 135,
|
||||
nonce: [3]uint32{0xa5feca5a, 0x753ac1b4, 0xc5a46609},
|
||||
key: [8]uint32{0xabbf4859, 0x828d9bf6, 0xf7f7aa6d, 0x25208ca2, 0xd7a4c0ad, 0x2fdd3282, 0x2bfcb8c2, 0x8389d84b},
|
||||
input: "d9404ccdcc8ef128a1b1ace4f9f1669d274ec82aa914cac34b83ac00b236478fd6167e96ec658850c6c139eb0f6fc0dd7191ba9a39828032008f7f37eb9a8df9d6cdd54240e600efe7fc49a674000c5030d825b2c5c96d0f19b8ecdbf4eeb86d3e569c5e3131abc7d6359dd4255284ccacf150d42e7a899536d51ee6db329654a4581c5ac6e419",
|
||||
output: "c5534b5fb40b4834300e9577a9d87440c5272263d06e6aee84aa92cdf5d1b033145d336f26e5fe55c09a7e75753af93d0786dfc1cb435e86c67bd3ec8e766d0801b99e68691e2c3c3ffec539cf62e68285ea9027daa2716cd6f97e8eb7b9e266357a25eb2d4839a829508a6b7228f2832b3cd998f77597ae530430e6e4ecb53eb9efe456863a04",
|
||||
},
|
||||
{
|
||||
length: 135,
|
||||
nonce: [3]uint32{0x12aa5846, 0x88604f6c, 0xc10d9585},
|
||||
key: [8]uint32{0x1491ccd6, 0x602f559d, 0xd4080c06, 0x202fabd, 0xffd3f4f8, 0xbf144c17, 0x88bf3f3c, 0x8083375},
|
||||
input: "231765f832927461f338aceb0f4cf51fd8469348c69c549c1dec7333d4aa4968c1ed58b65ab3fe3d0562600a2b076d56fd9ef91f589752e0455dd1d2e614cacfc0d757a11a4a2264bd38f23d3cca108632201b4f6c3b06477467726dde0c2f3aee01d66d788247663f1d0e66b044da9393ede27b9905b44115b067914961bdade85a2eca2844e1",
|
||||
output: "1dd35f3f774f66d88cb7c2b23820ee078a093d0d85f86c4f103d869f93e2dbdd8a7cb8f101084fe1d7281a71754ec9aac5eb4fca8c365b24ed80e695caace1a8781a5a225938b50b8be96d0499752fdabd4f50d0b6ce396c6e2ca45308d1f2cc5a2a2361a8ca7a334e6ee62d466d74a1b0bf5b352f4ef6d8f8c589b733748bd3d7cda593243fab",
|
||||
},
|
||||
{
|
||||
length: 140,
|
||||
nonce: [3]uint32{0x1c9d70f0, 0xa088a367, 0x4ec24d2b},
|
||||
key: [8]uint32{0x494e9775, 0xd07a852, 0xaf8af24a, 0xc65b825c, 0xc5e06780, 0x17fbbace, 0x651d71b5, 0xf548d8ef},
|
||||
input: "e46841f12d98aeb7710b9162d342895a971b0e3a499886bbb6aa74dc744a28d89a54542b628acdc2f693cb7c03f73fc3b74069bc3f2d000a145fb8a806cdc7d6fa971da09a33b92851cc3d1f6f5646d7fa2b1d564876feefeb63b6e66dba1c0b86ca345235bb822e0f93132346840d2a3d6eb1b541178ea51affc7b31f8da02732cc4e5bcb5d8683ae0a91c9",
|
||||
output: "1dcbfd0bb2b905656c52bd7b1bcdad9b4d434ae9ac221a0d3a316115cdd4a463fa9b3444d2612a4e277d0dcd881fa6e80e59e5a54e35e1a14747aed31edf4ac24214f9d9c329ebe2157620b64efaded9976549bc4aa100d5c15be3f85f700f8a21dfe77590dfee2de9a23cc1ed1e44f32ebf68ca289b097bc13b42802dc7c75309c4afc25b5741839f7db3d5",
|
||||
},
|
||||
{
|
||||
length: 144,
|
||||
nonce: [3]uint32{0x23067b8b, 0x5b276c6d, 0xaeca6c60},
|
||||
key: [8]uint32{0x29d64488, 0x893a2973, 0x32e3b4ef, 0x2af3d5d4, 0x95ec01b, 0xc805b64c, 0x884e8b7d, 0x798d7062},
|
||||
input: "e98e4a9550bdd29e4106f0cc8669dcc646a69438408e9a72c7cdb9b9d437b5f7a13fcb197629541c55bca1f8972a80cd1c1f591a0e24f977cdeb84763eab2648e42286e6473ea95e3a6a43b07a32b6a6cd80fe007ba0cf7f5ac7e651431f5e72690ec52a7134f9757daf0d8eff6b831a229db4ab8288f6bbf81e16fedebe621fd1737c8792cfd15fb3040f4f6a4cbc1e",
|
||||
output: "5c69cf522c058790a3bc38979e172b60e71f7896d362d754edc1668d4f388b3fc0acdf40786d2f34886e107a142b1e724b9b9b171cb0e38fd78b35f8ac5269d74296c39c9f8628d848f57af9d8525a33f19021db2b9c64ba113171ebb3882075019ec7e77b51ce80b063ed41d48dad481d9536c030002a75d15c1c10ce0ec3ff17bc483f8416055a99b53035f4b6ea60",
|
||||
},
|
||||
{
|
||||
length: 148,
|
||||
nonce: [3]uint32{0x2b079658, 0xbdf5da85, 0x8a75450d},
|
||||
key: [8]uint32{0x49c9eaa3, 0x62048819, 0x9baacfa5, 0x3870addc, 0x5c682e1, 0xf4f9fff3, 0xa3848e4b, 0xac1ebc1},
|
||||
input: "ce0f0d900dd0d31749d08631ec59f216a1391f66a73bae81d3b0e2919a461bc9a14d6a01b827e3bcb55bbccf27c1ed574157e6becd5cf47181a73c9d3e865ab48a20551027e560e965876b0e1a256bfa5cb5179bf54bd8ec65e5570e374b853b37bf4b3ef1ec612d288ebc19275fa88da9419e012f957f9b6a7e375b3377db0eb3619c731aebfeb0930772b4020d3a3e90723e72",
|
||||
output: "b06981b57fe184091ef9f8ccf522a5bcdb59bf9a68a3ddb817fdd999a6ecf81053a602141cf1b17017bae592b6b6e64756631a2b29a9e1b4f877c8b2ae30f71bc921e4f34b6f9cd8e587c57a30245f80e95005d0f18f5114400785140e6743da352d921fb4a74632a9c40115ad7706263ac9b41a11609fa0c42fc00f8d60931976162598df63ebad9496dd8943d25a03fa47475c",
|
||||
},
|
||||
{
|
||||
length: 148,
|
||||
nonce: [3]uint32{0x98e8ab8, 0x84d8e77b, 0xbb305841},
|
||||
key: [8]uint32{0x46b5f93c, 0xc8b2778d, 0x2cc5278f, 0xd2a3904c, 0x6ce5d4f, 0xc4459e8, 0x4a35c30, 0x2feadc02},
|
||||
input: "eccfd66bdc691478f354b8423d6a3f20932a1f591d8e6cefa734975fb8ee6881b6dc92c0d1d5ed54fd1999efd7f11ac697a1f130587dd895eb498c9a8fc7d1714c385ec156ecae3bdea2a3462834245e724531d0fedda2b77693a53ed7354b758e875b23cfc83219a091fb2076e7a88cd77f779ed96f8d81ffa3fe5059303ac706086494b9f2982f4f88a0c6fadc3748625004db",
|
||||
output: "925529047d4177b72bf50905ba77e47608815522c1829b24046e439d5451901257903a5409fb910373167e8b7f4fdfa543a477608ddfc11bbd1efc138366961463b9915b302a346b795dd593f6fcf4fa73529b6fe83079552aabbe99474a72806f59688d826675fa7f6649b9f5307e5028853c9821b8c4a1a0fc4bfdc7c8c78b25aeaba2b5821d17b36317381a3bd578917d2504",
|
||||
},
|
||||
{
|
||||
length: 152,
|
||||
nonce: [3]uint32{0x2e2a6e4a, 0x9a6d488a, 0xf9966cb6},
|
||||
key: [8]uint32{0x58903bff, 0xc2be173f, 0xe26128b5, 0xb6b6af53, 0x92f8eeb, 0x38cf3336, 0x7fdf90fb, 0x7ae24b37},
|
||||
input: "f0c7139c69413869bca980d7f192b2bc3f57e34ca4f26164e1a54a234e84e1aa285cc02cfbaef3dfba2dbb52a555ec1f6ef0e89d0b2f0bd1846e65b74444b5f003a7308965e67bed558689be2668ca10ca368fac072e0e4535a031af23b3c37c561e185872b86c9bceddb5c1199e43fb5f735384766d33710460b541b52d3f5b6c108c08e76724bcac7ad2d866a8bbeeea92a3d867660d2e",
|
||||
output: "d2c16c7a242b493038203daec65960de384c030eb698ef6a53c36eabb7556cbfa4770eaa8bc0a2b385ad97495eeb1c03ff4e6efcb804aefa81c177dc62700a9eefe6e8dd10cff5d43a2f47463cab5eb1ee260c3826cac9bfa070f1e0435541a89ebd224d13cc43f8fff12f38091c2b3f2102d5c20d8b1c3ae4f129364bbe9f9ce2147dcf0639668ddb90dffe6a50f939f53fa7ba358e913f",
|
||||
},
|
||||
{
|
||||
length: 155,
|
||||
nonce: [3]uint32{0x243e0198, 0x884448c, 0x9a31e760},
|
||||
key: [8]uint32{0x37e017bc, 0x9b1e2e90, 0x15679daa, 0xf94a23ee, 0xda86dfe, 0xc3eea84c, 0xdd199799, 0x6eeffb92},
|
||||
input: "7024974ebf3f66e25631c0699bcc057be0af06bc60d81a7131acaa620a998e15f385c4eaf51ff1e0a81ae5c6a7442d28a3cdc8aeb9701055e75d39ecac35f1e0ac9f9affb6f9197c0066bf39338a2286316e9d1bb7464398e411da1507c470d64f88d11d86d09e6958fa856583ace697f4ee4edc82618662cb3c5380cb4ce7f01c770aab3467d6367c409a83e447c36768a92fc78f9cbe5698c11e",
|
||||
output: "ff56a3a6e3867588c753260b320c301ce80de8c406545fdd69025abc21ce7430cba6b4f4a08ad3d95dc09be50e67beeff20d1983a98b9cb544b91165f9a0a5b803a66c4e21bd3a10b463b7c1f565e66064f7019362290c77238d72b0ea1e264c0939d76799843439b9f09e220982eb1dc075d449412f838709428a6b8975db25163c58f40bf320514abf7a685150d37a98bac8b34ccb5245edb551",
|
||||
},
|
||||
{
|
||||
length: 160,
|
||||
nonce: [3]uint32{0xd24e866d, 0xc59d25d8, 0xfcf623f1},
|
||||
key: [8]uint32{0x5f32cca0, 0x4167cac5, 0xc04943ee, 0x507fa1ec, 0xad8fdfc0, 0x6266fa2d, 0x22f05341, 0x8074143e},
|
||||
input: "8d79329cf647e966fde65a57fc959223c745801c55312046b791671773cca0af4cd48ead1f316eba0da44aa5d18025eced0c9ed97abaabb24570d89b5b00c179dca15dbae89c0b12bb9e67028e3ae4d6065041b76e508706bec36517a135554d8e6ef7cf3b613cbf894bec65d4dc4e8cb5ca8734ad397238e1e5f528fa11181a57dc71cc3d8c29f3aba45f746b1e8c7faace119c9ba23a05fffd9022c6c85260",
|
||||
output: "60aea840869f7be6fcc5584b87f43d7ba91ed2d246a8f0a58e82c5153772a9561bdf08e31a0a974f8a057b04a238feb014403cd5ffe9cf231db292199198271f9793c9202387f0835a1e1dc24f85dd86cb34608923783fd38226244a2dd745071b27d49cbffebea80d9dacad1578c09852406aa15250de58d6d09cf50c3fcfff3313fac92c8dad5cb0a61ccc02c91cecee3f628e30c666698edecf81831e55ec",
|
||||
},
|
||||
{
|
||||
length: 167,
|
||||
nonce: [3]uint32{0x30b61047, 0x810cf901, 0x4d681524},
|
||||
key: [8]uint32{0xe51476d0, 0xdf98008d, 0x59dfe69e, 0xdb39166, 0x6c1e4a4a, 0xfb76165e, 0x5180f185, 0x7359fb35},
|
||||
input: "85484293a843d2d80b72924b7972dfa97cbe5b8c6bcc096f4d5b38956eb3f13f47b02b0f759ea37014ecdecfb55f2707ef6d7e81fd4973c92b0043eac160aaf90a4f32b83067b708a08b48db7c5900d87e4f2f62b932cf0981de72b4feea50a5eb00e39429c374698cbe5b86cf3e1fc313a6156a1559f73c5bac146ceaaaf3ccf81917c3fdd0b639d57cf19ab5bc98295fff3c779242f8be486ba348bd757ba920ca6579be2156",
|
||||
output: "bb1650260ef2e86d96d39170f355411b6561082dcc763df0e018fdea8f10e9dc48489fb7a075f7f84260aecc10abcfadbc6e1cd26924b25dedb1cc887ada49bb4e3e02006bdd39098ef404c1c320fb3b294ded3e82b3920c8798727badfb0d63853138c29cf1ebf1759423a1457b3d2c252acf0d1cde8165f01c0b2266297e688ff03756d1b06cb79a2cc3ba649d161b8d9ef1f8fb792bd823c4eabb7fb799393f4106ab324d98",
|
||||
},
|
||||
{
|
||||
length: 172,
|
||||
nonce: [3]uint32{0x42020cbe, 0xad62af90, 0x29e53cd},
|
||||
key: [8]uint32{0xabad2095, 0x601ec477, 0x3bc923a1, 0x1edede1a, 0x33612355, 0x285b4858, 0xd3fd6714, 0xe0f4bcc3},
|
||||
input: "a2fc6e1b5281a4e0330eecd1ab4c41670570423173255979953142b78733b2910fa5540e8294208df6ae4f18672d5ac65acf851bcd394e1932db13c81b21e6f165e5538aff862e46126c650bbe055e54b31c78f2f0221d2631d66ef6d3f4c5ae25eada043b74d8770e2c29799c0954d8ccbd17766b79e6e94e88f478db3566a20cb890846917591a07738328d5c05f7ed4695a82607660f1239661faa9af0368aeb89726f13c2aaecf0deaf7",
|
||||
output: "d8fe402a641c388522842385de98be60f87d922c318215947d4b7562d4ca1e2dbc7ee86494e65fb0bfddfdebdb2ae6469312f95b32c722b2720d64bb8d7cc3dd82f9055b1d89f05b77984f91f94ba4ac79c5129cd7c91cc751b0defc3f2799518e372d27aa683f1e7bbd4f55414c48fe8a3a37ac1f179a1a329cda775aec0d31d75a5a38addb1de67c06bddbedf4c8d87abc18c9f9dd072d457ea29ad4dfb109ce7e99a4a82fbe330b0afbb5",
|
||||
},
|
||||
{
|
||||
length: 176,
|
||||
nonce: [3]uint32{0xa8021c8f, 0x667a02c4, 0x7a68b693},
|
||||
key: [8]uint32{0xece401c8, 0xfa805a47, 0x6d572fca, 0x9c1c780c, 0x647545e5, 0xd7ef4c11, 0x91dc1e46, 0xba2a694e},
|
||||
input: "480387bc6d2bbc9e4ced2448d9ec39a4f27abe8cfb46752d773552ad7808a794058962b49e005fef4e403e6a391d1d3f59025eeb5fb8fbbe920f5361862c205d430eac613cd66108f2f2f0bd4d95a8f6ca7bd1f917eaeb388be87d8b7084a2eb98c575034578edf1b3dafff051a59313873a7be78908599e7e1c442d883d3fd3d26787eb7467eed3a3fb2d40046a4460d5d14215565606bcf8b6270af8500e3504d6d27dacf45bace32214472d525fdc",
|
||||
output: "ab81a9c28358dfe12e35a21e96f5f4190afb59214f3cf310c092ab273c63cd73a783d080c7d4db2faccd70d1180b954cd700c0a56b086691e2c2cd735c88e765e2266cd9ebe1830d63df4b34e2611a8abeeca9c8c4fac71135dafb1cb3569540ed1362ddeb744ed62f6fd21de87b836ec2980f165c02506e0c316ae3cf3d18a862954d9781f726ecc1723af4a730ccc6d6de82553450a52499acb58fb2008969401c45b2f20e12b58f308db1d199b4ff",
|
||||
},
|
||||
{
|
||||
length: 176,
|
||||
nonce: [3]uint32{0x414e687c, 0xc6fc69c2, 0xd3ca12d3},
|
||||
key: [8]uint32{0x1b51cca, 0xbc8455af, 0x3f904842, 0x6042b452, 0xcd4dd164, 0xda83f3f0, 0xff04b972, 0xf972dd0e},
|
||||
input: "b274e61059f3215173ae226e30a92ee4b4f8a3da95f2e768e3fac2e54ddac92c200c525f190403a6ef9d13c0661c6a7e52ed14c73b821c9680f1f29711f28a6f3163cf762742ed9474dbea51ff94503a5a404adbbdfbf4c6041e57cb14ea90945dc6cb095a52a1c57c69c5f62ac1a91cd8784b925666335bbfee331820b5f7470bc566f8bbb303366aafe75d77c4df5de2649ed55b2e5e514c3cb9f632b567594a0cf02ec6089a950dbe00554ee4dfb9",
|
||||
output: "a0969730d48ee881792a3927b2f5d279aba9f2ed01e6b31b92d0e1fb8ba7f35a236d838e0ce5f8654957167de864f324c870864b4e7450a6050cd4950aa35e5a1a34a595e88dd6f6396300aff285de369691b6e0e894106dc5b31525e4539c1e56df3ceedbbab1e85da8c0914e816270a4bae3af294b04a3ea6e9ef7e2aab4da5f5370df2706b5e3f000d88179ac756deaa652a1cc85e80ad9622f1bf91a2776262eb7289846d44f7f8192e763cb37aa",
|
||||
},
|
||||
{
|
||||
length: 183,
|
||||
nonce: [3]uint32{0xdd315c1d, 0x2335da98, 0xe0a0da0f},
|
||||
key: [8]uint32{0x6419c7d6, 0xd340f42, 0x7af2f4b8, 0x3536cf42, 0x2f68c6fb, 0xac9d855f, 0x7c4d490, 0x9711b1b1},
|
||||
input: "ee849039c6cd972dc943d2a4468844d130c0150276f4e0889047e2300c3ecc6792c4527bfe9437dad877eb986e6b1aa9b867d1798c9d314243f0a87ec9ee5b601c2554876c87cbf50df3334a077c4152f8b8fef4a2d301ddbfa90c887ece757c3eb6c4fc1e0212d6b5a8bb038acaec28cba064c9b34f5364cb7f0fc2ac4ef2c7ddde0f5ba17014459eaa78f08a46a01882ebf7c6e409dadda250bb899dc8b3b70e160bbcb4412a9963b174d0fc6bc16383a46ffaacb6e0",
|
||||
output: "3e272ded9c0a5cebe7cf17ac03f69eb20f62996e047501b6cc3c8691ddb2780ea72c21a81888bfea96e4373a412c55ca95648390de740102d661143043baec3976230e024477d134b8504a223c36a215b34164c9e9e1fa99a49fdc56f2f04ea525a6b82997d9bbc95c4b5baeab4dec50061efb7c1a757887acb8b47b142e0a2e61885a2c14c4642d83d718a0546b90699adc545a48129603862a1c89d8e665cde54b3ba487754db6d6f5acf6a4b95693cc569577a2dc48",
|
||||
},
|
||||
{
|
||||
length: 185,
|
||||
nonce: [3]uint32{0xebb44f7c, 0xaf14c7dd, 0x4543cd7a},
|
||||
key: [8]uint32{0xce71977, 0x99790e86, 0x6510d6dc, 0x37968ae7, 0x2917fb9a, 0x19ef25f, 0xd282d085, 0x6128d043},
|
||||
input: "0992396a6f29b861dd0bc256e1d1b7dce88435733506a6aa20c62e43afa542d1c46e28b2e6d8e2eacb7c08db05e356fe404684b0e3a9849596db82eb788aa09258c28eb19e9838f757425b4edef12deeca56e30cf030272e325d4246d6e083219b2f965124963ca91f066d47bf5a8282a011a78b0155aa70038259a4a59135f241fd2f88c908b9f4eef7b7df0f3a1c16a52c009b522f89dabd52601bbf6e3ce68732e1a6d444469480f06da218786cf6c9666362e7a7f7be12",
|
||||
output: "545c05a84b5a4fffd1dd623c8f2b11443818560bdb0c26dadd3b694d4790d294b99059f4127b7cca122c4000954d745af96094ff4623f60db33e994bb6903263d775f48d7047427b3a498c2ecde65bd37bcb8ee7e240a1e08c884c0079cab518f4e1c38ba5ea547f4da83b7c6036e4259bee91c42e8fae895df07781cc166f1d50e1550a88ee0244bb2950070714dd80a891aa8a9f0580a67a35cb44609b82a5cc7235f16deea2c4f3667f2c2b33e8eeef944e1abdc25e48fa",
|
||||
},
|
||||
{
|
||||
length: 187,
|
||||
nonce: [3]uint32{0x35cb7190, 0x212e9a86, 0xbc423ce4},
|
||||
key: [8]uint32{0xfa19cede, 0x576ae8f2, 0x58055dab, 0x91b3355d, 0x69d2501a, 0x736323c2, 0x266c1385, 0x134f4557},
|
||||
input: "3b9efcbbb607fad5e9f1263dad014cc5c2617d439fcd980408f4f9a93acb1a33d1c3a22f38c037e4603dfbbfb5571bc08c4a1958cbbf510e3e4dd19007fe15fad7808369149a9c4db7ca0496f7a600a6f2454ee1cffd5a68d45c270e4b53ac9b77f33a1ffbb1804244f57d2b05b8036fe2cda9efead3d4eff074ea5c07128e0b354a4a11ffa179163933bc6bd10d200804cc93b64575746e94e975f990bddcc8a4335e99e2459fbe9bc0e004ffcd6cac52f48ef55cc0637a75c1dc",
|
||||
output: "631ba7301e33236da2477506ea98d3b732447389e849b68e1f09bd5fd814f40dc3247a1012fa654f08e3dda0c104ee2dff12ecf5cb018644de50d70dfb6c8cc1f5f552e5f1e50466bbb538ad6b98fd37f33fe615c326efc9cc97899b829b007f91569fa9b28ce0076c53daedf9cc0f838e22cf1125b86a6a2c2eb4a45dadea45ad00fb4f054e7d6b09c13ab1dd5328debfbf4f1b70af2b8a5b1d02df8a87d7661473e0c180ba4c815f14db87c5bdc15f11a29d8e0ce3d747d5dcd4",
|
||||
},
|
||||
{
|
||||
length: 191,
|
||||
nonce: [3]uint32{0xccc941ac, 0xdba45b02, 0xab0d7ad6},
|
||||
key: [8]uint32{0x9b750752, 0xa627090a, 0x967c95f0, 0xf8ff2c3f, 0x69beb97e, 0xa30b99c1, 0xadddc83, 0x443f9baf},
|
||||
input: "f28a71efd95e963e5e0bc0fcf04d8768ce93cb55dc73c32e6496022e214596314b7f843f5c7b136a371c2776a0bfbdd534dccbe7f55e9d3d3b5e938f2d7e74393e4caf6c38fa4b05c948e31dc6a9126817fa3d7892c478f75ab9f6ab85c0e12091bd06e89c7d3ca8d9dcdd4c21fead3d769a253919c2c72dd068474ea322b7e71cafa31684e05a63e179e6432fb70661792cc626a5060cec9e506b35d9286f15dc53cc220b1826314eec337dd8e7af688e5950b2316c30516620569ea65aab",
|
||||
output: "1bcea54b1bf4e6e17f87e0d16388abe49b988b9c785b31f67f49f2ca4011ecd2ad5283d52ef707dd3b803e73a17663b5bfa9027710e045a0da4237f77a725cf92792b178575456de731b2971718937dd0e9ea12558c3fa06e80bbf769e9799f7470db5b91476d6175f1a6d8e974fd505854c1230b252bb892a318e6d0c24dcc9ecb4861769cd746abab58805bc41c6086a6d22b951fba57b00c5b78f6dcb2831715b9d4d788b11c06086f1d6e6279cd130bc752218d7836abc77d255a9e7a1",
|
||||
},
|
||||
{
|
||||
length: 198,
|
||||
nonce: [3]uint32{0x987e7c58, 0xcc839a94, 0x30952e60},
|
||||
key: [8]uint32{0xe34a286f, 0x4adcd996, 0x97168712, 0xa82dde8, 0x14249e5, 0x5e82810b, 0xb4a445e8, 0x9579adb0},
|
||||
input: "c1d1ede73bd89b7c3d4ea43b7d49c065a99f789c57452670d1f92f04f2e26f4f5325c825f545016c854f2db2b3448f3dc00afe37c547d0740223515de57fd7a0861b00acfb39931dc9b1681035d69702183e4b9c6559fb8196acbf80b45e8cc5348b638c6d12cea11f6ef3cc370073c5467d0e077d2fb75e6bf89cea9e93e5cf9612862219ca743ef1696783140d833cd2147d8821a33310e3a49360cb26e393b3fee6dba08fcda38d1b7e2310ec1f715e3d8fa0c6b5e291eea07c25afd5c82759a834a89cc5",
|
||||
output: "11a8493cdc495c179f0d29c2b4672997205a9080f596ee3c80d79b55162b1c875ac18eb94bf2a9e05b08024f524a1e9665912394a330c593d23260e6bdf87620c10a48f678693196fb744c49054182fba667c601e7b7ebf0f068e8d69ba004b804fda616a4a0d5350e1a3bd424b8266462be282308219c578569aefc1ccd09ecdf5da283356c9e524e14e69d25b0e19643dab26f54373a7272b43755c3f1ddaee6c5fb9e8e093110c41697e95f73a68c75454e050239197c9fbd8cec76698bd11894ebf6e2b2",
|
||||
},
|
||||
{
|
||||
length: 204,
|
||||
nonce: [3]uint32{0x851f025a, 0xe6f3c800, 0x85ae7530},
|
||||
key: [8]uint32{0x2d0dbe47, 0xda05e465, 0x42f6b3b2, 0x7026e79e, 0x9e446680, 0x691df976, 0xf7b23da2, 0xbb3421fa},
|
||||
input: "37b2dc4b6a5203d3a753d2aeffcdaed5a7c1741ed04d755dd6325902128f63b6981f93c8cc540f678987f0ddb13aae6965abb975a565f0769528e2bc8c6c19d66b8934f2a39f1234f5a5e16f8f0e47789cd3042ca24d7e1d4ddb9f69d6a96e4fd648673a3a7e988a0730229512382caaded327b6bbbbd00a35df681aca21b186bc7ac3356d50889bbf891839a22bb85db4c00bfa43717b26699c485892eb5e16d1034b08d3afa61f3b5f798af502bba33d7281f2f1942b18fb733ca983244e57963615a43b64184f00a5e220",
|
||||
output: "b68c7a2a1c8d8c8a03fc33495199c432726b9a1500bc5b0f8034ce32c3e3a78c42c1078e087665bd93c72a41df6bfa4e5beb63e3d3226aeeba686128229a584fab0c8c074a65cef417ad06ab1565675a41cf06bb0fb38f51204eccccb75edd724cdd16b1d65a272f939c01508f0385ca55ac68a0e145806317cc12e6848b1124943a6b2d99a8c92083fc5f31ab2e7354db3f8f2d783dbf1cfec9c54f8bfcb93d6f28ef66f18f19b0fab8836458e9b09bee742ba936cb2b747dd9dcf97ca7f6c82bf0af6f1b433592d65143fe",
|
||||
},
|
||||
{
|
||||
length: 210,
|
||||
nonce: [3]uint32{0xaebfd97f, 0xf583442d, 0x15ab2f1f},
|
||||
key: [8]uint32{0xd3d1cf9b, 0xe43187e6, 0x5071a757, 0x412a83b4, 0x3f27716f, 0x17fdc488, 0x271f77ed, 0x6c4bb056},
|
||||
input: "68c2c5612912b5f994172720130dff092ee85a2c1395111efa64d5a281ca864d3db9600e685854d81c6de7e8747b92fb7c4c2efa829d3d4c0c9fc9d689e2e5c84c9eae8ba4ab536fb6c7523124b9e9f2997f0b36e05fb16163d6952eee066dd22fb7585925ffded0204cc76818bcead0d1f8095ca2cf9cd1ddcd0361b9c9451940e14332dac4e870e8b2af57f8c55996447e2a8c9d548255fe3ed6c08aedaf05bb599743ecb0df8655152bbb162a52e3f21bea51cb8bf29f6df8525eb1aa9f2dd73cd3d99f4cca31f90c05316a146aab2b5b",
|
||||
output: "d0ae327fa3c4d6270a2750b1125145bdeef8ab5d0a11662c25372e56f368c82c6f5fc99115a06a5968f22ffe1e4c3034c231614dd6304e6853090c5940b4d1f7905ef4588356d16d903199186167fec57e3d5ce72c900fe1330a389200ed61eec0bdc3672554f1588ec342961bf4be874139b95df66431178d1d10b178e11fcbd26963ff589d5d5faf301b7774a56bbfa836112a6ea9c3026ebdd051085f9131132c2700674bef6e6c2c5b96aace94eb2ba6c0e0aef0eefa88995e742ca51ac50af83683b801b7c2c5af4880e2b344cc5564",
|
||||
},
|
||||
{
|
||||
length: 216,
|
||||
nonce: [3]uint32{0xf9e973b8, 0x2485a6a7, 0x2ea7dee6},
|
||||
key: [8]uint32{0x96edef11, 0x8cf57f26, 0xb6e3a83c, 0x9ef434c6, 0x4607ea48, 0xace87e4d, 0xa0d87475, 0x3a9c9458},
|
||||
input: "fed3d1efa309c8b50cb9da02b95167f3b77c76e0f213490a404f049270a9c105158160357b7922e6be78bc014053360534add61c2052265d9d1985022af6c2327cf2d565e9cef25a13202577948c01edc22337dc4c45defe6adbfb36385b2766e4fa7e9059b23754b1bad52e42fce76c87782918c5911f57a9394a565620d4b2d46716aa6b2ba73e9c4001298c77bfdca6e9f7df8c20807fa71278bd11d6c318ed323584978ad345c9d383b9186db3bd9cec6d128f43ff89998f315dd07fa56e2230c89d803c1c000a1b749107a3159a54398dac37487d9a",
|
||||
output: "6a95fba06be8147a269599bccda0ce8f5c693398a83738512e972808ec2f25bc72402d4bcd1bc808cc7772b6e863b0e49d1d70c58fcf4fcaa442215eeb3a4648ade085177b4e7a0b0e2198f0acf5465c97bd63f93781db3f0b9a0a184c3e06a76c4793a13923f83b2242b62511c2edff00b5304584cbe317c538de23785d2504fae8faabee81c5315298186ce3dcbf63370d1ccd9efec718cbc90b3d2e0b0b6aefb3a9b31e4311f8f518be22fdc2b0f00e79a283701c53f6936dd63734ecb24480d5365d1a81392498faf9a1ddee577007acc5f8c87895be",
|
||||
},
|
||||
{
|
||||
length: 217,
|
||||
nonce: [3]uint32{0xe3bd4c44, 0xa3b75a31, 0xfe92010f},
|
||||
key: [8]uint32{0xdd05ab8b, 0x5ac7cd1, 0xb8113720, 0x53524706, 0x8e0ceea1, 0x52eb23e7, 0x1c85730b, 0xb33914d5},
|
||||
input: "d776bee5625d29a2ebf6fec4df94d2b9ac62e8e7c56704fd38a87ee932b787cbc555621535e76ea30183cb0ee30604f485b541f45feb8c01b9750d37fded5cdffbbc34fb90fdc9c7c7ddf949a1d50b796f1ea5db437238c7fb83c4b22c9e491f75b33d84746f1cd10bfda56851b8514ff0ded0adfd5092a66a85202d06bd967485d06a2c56011110da74bf40b6e59f61b0273164744da02ce2b285d5c3f03aee79eea4d4503e517177692ed3bb035071d77fc1b95c97a4d6cc0d41462ae4a357edf478d457c4805fa586515614697e647e19271091d5734d90",
|
||||
output: "60e9b2dd15da511770162345251edfb15cea929fb79285a42f6c616dfde6befc77f252e653b2d7902a403032fc4ce4934620931a2ec952a8d0f14bf1c0b65cc287b23c2300999ed993446eb416749bf0c9c7dfe60181903e5d78a92d85e7a46b5e1f824c6004d851810b0875ec7b4083e7d861aabdd251b255b3f1fd1ee64619a17d97fde45c5704ab1ef28242d607d9501709a3ac28ee7d91a3aac00cd7f27eb9e7feaf7279962b9d3468bb4367e8e725ecf168a2e1af0b0dc5ca3f5a205b8a7a2aae6534edd224efa2cf1a9cd113b372577decaaf83c1afd",
|
||||
},
|
||||
{
|
||||
length: 218,
|
||||
nonce: [3]uint32{0xcdabfd50, 0xd10d5b99, 0x9e160a85},
|
||||
key: [8]uint32{0x8231a4e9, 0x89f33c8b, 0xf96b11b, 0x853cae9d, 0xf6624a33, 0xee9523ee, 0x28bb7853, 0x688ac6f8},
|
||||
input: "4f57848ff5398e61bcafd4d4609bcd616ef109c0f5aa826c84f0e5055d475c6a3a90f978a38d0bd773df153179465ab6402b2c03a4bf43de1f7516eb8626d057ae1ab455316dd87f7636b15762a9e46a332645648b707b139e609b377165207bb501b8bccfa05f1bf0084631c648279afdf51c26798899777812de520f6a6f0d3c7f3ef866982f5d57f9c8d81c9a4eabb036651e8055a43c23a7f558b893dd66d8534bf8d179d8aa7d9e8987cfdaaa7b5a9381ba9c79d5c1161b1bdbd30defdd304ee07f19b7ba829a0d5b40a04b42edd6407b68399caac69069",
|
||||
output: "e096cc68956ed16d2dea1154a259e01647913eeea488be0b54bd1816c781a35e161772ae1f7a26b82e864ade297a51cc9be518641b2e5f195b557ec6fc183e4e5c1fc01d84fe6ca75e5b073af8339427569b1b8ee7fcff0ffa5e7e6237987c40deec0abf091c06a3b28469c8f955fc72e4f3727557f78e8606123e0639dff782e954d55e236448f4223ff6301accda9f8fa6cd43a8d6381e5dde61851a5aec0f23aeca7262659bc793ce71fa7992f80e44611ae080b7d36066e5c75c30851306f0af514591d4d5034ecdf0d6c704bfdf85473f86141c9eb59377",
|
||||
},
|
||||
{
|
||||
length: 219,
|
||||
nonce: [3]uint32{0x67de323f, 0xa0442ac9, 0x9d77b1d9},
|
||||
key: [8]uint32{0xca8d33d4, 0x834349d9, 0x5e68d581, 0x99a7c30e, 0xdc7f6038, 0x697e8b63, 0x284c2ece, 0xee3e3bfa},
|
||||
input: "046a61c0f09dcbf3e3af52fab8bbcded365092fad817b66ed8ca6603b649780ed812af0150adbc8b988c43a6ada564a70df677661aff7b9f380d62977d8180d2506c63637c0585dcef6fe3f7a2cf3bbb7b3d0df7769f04bf0f2e3af9439ab7615c304b32055aea0fc060890beb34fa9f90084814b6ed7363b400dfc52ee87925c5b4a14a98e3b50c7f65adc48c89ddd6414626c5e0bdefabab85c4a0e012243e682d4931be413af62fd7123ab7e7774fcae7e423bf1d3a31d036195437e9ea8f38aa40182daa9aacf3c9f3d90cc0050977c6065c9a46bcca6ba745",
|
||||
output: "cd5a6a263e3ee50dda0e34c614b94c3ec1b14b99a2f4095a6b5715fdfc3449fcdf8a09d1ae02d4c52e5e638f1ee87a4a629f99f15a23dd06718792f24285f5a415e40f698752c697ee81f2f9248da1506ce04a7f489f8e2b02e6834671a2da79acc1cdfb78ea01822d09a1c4a87ffa44e56c4f85f97507044cf946ccb6a2e06e2917bac013f608d75ee78fa422a5efc9c569226bf7068d4705fde3a9fad2030256db0acf9a1d12666e0acf9f5346ad62e5af4c01a008d67ab1224b3e98278d073116ff966cdc779fb3aff985ec9411a3eefa042d71dd4ae5b15d5e",
|
||||
},
|
||||
{
|
||||
length: 221,
|
||||
nonce: [3]uint32{0xa36a3d5a, 0x1747a05f, 0x5440eb4},
|
||||
key: [8]uint32{0x2d701ee6, 0x143d5a1a, 0xbb67b9ab, 0xabc88ccc, 0x20baad8f, 0x6507e48b, 0xdb1e1b39, 0x9e521d80},
|
||||
input: "af516216f74a6344cbe458cbba820f7e25c0b10aa84b790da2ee6317e059171076d7246c2878be83fc00c200d546c007f849e4c163d52c7b0da31beff4abff481be3266b92e668cf4dd1c84d9d7b3e5191dcd6ddb51d17d337621046e83e9ac035fccfb239648bc3c6fd340fbb50707e5a33b3ef439d292192d0e4bc727690c61450e5a28789e5ea50e746bc66d039493e080fb70e9ae06d89004cb71de8178941c422f1e9862492fc9149a4864ff52b1277b9f5a63c2f16e9adb5263cf65a034a62ebb0f1a385d2681c87a35f1c45670b4edef1c68fe9544fcf411d95",
|
||||
output: "b22ffd8f0e549bd3e0206d7f01ff222f92d39b41cf995a331d5ef0cf5c24bcc3ddb36e64d351b5755400246fe4989b5f912e18daa46cdd33e52dafbd2872f16e94220b56315d72c1dbb1525fd34831d7202970c11711ff36de3fc479407c34fef0aea86e172f9beb0f393194355b9dd59625639f4a6bf72ba571c229f2fb053c1114e82793deb2dfe8232f1a327949689d2fb2820662dcd2a39a2546c7df12b3ff7e87e58c74badf568cddebd3c558f0f7874c834c4b8aa988653f138ec79620f5e3ed737690928a30f981dca9f2920ac7307607063b40f87c204de47c",
|
||||
},
|
||||
{
|
||||
length: 223,
|
||||
nonce: [3]uint32{0xb92be022, 0x1e1257c7, 0xad7c01e},
|
||||
key: [8]uint32{0xca1dbb9c, 0xaadb9504, 0x77b8a95c, 0xc50deb5e, 0x2dbc0fb8, 0x9e654bc2, 0x94d8925a, 0xfe9cfb66},
|
||||
input: "a3d70bdb509f10bb28a8caab96db61652467cf4d8e608ee365699d6148d4e84d5d93bdabe29aa4f0bc8ee155f0b1fb73293c5293929eaacdd070e770c7cccfb2de120b0c3811abeeddaf77b7214a375ca67d618a5d169bb274a477421d71a651cfb9370bcf7e0d38f913754c11002089cf6cd6a8de1c8a937fb216591d57b37efdf3797f280773950f7eddeb9c3385c8315ff5ff581c64610a86ada7ff6a1657e262df94892dff9fdfb6e958d101f4c26296470c138dc4e1ca4bb565b3ff877a7f78b3d11d64b7c24e27ba6f6b06f6e368f5ac218cd5d11b815ab0987678eb",
|
||||
output: "646314264896a6e25601e536f6e783d465b2ead1e0be4422bc9cc8eacabae4a749ad533eb28091be8397328dcfb34c92006bbda930ab070ed7b806095bb1c8f476350e7b08ffbd4d7d6055c8defaa8deff9d54f5215c2d7db27ce09e08f5d87a859145ea3126e2a01882921c3fddef3985bd451bca44063258390aec8ec725b07d064314fe43a9c83e9287b47616dfefbf539b82da209aa08a6d3176b7e3b4be4a17d44e581280a684e4a64414649bfcea82b541729f8178b580e8b972a89f5b8c4f9b68205e9396d8ae5e81873b61da074080fd44c52d50fb0880ee9c35da",
|
||||
},
|
||||
{
|
||||
length: 224,
|
||||
nonce: [3]uint32{0x5091927, 0x661c75ba, 0xc23dad},
|
||||
key: [8]uint32{0x2e00499d, 0xafdc63db, 0xc3c62efb, 0xb4157a19, 0x84ce8b13, 0x85326279, 0x2ee71e9d, 0x318721e4},
|
||||
input: "f48b5ae62f9968baa9ba0754276cd8e9dcfa8a88e4571856d483ee857b1e7bc98b4732e81f1b4421a3bf05ab9020d56c573474b2a2ac4a2daf0a7e0c3a692a097e746d12507ba6c47bec1d91d4c7cfc8993c6700c65a0e5f11b1ccd07a04eac41f59b15b085c1e2a38b7d3be9eb7d08984782753ae23acdafbd01ae0065ab9c6d2a2d157c1fc9c49c2444f2e5f9b0f0bbfb055cc04e29b2658b85d414b448a5b62d32af9a1e115d3d396387d4bb97ba656a9202f868b32353cc05f15ae46cbe983d47b78ba73d2578a94d149e2c64a48d0c1a04fc68baf34c24b641ea0b7a800",
|
||||
output: "b9af1016275eaff9905356292944168c3fe5fdffd9e4494eb33d539b34546680936c664420769204e91ead32c2bb33a8b4868b563174d1a46108b9dfe6d9ac6cc1e975f9662c8473b14950cbc9bc2c08de19d5d0653bb460bea37b4c20a9ab118a9550bfeb1b4892a3ff774e8efe3656adcdf48239f96e844d242525ee9f9559f6a469e920dcb3eaa283a0f31f5dfac3c4fac7befa586ac31bd17f8406f5c4379ba8c3e03a6992a1915afa526d5ed8cc7d5a2605423ece9f4a44f0c41d6dc35a5d2085916ca8cabd85ac257421eb78d73451f69aaedeb4ec57840231436654ce",
|
||||
},
|
||||
{
|
||||
length: 227,
|
||||
nonce: [3]uint32{0x5d6d997c, 0x9d623987, 0x5742de36},
|
||||
key: [8]uint32{0x57b2a5ea, 0xc5bdd68b, 0x99c7b0c6, 0x26aea960, 0xba5c75f1, 0xa904cf6b, 0x685031de, 0xa0f0e99},
|
||||
input: "b39101601efa2ecdf41878b0fd920a3005ce709e4ec2970abb76e32c232ea21069f81b246eda75aace7555ce8ae203455d3723e684bd671389300e353eec0d2f499d10654fafda2e7a69bfca7198eb172249167ca8864b5d5f58d28723090ec86e251a1bac0346d52fd81f06e0c05429e0b2b895588290b7d00878a4da3378eb6c7e61487de2b318fedf68fa7ad7c88ee746827c1f60d98c7716f3f9695c5ffd4670f71a0fa78a1fb554ba482c5de83feaed7c65fc71acc9f541342eb8f7622b12bb2cfa222fa2ddd8b3ed210ce442275afa3132c8a0e17dd504ecbc92525c118952be",
|
||||
output: "50eb5b21c179a03b9a822f0075906a3ce4acc32486139f92635c7d834f69071d5a6dc0e15ed06a5cee37147071d59641d140a82ad5815b954e7f28e080c3dbbeaf13943d7b7c66d49d51ba1132eeadd4cb7a7e7d726d08d95f1578d55519f267f753f3e16ff39504a87b2286d8bfba0fe6bc28887b466bf276453a82cdd0abbbbf08db0e1c26c317d50ad9b8dc09cd621bc566d362024e8404739df6468869d2125c58b25d70e392f5e75924c4341be81c263915bb514ad436fb24c2c67450e84f6d1b72d1a02a3310c07a7814d930264fdbbf5ddca7067e18e8a44faa87169b7f2e35",
|
||||
},
|
||||
{
|
||||
length: 233,
|
||||
nonce: [3]uint32{0x75bca707, 0x89f6d1f4, 0x2a6f657a},
|
||||
key: [8]uint32{0x949f42cc, 0x2b5d3c48, 0xfe0be473, 0x17ac92aa, 0xbdc9d9dd, 0x74f9df26, 0x26487508, 0x7c7b41a2},
|
||||
input: "0a42f63b975ad0e12a1e32615813dfd6f79e53ce011e2a2f0534dd054689f8df73a8326fecfd517ff7fe530d78081af66c3a8c7c189eb9d9efed1e5577b5512d42ef1fe273f670ce380c64bc62e217a7e410a8ed89998344e29301e4e053a3a3cf7e71587fd056a6bd976f16e157476a06997dfaaff32172dd84190570621f2221420c0a0ea607ea756e9792c8c0e7157c95b89c9490e20b750ee85e4c27c9b8f409e848ec90afcad33342010bb9808358afbcb3d9b094127c38c243a204e76899677079758e7cbada9a5c18363449eebc07bab516a16372722403a046df85c7dd2ffc804c54d38aab",
|
||||
output: "87a47bcaa1c1eb8e55151011c4f39af4b9e108a55a7124cdcf66d0dee727306e6971f783b038bd6b215f530cdbb53e17975742ec304fdb3792a88b674504396978c6a5e4a9c87a7c3ca430d61165c1a3f6162eeaf38c93e18b6ccb6a595ad428cdc98efef8f84463eed757a72ffd827b71c0579fcc1f4baa11812be2bc5a2a95df8e41d04b33343df09ce628c367d1f88488f7a2787f013c8e76f0b9257cee777ec4adc6df8c5790e41ea02da85142b777a0d4e7c7157a48118046935f8888b5352d1750bf00b92843027a349cf5685e8a2a2efde16dcf5e1c1ed8c779bb38cabfb42ec4dd87d58273",
|
||||
},
|
||||
{
|
||||
length: 234,
|
||||
nonce: [3]uint32{0x5003a4f7, 0x40bd8cde, 0xfe35fb25},
|
||||
key: [8]uint32{0x576e49d9, 0xe84e9df, 0x9f227a3, 0x437c9de0, 0xc46ac8de, 0x1a6a2d2b, 0x42ab7684, 0x4253fbb6},
|
||||
input: "abeff48fa082dfe78cac33636c421991b0d94c3bc9e5bd6d22763601a55201fa47b09ce60cb959ba107020213c28ae31d54923d1e74ab1d9ddc2762b2d23d8c6961d81068230884a39682fa4b30676ffec19319362c075df0b879a0f083a67b23597bf95c4bb997fae4736479cb8a9c00520ba2f6e5962d54c313c576180d17779ff239ad60f1f1373627770d50a1c49718b2b2e536846299e052f8c1a5d3079e91cb1b8eac4661daac32d73b3b99e2051f8f694a61d1e9d3935f802921a4d979b6ade453cf30d73a4a498a6a2c5395c60fcf271d50b4967ac12b0d7bf818c2679d552e9b3b963f9f789",
|
||||
output: "a0d11e732984ad575570ed51031b8ac2d7b4c536f7e85f6fce9ef5d2b946cefe2ee009227d6747c7d133ba69609f4a1e2253d0eb59d1f930611e0c26a7c0cf2d2ce7ccea6e079eadf2eb1acf0463d90fb4b3269faae3febfc88cb9fb0873d8b74894506199394c8e44a96e6b479bd3e045749cce1c3f57243abdb37e67084eb573cd820c6cee424227019592a027e9da8f7b8997bfb292627a986f83c8fb8d156a91a12a8b52659cf9272924631745ed3a2453a4c2d87a167faa9104e799c715ed597bcb66949ab15dae29a86ba147507e8d8af66e96c09c53caa053ad3b79d9ed3c0c6c00169eaec3a3",
|
||||
},
|
||||
{
|
||||
length: 237,
|
||||
nonce: [3]uint32{0xc6ae48ce, 0x26f0906f, 0xfd8ab8bf},
|
||||
key: [8]uint32{0x42b82c50, 0x7f519e0d, 0xcbb95098, 0x6f75e532, 0xe2c9f61b, 0x5a4af942, 0x2679777b, 0x6a8e1c9c},
|
||||
input: "a77b7a5870335b9145fd2e08ec898ba2f158fda16e8a2661a7a416857b6ba6937b4843ecaa79d3635d28383af80290842de9ca0bb621ee22b7fd6bf379922741e812b1739c33dd6923d0607826fc84d46bbdbd1fe9d1255f56a167779a560a6eed1b9c9579b8f771147df467e67a070d9e9ce8ad92dc0543d1c28216c1dec82614ac5e853ed49b6abac7eb3426ef0c749febce2ca4e589d06ccfc8f9f622ede388282d69ceb2fd5122ba024b7a194da9dffc7acb481eabfcd127e9b854be1da727483452a83d1ca14238a496db89958afd7140dd057773ea9a1eee412875b552d464ba0fab31239c752d7dd3d9",
|
||||
output: "b330c33a511d9809436ab0c4b84253eeda63b095d5e8dc74803de5f070444a0256d21d6c1cf82054a231b43648c3547aa37919b32cfd9893e265b55545be6d7cd11d3f238ef66c3c278fcccb7dd0dc59f57750562cb28da05d86ee30265ff6a3991a466ba7e6208c56fc8862e19ac332e5fb3cbcc84e83a6205dee61a71acd363a3c9de96d54070a69860c152d4ceb9c4b4cc3b878547b6116699885654b11f888dc3c23483a4b24fbe27c52545c06dd80ab7223d4578ab89bff5f9cbf5d55b19611a5251031df5da5060a1f198226c638ab5e8ec5db459e9cd8210f64b2521a2329d79228cc484c5065ef8a1d",
|
||||
},
|
||||
{
|
||||
length: 244,
|
||||
nonce: [3]uint32{0xea38678b, 0xc41eada, 0x3381147b},
|
||||
key: [8]uint32{0x268fc2ac, 0x21297e86, 0xdf9ef8cf, 0xd4b45234, 0x2a95c4f2, 0xcec36ce3, 0xd5fa38c9, 0x7dc43790},
|
||||
input: "322d634bc180458123e10d0509870b54e0f0a3a72a2bd9e9cf44324c7a1ca37dd6adf9db1fcc8dadabd881f91d47d93b58382802b42ee936802fac8612ea4dd9eca5f215935ea9ba6233b9c8bddba3385861de669d95c888c8977851cb305db577a4eb2360f362fa459d61ffc8fcaa1502905b073bd8e9567ac7cff8e5fb1002c55641a3af5fc47ac0131fae372f073e19721ffcce9821e0241d7fa67bfc499c8f100e050d39bd4d7cae4557d208629603ec4a007852762ec1905d0e81b873510fd334dedcd9c288eb8415db505913af06bea94d197ab627d58f6a9944f6c56247595fc54ae3f8604aa37c3466f74561131e11dc",
|
||||
output: "edbfb1090987762f75eba2439d746cdbefe8605b8ebad59e075d28b54edfe48813ccae891f6ed655c5ab5211ba896fff0c8e09bd1554aad987dc53f355d0822e9b0f524a99a79c68a9f3b4e30506cd725b07be135e4540078be88dac64fc545c433837b96a924452f6b844291c4c3fb5f8cc94f06d9f19dad7fc945f093020e82ed19f9eb3ddff68b813629991d1a460e5455e1cb41cf23bb3d96fdb6b96581c3bf9ef72814406329bbbba5b835e7724c728cebe88efcd996dea71d0fd5c53e081c21ce8b3764738d693e390fbf8e0137a716760fc9cd2014cd9bf3fd706bc3464d1f15803606976e96b1077cda0a62921ff7c32",
|
||||
},
|
||||
{
|
||||
length: 250,
|
||||
nonce: [3]uint32{0x883ac584, 0x8fb8e7d5, 0xdf07de66},
|
||||
key: [8]uint32{0xc7747e47, 0x853d88c6, 0xbf9aa631, 0x78f16480, 0x7c248080, 0x15ff973b, 0x31528a40, 0x629686e5},
|
||||
input: "e6b8a9012cdfd2041ab2b65b4e4f1442794fdf1c3685e6622ce70f80b9c2252ba6d9e6384d474a7622053d35df946a3b19408b3e1712da00525070279ce381359b542a9ad7c07750e393e0834593777352c1f7dbc84cc1a2b1eba787377d2cb1d08a7d20e1393d44022107acac5d765be37f9075af02e4bbf8e60ceb262aa34e2b870cc7adcf54329a667249cb4958393bff4f4333338cae45cbca419d59e605aa0cecb1241080339198b9b283e4201afc07360b8ae2a57b0b9b97167c315f03fd7a87a00ae73f91ca560a1505f3cdf04576b9aee5ea775f719916f1e1942ad5311c7f87153f8e62855ace3f34afb08d4d7c7f4fd2bf83e42f76",
|
||||
output: "fc2673c80812d101bca7a2e0e105fa449550e695a016596f5c3cde11fb7dc518b94fdb74058e634546a726c37896110e1d1f9cdeccba1c89958041061ded8e8bc2751ec6dad76a305e70c57f9c81a5a65b5116390af4f7bf7053a03ec13f5d60a58cc5ba61f8c46ef6d2d291de490082dcfdf294aeb3a9414d64e4bd6497d4625acfa591627bfd98f0aec7e7def71515c09942db6911d73b96b4bd2d6df03bb729e945d71549d40e4bc401e1f73baf263a74280537692240638619f92645a5ade1eb8151191c7ff8bd715b3c1cd667e69745b806e16d46d9aa680a7367b8fb45a1598631cf3d44c1f5cfcd95bc8dafdb65a2083905a6937fcf21",
|
||||
},
|
||||
{
|
||||
length: 256,
|
||||
nonce: [3]uint32{0x79cd7a62, 0xae619be, 0x7d96d236},
|
||||
key: [8]uint32{0x7dec8e64, 0x9f12b14, 0x6c70df2a, 0xeae0aa0d, 0x27b1ac14, 0x7a00d833, 0xe63c0aca, 0x189438e2},
|
||||
input: "0cfd93b195e37dd15dfae83132c24ed5bfce7fe6fad4064b213b2c31a39e39ddad2f977e904c9c5b055ed03db46fcdd845bbb6ff0ab5a8c92e89295b6801f36ae63eba61fba24a3858aeb36f2da226b23b24d7b2c7d2670f23a9a1b60db85c0ecee584bef1b00e42d10ca17432a74bbb220d88356d82c850da4c09dd5baf413caf8f9479e02a330065fb865489c0f59605d56146ec8434182345de2d15e2a1dceeeee2fe94871d41913f6788738947ed9849ca0ae985e3e19a97bee82b96feeddceb196c9b6012264661945981c279f43db9599a4ef01116f592478619690daa64387290484d21e8d2444751194e1f361fb37f04014a3c7e4b409e5c828d8990",
|
||||
output: "0502848571d1472ff10bec06c1299fad23a2cb824d88bf91b5447c5139500bd837a2fddc629e4a964e84907c1e6740263f1fef4f5ed41062982c150d9e77a1047b7d86c0e191945e8db00ca3845a39560857fc9e0e4a394eea4ba80a689cb5714c4bab7124ffdbfa8bbb91c3eb3caa1621f49dba1eea3ebf1d547ee337f9085638a12317b86c11aa1525813445107038942fc519eebdc1b98d313ad822bf0b94a054259aa8cf1be4b3a68f974269729941747f9a23fa5d83453071b431dac62274c24f6a32248b0785ff90aad5840fadc89af0aef7553d9352cfb00d3999ffbe28cd9fde7854e95710f4532b8bf5011e518c93361e58d22a2302182e00e8bccd",
|
||||
},
|
||||
{
|
||||
length: 268,
|
||||
nonce: [3]uint32{0xb7581e00, 0x9a1bba92, 0x64356674},
|
||||
key: [8]uint32{0xdc2c9fcd, 0x5e50de1a, 0x8546466b, 0xc1b49b21, 0x36a670cd, 0x2887f367, 0x2fbf4300, 0xf90a0374},
|
||||
input: "0d8d864010ce8df1c0179cf0236dce1c100f9c115eaa5294c24a2e1afa27f9d57ebc18f00482be0218d44262bd4db73002ff53c6388f5e333470aced2a42a73b376686c8d02e05ece27cdd8b1e3f675c715981f8b656d68d0e16227b529cf881d2433e4371fbcd933eaa72346e77e688ac80ee95324512c66a4c16338cf38c941b72c21c3d01e005a07c0eb436014fb1ee61806de7e96842ca3217ab8c7607d609dd2f637f9fda8a85cb0549f262c9e4a955c384319a6ad2b696e2593d7d174f5ddb98e2a8d5d12558c18ab67571e9a0202e91ce26d720cbe41a3a6a4f309296ca4d9d9a59a9043dd2e5a707ed7d5034023d5ea06ab14b39b7852e5c984848d5670c6f2f0b189c2a8a4a4bca",
|
||||
output: "d2a5693c9d503a8821751d085a0837579233e65b691366e4a7464481d22800e786939349f721a815f28b4e47c8889f0814fb95d592d1185e45d6dbcac14ffa4f1d6c79194f2f7eb7323439d9607edf80f01e3a968b483eb93c01d9cb9d3625d21d66927e7aeedc1d9bd589560ed2b61cbed5ad0e0310c8ebe140c64c67d4909c010902d5386efa359ab60a9573493d3e5d8761cfd4023eba23de48372032d4673b5f6ad66cd0dfab02a73aa81f269ae88fcabb3ae9cb09f6bf60fd3575a3046bc6843f444e1e9fb9ff9b991620344fb99da68df09496b40f8b9dfc34e830a87f65710940603ebab554d36e8b4c9228bc9c26c07b828f34cdfdd40b161717236ba325e8c20bd018b324345e09",
|
||||
},
|
||||
{
|
||||
length: 305,
|
||||
nonce: [3]uint32{0x2c641fcb, 0x5170c7e2, 0x62a23688},
|
||||
key: [8]uint32{0x5aed5915, 0xc5c4cc18, 0xf0e51574, 0x75d894c6, 0x1b7082d1, 0x5d2ea1db, 0x709fd24, 0xf5f69898},
|
||||
input: "07c50a69e168e388caf6f91471cf436886a3de58ef2c44795d94fba6538add8d414d84f3ef0ac9377fd5bed6aa6805a695f3a711025550bb6f014893c664e09bd05f4d3b850771991fc02f41c7353cd062156243b67fce9c1f0c21eb73087a5de0db0578923eb49bf87a583351e8441c7b121645bcb64ef5960fdca85af863dca7ebb56662e9707d541513bc91bf9b301431423b552e2c148e66ecfd48045ecb3a940dd65694d7fc8bf511e691b9cfd7547fe7bca6465b72ff9f1748723c4eb14f8bc1efb2fbc6726115c597a3881e0d5019335daf2e5ea8796c2a8b893ca798c4ef2639465505c4bd492bf7e934bb35be9b66c9f35730736c65fa4c1a2485378b9d71912cb924634a8e0db2802b75728818dc00fc28effdf1d8a05e4de4608bb6a78bb19c377d5ec77dca1b5ad38fded7",
|
||||
output: "3dff5fde2ca24bf419e13cb7d12368e70449d41f2aa22e4b567f5cbdbcf3257975e44097deb180f2621ec36acf375dad3b7a19234b9856dc6c7842a7f86be00304b41a8c1662a02e8390346cbd0ff6be7bc1ceb821dbd805ab5c93c9c6ea5093249b5dc52081cbbbe1b326e831ef3c6c42fb791790086d1586f7daf031e70a71b54e9134f942e9ce229fc77980eb80c985ee0c5965eaba375d156f9b423b0615f4ca6fd77de28e28f35aba327e4f1b75725730155b7b4d6c5c264bf3d9dc9a16e7ededcc261add8c666278bac5cf0b3275d6d6678060eae30bbf2ce5f63e6a53a450b65aa0adbd1c90cf045f5ddd9700c2a99c80586c5244cf4c08035b6ff630c82cec3a4fcc83860e987898b42fe746939f8b37c814f8dab65de276e9784fb90f0751d3ba0826889e1e7e4fdbf8a90942",
|
||||
},
|
||||
{
|
||||
length: 430,
|
||||
nonce: [3]uint32{0x99b172cc, 0x91056d0, 0x48057533},
|
||||
key: [8]uint32{0xe6cf398e, 0xc3c56066, 0xc5ff194c, 0xf6d2d8c4, 0x6d1d8908, 0x63e62065, 0xcca485cb, 0x1eb03dd6},
|
||||
input: "3ddcd3c00014747903c95e49f64258615455a0b26c5070a9532382a9bbd18eeb19c9fe1a902f5c6baf544c5938fc256d310a9332223dc3c54a6eb79a4b4091c3b01c798d2800418863f2865c1cd8add760e445588576d4a6c945e1d6d50dc913674daa4737ac94d84eb0ff57cda95df915989c75adc97c4e3c1c837c798a432ba4803a246bb274b032db77e5c1bb554a5342ef2e5d3ff7f102adb5d4e282ad800ccae83f68c4bfd3b6046786a8cfaa2b63c62d64c938189b1039ae1a81ce5c91530772cca0f4a3470ba68e4e0548a221eb4addf91554e603155a4592dc5c338aa0f75a8cc2822b318fbfba4a8f73fa08512132705dae792eed6b809c251d35cca60c476406d964187b63cd59333771e37367671d0ccb393f5b8bde77bebc133485ec5c66bdd631d98cdbee78a3cf435d2f824fa2f9e91e89af28b2e155df4fb04bbe4ce0b6162dcd8e81ee8d5922ebf9c957b26c343a0396d91f6287a4af9e11b7fbb5a5a5c1fcdb186365a20617d4ff5037b0bfa97b6213a6ebcf0b78b81c65737378787b255cba03d715fed4addc2c70c1fb4d3ab16f2bff287186c26a164dae2fe9dbe3c4a2e1617f01cae79f",
|
||||
output: "ecea5fc18dc4aed23359cacb8f79a457512e0a27d9816f353e315519d2b2faf74d14ae8ae5e227b203823998a47a050c363a807f45f610942fed4518b8091b88dff8b2af8fb6552eb654c85d2b6a918bcf56fb898392941d983b1afd867ef840e12313059ed3e4d217498dd511563a939c3c536fbbf8e019deed29262f0a655fc680b15939475e0cee0ce2e8bab5834f7354b93e2e0958a5bc608fab369b6aee3c9d73a6898e402484eac7300150517bbd137bf55762897696a3dc4be74b0c141755ac8f2f6e59f707b1690c451a774c46bbe195d826a6784f8d807b78f8ebc343ecacf37cb9b1b2fdbff6a1237b5098853d783e77515c419894c2628f8b5117042294ee2ed58a33746f9e79b13fdfaa25a75fc95340a89076e786e0ecad7de437a9a3fb3092146d255005b22895310b1252a3e34572cf74665b97f4adc30dd0f34e3216c7757953a4b618a775bbe68f9e0922d75afc80a1379aaf1745f2263afb6f0b37553d9c984f1ef781ea75b1980c559c77565c83f3e0bd7a3cd7cdb594658beb7e5eb940633dbc6ae2f50383beea676cb6c814b17b1d73dd133f544da88ab371415889ead21803c1ffe3f2",
|
||||
},
|
||||
{
|
||||
length: 449,
|
||||
nonce: [3]uint32{0x2adb4a6d, 0x33d00c1c, 0x10a0193c},
|
||||
key: [8]uint32{0x8bd707df, 0x70212019, 0xdb685581, 0x9cdbd1a3, 0x7db9ff1a, 0x1af119ee, 0xb1d8c0ff, 0x3c4a22cb},
|
||||
input: "93ce72a518ae892e00c271a08ead720cc4a32b676016612b5bf2b45d9ae9a27da52e664dbbdf709d9a69ba0506e2c988bb5a587400bca8ae4773bf1f315a8f383826741bfd36afeae5219796f5ce34b229cac71c066988dbcae2cbcfcdbb49efcf335380519669aaf3058e9df7f364bfd66c84703d3faaf8747442bdd35ac98acdc719011d27beba39f62eab8656060df02fab7039223f2a96caac8649bc34da45f6f224f928d69c18b281a9b3065f376858c9fd10f26658ae21f5166a50fe9a0d20739402eec84f5240ee05e61268f34408089e264e7006a59bb63eeaa629ba72603e65718d48e94e244e7b39d21d85848d5f6f417631f3876f51b76b6c264356d7d7b1b27bbac78316c5167b689eff236078cf9e2e4626a4ae8bedeecbcaf6883e2e6e9304969b4fc7a4280dcdc5196267e9bb980e225fcbf7a9b2f7098f7f5c9edd06f50c8791edaf387ff3e85ff7bee1f61e4660fddd4eaf5ab0320508e3ccaa9823ae5a71faa86bd76e16d862d83ed57bf6a13de046a3095a74a10c4da952b3c9b8fbde36048537f76eef631a83d55d3a13096e48f02b96a5a8da74c287a9164ce03ddf2f868e9ca3119ec41f0233792e64086c903eb9247dbae80e923eae",
|
||||
output: "bcf49d62dcd1cff9dc37d7096df0c39031e64ccaeea3830fa485edb71b7fcf2ec709a4b327ef9c7d4ea2b35f113a8485d4c236e06b3baccee30e79c6c08739fe5fbed59db30479b56dfbe584a5d79b169b200430ed27072137e940a34170606b31f22095f2151b4d9b901f6337f991a23e4c8997a1ebf5105361fdade1c889b8dc9565e3b33e0bd608c39d725becbb60da8a797186fe0986736112da3d09906442364d6e253e5b27fd5ad72e877c120ea7a11d42b19948f0df5ddabf9cf661c5ce14b81adc2a95b6b0009ece48922b6a2b6efffdf961be8f8ec1b51ad7cfc5c1bca371f42cdac2389cbddcdc5373b6507cdf3ffc7bfb7e81487a778fcf380b934f7326b131cb568bbaa14c8f427920aa78cc0b323d6ea65260022113e2febfb93dcfce791ab6a18489e9b38de281169f1cd3b35eee0a57ed30533d7411a7e50641a78d2e80db1f872398e4ae49938b8d5aa930c0c0da2182bd176e3df56ab90af3e46cdb862cfc12070bc3bd62d6b0387e4eee66d90c50972427b34acaf2baff9d8a76002a20f43c22ac93686defc68b98b7b707d78d0e7265aabadde32507a67f425cbd16c22a426d56b9892bac3a73dd2d2c03efdb22ecc6483f8d1ca67fc7d5",
|
||||
},
|
||||
{
|
||||
length: 487,
|
||||
nonce: [3]uint32{0xecf15215, 0x45e31add, 0x56499d31},
|
||||
key: [8]uint32{0xf5988496, 0x49bcc2df, 0x7b4ba3c3, 0x5d5138be, 0xd6cb466b, 0xe98c82f8, 0x147d3f27, 0xc82389f0},
|
||||
input: "f72bec13b0f0b6f2317118f14c2a0d8e963b1bd49ae7584e710dbde75bb1e30c79281847cb822a5f3ae4fa56825e511212f17f0d293cfe80f872e6992d304e9283d08ce65ceeacb003b36a862c91282a22536e0b9c19953512a1bf9e20d3e7a8f1a2dff45dec0b9b04c592e88a7814540cf636a024d10008463d0b3aafbc4c9359889149433ef173124866aa6f53526ef3b3f2c630860ecdd08ffd9fc050e95da512cc87f812f9391085cdec5cc87258b8560806a52336d612da7ab05e0f60566b950904aa27c975a48c7d78455728c87f9b53aa4978374ab9592e12c22d9a760e26eb527133534ac5bbf969596b71cde8b4ef3587fa7ffa7116834348c275ad4dce68ab3397521ddc8e54380129cc81b981f9b32db20dddb0ecaa0f1ff7b06495a42b4a800a207b8e9ca38794e2fa9f40546e0e3aef7b5236d7fdadd72b1158714a5ad8d6264df1e75120088e449b9e911eddac59f1f19a795205ab7532783a93159876133b3fe3a518475a545fbe8dd2ac143f33c35d98e3ee13b63606b1e671917ac3ff9412773a3ac47b8c6627b8ba9dde6820f4f16c2ed9cb7d7086cfbb0cf2d7533eff253d14f634ab2aad3fb4289b9a0bb667a6fdd0acd5949185d53f1dd2b96ff060bb44f872a67259100669e6eaf1a7e2b11dd5fc35792db0c44a1127765934a068bf",
|
||||
output: "bb618ae6b7739a4dedde1dbacf864b0892b93dea3007237d2f6f23be0718bdd29321e6b0fcb6a44dacf0f5c53d91e16165997e2302ae7ebc2dbd02c0fd8e8606a4ad13e409a4e807f331cf4174171c5fff23ca232192906b4eefdf2ffb4c65af78be01b0ba7d15b4341dd5a2edd49b17db2812358c8af0a4a9724e0169f50d1d331936bc2400012a60849876c3ead52cc9fe60173c9992f83f3e41ebd24fe3961835109612994c7620280539d483f91ef9a64c16032a35612a119589efe6357fa35b19531274576e304be75bc7e91d58015792095bb00ce4de251a52b946554366ea7ed9ce9317020ec155ae0071e022af36ad10eda5d671e5090c136e381cecdb8bc179474fabc7dab2d8a134772976cf0791b6cebe2333d34b4b8e2b6b2eab2b5dc7c6a08a583d091df64328cbcde36bc1b81095d82c741a1503c55d833d551a855e098166c5efffb8e4146e32e54abcaa85076ca6660abdfca9e82824217b5d3f23f7ff3455872bc76751480c1a8e3e725365c82fc135cd3713cc0f1ea733754142f8c37716a2a4fa8a6b898215c287565325774c2510df6b49e78cb986853ac5ca532c9a7e2bceb7c0157f60433f29fe29009343d6035d7b5892c77f821b644590615dc505604501dd218dcab789e6f0525387919cf25c7c6d62a8979e39d346decbed2657",
|
||||
},
|
||||
{
|
||||
length: 511,
|
||||
nonce: [3]uint32{0xba68c47, 0xbc020097, 0xbf7d14a7},
|
||||
key: [8]uint32{0x3bbeedde, 0x6e8f4d6c, 0x6e27cd72, 0x140ff360, 0xc891efa0, 0x4aaa227f, 0x733cfef2, 0x2b51f1f3},
|
||||
input: "96eb94e1adbcc0646440c8824a2fc0f2c4b17d9cbddbb8ba8d9dbd6482fbf7201c74eb923153e0138b2f6f182f9c3d5656ee40bb7c26a01740b5c7d125261d4e4197614800aa152b402ba581bfbf4288e73c9ef7e7e37491212b921420eaaff880eeb458e3d0aa108b01b53492c97e328e9d10e3220b924351d583c00e76aee9325d6b89b1f162ffa30b386b37b5eaf4dfc25d22987dde4496158818c4d8f19ea300fe140be921d3f1abdaf9ab8946833a57cda5f41f995ff80e98b0f10f7afd736dd33438dfd395547f11563056078ff8f7c202aac262955f0ca5dae2365472de40f069028104ac552ea5a45ff2773335e5d3242f1e62e0e98003333dc51a3c8abbaf368f284536672e55d005b24b7aeba8e4cef23289adc12db2213aa037c797e7e753ae985568199cfe14cf1704fbca443e6036bdd05859e3583897cbefe7a0cf268b75d554b2da6e503ee04b126fbf74eaac0ebca37e84ab9c726973af780fe2bc9869fe67b7d9e4a04062ee535b2c1740d1347224e211b5cd37ee14c3325f40abee930eb6a1634986e756b3a1f86a3d7ee7184d95ea948506d8ab8b23f92ecf3eb0586f7a8b1bc227e08a0e32ca75ca4eeffc5c0a2a623547788bca66f3dc2c48671e462544d52a87d34307a7f111aeacb7da50262deab33d9f29dd6b47c3bb555be598d619cc66be8c4b74b01772725268a43d467f39bc565e5efcd0",
|
||||
output: "590965d18ebdf1a89689662cfae1b8c8a73db8b26941313006b9b9bd6afa6a57149d09a27390b8883069e4fc2dfcf75035def1f8b865e24c21b1a1ed3e9f220d7b48046577b661bc92d9888a912984ad415ea2fc92c9e37da0bef5c7dab11495c612c27b5babe6eee28fd26482272fce69ca7f11bac95251735ad808365ac587830ec04105304f8e440a4da47d30e788718da4282941c9c76f18de4f954b8be750b54cb1145489edf273625a0df9a694a23fe7bfea12579b53c3b2a3de85705568cd7e603f3b8beba9a14cad9979ea283a8a291d3e1105b7f890e2a569804d9b7dd4c7e50bd0dcd11223fd7247af77f04212ece1b98c238d2fa0386a994bc502f83dcdd2e5a0d45b185155e1a395d91726d383c2c198fff1590e983c65ee041638510787c8c59c2e96f31678226a033e027bb40c416b73c3dbef31affc93a659c8ec7ffeca313fd5283a80533b2d63941c8f245d22b160c5fe57c5fa4b759c407b9acd6d9c4f80f244360b9acd11e2b43d4af757e16a6ef9d6756df39ca3a8a235e74351f50b2ebf54df633c8c400fd80b41b07117676d486377095660f2f20f62c034563b4560b473a8f4d6a740306d2a822fd8bd98012a840ba9b1709df9a0d61ecc305f7180fd764e334045d9a8ca23cb8036c05616a8b21fc488429ba4168c59dfa231f0ffa668a3be7b16583df1a55bb9c15d51660ddeca730d66f7a9",
|
||||
},
|
||||
{
|
||||
length: 607,
|
||||
nonce: [3]uint32{0x9419df54, 0x4593f2a, 0x71c06dd6},
|
||||
key: [8]uint32{0x7b517740, 0x41e86353, 0xed629408, 0x5fe32cea, 0xb06bc5df, 0xaec9b350, 0xc00c2a6f, 0xb3aaf44f},
|
||||
input: "be3f309c6e7b89e1ec4a855cf161156d09f8a04d5630534ee19e9e071e3f4603f23f0c59a7b7f8a32c4c203ec8c129a268faba09abde7b61135c6c37fd091e2d695f0e242488098ebed30c7d321f4dcef0bdd23fa85a53569868cf2008bf4d2ee7a12a6673298c7e797321b9f4559748223b590e6fcf17aa72251586b01181cefcd32c6a1a20a0fc27143426f6572b1aab0e7301e390cb857f912d78d5153906c698ee140b36cdc72693cc019cb7add747ca3a07b2b82a2332bfa76c962b186ad94209fcf590ed0f6a73b08a771a58eb9649f2f1da4f7c385da83d50c939231f745514d14b0920deedd9c4dc6d2e547f83643d13541870875e52c610372b14b602e7a47f0b3721cfca60ec68e2eee91f40ceba2d0fdb4ebe19cb1d1ab170726c9e600030454ef355f9a40033672be520e528937f38e7a862a5ae50cd94f667cd015a72ee3f91b1a09031bf4c207e0c516b2e7a4baedf373f1ee71843e560741ed3a3094d2b513e2248caf27ce135716f6887d9f1fe5b11e02c12c989d29054ab183a3f55d9b40d78e12ff56edf936ab966c7c3130bea472b71fd69e70165a76afbf720e2c1587a77943b35acfd81b2ab6f39476623edf3663024fb84da8057ed3a361e9533caf9fc58a5e4897e4bf84f58ed063b5c353bdca3792952eec0a1404149ebeb5b17cd6350ab3e27e44e40fbcb00780d001a48d0365d534ff830553409919608881e665f83bb5cf0736d728c41cc4e985c377f89ee1186303d0d76bc634875ab3ebd87059969f24b0464ae11967bcc47f300a34e3b917b1affceea716c5ad9abf1aa3a1106e2f4d006514dc62cfd2a52426968f2f3991c9f9d8fcd",
|
||||
output: "e4032c01bcece73fde73961ed216820dcb44ce20134678c98afb674bb03afec2f4aacbade7f87a32fff57ae9213eaf0509e9d9db1313b06fd1df53561f85896ba627cccd2d0e2ae4f24f5579bf02f6599f5e63412ba084cf53a5bc9a8061b5c029b755329fcd73f629fadd3bcf6cb4c572fea86466cb5159d19eaaf0f44c3471d0323bc7206bb514ed8117a61c6d98d44faff6a83716657531d965ba3efbcf067c452e0d2807db3423958d9a4421886fe132d7c47e82086db9507616b67f0051dffc1a49ecce3ca8e4d5f5af15684cd8837a471430ddd333ea0b6ee603b7d9e702692f857fab060ccf26f2a8e61dfd3b12923acca78b83a6004e4ff09113becf6bdd0bec3a449a195559dfeafd4e2a79ead5ae3c993a15ad9b1a2ce818e18edb010b7fece9aa437d85ba9841d89026d6aac1a3a6ab6dad932a26d7db6f3664b06d51584cf4d22a75c06e2840db7292798306e4d39379af85a6bc8dcaebb5246e07fadd5e336f122de0ecb99ca24a971701a1f43bd69933beef6e52d299b132e7510caf27b99739e32bd272afc36755ea80cc7ed3957d91325584b338d15b19fe554ee70bee903babe21d0cbecd49235c70a3a4f516ce16761d1cfcd70bb4b9c7c73c359f3fdd0753d6c1ac1a1463142f18266b6a9c84675f247d56563646fb2c8c3b6b81944c2ba2b76b685ba5ea40cf539bcf3850a8af3e0a69c0b38164de520a3bea82b91f67d36bbd87877b5be7f06c2d26b2dc747a26a51f51fe293197db0e91e6ac617c71ddc6edfeb7db8f067ac2012268deb7e5f00a640c1bbec5c4c71f10f921071308cadededad5c90e72d744d0bf790b043fd35729570889ebe5",
|
||||
},
|
||||
{
|
||||
length: 682,
|
||||
nonce: [3]uint32{0x17cebe90, 0xeffe259b, 0xbdf9d4ca},
|
||||
key: [8]uint32{0x172d51e8, 0x5b80f5c6, 0xb9c9e438, 0xa56119c0, 0x62212323, 0xf5386589, 0xde7079a3, 0x669e643},
|
||||
input: "0aa4fbce7e1774f0607e7ea01fc0e6d210bb283964ae75e180a9f6ff3d2c4d50914bfc32bca6d243eb33551521d54d66f377fdc1d31974ece79b157905ff7e7a9b064f349727ce37c83c15ae13df635c3e6b4baf994d9aa0bb90b06c6cda51deefda72c97a2993448e654b746b216d2b949bff1af5238558205cfc3162f1d7a020a919db4d4eb44bcf7b269d4df57e24133d1e540694b9148444cee16e64035ef006a6079dff449949c1b342991f2a27f21c8bd74ccf4bc944284a46e9fd9f9bfd4b95f80c05553950fabbf5e5aed6babb8427832266aa4d175114de9127ff6ee848534d6dd5aa6d2dc361319863cdf32cfb1b074faed17d368964393352df01fe8d86af0e994bc9dac315f7d9efa7bef47a16676cdf17a535ae71d399c4c11a3a3ba0491e8d41f419685258a4ec7d1ae588b3ca341719c0827ce5f5a653959a8671844f2d0293c09bc7d35497ed18c160fc7b6d073a311b621a7a37f7ded1df3d73dcba1821278c9e17a191997fa4dab0802e1ee1b468e91e4272c4569a17dc0b2805b980bde798640aa328a3605abea1865083d7446e960c27f69d32882a2a2295efc9c440dc203872373411925f8839715e9441d31dd9cc14bab09a3e03b4a63e14db3039d58725796326ea6327f189beecd63955f1409467c81f4691ecfe9f0ac5234f23dfb84e3199e415ee7b4f67189e8857ff6cb3f64c2ac1b554bfbd679a6ea8491cfd69d96d08ee2744d9103e0b044212560ff707974b1a9043e1f2c3592828fde8ab5e993652c00e2b3fdb19082611b67866ece6c4a2635f87e04d2136d679f632416b03ece4d7e9406f3437163f4fe0c8cc7b87d487f6de3b3022665bcafa847c2b9199e1ba9af7deb0e29b66ad41688d03a8369416dfbee6d03526adb3ebc4b4f8531d73589499a3010b5309e9d9d2f5a9cf347983a92722dbf6c4f0bae8aba57b37d322",
|
||||
output: "a31f9a532f35f20ba604a9ab9989260e5a4ed04e6ecfa1cb9e0e1d16943906acbbb4e761a2bebc86cad0ce8b3f26d98b455e4b0835eb8b43791cea29fe8fa6e5187b60198142059bbce98917aa2957ae2555bee70e6e9e21ff6197a51ac2ca2952c413efec4d9903a2f6883e88aebe7ca8316831f6a8f2cd0e486319b58dc8db862779adff98b7f35c33faa53d56acd7a81e0feffc286b728f3a11afab7cace4c30b1a45780276b1f0ab89242410d07cb1191c7b9da5d09db7c9a729d91ac3ed82f4350f2871a12d125ba672861d1b0af7219c360a0e023a8b7c23fb9d72631c72e032c097118d90e5db0576586d8224165a8376fe8d04de93516848e7c2653cb4f7d24a971ccf4f16c527ea5b4153fad5fd5bf473b15806671854507bf1a6d9e5fe4a6f6ec977197d21d69a041dd955e199031f895adefd850c8b0ae327ba0c18ca1783560e1ff0feb2f659137e34a91e9e9ff04fe3375b7db6e4326986e6265e5fef00297f6ae627c7563846e531762748fe8d0b6baff17acf1e6c5cfefa35a95ef634ff96f83f16342a6c62311fc653d314f8a6de109356ab7801316e69a48834cb6325816b1f66d5c67d6e9c9cbc8e1a0521fd6e4bf77a7d2609f99c9579e143f530677b99d198a97620d087f058edf35eb7271701ecebb8bfde5671641ed21aeee9e7db06b932e0def91be93cf2955159e9666c770cdffa03886eb6e98dfca8f91ff5cef1927c0f82b9226d65c68d011416cbef802c264e34244ead7a6ebbe28a510a37e1276f4f3cf27a3944a08aaa23bd321092761627dae20dc269b6150545c75e995cfee0a9bcedb1ad8b364beb8839fd5c9f7984fa0a08a1a354aebe18f62acf6d6664978fcfda2ce6fc16eaa2cda5b835339001b3b98d3a407a3e18e0ec2da6ee3d1448c1ece2ed67c3f51f01e76ed59f0e61102b103a3c65aea94275e8d1f0d331538efe",
|
||||
},
|
||||
{
|
||||
length: 768,
|
||||
nonce: [3]uint32{0xb1c9bd09, 0xdbe6497d, 0x16c73b95},
|
||||
key: [8]uint32{0xbf9d9e5, 0x2eede668, 0x631dca95, 0x4233e36d, 0xd83fe644, 0x99b11f89, 0xef055717, 0x1ae9695f},
|
||||
input: "e097b1e8dea40f63714e63ab3ad9bdd518ac3e188926d1086a9850a5580affb592f6e421abc617c103479ba39a3924eea1c0bbbb051614c4b5003bbd5fcbb8093864fc1c130748194d6b560e203b889b98b574a98ec3e0e07cb2d9f271ba7794e5419123b4f2ebc7e0d65cd404104868905ff2c38d30c967fe9d77ebdd4b8fa836c3b0ad15e3e70e9a28236d5593e761e694b047f63bc62c7b0d493c3e2528c8af78f56725172ac9416ec2bdc54de92b92a63f9ccb61e686f9249c7cc337d99b2160400bb5535eb8f8eb1e3cafcbceaa821c1088edbacb3b01b5bed977e702de747ad00268ffe72e3d877dd75816db65b5459607cd1b963fe43bf2405ec223ddc0de514d59cde74f7522dc72285caa3eeb7eae527a7723b33d21ce91c91c8d26bf36eeb1dcdfc1e9e475c1565ed9c7e64ef601874a4f277280a5ceec26717e9385aee8b159379e3feed7952b87240c942970d63351259aa7a286ddb4a2620fa67565c92f592902e49422f1eecea2f44d1c0bbbf54a9e5612b86a9549aa3e6639a924c7bbe2d3c1b5669da73c0e2c6f6f6084f54a912ad2635d0141c2f5ac925414dce0da09ab8f86eae2a7b7e48741253189e5fd554d5c04d9807ac6ffd8a4f8229a3e8ab75ca5c778bd7ec5a5c02085faba9792cbc47f9e9311f3444e6544359769e1b3eb4d42ac8923ec94536e1a44497766b5da523f5763749dbc2738dfa8e13c191dfeac56c7614a96bd3ae23e4e6e5ac00be851ac9831108989b491eaade62113c531385ef3e964ce817c8ed0857adca946467682c2f4387fab2f31ce71b58370853171720268459588d5d216faca58d0bebbd7cd83a78445d9b49e83ec2cdb59b5d760880bf60532178d60372752b47d52562b316c7de5c74af9cd588643002d66bc6260595a540d2f82cf2c07fa64e0cdd1f79877b6a25b0608c735a7d35ca10852da441fcfb31061fd7e482a0989866f9eea8b0b39c3d519715c1c2766c3ad99f041143cdb36557ed647403458155dccbb80c3a365f0a85b1135695648ab67ac76b3d219c7b77e49d735c72ac947b1d7eeb279beb9d2602aba7b36ca",
|
||||
output: "7b6e07e6415660affba56047b988f4548b308e7a642c76791f5c3742cc4cb744cde48fc30e50d458084e06c6dd29a52cb4c306a69a493a17c0838d14b107d07b81c983a2dbad09b80f087ba48465a8beaae5b16e8093e17cfb9e84ea3bdb9af00889268a5c01ddf25af434de56f65882322432aa275fac8519e317ef4d89478f29182143f97350983050f5d37c4b518611da6fa2aed7bb73e614231a194fe17c9073e377fc6ea0aa491e15ca54808e0536c8c3f1bf657283f807ebfc89b55049ac8fb86f89f17974fcf0afc1a2c690c0442842d0f4af9ee29dd960e499d1077bfdad4c0c9189a6e83799bb585acdb853c1e99da7ce9c7eeb9bf431f8d364d0ea80b0a95a7807f196c6ee69fe90e6d1f5d23e5cb256e37e65826d7a111f2272884d6319f968580b3164b2697ea6556816cea3ca316651fe2fd68dfa905d080c28622606f7d24da216289fa2c54c6f42dc244ecb047512ace62f0801f2dfad8f0218f45e2b3bbac97c2176c842398b16dfa1fdfc9a68b7b5a1e785d2a0cc592bc491f5a69c81127b758ee02c66b81674d3135c5882d1dc89dadcffa06f4b0644df5c7fd65c72611d79be7ad637edd6fc38b39946aa2a2c6d08ca9d3ff9a8ffe2e7989546489539b1a623fa937c468e59e0978602526b4367de277526895aa222fbaeae2084f418c5745d8ee844da0baa47f592970c14cf710f49539c12104a62baddb3382f5773dd18c83ecb238ae2e749a51584a38e394ebadd175bf5c3cec787907abb1d94af70ae63d3b7d8d5ff254da90b78ec8fe2ea95dfbc6e3e69ecad856c9e54906df8fe39859f2014b74dc3ca0ee2a957001939d37a6c0b489bd3f1658b835a57b24aa282c23e875c9e67e6eb8b32fe44e7d7d8e285d85da0ce1b53990f9fdb5e2e74728e433ed2c1044df9e89cb9bb316c39fc6fc8bcc74a382093926a288170e857d6b7f47858a4c2d05c74263dc9e8199332d0179687f4a4cdfc80ee6737300cefba75905b22d21e897f887b67aa3051877fff11d98bf96ca5091bb225bddd5eae697f3dfb0efcdb788ebf6694b5b39dbb0d4bf9427382a3a58f0b",
|
||||
},
|
||||
{
|
||||
length: 828,
|
||||
nonce: [3]uint32{0xc7e503e, 0xf8110ddf, 0x83316c8c},
|
||||
key: [8]uint32{0xfa2d1cd, 0x4fe7f905, 0x2b9e4c1b, 0x115bc881, 0x2922bcc5, 0x3f60aa25, 0x13c26d31, 0x2096af63},
|
||||
input: "0a1064714f20d9e47fe53250ecfec759f4137e60afaf65755f4709a483504c3855833b6dcaf7aa0180fd735fa9a73d46697f6c45004adf12452ea4c04a720fd7c20b9783b74b8b3ea0c8b1563d5a85f44af8afd7d91ca6298ca22642a684f66e365edd6f6bdb2dd32dfa13c62dc497fb341b86f65d40655931171416e23e3b2623c0b4a67d448877b6e3d4e0fe284034a10162b2b5e21639047036874f4bcde22b145b5f18aa8ff32dec81e6a5ac68b3c30c24bd8fd3b8e098a1cf202e2ab2a3bb66a9393222b9f7384653cda7707f00bc3c81e9591fd040a07d3629410c2db78781a4c9db3df5f9d648162f1b087974f56a89db07aa21ba827e3864a1618945b2fba06853a13c35da2909f5013feb313bae09870b8eab904024adab0d6ac46c1a1499791b47413139dee59db676949b9e9ab8d3d6abaa954ec2a9fc83953c91b483c3b6bd6700b96484850734e72e3710a1b379c0d0698aeaf68f13a0d317bfd689471e3299288e7a383a58522f0daaff210cc4917fa05f0b8ceefc2afc46148a05a100d30787accfb4da094e61ea6b58f132692aedcabae928e53c2594b01507b8fc2d0a85a1d111d1f4de0b95258281ae01873a72606753b6f878ecd8c4f613fb3477710d260f0bca0d4c06f675ab7113eded395f88755a98a0ad22b4a002cfe9447c4e39eda13738f4eccb9c13367ebc2878257c4647d31b67e5e32b6a77f23e9593658d19c0a40e8a7228767afba1cf23072b013b2d76ee66e42b57bec2797ce3619c695a661004c8129cb5c5d6a2836be22483f3b7e40bf8ac5535bf6cd065c4821a87829948c88163cfe3c0f60cea4e7ff59df4cdbf80064b2d664b39487413039999b5e86f1d467b12682d0cd355e9f7cd980e87d584ddbda89f68632d3b8fd6bc3b80205d7feb97a46842b093f74aa14bb21accda7474247b5e39ac76ef75e9b5b52b6a829a7e2297ab88fb0eb690d54ab1af2d7437149a6202035ce15f1e6c6267458d62677c263d83d3f8119af191b7d766582620e0f08b411c996c25ba6a32c2d73f592e789ed662e94103329bfa5e6573f1116ec04438997f3e4ad91b4123b570743455020d914bde2d8417fb24671e6db261732fb89dda1a36614b095529e4f97374c9bc0e55aa577bfffa663c816ca9fae3472e0a",
|
||||
output: "b00a7caf5359c5bcebe590e6bab9aa03370050c55cbd45a257f4869937e922a15f2d38121b1493d6b5dd4a8a47d7b4e5cb049d396ad84ed421df774b0408b6939f18ebf5cf83f48c540affcc2a885967bf4bd222c42904b8a73c4185bde3f97e874fad25b46714235e60c9ff53ed2975c9c85ebad0752249e4b627ffa41555eb9074f63a5f7d61d207d2ce11b2a9fa23a13a0832eccb91efa2afd8d9acfee94ac78a733fa156bfea5006da1d0127c32aadbb75c015b68c627903e1c85bf3a1a9f99c6cfbdbb5c871f7f9661b78cf5e16d819f53e9930e201d4f58e69bcdce77ec5b9b1d2cf206a71f744342273c26b9abc71303c20df3d51f52222893d803fc8e0e0afcd99ee1c7f95b48680403566f7f9e296d7ccc0ec348b6ad515af58d11fd82c628ea29ee6a5d67aaeabd8823addc01a078b04313af73105d4ce4abef8e6ee8ce649640a19678292d4f1017d121549fd2c19ba6cdc0b613e512bc9551d759c6d38aea7e35c0847a142e273a16bb1495e652f9668b97801ba3f6d9931c0a1efaa4452e15732dca1ca9cb45ed289e0fd08d1cee1cdcc9dfba8d0b2562b0b1a180f4ee69d63573222c8d4789bf0d63d2a201a70c7b27c84e620e33e8a863cf49b784269a51ead3d4ad26f044d5859988d5485a11533ea805f5a8f6313caa6b421071a34f57170fdd8e4663e9a4cdcdcc1ddaa9f6e651fb365cf827667b018ae7d028c7f96295b2b4f9eeb4b361b48af86463a79f50b107ab0935e3cec3f4f203cea801ff95fb870d2c2f0e315dc8a6a547dd3c390a1f5403917315164bd2d40362489b389a54e8dc0ddb83e6a43a26c65923e6f76ee0ee0e3a33b0a9066620a01f0319e20b9f1beb3910ad962a3000e6aacb0ae57f3f6c5e0315be5de93edcf0e45e0e47332f9daf7f33e6e8bf1929910b78b8f88ca12bf5519a3217b7554c8c8350cc314561d580bf67a3878e3979430d070121a5e070a3458742e8549bda972f603222e2b30eb8a49a955805307e6e02f8c60a08188f69340e116422458d4a8841f46a78c833b1a822e3f6c9c97422c918f17c36175ca4b3d1c081ee4b175b4b07bf101c3836eb5b9e3cbd08a89b4a1c50edcb41ea8ea6ceb1532f5b842715d50dc21e2499e08c373d3dedb96bb477c8802ab7aa957e0b5810f38",
|
||||
},
|
||||
{
|
||||
length: 859,
|
||||
nonce: [3]uint32{0xeb02dac9, 0xa7cba06c, 0xc24764c},
|
||||
key: [8]uint32{0xe9414a57, 0xd5e29546, 0x1a5e2f4c, 0x806e4c46, 0x48098d1f, 0x4351ca1a, 0x53ed97c, 0xa6a495ca},
|
||||
input: "00fa3b13b5cfa9b5d65a41cc2d3c420518802c22c4582873f1ad52a22032d2cef7c975078b199787e852fb1f914529f60d1cc854e5d6d547216dce043e0fc94866bb2193343c3a07fde60e668266d1cee3067c6f2ce0f9f63456ad08094b6c7f515f7ca90caa96494e2a6835ba1f3f166012ad1ff6af6b5f8455d5c26e72402966af9066ca70ad027eed23b0eb02c751195064a62283975efeb29bc5993f83360d012a2f5275ac758a9e8fe458fc7cc0673e6b9e338678f0faff60a67fff3784c3054dcbd95d1b00ed4c6156b3831cc42a2ccdeee55541f228b88e6c318e2d797c6fc035ae12868c4a4e3843b5b25a530b1477dec3f5ac27644476b5766e0ee132d833f9a63200eb0980bf72c3666150e567e01e3e1f469cf36beea65946fce714a3f354983e54ca4315b57ea35c5f48bd5eada05f49db1004cbb39888ebab3afad62f6509abad77ca8c4ff28731c7ae545e6876c8f4a80b6cc26928ee05001a9764694b52edd605e182d5a3a5fd192bff58aba90f57e4debe612d02cf6f08af33a78ebf8823bb3eb46d4da25b7dfa15ad436c380633d3db3d0dc4dfec6c2324d105e7090e65342b554854e777b40b5dab8125a58e8b212364ff88459a8466ff5ae661034abc8286a78ad5aa582e2dabbcd7a0b0cedcb9fd5f0bb8c3bef9117f2ca6520a72b94e528c1a4a464398e654995d5f4c77cbabf2b204b96a058cf1b38284b34e41ac37b05a003ed51be9602050f21c6b9326714bc425c1e22833da95a6e77571691d4dcab4ef9056c4c7f85d5b445b902eb375b5164c6bdf629ccfd4127a6c024bb6c4da0b6b08350432e58f8229e04e2e76f704be17d36e0c04fcc7a98f721d4572aa7f66ae8e9664300a189bc3862da47b60c8b33424f6d577cc10f4755f36c2a6decc30ba81bf48f96616ccfcfb74965d6bdcab82728bb224c560d1cfd7a175413ad1c14c734746be3b062b4e7514e9075c688103515e32e3335dbd272a315024d56f4ecd354264da9bc712080657b2b51b06dc7c4c441d9858935a4c3e6b207bde38ea83bba4c6854b2bcf914d758e0a174c0528e0e385c7cff355c38db1c22440369141e91266824c59f1ed23e7d4b99d31b0baa7bed4526e24259dbef5c9ae275e97267b756645f804c274d65ac7ab0f7683435bc2e4f24075cd1b790aa2b53fbf044e8f2092bdf0dbe88a582ff8f8de291e8220",
|
||||
output: "bea32587095caac661c3ac49e65654b282192b2addf5b9a403aea6c8bd0096291a0a66ca4062acf1da91fb5749952096ec63ab652ecf94c29807f0aaac939b6896edcd6f0cd8dd8d208b906ef4d7a8766831fecd6ce98f4ea0c34fa9a5114dbeb23c2cd6d3aa962e39b18cb343c24e65d49fad0a0fb50736f8d2b24b011108932484399f4c4510ac9a5e6bc78ff0b450e67f87b49f253b99d95d6294e15a9934fc8b89a5913c08f75d3516766fb0f60f82e2b2647b4619991c78adbcf548c07c0dda30c629349d84f298313c3e629e03760b1cf860264205a950d6fd86732a6513827f72c0dff5aff96f7203464f60849c1065beb70f282cca1334f6f6c767dfff94f063361f592e85597de5d313eaed17bd533db24818d9ba9aea2afa797721fbd19eea7b8d46bbc4b9dc0164636d2e754f5e9e8c04e2a381096331731c645ea1f613a37bfa9a6fb2c6307e9bacacbeab7f5672163ff9742a8115049bce0269d7d5f6f35787be031dbee1535b0516ec0b46d12f5833cde5f2cc569edcdd20993e9776aacf48ace7bfadf79065f2803fba6b2b27aa622abb7ae023ff2b27b727f509f313f92026392485a5ed4fd53b2e22b2d2dc1538ce158d34921214638be30ae054a0f5f1d4f9c590a2d215ac2a5b23ed33871ab26c8bb6db7fe9d6f51e527c9547248a4e9734c64658b22893f4f6867a35f18e2bbfd7d62142025955cb51af8e40b6fcb91c7e959cea2c92022c87c29dae107a306f41b00e73c7bceef8cb070e8f9e830caeee463170e919cba6eee63092a5a7ee33b74db09cdd022fdafbcd5d524253a29a103ba6f4d668d31d18f867557871c0e0258221c3050d57c18bdae4cc4ff8da0daddb5c08619be127ee76a317b59a9d8e67808603a1bfce6b4e0d070082b283bf9c0e6ef8256208e482f3e2d1a40d30807f60a868e2279dfbc3586d44ee25fdca3505cd39fd469c2cd03bc2f921d22a8346750f346c919e7247301c1c8a4a3ddb8eabc6e80d85cd2459afe1cbb4851ea2c86b8075e0fef3177cb074894410ecf681242fac62b5fa4ed3a10ddaa595427851d376cf69e350207b667f7aa26d003f1ec739a8792532ebd93f3cafb1fea40d227bcadda2fb6da794cea3371240f257f80b1b8a857ea453b46938397c1f4b303a46257750003a60666a11d03bf2afb5c71e059933d617288891733b63784bd9c662234f",
|
||||
},
|
||||
{
|
||||
length: 985,
|
||||
nonce: [3]uint32{0x3c2b47a4, 0xf614c813, 0xa26f7014},
|
||||
key: [8]uint32{0x39bd3d18, 0xc9aacd67, 0xcb5485b5, 0x20536a22, 0xbb22ac87, 0x1c9da580, 0x7d996b2e, 0x456fe461},
|
||||
input: "01847d8a97d56e55e12f89adb13c8c0f9dea5555e8dc61171fbb8e181f6cf846a4dd68b2c75335c0896fa215bf7f9eb7e398e4520aaaf33461ecfb61051f43d43569fb75fabd79d319bf39469f951e4da7932a74624c46d8d26a9499c701c00d3dea57a6f65b4c0f33b568d13989340294d17cd005b26d89cf6fa1c88e7b6ef4d074291fa8c117ae05d7c785459ef4561c45af63a811e9aa1c31b69a5bdac2356d955a0f579791247a757a691b3de447a53619878397cd82a74053f06da3574045bc856500ec01fd2afbc64d8dd283ac876a50e9396f78c424ab157f481316fd9c90cd899f5aca46dad32c68f1d64ea7f1c4bdb994ad847072609bd89adc2fa8382a5d573b680533640b8321b6adf27926274660b2cbaf04fbc9a4fb17ce8957c38c7bab1aafd5bf7263171e47d2e1ae5cf0494815642209d303dba561754479c24ea01a573c9083b68acc49907b1748924d3c6a82feb9417ca932578c123f9db35521c0d992565f7396f0c23e436289c1720e4e7c6e285c04a8159f93e06801334e523b18fe188355cc6a155febe64ba053e6b5d1cc87787fd5ae68fa86d8c51868b9f6a9664cf0d56aa6cb8463362bb671e6b8423bcbefe2a1a0acba3f135496736b5cec5e329494af46aba322bf5d1cc108c98298459558773a316e09b0bb960a26f4b0bfbaa493b5f98a0e522b6203c471b10e662abe9b9e60de2a1517843933add02017fadd62608383ad53796159f3d21b2c8ed7295802ca79ea65d550114ca2bcc7f7c3b4c6709fffc3c2de00da06e83d8f0cf04b8c8edd21c0fc11a0b2aa7f6adad255fef25e5c0a9d59546e97446e1fbf6a51a8ea6cad54cabfdd19cd10d7d33ff0549b710557e3931821dd8809ab0a9d3aaa761a01ae0f2e378906672924d6a1b12fb1cca7bed41f31974b9917a05de60c32796f502e7035a2c01cb49bc8e1734b9fa138b81b4dfe19d37f5942dd1b42f03e1e5a6a046ecd457174150e17dd148e4bfea44b72da35ef42a7251244700e59e702033677d42611168fd246e1b18b9a464b6c20fc7fcf6360cd00466ece059a69d7d54a4f5565d08799f85dd3c849a08ba43415077c1c0e5dbdba52bb3167ee99a11db551f0260493be1dde58d2072e8c02251f4f574b6e115cbb6136dc2c3fbce75fdcefe812d9c07a91a89088985a52cb1fb9f6cef80fa30364706414175e42c75e8e37f6e7cd028c99f59caa88c49db5b46e8d6301bc39034013718a9eeef5506415016fb21d70e46a03b4c5ba72f91dd9321ff5e210e5e5f7b0723a3bc4bb02b5a74c1f4a63aa5a993a31f79a768fe8033c9abfeb4deb536af1054be02d8d1c4a6a0fa75f3eb787d57a03b7ae994fb1b54b2c43b230ce32e6245d944b3cea4fa6",
|
||||
output: "785dbea5d1e50af4743ed5fd2209e441fc7c50bc7f6fd9cc7f24654c619e2606178dcbbd81a1f94c1b3176837024098bd31326145be326b32fd9277a55a6fb38780c8dc8b471a3184379d90da4aa87d80b889b1f4d8d0755c1704a526b99ac829b8ad157ca54b2b05ff8b2917e27b0c147ab54add9a89fdcad7b93ba1fe2d5be9de88b68a5324f1b42943e45ee31c4ef783ec9e2337b3f2834b10cf452b313fafdf0c03719140f64060da0a565e185cb8e544e1c185ca230ff2321739a285abe8be4be0ce76678a7b0902a77a645194de49fef8ff64cc464ea25e1f1d72c775e450f08ddd7680d27a4142879787b198583d93b84cd87fd5b4063d92d13d9c9cb580c01fac0174686a18f64e6fa0b3589624cfae04aad74950559bdf92b2b199c60cb04013aa0ef56d1f9ec5b7e968f6a83756ecc9cee7dd8b433f64649f948df5474a64549e71e46fd8bb16568d21f5fb67f5ed555f2b8aec4709383e8cbc45b9fe47c0434178ad4c6d0d42606d6eef0e21d0370898d1d5d646830a88d5f024094fe9c7a2003ca13d20ab7cd748dc11a22f578ddab416f3500eff3d89fc177b46436108e2e2c7973910cb8454a01c9e9b98f966848325444b2ac205b1ed6919fa76aaf63717574761b7f62b10649357df49f85a845a30b6acd57fa202fe58673930ec59399f537e9682b1f5f6f409988789a8e0c1f803478dded14b40d3b6eb3109758efeb6a7fe21f41c4dcc8027258da27ad74010839dbfdf8fe55050511f85c321e653f76e55f22248f46da529a380c6b1a16a19ce73af9715545c2cae098dc42dd61248dbcf7b295f4dc6b8930b41baeef677156c534869be65e723e1aa0336e8be8a3b138f840c9cd63bab6d9d61f239a47d8cf56258544e6ef65edca27069f7a57f087a7cc021fa1294b75c0c0f1093c025e426e4f041ed5187f358402676d5da5fb6ceba76a178f65c8c3046f258531c165b8808bdd221c59ff56e3e06247576e144aac01ea96a07f1be15d7a2b0b3b6c259a9133f8a50b56154ecf9f61022f470027247e6e70e6eaf7ece5e324ec8f95667ffed10337652b119e7cb8d197e306e81ea251340b9fb2c33aa230c0a16e1ca783f9344b3acbf413acd96616e6d477dba90e39326089934bc5ca6620855cdc442e25bf8b8debf335e16e7e25cceb68659cc81b13a507fbd9f30b347126beeb57016bd348fe3df592d4778011664a218227e70d7360d139480500b7f6f84153e61ca4dea105875e19ce3d11a3dfd0ad0074035ff6a9fac0ece91afd8be74c168da20c8baafcc14632eb0e774db758a3d90709cddf0266c27963788c35a842beea8ba2d916234431efde4bb32fd7e1cef51dcf580f4697206bbc3f991f4046360aea6e88ec",
|
||||
},
|
||||
}
|
||||
43
vendor/golang.org/x/crypto/internal/chacha20/xor.go
generated
vendored
Normal file
43
vendor/golang.org/x/crypto/internal/chacha20/xor.go
generated
vendored
Normal file
@@ -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 src the LICENSE file.
|
||||
|
||||
package chacha20
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// Platforms that have fast unaligned 32-bit little endian accesses.
|
||||
const unaligned = runtime.GOARCH == "386" ||
|
||||
runtime.GOARCH == "amd64" ||
|
||||
runtime.GOARCH == "arm64" ||
|
||||
runtime.GOARCH == "ppc64le" ||
|
||||
runtime.GOARCH == "s390x"
|
||||
|
||||
// xor reads a little endian uint32 from src, XORs it with u and
|
||||
// places the result in little endian byte order in dst.
|
||||
func xor(dst, src []byte, u uint32) {
|
||||
_, _ = src[3], dst[3] // eliminate bounds checks
|
||||
if unaligned {
|
||||
// The compiler should optimize this code into
|
||||
// 32-bit unaligned little endian loads and stores.
|
||||
// TODO: delete once the compiler does a reliably
|
||||
// good job with the generic code below.
|
||||
// See issue #25111 for more details.
|
||||
v := uint32(src[0])
|
||||
v |= uint32(src[1]) << 8
|
||||
v |= uint32(src[2]) << 16
|
||||
v |= uint32(src[3]) << 24
|
||||
v ^= u
|
||||
dst[0] = byte(v)
|
||||
dst[1] = byte(v >> 8)
|
||||
dst[2] = byte(v >> 16)
|
||||
dst[3] = byte(v >> 24)
|
||||
} else {
|
||||
dst[0] = src[0] ^ byte(u)
|
||||
dst[1] = src[1] ^ byte(u>>8)
|
||||
dst[2] = src[2] ^ byte(u>>16)
|
||||
dst[3] = src[3] ^ byte(u>>24)
|
||||
}
|
||||
}
|
||||
32
vendor/golang.org/x/crypto/internal/subtle/aliasing.go
generated
vendored
Normal file
32
vendor/golang.org/x/crypto/internal/subtle/aliasing.go
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
// 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 !appengine
|
||||
|
||||
// Package subtle implements functions that are often useful in cryptographic
|
||||
// code but require careful thought to use correctly.
|
||||
package subtle // import "golang.org/x/crypto/internal/subtle"
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// AnyOverlap reports whether x and y share memory at any (not necessarily
|
||||
// corresponding) index. The memory beyond the slice length is ignored.
|
||||
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]))
|
||||
}
|
||||
|
||||
// InexactOverlap reports whether x and y share memory at any non-corresponding
|
||||
// index. The memory beyond the slice length is ignored. Note that x and y can
|
||||
// have different lengths and still not have any inexact overlap.
|
||||
//
|
||||
// InexactOverlap can be used to implement the requirements of the crypto/cipher
|
||||
// AEAD, Block, BlockMode and Stream interfaces.
|
||||
func InexactOverlap(x, y []byte) bool {
|
||||
if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] {
|
||||
return false
|
||||
}
|
||||
return AnyOverlap(x, y)
|
||||
}
|
||||
35
vendor/golang.org/x/crypto/internal/subtle/aliasing_appengine.go
generated
vendored
Normal file
35
vendor/golang.org/x/crypto/internal/subtle/aliasing_appengine.go
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
// 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 appengine
|
||||
|
||||
// Package subtle implements functions that are often useful in cryptographic
|
||||
// code but require careful thought to use correctly.
|
||||
package subtle // import "golang.org/x/crypto/internal/subtle"
|
||||
|
||||
// This is the Google App Engine standard variant based on reflect
|
||||
// because the unsafe package and cgo are disallowed.
|
||||
|
||||
import "reflect"
|
||||
|
||||
// AnyOverlap reports whether x and y share memory at any (not necessarily
|
||||
// corresponding) index. The memory beyond the slice length is ignored.
|
||||
func AnyOverlap(x, y []byte) bool {
|
||||
return len(x) > 0 && len(y) > 0 &&
|
||||
reflect.ValueOf(&x[0]).Pointer() <= reflect.ValueOf(&y[len(y)-1]).Pointer() &&
|
||||
reflect.ValueOf(&y[0]).Pointer() <= reflect.ValueOf(&x[len(x)-1]).Pointer()
|
||||
}
|
||||
|
||||
// InexactOverlap reports whether x and y share memory at any non-corresponding
|
||||
// index. The memory beyond the slice length is ignored. Note that x and y can
|
||||
// have different lengths and still not have any inexact overlap.
|
||||
//
|
||||
// InexactOverlap can be used to implement the requirements of the crypto/cipher
|
||||
// AEAD, Block, BlockMode and Stream interfaces.
|
||||
func InexactOverlap(x, y []byte) bool {
|
||||
if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] {
|
||||
return false
|
||||
}
|
||||
return AnyOverlap(x, y)
|
||||
}
|
||||
50
vendor/golang.org/x/crypto/internal/subtle/aliasing_test.go
generated
vendored
Normal file
50
vendor/golang.org/x/crypto/internal/subtle/aliasing_test.go
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
// 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 subtle_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"golang.org/x/crypto/internal/subtle"
|
||||
)
|
||||
|
||||
var a, b [100]byte
|
||||
|
||||
var aliasingTests = []struct {
|
||||
x, y []byte
|
||||
anyOverlap, inexactOverlap bool
|
||||
}{
|
||||
{a[:], b[:], false, false},
|
||||
{a[:], b[:0], false, false},
|
||||
{a[:], b[:50], false, false},
|
||||
{a[40:50], a[50:60], false, false},
|
||||
{a[40:50], a[60:70], false, false},
|
||||
{a[:51], a[50:], true, true},
|
||||
{a[:], a[:], true, false},
|
||||
{a[:50], a[:60], true, false},
|
||||
{a[:], nil, false, false},
|
||||
{nil, nil, false, false},
|
||||
{a[:], a[:0], false, false},
|
||||
{a[:10], a[:10:20], true, false},
|
||||
{a[:10], a[5:10:20], true, true},
|
||||
}
|
||||
|
||||
func testAliasing(t *testing.T, i int, x, y []byte, anyOverlap, inexactOverlap bool) {
|
||||
any := subtle.AnyOverlap(x, y)
|
||||
if any != anyOverlap {
|
||||
t.Errorf("%d: wrong AnyOverlap result, expected %v, got %v", i, anyOverlap, any)
|
||||
}
|
||||
inexact := subtle.InexactOverlap(x, y)
|
||||
if inexact != inexactOverlap {
|
||||
t.Errorf("%d: wrong InexactOverlap result, expected %v, got %v", i, inexactOverlap, any)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAliasing(t *testing.T) {
|
||||
for i, tt := range aliasingTests {
|
||||
testAliasing(t, i, tt.x, tt.y, tt.anyOverlap, tt.inexactOverlap)
|
||||
testAliasing(t, i, tt.y, tt.x, tt.anyOverlap, tt.inexactOverlap)
|
||||
}
|
||||
}
|
||||
9
vendor/golang.org/x/crypto/nacl/secretbox/secretbox.go
generated
vendored
9
vendor/golang.org/x/crypto/nacl/secretbox/secretbox.go
generated
vendored
@@ -35,6 +35,7 @@ This package is interoperable with NaCl: https://nacl.cr.yp.to/secretbox.html.
|
||||
package secretbox // import "golang.org/x/crypto/nacl/secretbox"
|
||||
|
||||
import (
|
||||
"golang.org/x/crypto/internal/subtle"
|
||||
"golang.org/x/crypto/poly1305"
|
||||
"golang.org/x/crypto/salsa20/salsa"
|
||||
)
|
||||
@@ -87,6 +88,9 @@ func Seal(out, message []byte, nonce *[24]byte, key *[32]byte) []byte {
|
||||
copy(poly1305Key[:], firstBlock[:])
|
||||
|
||||
ret, out := sliceForAppend(out, len(message)+poly1305.TagSize)
|
||||
if subtle.AnyOverlap(out, message) {
|
||||
panic("nacl: invalid buffer overlap")
|
||||
}
|
||||
|
||||
// We XOR up to 32 bytes of message with the keystream generated from
|
||||
// the first block.
|
||||
@@ -118,7 +122,7 @@ func Seal(out, message []byte, nonce *[24]byte, key *[32]byte) []byte {
|
||||
// Open authenticates and decrypts a box produced by Seal and appends the
|
||||
// message to out, which must not overlap box. The output will be Overhead
|
||||
// bytes smaller than box.
|
||||
func Open(out []byte, box []byte, nonce *[24]byte, key *[32]byte) ([]byte, bool) {
|
||||
func Open(out, box []byte, nonce *[24]byte, key *[32]byte) ([]byte, bool) {
|
||||
if len(box) < Overhead {
|
||||
return nil, false
|
||||
}
|
||||
@@ -143,6 +147,9 @@ func Open(out []byte, box []byte, nonce *[24]byte, key *[32]byte) ([]byte, bool)
|
||||
}
|
||||
|
||||
ret, out := sliceForAppend(out, len(box)-Overhead)
|
||||
if subtle.AnyOverlap(out, box) {
|
||||
panic("nacl: invalid buffer overlap")
|
||||
}
|
||||
|
||||
// We XOR up to 32 bytes of box with the keystream generated from
|
||||
// the first block.
|
||||
|
||||
7
vendor/golang.org/x/crypto/nacl/sign/sign.go
generated
vendored
7
vendor/golang.org/x/crypto/nacl/sign/sign.go
generated
vendored
@@ -24,6 +24,7 @@ import (
|
||||
"io"
|
||||
|
||||
"golang.org/x/crypto/ed25519"
|
||||
"golang.org/x/crypto/internal/subtle"
|
||||
)
|
||||
|
||||
// Overhead is the number of bytes of overhead when signing a message.
|
||||
@@ -47,6 +48,9 @@ func GenerateKey(rand io.Reader) (publicKey *[32]byte, privateKey *[64]byte, err
|
||||
func Sign(out, message []byte, privateKey *[64]byte) []byte {
|
||||
sig := ed25519.Sign(ed25519.PrivateKey((*privateKey)[:]), message)
|
||||
ret, out := sliceForAppend(out, Overhead+len(message))
|
||||
if subtle.AnyOverlap(out, message) {
|
||||
panic("nacl: invalid buffer overlap")
|
||||
}
|
||||
copy(out, sig)
|
||||
copy(out[Overhead:], message)
|
||||
return ret
|
||||
@@ -63,6 +67,9 @@ func Open(out, signedMessage []byte, publicKey *[32]byte) ([]byte, bool) {
|
||||
return nil, false
|
||||
}
|
||||
ret, out := sliceForAppend(out, len(signedMessage)-Overhead)
|
||||
if subtle.AnyOverlap(out, signedMessage) {
|
||||
panic("nacl: invalid buffer overlap")
|
||||
}
|
||||
copy(out, signedMessage[Overhead:])
|
||||
return ret, true
|
||||
}
|
||||
|
||||
11
vendor/golang.org/x/crypto/ocsp/ocsp.go
generated
vendored
11
vendor/golang.org/x/crypto/ocsp/ocsp.go
generated
vendored
@@ -488,10 +488,6 @@ func ParseResponseForCert(bytes []byte, cert, issuer *x509.Certificate) (*Respon
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(basicResp.Certificates) > 1 {
|
||||
return nil, ParseError("OCSP response contains bad number of certificates")
|
||||
}
|
||||
|
||||
if n := len(basicResp.TBSResponseData.Responses); n == 0 || cert == nil && n > 1 {
|
||||
return nil, ParseError("OCSP response contains bad number of responses")
|
||||
}
|
||||
@@ -544,6 +540,13 @@ func ParseResponseForCert(bytes []byte, cert, issuer *x509.Certificate) (*Respon
|
||||
}
|
||||
|
||||
if len(basicResp.Certificates) > 0 {
|
||||
// Responders should only send a single certificate (if they
|
||||
// send any) that connects the responder's certificate to the
|
||||
// original issuer. We accept responses with multiple
|
||||
// certificates due to a number responders sending them[1], but
|
||||
// ignore all but the first.
|
||||
//
|
||||
// [1] https://github.com/golang/go/issues/21527
|
||||
ret.Certificate, err = x509.ParseCertificate(basicResp.Certificates[0].FullBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
33
vendor/golang.org/x/crypto/openpgp/keys.go
generated
vendored
33
vendor/golang.org/x/crypto/openpgp/keys.go
generated
vendored
@@ -346,22 +346,25 @@ EachPacket:
|
||||
|
||||
switch pkt := p.(type) {
|
||||
case *packet.UserId:
|
||||
// Make a new Identity object, that we might wind up throwing away.
|
||||
// We'll only add it if we get a valid self-signature over this
|
||||
// userID.
|
||||
current = new(Identity)
|
||||
current.Name = pkt.Id
|
||||
current.UserId = pkt
|
||||
e.Identities[pkt.Id] = current
|
||||
|
||||
for {
|
||||
p, err = packets.Next()
|
||||
if err == io.EOF {
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
break EachPacket
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sig, ok := p.(*packet.Signature)
|
||||
if !ok {
|
||||
return nil, errors.StructuralError("user ID packet not followed by self-signature")
|
||||
packets.Unread(p)
|
||||
continue EachPacket
|
||||
}
|
||||
|
||||
if (sig.SigType == packet.SigTypePositiveCert || sig.SigType == packet.SigTypeGenericCert) && sig.IssuerKeyId != nil && *sig.IssuerKeyId == e.PrimaryKey.KeyId {
|
||||
@@ -369,9 +372,10 @@ EachPacket:
|
||||
return nil, errors.StructuralError("user ID self-signature invalid: " + err.Error())
|
||||
}
|
||||
current.SelfSignature = sig
|
||||
break
|
||||
e.Identities[pkt.Id] = current
|
||||
} else {
|
||||
current.Signatures = append(current.Signatures, sig)
|
||||
}
|
||||
current.Signatures = append(current.Signatures, sig)
|
||||
}
|
||||
case *packet.Signature:
|
||||
if pkt.SigType == packet.SigTypeKeyRevocation {
|
||||
@@ -500,6 +504,10 @@ func NewEntity(name, comment, email string, config *packet.Config) (*Entity, err
|
||||
IssuerKeyId: &e.PrimaryKey.KeyId,
|
||||
},
|
||||
}
|
||||
err = e.Identities[uid.Id].SelfSignature.SignUserId(uid.Id, e.PrimaryKey, e.PrivateKey, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// If the user passes in a DefaultHash via packet.Config,
|
||||
// set the PreferredHash for the SelfSignature.
|
||||
@@ -529,13 +537,16 @@ func NewEntity(name, comment, email string, config *packet.Config) (*Entity, err
|
||||
}
|
||||
e.Subkeys[0].PublicKey.IsSubkey = true
|
||||
e.Subkeys[0].PrivateKey.IsSubkey = true
|
||||
|
||||
err = e.Subkeys[0].Sig.SignKey(e.Subkeys[0].PublicKey, e.PrivateKey, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return e, nil
|
||||
}
|
||||
|
||||
// SerializePrivate serializes an Entity, including private key material, to
|
||||
// the given Writer. For now, it must only be used on an Entity returned from
|
||||
// NewEntity.
|
||||
// SerializePrivate serializes an Entity, including private key material, but
|
||||
// excluding signatures from other entities, to the given Writer.
|
||||
// Identities and subkeys are re-signed in case they changed since NewEntry.
|
||||
// If config is nil, sensible defaults will be used.
|
||||
func (e *Entity) SerializePrivate(w io.Writer, config *packet.Config) (err error) {
|
||||
err = e.PrivateKey.Serialize(w)
|
||||
@@ -573,8 +584,8 @@ func (e *Entity) SerializePrivate(w io.Writer, config *packet.Config) (err error
|
||||
return nil
|
||||
}
|
||||
|
||||
// Serialize writes the public part of the given Entity to w. (No private
|
||||
// key material will be output).
|
||||
// Serialize writes the public part of the given Entity to w, including
|
||||
// signatures from other entities. No private key material will be output.
|
||||
func (e *Entity) Serialize(w io.Writer) error {
|
||||
err := e.PrimaryKey.Serialize(w)
|
||||
if err != nil {
|
||||
|
||||
88
vendor/golang.org/x/crypto/openpgp/keys_test.go
generated
vendored
88
vendor/golang.org/x/crypto/openpgp/keys_test.go
generated
vendored
@@ -29,16 +29,16 @@ func TestKeyExpiry(t *testing.T) {
|
||||
//
|
||||
// So this should select the newest, non-expired encryption key.
|
||||
key, _ := entity.encryptionKey(time1)
|
||||
if id := key.PublicKey.KeyIdShortString(); id != "96A672F5" {
|
||||
t.Errorf("Expected key 1ABB25A0 at time %s, but got key %s", time1.Format(timeFormat), id)
|
||||
if id, expected := key.PublicKey.KeyIdShortString(), "96A672F5"; id != expected {
|
||||
t.Errorf("Expected key %s at time %s, but got key %s", expected, time1.Format(timeFormat), id)
|
||||
}
|
||||
|
||||
// Once the first encryption subkey has expired, the second should be
|
||||
// selected.
|
||||
time2, _ := time.Parse(timeFormat, "2013-07-09")
|
||||
key, _ = entity.encryptionKey(time2)
|
||||
if id := key.PublicKey.KeyIdShortString(); id != "96A672F5" {
|
||||
t.Errorf("Expected key 96A672F5 at time %s, but got key %s", time2.Format(timeFormat), id)
|
||||
if id, expected := key.PublicKey.KeyIdShortString(), "96A672F5"; id != expected {
|
||||
t.Errorf("Expected key %s at time %s, but got key %s", expected, time2.Format(timeFormat), id)
|
||||
}
|
||||
|
||||
// Once all the keys have expired, nothing should be returned.
|
||||
@@ -105,6 +105,33 @@ func TestGoodCrossSignature(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRevokedUserID(t *testing.T) {
|
||||
// This key contains 2 UIDs, one of which is revoked:
|
||||
// [ultimate] (1) Golang Gopher <no-reply@golang.com>
|
||||
// [ revoked] (2) Golang Gopher <revoked@golang.com>
|
||||
keys, err := ReadArmoredKeyRing(bytes.NewBufferString(revokedUserIDKey))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(keys) != 1 {
|
||||
t.Fatal("Failed to read key with a revoked user id")
|
||||
}
|
||||
|
||||
var identities []*Identity
|
||||
for _, identity := range keys[0].Identities {
|
||||
identities = append(identities, identity)
|
||||
}
|
||||
|
||||
if numIdentities, numExpected := len(identities), 1; numIdentities != numExpected {
|
||||
t.Errorf("obtained %d identities, expected %d", numIdentities, numExpected)
|
||||
}
|
||||
|
||||
if identityName, expectedName := identities[0].Name, "Golang Gopher <no-reply@golang.com>"; identityName != expectedName {
|
||||
t.Errorf("obtained identity %s expected %s", identityName, expectedName)
|
||||
}
|
||||
}
|
||||
|
||||
// TestExternallyRevokableKey attempts to load and parse a key with a third party revocation permission.
|
||||
func TestExternallyRevocableKey(t *testing.T) {
|
||||
kring, err := ReadKeyRing(readerFromHex(subkeyUsageHex))
|
||||
@@ -370,6 +397,20 @@ func TestNewEntityWithoutPreferredSymmetric(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewEntityPublicSerialization(t *testing.T) {
|
||||
entity, err := NewEntity("Golang Gopher", "Test Key", "no-reply@golang.com", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
serializedEntity := bytes.NewBuffer(nil)
|
||||
entity.Serialize(serializedEntity)
|
||||
|
||||
_, err = ReadEntity(packet.NewReader(bytes.NewBuffer(serializedEntity.Bytes())))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
const expiringKeyHex = "988d0451d1ec5d010400ba3385721f2dc3f4ab096b2ee867ab77213f0a27a8538441c35d2fa225b08798a1439a66a5150e6bdc3f40f5d28d588c712394c632b6299f77db8c0d48d37903fb72ebd794d61be6aa774688839e5fdecfe06b2684cc115d240c98c66cb1ef22ae84e3aa0c2b0c28665c1e7d4d044e7f270706193f5223c8d44e0d70b7b8da830011010001b40f4578706972792074657374206b657988be041301020028050251d1ec5d021b03050900278d00060b090807030206150802090a0b0416020301021e01021780000a091072589ad75e237d8c033503fd10506d72837834eb7f994117740723adc39227104b0d326a1161871c0b415d25b4aedef946ca77ea4c05af9c22b32cf98be86ab890111fced1ee3f75e87b7cc3c00dc63bbc85dfab91c0dc2ad9de2c4d13a34659333a85c6acc1a669c5e1d6cecb0cf1e56c10e72d855ae177ddc9e766f9b2dda57ccbb75f57156438bbdb4e42b88d0451d1ec5d0104009c64906559866c5cb61578f5846a94fcee142a489c9b41e67b12bb54cfe86eb9bc8566460f9a720cb00d6526fbccfd4f552071a8e3f7744b1882d01036d811ee5a3fb91a1c568055758f43ba5d2c6a9676b012f3a1a89e47bbf624f1ad571b208f3cc6224eb378f1645dd3d47584463f9eadeacfd1ce6f813064fbfdcc4b5a53001101000188a504180102000f021b0c050251d1f06b050900093e89000a091072589ad75e237d8c20e00400ab8310a41461425b37889c4da28129b5fae6084fafbc0a47dd1adc74a264c6e9c9cc125f40462ee1433072a58384daef88c961c390ed06426a81b464a53194c4e291ddd7e2e2ba3efced01537d713bd111f48437bde2363446200995e8e0d4e528dda377fd1e8f8ede9c8e2198b393bd86852ce7457a7e3daf74d510461a5b77b88d0451d1ece8010400b3a519f83ab0010307e83bca895170acce8964a044190a2b368892f7a244758d9fc193482648acb1fb9780d28cc22d171931f38bb40279389fc9bf2110876d4f3db4fcfb13f22f7083877fe56592b3b65251312c36f83ffcb6d313c6a17f197dd471f0712aad15a8537b435a92471ba2e5b0c72a6c72536c3b567c558d7b6051001101000188a504180102000f021b0c050251d1f07b050900279091000a091072589ad75e237d8ce69e03fe286026afacf7c97ee20673864d4459a2240b5655219950643c7dba0ac384b1d4359c67805b21d98211f7b09c2a0ccf6410c8c04d4ff4a51293725d8d6570d9d8bb0e10c07d22357caeb49626df99c180be02d77d1fe8ed25e7a54481237646083a9f89a11566cd20b9e995b1487c5f9e02aeb434f3a1897cd416dd0a87861838da3e9e"
|
||||
const subkeyUsageHex = "988d04533a52bc010400d26af43085558f65b9e7dbc90cb9238015259aed5e954637adcfa2181548b2d0b60c65f1f42ec5081cbf1bc0a8aa4900acfb77070837c58f26012fbce297d70afe96e759ad63531f0037538e70dbf8e384569b9720d99d8eb39d8d0a2947233ed242436cb6ac7dfe74123354b3d0119b5c235d3dd9c9d6c004f8ffaf67ad8583001101000188b7041f010200210502533b8552170c8001ce094aa433f7040bb2ddf0be3893cb843d0fe70c020700000a0910a42704b92866382aa98404009d63d916a27543da4221c60087c33f1c44bec9998c5438018ed370cca4962876c748e94b73eb39c58eb698063f3fd6346d58dd2a11c0247934c4a9d71f24754f7468f96fb24c3e791dd2392b62f626148ad724189498cbf993db2df7c0cdc2d677c35da0f16cb16c9ce7c33b4de65a4a91b1d21a130ae9cc26067718910ef8e2b417556d627261203c756d627261407379642e65642e61753e88b80413010200220502533a52bc021b03060b090807030206150802090a0b0416020301021e01021780000a0910a42704b92866382a47840400c0c2bd04f5fca586de408b395b3c280a278259c93eaaa8b79a53b97003f8ed502a8a00446dd9947fb462677e4fcac0dac2f0701847d15130aadb6cd9e0705ea0cf5f92f129136c7be21a718d46c8e641eb7f044f2adae573e11ae423a0a9ca51324f03a8a2f34b91fa40c3cc764bee4dccadedb54c768ba0469b683ea53f1c29b88d04533a52bc01040099c92a5d6f8b744224da27bc2369127c35269b58bec179de6bbc038f749344222f85a31933224f26b70243c4e4b2d242f0c4777eaef7b5502f9dad6d8bf3aaeb471210674b74de2d7078af497d55f5cdad97c7bedfbc1b41e8065a97c9c3d344b21fc81d27723af8e374bc595da26ea242dccb6ae497be26eea57e563ed517e90011010001889f0418010200090502533a52bc021b0c000a0910a42704b92866382afa1403ff70284c2de8a043ff51d8d29772602fa98009b7861c540535f874f2c230af8caf5638151a636b21f8255003997ccd29747fdd06777bb24f9593bd7d98a3e887689bf902f999915fcc94625ae487e5d13e6616f89090ebc4fdc7eb5cad8943e4056995bb61c6af37f8043016876a958ec7ebf39c43d20d53b7f546cfa83e8d2604b88d04533b8283010400c0b529316dbdf58b4c54461e7e669dc11c09eb7f73819f178ccd4177b9182b91d138605fcf1e463262fabefa73f94a52b5e15d1904635541c7ea540f07050ce0fb51b73e6f88644cec86e91107c957a114f69554548a85295d2b70bd0b203992f76eb5d493d86d9eabcaa7ef3fc7db7e458438db3fcdb0ca1cc97c638439a9170011010001889f0418010200090502533b8283021b0c000a0910a42704b92866382adc6d0400cfff6258485a21675adb7a811c3e19ebca18851533f75a7ba317950b9997fda8d1a4c8c76505c08c04b6c2cc31dc704d33da36a21273f2b388a1a706f7c3378b66d887197a525936ed9a69acb57fe7f718133da85ec742001c5d1864e9c6c8ea1b94f1c3759cebfd93b18606066c063a63be86085b7e37bdbc65f9a915bf084bb901a204533b85cd110400aed3d2c52af2b38b5b67904b0ef73d6dd7aef86adb770e2b153cd22489654dcc91730892087bb9856ae2d9f7ed1eb48f214243fe86bfe87b349ebd7c30e630e49c07b21fdabf78b7a95c8b7f969e97e3d33f2e074c63552ba64a2ded7badc05ce0ea2be6d53485f6900c7860c7aa76560376ce963d7271b9b54638a4028b573f00a0d8854bfcdb04986141568046202192263b9b67350400aaa1049dbc7943141ef590a70dcb028d730371d92ea4863de715f7f0f16d168bd3dc266c2450457d46dcbbf0b071547e5fbee7700a820c3750b236335d8d5848adb3c0da010e998908dfd93d961480084f3aea20b247034f8988eccb5546efaa35a92d0451df3aaf1aee5aa36a4c4d462c760ecd9cebcabfbe1412b1f21450f203fd126687cd486496e971a87fd9e1a8a765fe654baa219a6871ab97768596ab05c26c1aeea8f1a2c72395a58dbc12ef9640d2b95784e974a4d2d5a9b17c25fedacfe551bda52602de8f6d2e48443f5dd1a2a2a8e6a5e70ecdb88cd6e766ad9745c7ee91d78cc55c3d06536b49c3fee6c3d0b6ff0fb2bf13a314f57c953b8f4d93bf88e70418010200090502533b85cd021b0200520910a42704b92866382a47200419110200060502533b85cd000a091042ce2c64bc0ba99214b2009e26b26852c8b13b10c35768e40e78fbbb48bd084100a0c79d9ea0844fa5853dd3c85ff3ecae6f2c9dd6c557aa04008bbbc964cd65b9b8299d4ebf31f41cc7264b8cf33a00e82c5af022331fac79efc9563a822497ba012953cefe2629f1242fcdcb911dbb2315985bab060bfd58261ace3c654bdbbe2e8ed27a46e836490145c86dc7bae15c011f7e1ffc33730109b9338cd9f483e7cef3d2f396aab5bd80efb6646d7e778270ee99d934d187dd98"
|
||||
const revokedKeyHex = "988d045331ce82010400c4fdf7b40a5477f206e6ee278eaef888ca73bf9128a9eef9f2f1ddb8b7b71a4c07cfa241f028a04edb405e4d916c61d6beabc333813dc7b484d2b3c52ee233c6a79b1eea4e9cc51596ba9cd5ac5aeb9df62d86ea051055b79d03f8a4fa9f38386f5bd17529138f3325d46801514ea9047977e0829ed728e68636802796801be10011010001889f04200102000905025331d0e3021d03000a0910a401d9f09a34f7c042aa040086631196405b7e6af71026b88e98012eab44aa9849f6ef3fa930c7c9f23deaedba9db1538830f8652fb7648ec3fcade8dbcbf9eaf428e83c6cbcc272201bfe2fbb90d41963397a7c0637a1a9d9448ce695d9790db2dc95433ad7be19eb3de72dacf1d6db82c3644c13eae2a3d072b99bb341debba012c5ce4006a7d34a1f4b94b444526567205265766f6b657220283c52656727732022424d204261726973746122204b657920262530305c303e5c29203c72656740626d626172697374612e636f2e61753e88b704130102002205025331ce82021b03060b090807030206150802090a0b0416020301021e01021780000a0910a401d9f09a34f7c0019c03f75edfbeb6a73e7225ad3cc52724e2872e04260d7daf0d693c170d8c4b243b8767bc7785763533febc62ec2600c30603c433c095453ede59ff2fcabeb84ce32e0ed9d5cf15ffcbc816202b64370d4d77c1e9077d74e94a16fb4fa2e5bec23a56d7a73cf275f91691ae1801a976fcde09e981a2f6327ac27ea1fecf3185df0d56889c04100102000605025331cfb5000a0910fe9645554e8266b64b4303fc084075396674fb6f778d302ac07cef6bc0b5d07b66b2004c44aef711cbac79617ef06d836b4957522d8772dd94bf41a2f4ac8b1ee6d70c57503f837445a74765a076d07b829b8111fc2a918423ddb817ead7ca2a613ef0bfb9c6b3562aec6c3cf3c75ef3031d81d95f6563e4cdcc9960bcb386c5d757b104fcca5fe11fc709df884604101102000605025331cfe7000a09107b15a67f0b3ddc0317f6009e360beea58f29c1d963a22b962b80788c3fa6c84e009d148cfde6b351469b8eae91187eff07ad9d08fcaab88d045331ce820104009f25e20a42b904f3fa555530fe5c46737cf7bd076c35a2a0d22b11f7e0b61a69320b768f4a80fe13980ce380d1cfc4a0cd8fbe2d2e2ef85416668b77208baa65bf973fe8e500e78cc310d7c8705cdb34328bf80e24f0385fce5845c33bc7943cf6b11b02348a23da0bf6428e57c05135f2dc6bd7c1ce325d666d5a5fd2fd5e410011010001889f04180102000905025331ce82021b0c000a0910a401d9f09a34f7c0418003fe34feafcbeaef348a800a0d908a7a6809cc7304017d820f70f0474d5e23cb17e38b67dc6dca282c6ca00961f4ec9edf2738d0f087b1d81e4871ef08e1798010863afb4eac4c44a376cb343be929c5be66a78cfd4456ae9ec6a99d97f4e1c3ff3583351db2147a65c0acef5c003fb544ab3a2e2dc4d43646f58b811a6c3a369d1f"
|
||||
@@ -467,3 +508,42 @@ SqLHvbKh2dL/RXymC3+rjPvQf5cup9bPxNMa6WagdYBNAfzWGtkVISeaQW+cTEp/
|
||||
MtgVijRGXR/lGLGETPg2X3Afwn9N9bLMBkBprKgbBqU7lpaoPupxT61bL70=
|
||||
=vtbN
|
||||
-----END PGP PUBLIC KEY BLOCK-----`
|
||||
|
||||
const revokedUserIDKey = `-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mQENBFsgO5EBCADhREPmcjsPkXe1z7ctvyWL0S7oa9JaoGZ9oPDHFDlQxd0qlX2e
|
||||
DZJZDg0qYvVixmaULIulApq1puEsaJCn3lHUbHlb4PYKwLEywYXM28JN91KtLsz/
|
||||
uaEX2KC5WqeP40utmzkNLq+oRX/xnRMgwbO7yUNVG2UlEa6eI+xOXO3YtLdmJMBW
|
||||
ClQ066ZnOIzEo1JxnIwha1CDBMWLLfOLrg6l8InUqaXbtEBbnaIYO6fXVXELUjkx
|
||||
nmk7t/QOk0tXCy8muH9UDqJkwDUESY2l79XwBAcx9riX8vY7vwC34pm22fAUVLCJ
|
||||
x1SJx0J8bkeNp38jKM2Zd9SUQqSbfBopQ4pPABEBAAG0I0dvbGFuZyBHb3BoZXIg
|
||||
PG5vLXJlcGx5QGdvbGFuZy5jb20+iQFUBBMBCgA+FiEE5Ik5JLcNx6l6rZfw1oFy
|
||||
9I6cUoMFAlsgO5ECGwMFCQPCZwAFCwkIBwMFFQoJCAsFFgIDAQACHgECF4AACgkQ
|
||||
1oFy9I6cUoMIkwf8DNPeD23i4jRwd/pylbvxwZintZl1fSwTJW1xcOa1emXaEtX2
|
||||
depuqhP04fjlRQGfsYAQh7X9jOJxAHjTmhqFBi5sD7QvKU00cPFYbJ/JTx0B41bl
|
||||
aXnSbGhRPh63QtEZL7ACAs+shwvvojJqysx7kyVRu0EW2wqjXdHwR/SJO6nhNBa2
|
||||
DXzSiOU/SUA42mmG+5kjF8Aabq9wPwT9wjraHShEweNerNMmOqJExBOy3yFeyDpa
|
||||
XwEZFzBfOKoxFNkIaVf5GSdIUGhFECkGvBMB935khftmgR8APxdU4BE7XrXexFJU
|
||||
8RCuPXonm4WQOwTWR0vQg64pb2WKAzZ8HhwTGbQiR29sYW5nIEdvcGhlciA8cmV2
|
||||
b2tlZEBnb2xhbmcuY29tPokBNgQwAQoAIBYhBOSJOSS3Dcepeq2X8NaBcvSOnFKD
|
||||
BQJbIDv3Ah0AAAoJENaBcvSOnFKDfWMIAKhI/Tvu3h8fSUxp/gSAcduT6bC1JttG
|
||||
0lYQ5ilKB/58lBUA5CO3ZrKDKlzW3M8VEcvohVaqeTMKeoQd5rCZq8KxHn/KvN6N
|
||||
s85REfXfniCKfAbnGgVXX3kDmZ1g63pkxrFu0fDZjVDXC6vy+I0sGyI/Inro0Pzb
|
||||
tvn0QCsxjapKK15BtmSrpgHgzVqVg0cUp8vqZeKFxarYbYB2idtGRci4b9tObOK0
|
||||
BSTVFy26+I/mrFGaPrySYiy2Kz5NMEcRhjmTxJ8jSwEr2O2sUR0yjbgUAXbTxDVE
|
||||
/jg5fQZ1ACvBRQnB7LvMHcInbzjyeTM3FazkkSYQD6b97+dkWwb1iWG5AQ0EWyA7
|
||||
kQEIALkg04REDZo1JgdYV4x8HJKFS4xAYWbIva1ZPqvDNmZRUbQZR2+gpJGEwn7z
|
||||
VofGvnOYiGW56AS5j31SFf5kro1+1bZQ5iOONBng08OOo58/l1hRseIIVGB5TGSa
|
||||
PCdChKKHreJI6hS3mShxH6hdfFtiZuB45rwoaArMMsYcjaezLwKeLc396cpUwwcZ
|
||||
snLUNd1Xu5EWEF2OdFkZ2a1qYdxBvAYdQf4+1Nr+NRIx1u1NS9c8jp3PuMOkrQEi
|
||||
bNtc1v6v0Jy52mKLG4y7mC/erIkvkQBYJdxPaP7LZVaPYc3/xskcyijrJ/5ufoD8
|
||||
K71/ShtsZUXSQn9jlRaYR0EbojMAEQEAAYkBPAQYAQoAJhYhBOSJOSS3Dcepeq2X
|
||||
8NaBcvSOnFKDBQJbIDuRAhsMBQkDwmcAAAoJENaBcvSOnFKDkFMIAIt64bVZ8x7+
|
||||
TitH1bR4pgcNkaKmgKoZz6FXu80+SnbuEt2NnDyf1cLOSimSTILpwLIuv9Uft5Pb
|
||||
OraQbYt3xi9yrqdKqGLv80bxqK0NuryNkvh9yyx5WoG1iKqMj9/FjGghuPrRaT4l
|
||||
QinNAghGVkEy1+aXGFrG2DsOC1FFI51CC2WVTzZ5RwR2GpiNRfESsU1rZAUqf/2V
|
||||
yJl9bD5R4SUNy8oQmhOxi+gbhD4Ao34e4W0ilibslI/uawvCiOwlu5NGd8zv5n+U
|
||||
heiQvzkApQup5c+BhH5zFDFdKJ2CBByxw9+7QjMFI/wgLixKuE0Ob2kAokXf7RlB
|
||||
7qTZOahrETw=
|
||||
=IKnw
|
||||
-----END PGP PUBLIC KEY BLOCK-----`
|
||||
|
||||
2
vendor/golang.org/x/crypto/openpgp/read_test.go
generated
vendored
2
vendor/golang.org/x/crypto/openpgp/read_test.go
generated
vendored
@@ -124,7 +124,7 @@ func checkSignedMessage(t *testing.T, signedHex, expected string) {
|
||||
return
|
||||
}
|
||||
|
||||
if !md.IsSigned || md.SignedByKeyId != 0xa34d7e18c20c31bb || md.SignedBy == nil || md.IsEncrypted || md.IsSymmetricallyEncrypted || len(md.EncryptedToKeyIds) != 0 || md.IsSymmetricallyEncrypted {
|
||||
if !md.IsSigned || md.SignedByKeyId != 0xa34d7e18c20c31bb || md.SignedBy == nil || md.IsEncrypted || md.IsSymmetricallyEncrypted || len(md.EncryptedToKeyIds) != 0 || md.DecryptedWith != (Key{}) {
|
||||
t.Errorf("bad MessageDetails: %#v", md)
|
||||
}
|
||||
|
||||
|
||||
113
vendor/golang.org/x/crypto/poly1305/poly1305_test.go
generated
vendored
113
vendor/golang.org/x/crypto/poly1305/poly1305_test.go
generated
vendored
@@ -5,7 +5,6 @@
|
||||
package poly1305
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"flag"
|
||||
"testing"
|
||||
@@ -14,80 +13,51 @@ import (
|
||||
|
||||
var stressFlag = flag.Bool("stress", false, "run slow stress tests")
|
||||
|
||||
var testData = []struct {
|
||||
in, k, correct []byte
|
||||
}{
|
||||
{
|
||||
[]byte("Hello world!"),
|
||||
[]byte("this is 32-byte key for Poly1305"),
|
||||
[]byte{0xa6, 0xf7, 0x45, 0x00, 0x8f, 0x81, 0xc9, 0x16, 0xa2, 0x0d, 0xcc, 0x74, 0xee, 0xf2, 0xb2, 0xf0},
|
||||
},
|
||||
{
|
||||
make([]byte, 32),
|
||||
[]byte("this is 32-byte key for Poly1305"),
|
||||
[]byte{0x49, 0xec, 0x78, 0x09, 0x0e, 0x48, 0x1e, 0xc6, 0xc2, 0x6b, 0x33, 0xb9, 0x1c, 0xcc, 0x03, 0x07},
|
||||
},
|
||||
{
|
||||
make([]byte, 2007),
|
||||
[]byte("this is 32-byte key for Poly1305"),
|
||||
[]byte{0xda, 0x84, 0xbc, 0xab, 0x02, 0x67, 0x6c, 0x38, 0xcd, 0xb0, 0x15, 0x60, 0x42, 0x74, 0xc2, 0xaa},
|
||||
},
|
||||
{
|
||||
make([]byte, 2007),
|
||||
make([]byte, 32),
|
||||
make([]byte, 16),
|
||||
},
|
||||
{
|
||||
// This test triggers an edge-case. See https://go-review.googlesource.com/#/c/30101/.
|
||||
[]byte{0x81, 0xd8, 0xb2, 0xe4, 0x6a, 0x25, 0x21, 0x3b, 0x58, 0xfe, 0xe4, 0x21, 0x3a, 0x2a, 0x28, 0xe9, 0x21, 0xc1, 0x2a, 0x96, 0x32, 0x51, 0x6d, 0x3b, 0x73, 0x27, 0x27, 0x27, 0xbe, 0xcf, 0x21, 0x29},
|
||||
[]byte{0x3b, 0x3a, 0x29, 0xe9, 0x3b, 0x21, 0x3a, 0x5c, 0x5c, 0x3b, 0x3b, 0x05, 0x3a, 0x3a, 0x8c, 0x0d},
|
||||
[]byte{0x6d, 0xc1, 0x8b, 0x8c, 0x34, 0x4c, 0xd7, 0x99, 0x27, 0x11, 0x8b, 0xbe, 0x84, 0xb7, 0xf3, 0x14},
|
||||
},
|
||||
{
|
||||
// This test generates a result of (2^130-1) % (2^130-5).
|
||||
[]byte{
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
},
|
||||
[]byte{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
[]byte{4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
},
|
||||
{
|
||||
// This test generates a result of (2^130-6) % (2^130-5).
|
||||
[]byte{
|
||||
0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
},
|
||||
[]byte{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
[]byte{0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
|
||||
},
|
||||
{
|
||||
// This test generates a result of (2^130-5) % (2^130-5).
|
||||
[]byte{
|
||||
0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
},
|
||||
[]byte{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
[]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
},
|
||||
type test struct {
|
||||
in string
|
||||
key string
|
||||
tag string
|
||||
}
|
||||
|
||||
func testSum(t *testing.T, unaligned bool) {
|
||||
var out [16]byte
|
||||
var key [32]byte
|
||||
func (t *test) Input() []byte {
|
||||
in, err := hex.DecodeString(t.in)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return in
|
||||
}
|
||||
|
||||
func (t *test) Key() [32]byte {
|
||||
buf, err := hex.DecodeString(t.key)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
var key [32]byte
|
||||
copy(key[:], buf[:32])
|
||||
return key
|
||||
}
|
||||
|
||||
func (t *test) Tag() [16]byte {
|
||||
buf, err := hex.DecodeString(t.tag)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
var tag [16]byte
|
||||
copy(tag[:], buf[:16])
|
||||
return tag
|
||||
}
|
||||
|
||||
func testSum(t *testing.T, unaligned bool, sumImpl func(tag *[TagSize]byte, msg []byte, key *[32]byte)) {
|
||||
var tag [16]byte
|
||||
for i, v := range testData {
|
||||
in := v.in
|
||||
in := v.Input()
|
||||
if unaligned {
|
||||
in = unalignBytes(in)
|
||||
}
|
||||
copy(key[:], v.k)
|
||||
Sum(&out, in, &key)
|
||||
if !bytes.Equal(out[:], v.correct) {
|
||||
t.Errorf("%d: expected %x, got %x", i, v.correct, out[:])
|
||||
key := v.Key()
|
||||
sumImpl(&tag, in, &key)
|
||||
if tag != v.Tag() {
|
||||
t.Errorf("%d: expected %x, got %x", i, v.Tag(), tag[:])
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -125,8 +95,10 @@ func TestBurnin(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSum(t *testing.T) { testSum(t, false) }
|
||||
func TestSumUnaligned(t *testing.T) { testSum(t, true) }
|
||||
func TestSum(t *testing.T) { testSum(t, false, Sum) }
|
||||
func TestSumUnaligned(t *testing.T) { testSum(t, true, Sum) }
|
||||
func TestSumGeneric(t *testing.T) { testSum(t, false, sumGeneric) }
|
||||
func TestSumGenericUnaligned(t *testing.T) { testSum(t, true, sumGeneric) }
|
||||
|
||||
func benchmark(b *testing.B, size int, unaligned bool) {
|
||||
var out [16]byte
|
||||
@@ -146,6 +118,7 @@ func Benchmark64(b *testing.B) { benchmark(b, 64, false) }
|
||||
func Benchmark1K(b *testing.B) { benchmark(b, 1024, false) }
|
||||
func Benchmark64Unaligned(b *testing.B) { benchmark(b, 64, true) }
|
||||
func Benchmark1KUnaligned(b *testing.B) { benchmark(b, 1024, true) }
|
||||
func Benchmark2M(b *testing.B) { benchmark(b, 2097152, true) }
|
||||
|
||||
func unalignBytes(in []byte) []byte {
|
||||
out := make([]byte, len(in)+1)
|
||||
|
||||
14
vendor/golang.org/x/crypto/poly1305/sum_noasm.go
generated
vendored
Normal file
14
vendor/golang.org/x/crypto/poly1305/sum_noasm.go
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
// 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 s390x,!go1.11 !arm,!amd64,!s390x gccgo appengine nacl
|
||||
|
||||
package poly1305
|
||||
|
||||
// Sum generates an authenticator for msg using a one-time key and puts the
|
||||
// 16-byte result into out. Authenticating two different messages with the same
|
||||
// key allows an attacker to forge messages at will.
|
||||
func Sum(out *[TagSize]byte, msg []byte, key *[32]byte) {
|
||||
sumGeneric(out, msg, key)
|
||||
}
|
||||
10
vendor/golang.org/x/crypto/poly1305/sum_ref.go
generated
vendored
10
vendor/golang.org/x/crypto/poly1305/sum_ref.go
generated
vendored
@@ -2,16 +2,14 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !amd64,!arm gccgo appengine nacl
|
||||
|
||||
package poly1305
|
||||
|
||||
import "encoding/binary"
|
||||
|
||||
// Sum generates an authenticator for msg using a one-time key and puts the
|
||||
// 16-byte result into out. Authenticating two different messages with the same
|
||||
// key allows an attacker to forge messages at will.
|
||||
func Sum(out *[TagSize]byte, msg []byte, key *[32]byte) {
|
||||
// sumGeneric generates an authenticator for msg using a one-time key and
|
||||
// puts the 16-byte result into out. This is the generic implementation of
|
||||
// Sum and should be called if no assembly implementation is available.
|
||||
func sumGeneric(out *[TagSize]byte, msg []byte, key *[32]byte) {
|
||||
var (
|
||||
h0, h1, h2, h3, h4 uint32 // the hash accumulators
|
||||
r0, r1, r2, r3, r4 uint64 // the r part of the key
|
||||
|
||||
49
vendor/golang.org/x/crypto/poly1305/sum_s390x.go
generated
vendored
Normal file
49
vendor/golang.org/x/crypto/poly1305/sum_s390x.go
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
// 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 s390x,go1.11,!gccgo,!appengine
|
||||
|
||||
package poly1305
|
||||
|
||||
// hasVectorFacility reports whether the machine supports
|
||||
// the vector facility (vx).
|
||||
func hasVectorFacility() bool
|
||||
|
||||
// hasVMSLFacility reports whether the machine supports
|
||||
// Vector Multiply Sum Logical (VMSL).
|
||||
func hasVMSLFacility() bool
|
||||
|
||||
var hasVX = hasVectorFacility()
|
||||
var hasVMSL = hasVMSLFacility()
|
||||
|
||||
// poly1305vx is an assembly implementation of Poly1305 that uses vector
|
||||
// instructions. It must only be called if the vector facility (vx) is
|
||||
// available.
|
||||
//go:noescape
|
||||
func poly1305vx(out *[16]byte, m *byte, mlen uint64, key *[32]byte)
|
||||
|
||||
// poly1305vmsl is an assembly implementation of Poly1305 that uses vector
|
||||
// instructions, including VMSL. It must only be called if the vector facility (vx) is
|
||||
// available and if VMSL is supported.
|
||||
//go:noescape
|
||||
func poly1305vmsl(out *[16]byte, m *byte, mlen uint64, key *[32]byte)
|
||||
|
||||
// Sum generates an authenticator for m using a one-time key and puts the
|
||||
// 16-byte result into out. Authenticating two different messages with the same
|
||||
// key allows an attacker to forge messages at will.
|
||||
func Sum(out *[16]byte, m []byte, key *[32]byte) {
|
||||
if hasVX {
|
||||
var mPtr *byte
|
||||
if len(m) > 0 {
|
||||
mPtr = &m[0]
|
||||
}
|
||||
if hasVMSL && len(m) > 256 {
|
||||
poly1305vmsl(out, mPtr, uint64(len(m)), key)
|
||||
} else {
|
||||
poly1305vx(out, mPtr, uint64(len(m)), key)
|
||||
}
|
||||
} else {
|
||||
sumGeneric(out, m, key)
|
||||
}
|
||||
}
|
||||
400
vendor/golang.org/x/crypto/poly1305/sum_s390x.s
generated
vendored
Normal file
400
vendor/golang.org/x/crypto/poly1305/sum_s390x.s
generated
vendored
Normal file
@@ -0,0 +1,400 @@
|
||||
// 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 s390x,go1.11,!gccgo,!appengine
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// Implementation of Poly1305 using the vector facility (vx).
|
||||
|
||||
// constants
|
||||
#define MOD26 V0
|
||||
#define EX0 V1
|
||||
#define EX1 V2
|
||||
#define EX2 V3
|
||||
|
||||
// temporaries
|
||||
#define T_0 V4
|
||||
#define T_1 V5
|
||||
#define T_2 V6
|
||||
#define T_3 V7
|
||||
#define T_4 V8
|
||||
|
||||
// key (r)
|
||||
#define R_0 V9
|
||||
#define R_1 V10
|
||||
#define R_2 V11
|
||||
#define R_3 V12
|
||||
#define R_4 V13
|
||||
#define R5_1 V14
|
||||
#define R5_2 V15
|
||||
#define R5_3 V16
|
||||
#define R5_4 V17
|
||||
#define RSAVE_0 R5
|
||||
#define RSAVE_1 R6
|
||||
#define RSAVE_2 R7
|
||||
#define RSAVE_3 R8
|
||||
#define RSAVE_4 R9
|
||||
#define R5SAVE_1 V28
|
||||
#define R5SAVE_2 V29
|
||||
#define R5SAVE_3 V30
|
||||
#define R5SAVE_4 V31
|
||||
|
||||
// message block
|
||||
#define F_0 V18
|
||||
#define F_1 V19
|
||||
#define F_2 V20
|
||||
#define F_3 V21
|
||||
#define F_4 V22
|
||||
|
||||
// accumulator
|
||||
#define H_0 V23
|
||||
#define H_1 V24
|
||||
#define H_2 V25
|
||||
#define H_3 V26
|
||||
#define H_4 V27
|
||||
|
||||
GLOBL ·keyMask<>(SB), RODATA, $16
|
||||
DATA ·keyMask<>+0(SB)/8, $0xffffff0ffcffff0f
|
||||
DATA ·keyMask<>+8(SB)/8, $0xfcffff0ffcffff0f
|
||||
|
||||
GLOBL ·bswapMask<>(SB), RODATA, $16
|
||||
DATA ·bswapMask<>+0(SB)/8, $0x0f0e0d0c0b0a0908
|
||||
DATA ·bswapMask<>+8(SB)/8, $0x0706050403020100
|
||||
|
||||
GLOBL ·constants<>(SB), RODATA, $64
|
||||
// MOD26
|
||||
DATA ·constants<>+0(SB)/8, $0x3ffffff
|
||||
DATA ·constants<>+8(SB)/8, $0x3ffffff
|
||||
// EX0
|
||||
DATA ·constants<>+16(SB)/8, $0x0006050403020100
|
||||
DATA ·constants<>+24(SB)/8, $0x1016151413121110
|
||||
// EX1
|
||||
DATA ·constants<>+32(SB)/8, $0x060c0b0a09080706
|
||||
DATA ·constants<>+40(SB)/8, $0x161c1b1a19181716
|
||||
// EX2
|
||||
DATA ·constants<>+48(SB)/8, $0x0d0d0d0d0d0f0e0d
|
||||
DATA ·constants<>+56(SB)/8, $0x1d1d1d1d1d1f1e1d
|
||||
|
||||
// h = (f*g) % (2**130-5) [partial reduction]
|
||||
#define MULTIPLY(f0, f1, f2, f3, f4, g0, g1, g2, g3, g4, g51, g52, g53, g54, h0, h1, h2, h3, h4) \
|
||||
VMLOF f0, g0, h0 \
|
||||
VMLOF f0, g1, h1 \
|
||||
VMLOF f0, g2, h2 \
|
||||
VMLOF f0, g3, h3 \
|
||||
VMLOF f0, g4, h4 \
|
||||
VMLOF f1, g54, T_0 \
|
||||
VMLOF f1, g0, T_1 \
|
||||
VMLOF f1, g1, T_2 \
|
||||
VMLOF f1, g2, T_3 \
|
||||
VMLOF f1, g3, T_4 \
|
||||
VMALOF f2, g53, h0, h0 \
|
||||
VMALOF f2, g54, h1, h1 \
|
||||
VMALOF f2, g0, h2, h2 \
|
||||
VMALOF f2, g1, h3, h3 \
|
||||
VMALOF f2, g2, h4, h4 \
|
||||
VMALOF f3, g52, T_0, T_0 \
|
||||
VMALOF f3, g53, T_1, T_1 \
|
||||
VMALOF f3, g54, T_2, T_2 \
|
||||
VMALOF f3, g0, T_3, T_3 \
|
||||
VMALOF f3, g1, T_4, T_4 \
|
||||
VMALOF f4, g51, h0, h0 \
|
||||
VMALOF f4, g52, h1, h1 \
|
||||
VMALOF f4, g53, h2, h2 \
|
||||
VMALOF f4, g54, h3, h3 \
|
||||
VMALOF f4, g0, h4, h4 \
|
||||
VAG T_0, h0, h0 \
|
||||
VAG T_1, h1, h1 \
|
||||
VAG T_2, h2, h2 \
|
||||
VAG T_3, h3, h3 \
|
||||
VAG T_4, h4, h4
|
||||
|
||||
// carry h0->h1 h3->h4, h1->h2 h4->h0, h0->h1 h2->h3, h3->h4
|
||||
#define REDUCE(h0, h1, h2, h3, h4) \
|
||||
VESRLG $26, h0, T_0 \
|
||||
VESRLG $26, h3, T_1 \
|
||||
VN MOD26, h0, h0 \
|
||||
VN MOD26, h3, h3 \
|
||||
VAG T_0, h1, h1 \
|
||||
VAG T_1, h4, h4 \
|
||||
VESRLG $26, h1, T_2 \
|
||||
VESRLG $26, h4, T_3 \
|
||||
VN MOD26, h1, h1 \
|
||||
VN MOD26, h4, h4 \
|
||||
VESLG $2, T_3, T_4 \
|
||||
VAG T_3, T_4, T_4 \
|
||||
VAG T_2, h2, h2 \
|
||||
VAG T_4, h0, h0 \
|
||||
VESRLG $26, h2, T_0 \
|
||||
VESRLG $26, h0, T_1 \
|
||||
VN MOD26, h2, h2 \
|
||||
VN MOD26, h0, h0 \
|
||||
VAG T_0, h3, h3 \
|
||||
VAG T_1, h1, h1 \
|
||||
VESRLG $26, h3, T_2 \
|
||||
VN MOD26, h3, h3 \
|
||||
VAG T_2, h4, h4
|
||||
|
||||
// expand in0 into d[0] and in1 into d[1]
|
||||
#define EXPAND(in0, in1, d0, d1, d2, d3, d4) \
|
||||
VGBM $0x0707, d1 \ // d1=tmp
|
||||
VPERM in0, in1, EX2, d4 \
|
||||
VPERM in0, in1, EX0, d0 \
|
||||
VPERM in0, in1, EX1, d2 \
|
||||
VN d1, d4, d4 \
|
||||
VESRLG $26, d0, d1 \
|
||||
VESRLG $30, d2, d3 \
|
||||
VESRLG $4, d2, d2 \
|
||||
VN MOD26, d0, d0 \
|
||||
VN MOD26, d1, d1 \
|
||||
VN MOD26, d2, d2 \
|
||||
VN MOD26, d3, d3
|
||||
|
||||
// pack h4:h0 into h1:h0 (no carry)
|
||||
#define PACK(h0, h1, h2, h3, h4) \
|
||||
VESLG $26, h1, h1 \
|
||||
VESLG $26, h3, h3 \
|
||||
VO h0, h1, h0 \
|
||||
VO h2, h3, h2 \
|
||||
VESLG $4, h2, h2 \
|
||||
VLEIB $7, $48, h1 \
|
||||
VSLB h1, h2, h2 \
|
||||
VO h0, h2, h0 \
|
||||
VLEIB $7, $104, h1 \
|
||||
VSLB h1, h4, h3 \
|
||||
VO h3, h0, h0 \
|
||||
VLEIB $7, $24, h1 \
|
||||
VSRLB h1, h4, h1
|
||||
|
||||
// if h > 2**130-5 then h -= 2**130-5
|
||||
#define MOD(h0, h1, t0, t1, t2) \
|
||||
VZERO t0 \
|
||||
VLEIG $1, $5, t0 \
|
||||
VACCQ h0, t0, t1 \
|
||||
VAQ h0, t0, t0 \
|
||||
VONE t2 \
|
||||
VLEIG $1, $-4, t2 \
|
||||
VAQ t2, t1, t1 \
|
||||
VACCQ h1, t1, t1 \
|
||||
VONE t2 \
|
||||
VAQ t2, t1, t1 \
|
||||
VN h0, t1, t2 \
|
||||
VNC t0, t1, t1 \
|
||||
VO t1, t2, h0
|
||||
|
||||
// func poly1305vx(out *[16]byte, m *byte, mlen uint64, key *[32]key)
|
||||
TEXT ·poly1305vx(SB), $0-32
|
||||
// This code processes up to 2 blocks (32 bytes) per iteration
|
||||
// using the algorithm described in:
|
||||
// NEON crypto, Daniel J. Bernstein & Peter Schwabe
|
||||
// https://cryptojedi.org/papers/neoncrypto-20120320.pdf
|
||||
LMG out+0(FP), R1, R4 // R1=out, R2=m, R3=mlen, R4=key
|
||||
|
||||
// load MOD26, EX0, EX1 and EX2
|
||||
MOVD $·constants<>(SB), R5
|
||||
VLM (R5), MOD26, EX2
|
||||
|
||||
// setup r
|
||||
VL (R4), T_0
|
||||
MOVD $·keyMask<>(SB), R6
|
||||
VL (R6), T_1
|
||||
VN T_0, T_1, T_0
|
||||
EXPAND(T_0, T_0, R_0, R_1, R_2, R_3, R_4)
|
||||
|
||||
// setup r*5
|
||||
VLEIG $0, $5, T_0
|
||||
VLEIG $1, $5, T_0
|
||||
|
||||
// store r (for final block)
|
||||
VMLOF T_0, R_1, R5SAVE_1
|
||||
VMLOF T_0, R_2, R5SAVE_2
|
||||
VMLOF T_0, R_3, R5SAVE_3
|
||||
VMLOF T_0, R_4, R5SAVE_4
|
||||
VLGVG $0, R_0, RSAVE_0
|
||||
VLGVG $0, R_1, RSAVE_1
|
||||
VLGVG $0, R_2, RSAVE_2
|
||||
VLGVG $0, R_3, RSAVE_3
|
||||
VLGVG $0, R_4, RSAVE_4
|
||||
|
||||
// skip r**2 calculation
|
||||
CMPBLE R3, $16, skip
|
||||
|
||||
// calculate r**2
|
||||
MULTIPLY(R_0, R_1, R_2, R_3, R_4, R_0, R_1, R_2, R_3, R_4, R5SAVE_1, R5SAVE_2, R5SAVE_3, R5SAVE_4, H_0, H_1, H_2, H_3, H_4)
|
||||
REDUCE(H_0, H_1, H_2, H_3, H_4)
|
||||
VLEIG $0, $5, T_0
|
||||
VLEIG $1, $5, T_0
|
||||
VMLOF T_0, H_1, R5_1
|
||||
VMLOF T_0, H_2, R5_2
|
||||
VMLOF T_0, H_3, R5_3
|
||||
VMLOF T_0, H_4, R5_4
|
||||
VLR H_0, R_0
|
||||
VLR H_1, R_1
|
||||
VLR H_2, R_2
|
||||
VLR H_3, R_3
|
||||
VLR H_4, R_4
|
||||
|
||||
// initialize h
|
||||
VZERO H_0
|
||||
VZERO H_1
|
||||
VZERO H_2
|
||||
VZERO H_3
|
||||
VZERO H_4
|
||||
|
||||
loop:
|
||||
CMPBLE R3, $32, b2
|
||||
VLM (R2), T_0, T_1
|
||||
SUB $32, R3
|
||||
MOVD $32(R2), R2
|
||||
EXPAND(T_0, T_1, F_0, F_1, F_2, F_3, F_4)
|
||||
VLEIB $4, $1, F_4
|
||||
VLEIB $12, $1, F_4
|
||||
|
||||
multiply:
|
||||
VAG H_0, F_0, F_0
|
||||
VAG H_1, F_1, F_1
|
||||
VAG H_2, F_2, F_2
|
||||
VAG H_3, F_3, F_3
|
||||
VAG H_4, F_4, F_4
|
||||
MULTIPLY(F_0, F_1, F_2, F_3, F_4, R_0, R_1, R_2, R_3, R_4, R5_1, R5_2, R5_3, R5_4, H_0, H_1, H_2, H_3, H_4)
|
||||
REDUCE(H_0, H_1, H_2, H_3, H_4)
|
||||
CMPBNE R3, $0, loop
|
||||
|
||||
finish:
|
||||
// sum vectors
|
||||
VZERO T_0
|
||||
VSUMQG H_0, T_0, H_0
|
||||
VSUMQG H_1, T_0, H_1
|
||||
VSUMQG H_2, T_0, H_2
|
||||
VSUMQG H_3, T_0, H_3
|
||||
VSUMQG H_4, T_0, H_4
|
||||
|
||||
// h may be >= 2*(2**130-5) so we need to reduce it again
|
||||
REDUCE(H_0, H_1, H_2, H_3, H_4)
|
||||
|
||||
// carry h1->h4
|
||||
VESRLG $26, H_1, T_1
|
||||
VN MOD26, H_1, H_1
|
||||
VAQ T_1, H_2, H_2
|
||||
VESRLG $26, H_2, T_2
|
||||
VN MOD26, H_2, H_2
|
||||
VAQ T_2, H_3, H_3
|
||||
VESRLG $26, H_3, T_3
|
||||
VN MOD26, H_3, H_3
|
||||
VAQ T_3, H_4, H_4
|
||||
|
||||
// h is now < 2*(2**130-5)
|
||||
// pack h into h1 (hi) and h0 (lo)
|
||||
PACK(H_0, H_1, H_2, H_3, H_4)
|
||||
|
||||
// if h > 2**130-5 then h -= 2**130-5
|
||||
MOD(H_0, H_1, T_0, T_1, T_2)
|
||||
|
||||
// h += s
|
||||
MOVD $·bswapMask<>(SB), R5
|
||||
VL (R5), T_1
|
||||
VL 16(R4), T_0
|
||||
VPERM T_0, T_0, T_1, T_0 // reverse bytes (to big)
|
||||
VAQ T_0, H_0, H_0
|
||||
VPERM H_0, H_0, T_1, H_0 // reverse bytes (to little)
|
||||
VST H_0, (R1)
|
||||
|
||||
RET
|
||||
|
||||
b2:
|
||||
CMPBLE R3, $16, b1
|
||||
|
||||
// 2 blocks remaining
|
||||
SUB $17, R3
|
||||
VL (R2), T_0
|
||||
VLL R3, 16(R2), T_1
|
||||
ADD $1, R3
|
||||
MOVBZ $1, R0
|
||||
CMPBEQ R3, $16, 2(PC)
|
||||
VLVGB R3, R0, T_1
|
||||
EXPAND(T_0, T_1, F_0, F_1, F_2, F_3, F_4)
|
||||
CMPBNE R3, $16, 2(PC)
|
||||
VLEIB $12, $1, F_4
|
||||
VLEIB $4, $1, F_4
|
||||
|
||||
// setup [r²,r]
|
||||
VLVGG $1, RSAVE_0, R_0
|
||||
VLVGG $1, RSAVE_1, R_1
|
||||
VLVGG $1, RSAVE_2, R_2
|
||||
VLVGG $1, RSAVE_3, R_3
|
||||
VLVGG $1, RSAVE_4, R_4
|
||||
VPDI $0, R5_1, R5SAVE_1, R5_1
|
||||
VPDI $0, R5_2, R5SAVE_2, R5_2
|
||||
VPDI $0, R5_3, R5SAVE_3, R5_3
|
||||
VPDI $0, R5_4, R5SAVE_4, R5_4
|
||||
|
||||
MOVD $0, R3
|
||||
BR multiply
|
||||
|
||||
skip:
|
||||
VZERO H_0
|
||||
VZERO H_1
|
||||
VZERO H_2
|
||||
VZERO H_3
|
||||
VZERO H_4
|
||||
|
||||
CMPBEQ R3, $0, finish
|
||||
|
||||
b1:
|
||||
// 1 block remaining
|
||||
SUB $1, R3
|
||||
VLL R3, (R2), T_0
|
||||
ADD $1, R3
|
||||
MOVBZ $1, R0
|
||||
CMPBEQ R3, $16, 2(PC)
|
||||
VLVGB R3, R0, T_0
|
||||
VZERO T_1
|
||||
EXPAND(T_0, T_1, F_0, F_1, F_2, F_3, F_4)
|
||||
CMPBNE R3, $16, 2(PC)
|
||||
VLEIB $4, $1, F_4
|
||||
VLEIG $1, $1, R_0
|
||||
VZERO R_1
|
||||
VZERO R_2
|
||||
VZERO R_3
|
||||
VZERO R_4
|
||||
VZERO R5_1
|
||||
VZERO R5_2
|
||||
VZERO R5_3
|
||||
VZERO R5_4
|
||||
|
||||
// setup [r, 1]
|
||||
VLVGG $0, RSAVE_0, R_0
|
||||
VLVGG $0, RSAVE_1, R_1
|
||||
VLVGG $0, RSAVE_2, R_2
|
||||
VLVGG $0, RSAVE_3, R_3
|
||||
VLVGG $0, RSAVE_4, R_4
|
||||
VPDI $0, R5SAVE_1, R5_1, R5_1
|
||||
VPDI $0, R5SAVE_2, R5_2, R5_2
|
||||
VPDI $0, R5SAVE_3, R5_3, R5_3
|
||||
VPDI $0, R5SAVE_4, R5_4, R5_4
|
||||
|
||||
MOVD $0, R3
|
||||
BR multiply
|
||||
|
||||
TEXT ·hasVectorFacility(SB), NOSPLIT, $24-1
|
||||
MOVD $x-24(SP), R1
|
||||
XC $24, 0(R1), 0(R1) // clear the storage
|
||||
MOVD $2, R0 // R0 is the number of double words stored -1
|
||||
WORD $0xB2B01000 // STFLE 0(R1)
|
||||
XOR R0, R0 // reset the value of R0
|
||||
MOVBZ z-8(SP), R1
|
||||
AND $0x40, R1
|
||||
BEQ novector
|
||||
|
||||
vectorinstalled:
|
||||
// check if the vector instruction has been enabled
|
||||
VLEIB $0, $0xF, V16
|
||||
VLGVB $0, V16, R1
|
||||
CMPBNE R1, $0xF, novector
|
||||
MOVB $1, ret+0(FP) // have vx
|
||||
RET
|
||||
|
||||
novector:
|
||||
MOVB $0, ret+0(FP) // no vx
|
||||
RET
|
||||
931
vendor/golang.org/x/crypto/poly1305/sum_vmsl_s390x.s
generated
vendored
Normal file
931
vendor/golang.org/x/crypto/poly1305/sum_vmsl_s390x.s
generated
vendored
Normal file
@@ -0,0 +1,931 @@
|
||||
// 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 s390x,go1.11,!gccgo,!appengine
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// Implementation of Poly1305 using the vector facility (vx) and the VMSL instruction.
|
||||
|
||||
// constants
|
||||
#define EX0 V1
|
||||
#define EX1 V2
|
||||
#define EX2 V3
|
||||
|
||||
// temporaries
|
||||
#define T_0 V4
|
||||
#define T_1 V5
|
||||
#define T_2 V6
|
||||
#define T_3 V7
|
||||
#define T_4 V8
|
||||
#define T_5 V9
|
||||
#define T_6 V10
|
||||
#define T_7 V11
|
||||
#define T_8 V12
|
||||
#define T_9 V13
|
||||
#define T_10 V14
|
||||
|
||||
// r**2 & r**4
|
||||
#define R_0 V15
|
||||
#define R_1 V16
|
||||
#define R_2 V17
|
||||
#define R5_1 V18
|
||||
#define R5_2 V19
|
||||
// key (r)
|
||||
#define RSAVE_0 R7
|
||||
#define RSAVE_1 R8
|
||||
#define RSAVE_2 R9
|
||||
#define R5SAVE_1 R10
|
||||
#define R5SAVE_2 R11
|
||||
|
||||
// message block
|
||||
#define M0 V20
|
||||
#define M1 V21
|
||||
#define M2 V22
|
||||
#define M3 V23
|
||||
#define M4 V24
|
||||
#define M5 V25
|
||||
|
||||
// accumulator
|
||||
#define H0_0 V26
|
||||
#define H1_0 V27
|
||||
#define H2_0 V28
|
||||
#define H0_1 V29
|
||||
#define H1_1 V30
|
||||
#define H2_1 V31
|
||||
|
||||
GLOBL ·keyMask<>(SB), RODATA, $16
|
||||
DATA ·keyMask<>+0(SB)/8, $0xffffff0ffcffff0f
|
||||
DATA ·keyMask<>+8(SB)/8, $0xfcffff0ffcffff0f
|
||||
|
||||
GLOBL ·bswapMask<>(SB), RODATA, $16
|
||||
DATA ·bswapMask<>+0(SB)/8, $0x0f0e0d0c0b0a0908
|
||||
DATA ·bswapMask<>+8(SB)/8, $0x0706050403020100
|
||||
|
||||
GLOBL ·constants<>(SB), RODATA, $48
|
||||
// EX0
|
||||
DATA ·constants<>+0(SB)/8, $0x18191a1b1c1d1e1f
|
||||
DATA ·constants<>+8(SB)/8, $0x0000050403020100
|
||||
// EX1
|
||||
DATA ·constants<>+16(SB)/8, $0x18191a1b1c1d1e1f
|
||||
DATA ·constants<>+24(SB)/8, $0x00000a0908070605
|
||||
// EX2
|
||||
DATA ·constants<>+32(SB)/8, $0x18191a1b1c1d1e1f
|
||||
DATA ·constants<>+40(SB)/8, $0x0000000f0e0d0c0b
|
||||
|
||||
GLOBL ·c<>(SB), RODATA, $48
|
||||
// EX0
|
||||
DATA ·c<>+0(SB)/8, $0x0000050403020100
|
||||
DATA ·c<>+8(SB)/8, $0x0000151413121110
|
||||
// EX1
|
||||
DATA ·c<>+16(SB)/8, $0x00000a0908070605
|
||||
DATA ·c<>+24(SB)/8, $0x00001a1918171615
|
||||
// EX2
|
||||
DATA ·c<>+32(SB)/8, $0x0000000f0e0d0c0b
|
||||
DATA ·c<>+40(SB)/8, $0x0000001f1e1d1c1b
|
||||
|
||||
GLOBL ·reduce<>(SB), RODATA, $32
|
||||
// 44 bit
|
||||
DATA ·reduce<>+0(SB)/8, $0x0
|
||||
DATA ·reduce<>+8(SB)/8, $0xfffffffffff
|
||||
// 42 bit
|
||||
DATA ·reduce<>+16(SB)/8, $0x0
|
||||
DATA ·reduce<>+24(SB)/8, $0x3ffffffffff
|
||||
|
||||
// h = (f*g) % (2**130-5) [partial reduction]
|
||||
// uses T_0...T_9 temporary registers
|
||||
// input: m02_0, m02_1, m02_2, m13_0, m13_1, m13_2, r_0, r_1, r_2, r5_1, r5_2, m4_0, m4_1, m4_2, m5_0, m5_1, m5_2
|
||||
// temp: t0, t1, t2, t3, t4, t5, t6, t7, t8, t9
|
||||
// output: m02_0, m02_1, m02_2, m13_0, m13_1, m13_2
|
||||
#define MULTIPLY(m02_0, m02_1, m02_2, m13_0, m13_1, m13_2, r_0, r_1, r_2, r5_1, r5_2, m4_0, m4_1, m4_2, m5_0, m5_1, m5_2, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9) \
|
||||
\ // Eliminate the dependency for the last 2 VMSLs
|
||||
VMSLG m02_0, r_2, m4_2, m4_2 \
|
||||
VMSLG m13_0, r_2, m5_2, m5_2 \ // 8 VMSLs pipelined
|
||||
VMSLG m02_0, r_0, m4_0, m4_0 \
|
||||
VMSLG m02_1, r5_2, V0, T_0 \
|
||||
VMSLG m02_0, r_1, m4_1, m4_1 \
|
||||
VMSLG m02_1, r_0, V0, T_1 \
|
||||
VMSLG m02_1, r_1, V0, T_2 \
|
||||
VMSLG m02_2, r5_1, V0, T_3 \
|
||||
VMSLG m02_2, r5_2, V0, T_4 \
|
||||
VMSLG m13_0, r_0, m5_0, m5_0 \
|
||||
VMSLG m13_1, r5_2, V0, T_5 \
|
||||
VMSLG m13_0, r_1, m5_1, m5_1 \
|
||||
VMSLG m13_1, r_0, V0, T_6 \
|
||||
VMSLG m13_1, r_1, V0, T_7 \
|
||||
VMSLG m13_2, r5_1, V0, T_8 \
|
||||
VMSLG m13_2, r5_2, V0, T_9 \
|
||||
VMSLG m02_2, r_0, m4_2, m4_2 \
|
||||
VMSLG m13_2, r_0, m5_2, m5_2 \
|
||||
VAQ m4_0, T_0, m02_0 \
|
||||
VAQ m4_1, T_1, m02_1 \
|
||||
VAQ m5_0, T_5, m13_0 \
|
||||
VAQ m5_1, T_6, m13_1 \
|
||||
VAQ m02_0, T_3, m02_0 \
|
||||
VAQ m02_1, T_4, m02_1 \
|
||||
VAQ m13_0, T_8, m13_0 \
|
||||
VAQ m13_1, T_9, m13_1 \
|
||||
VAQ m4_2, T_2, m02_2 \
|
||||
VAQ m5_2, T_7, m13_2 \
|
||||
|
||||
// SQUARE uses three limbs of r and r_2*5 to output square of r
|
||||
// uses T_1, T_5 and T_7 temporary registers
|
||||
// input: r_0, r_1, r_2, r5_2
|
||||
// temp: TEMP0, TEMP1, TEMP2
|
||||
// output: p0, p1, p2
|
||||
#define SQUARE(r_0, r_1, r_2, r5_2, p0, p1, p2, TEMP0, TEMP1, TEMP2) \
|
||||
VMSLG r_0, r_0, p0, p0 \
|
||||
VMSLG r_1, r5_2, V0, TEMP0 \
|
||||
VMSLG r_2, r5_2, p1, p1 \
|
||||
VMSLG r_0, r_1, V0, TEMP1 \
|
||||
VMSLG r_1, r_1, p2, p2 \
|
||||
VMSLG r_0, r_2, V0, TEMP2 \
|
||||
VAQ TEMP0, p0, p0 \
|
||||
VAQ TEMP1, p1, p1 \
|
||||
VAQ TEMP2, p2, p2 \
|
||||
VAQ TEMP0, p0, p0 \
|
||||
VAQ TEMP1, p1, p1 \
|
||||
VAQ TEMP2, p2, p2 \
|
||||
|
||||
// carry h0->h1->h2->h0 || h3->h4->h5->h3
|
||||
// uses T_2, T_4, T_5, T_7, T_8, T_9
|
||||
// t6, t7, t8, t9, t10, t11
|
||||
// input: h0, h1, h2, h3, h4, h5
|
||||
// temp: t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11
|
||||
// output: h0, h1, h2, h3, h4, h5
|
||||
#define REDUCE(h0, h1, h2, h3, h4, h5, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11) \
|
||||
VLM (R12), t6, t7 \ // 44 and 42 bit clear mask
|
||||
VLEIB $7, $0x28, t10 \ // 5 byte shift mask
|
||||
VREPIB $4, t8 \ // 4 bit shift mask
|
||||
VREPIB $2, t11 \ // 2 bit shift mask
|
||||
VSRLB t10, h0, t0 \ // h0 byte shift
|
||||
VSRLB t10, h1, t1 \ // h1 byte shift
|
||||
VSRLB t10, h2, t2 \ // h2 byte shift
|
||||
VSRLB t10, h3, t3 \ // h3 byte shift
|
||||
VSRLB t10, h4, t4 \ // h4 byte shift
|
||||
VSRLB t10, h5, t5 \ // h5 byte shift
|
||||
VSRL t8, t0, t0 \ // h0 bit shift
|
||||
VSRL t8, t1, t1 \ // h2 bit shift
|
||||
VSRL t11, t2, t2 \ // h2 bit shift
|
||||
VSRL t8, t3, t3 \ // h3 bit shift
|
||||
VSRL t8, t4, t4 \ // h4 bit shift
|
||||
VESLG $2, t2, t9 \ // h2 carry x5
|
||||
VSRL t11, t5, t5 \ // h5 bit shift
|
||||
VN t6, h0, h0 \ // h0 clear carry
|
||||
VAQ t2, t9, t2 \ // h2 carry x5
|
||||
VESLG $2, t5, t9 \ // h5 carry x5
|
||||
VN t6, h1, h1 \ // h1 clear carry
|
||||
VN t7, h2, h2 \ // h2 clear carry
|
||||
VAQ t5, t9, t5 \ // h5 carry x5
|
||||
VN t6, h3, h3 \ // h3 clear carry
|
||||
VN t6, h4, h4 \ // h4 clear carry
|
||||
VN t7, h5, h5 \ // h5 clear carry
|
||||
VAQ t0, h1, h1 \ // h0->h1
|
||||
VAQ t3, h4, h4 \ // h3->h4
|
||||
VAQ t1, h2, h2 \ // h1->h2
|
||||
VAQ t4, h5, h5 \ // h4->h5
|
||||
VAQ t2, h0, h0 \ // h2->h0
|
||||
VAQ t5, h3, h3 \ // h5->h3
|
||||
VREPG $1, t6, t6 \ // 44 and 42 bit masks across both halves
|
||||
VREPG $1, t7, t7 \
|
||||
VSLDB $8, h0, h0, h0 \ // set up [h0/1/2, h3/4/5]
|
||||
VSLDB $8, h1, h1, h1 \
|
||||
VSLDB $8, h2, h2, h2 \
|
||||
VO h0, h3, h3 \
|
||||
VO h1, h4, h4 \
|
||||
VO h2, h5, h5 \
|
||||
VESRLG $44, h3, t0 \ // 44 bit shift right
|
||||
VESRLG $44, h4, t1 \
|
||||
VESRLG $42, h5, t2 \
|
||||
VN t6, h3, h3 \ // clear carry bits
|
||||
VN t6, h4, h4 \
|
||||
VN t7, h5, h5 \
|
||||
VESLG $2, t2, t9 \ // multiply carry by 5
|
||||
VAQ t9, t2, t2 \
|
||||
VAQ t0, h4, h4 \
|
||||
VAQ t1, h5, h5 \
|
||||
VAQ t2, h3, h3 \
|
||||
|
||||
// carry h0->h1->h2->h0
|
||||
// input: h0, h1, h2
|
||||
// temp: t0, t1, t2, t3, t4, t5, t6, t7, t8
|
||||
// output: h0, h1, h2
|
||||
#define REDUCE2(h0, h1, h2, t0, t1, t2, t3, t4, t5, t6, t7, t8) \
|
||||
VLEIB $7, $0x28, t3 \ // 5 byte shift mask
|
||||
VREPIB $4, t4 \ // 4 bit shift mask
|
||||
VREPIB $2, t7 \ // 2 bit shift mask
|
||||
VGBM $0x003F, t5 \ // mask to clear carry bits
|
||||
VSRLB t3, h0, t0 \
|
||||
VSRLB t3, h1, t1 \
|
||||
VSRLB t3, h2, t2 \
|
||||
VESRLG $4, t5, t5 \ // 44 bit clear mask
|
||||
VSRL t4, t0, t0 \
|
||||
VSRL t4, t1, t1 \
|
||||
VSRL t7, t2, t2 \
|
||||
VESRLG $2, t5, t6 \ // 42 bit clear mask
|
||||
VESLG $2, t2, t8 \
|
||||
VAQ t8, t2, t2 \
|
||||
VN t5, h0, h0 \
|
||||
VN t5, h1, h1 \
|
||||
VN t6, h2, h2 \
|
||||
VAQ t0, h1, h1 \
|
||||
VAQ t1, h2, h2 \
|
||||
VAQ t2, h0, h0 \
|
||||
VSRLB t3, h0, t0 \
|
||||
VSRLB t3, h1, t1 \
|
||||
VSRLB t3, h2, t2 \
|
||||
VSRL t4, t0, t0 \
|
||||
VSRL t4, t1, t1 \
|
||||
VSRL t7, t2, t2 \
|
||||
VN t5, h0, h0 \
|
||||
VN t5, h1, h1 \
|
||||
VESLG $2, t2, t8 \
|
||||
VN t6, h2, h2 \
|
||||
VAQ t0, h1, h1 \
|
||||
VAQ t8, t2, t2 \
|
||||
VAQ t1, h2, h2 \
|
||||
VAQ t2, h0, h0 \
|
||||
|
||||
// expands two message blocks into the lower halfs of the d registers
|
||||
// moves the contents of the d registers into upper halfs
|
||||
// input: in1, in2, d0, d1, d2, d3, d4, d5
|
||||
// temp: TEMP0, TEMP1, TEMP2, TEMP3
|
||||
// output: d0, d1, d2, d3, d4, d5
|
||||
#define EXPACC(in1, in2, d0, d1, d2, d3, d4, d5, TEMP0, TEMP1, TEMP2, TEMP3) \
|
||||
VGBM $0xff3f, TEMP0 \
|
||||
VGBM $0xff1f, TEMP1 \
|
||||
VESLG $4, d1, TEMP2 \
|
||||
VESLG $4, d4, TEMP3 \
|
||||
VESRLG $4, TEMP0, TEMP0 \
|
||||
VPERM in1, d0, EX0, d0 \
|
||||
VPERM in2, d3, EX0, d3 \
|
||||
VPERM in1, d2, EX2, d2 \
|
||||
VPERM in2, d5, EX2, d5 \
|
||||
VPERM in1, TEMP2, EX1, d1 \
|
||||
VPERM in2, TEMP3, EX1, d4 \
|
||||
VN TEMP0, d0, d0 \
|
||||
VN TEMP0, d3, d3 \
|
||||
VESRLG $4, d1, d1 \
|
||||
VESRLG $4, d4, d4 \
|
||||
VN TEMP1, d2, d2 \
|
||||
VN TEMP1, d5, d5 \
|
||||
VN TEMP0, d1, d1 \
|
||||
VN TEMP0, d4, d4 \
|
||||
|
||||
// expands one message block into the lower halfs of the d registers
|
||||
// moves the contents of the d registers into upper halfs
|
||||
// input: in, d0, d1, d2
|
||||
// temp: TEMP0, TEMP1, TEMP2
|
||||
// output: d0, d1, d2
|
||||
#define EXPACC2(in, d0, d1, d2, TEMP0, TEMP1, TEMP2) \
|
||||
VGBM $0xff3f, TEMP0 \
|
||||
VESLG $4, d1, TEMP2 \
|
||||
VGBM $0xff1f, TEMP1 \
|
||||
VPERM in, d0, EX0, d0 \
|
||||
VESRLG $4, TEMP0, TEMP0 \
|
||||
VPERM in, d2, EX2, d2 \
|
||||
VPERM in, TEMP2, EX1, d1 \
|
||||
VN TEMP0, d0, d0 \
|
||||
VN TEMP1, d2, d2 \
|
||||
VESRLG $4, d1, d1 \
|
||||
VN TEMP0, d1, d1 \
|
||||
|
||||
// pack h2:h0 into h1:h0 (no carry)
|
||||
// input: h0, h1, h2
|
||||
// output: h0, h1, h2
|
||||
#define PACK(h0, h1, h2) \
|
||||
VMRLG h1, h2, h2 \ // copy h1 to upper half h2
|
||||
VESLG $44, h1, h1 \ // shift limb 1 44 bits, leaving 20
|
||||
VO h0, h1, h0 \ // combine h0 with 20 bits from limb 1
|
||||
VESRLG $20, h2, h1 \ // put top 24 bits of limb 1 into h1
|
||||
VLEIG $1, $0, h1 \ // clear h2 stuff from lower half of h1
|
||||
VO h0, h1, h0 \ // h0 now has 88 bits (limb 0 and 1)
|
||||
VLEIG $0, $0, h2 \ // clear upper half of h2
|
||||
VESRLG $40, h2, h1 \ // h1 now has upper two bits of result
|
||||
VLEIB $7, $88, h1 \ // for byte shift (11 bytes)
|
||||
VSLB h1, h2, h2 \ // shift h2 11 bytes to the left
|
||||
VO h0, h2, h0 \ // combine h0 with 20 bits from limb 1
|
||||
VLEIG $0, $0, h1 \ // clear upper half of h1
|
||||
|
||||
// if h > 2**130-5 then h -= 2**130-5
|
||||
// input: h0, h1
|
||||
// temp: t0, t1, t2
|
||||
// output: h0
|
||||
#define MOD(h0, h1, t0, t1, t2) \
|
||||
VZERO t0 \
|
||||
VLEIG $1, $5, t0 \
|
||||
VACCQ h0, t0, t1 \
|
||||
VAQ h0, t0, t0 \
|
||||
VONE t2 \
|
||||
VLEIG $1, $-4, t2 \
|
||||
VAQ t2, t1, t1 \
|
||||
VACCQ h1, t1, t1 \
|
||||
VONE t2 \
|
||||
VAQ t2, t1, t1 \
|
||||
VN h0, t1, t2 \
|
||||
VNC t0, t1, t1 \
|
||||
VO t1, t2, h0 \
|
||||
|
||||
// func poly1305vmsl(out *[16]byte, m *byte, mlen uint64, key *[32]key)
|
||||
TEXT ·poly1305vmsl(SB), $0-32
|
||||
// This code processes 6 + up to 4 blocks (32 bytes) per iteration
|
||||
// using the algorithm described in:
|
||||
// NEON crypto, Daniel J. Bernstein & Peter Schwabe
|
||||
// https://cryptojedi.org/papers/neoncrypto-20120320.pdf
|
||||
// And as moddified for VMSL as described in
|
||||
// Accelerating Poly1305 Cryptographic Message Authentication on the z14
|
||||
// O'Farrell et al, CASCON 2017, p48-55
|
||||
// https://ibm.ent.box.com/s/jf9gedj0e9d2vjctfyh186shaztavnht
|
||||
|
||||
LMG out+0(FP), R1, R4 // R1=out, R2=m, R3=mlen, R4=key
|
||||
VZERO V0 // c
|
||||
|
||||
// load EX0, EX1 and EX2
|
||||
MOVD $·constants<>(SB), R5
|
||||
VLM (R5), EX0, EX2 // c
|
||||
|
||||
// setup r
|
||||
VL (R4), T_0
|
||||
MOVD $·keyMask<>(SB), R6
|
||||
VL (R6), T_1
|
||||
VN T_0, T_1, T_0
|
||||
VZERO T_2 // limbs for r
|
||||
VZERO T_3
|
||||
VZERO T_4
|
||||
EXPACC2(T_0, T_2, T_3, T_4, T_1, T_5, T_7)
|
||||
|
||||
// T_2, T_3, T_4: [0, r]
|
||||
|
||||
// setup r*20
|
||||
VLEIG $0, $0, T_0
|
||||
VLEIG $1, $20, T_0 // T_0: [0, 20]
|
||||
VZERO T_5
|
||||
VZERO T_6
|
||||
VMSLG T_0, T_3, T_5, T_5
|
||||
VMSLG T_0, T_4, T_6, T_6
|
||||
|
||||
// store r for final block in GR
|
||||
VLGVG $1, T_2, RSAVE_0 // c
|
||||
VLGVG $1, T_3, RSAVE_1 // c
|
||||
VLGVG $1, T_4, RSAVE_2 // c
|
||||
VLGVG $1, T_5, R5SAVE_1 // c
|
||||
VLGVG $1, T_6, R5SAVE_2 // c
|
||||
|
||||
// initialize h
|
||||
VZERO H0_0
|
||||
VZERO H1_0
|
||||
VZERO H2_0
|
||||
VZERO H0_1
|
||||
VZERO H1_1
|
||||
VZERO H2_1
|
||||
|
||||
// initialize pointer for reduce constants
|
||||
MOVD $·reduce<>(SB), R12
|
||||
|
||||
// calculate r**2 and 20*(r**2)
|
||||
VZERO R_0
|
||||
VZERO R_1
|
||||
VZERO R_2
|
||||
SQUARE(T_2, T_3, T_4, T_6, R_0, R_1, R_2, T_1, T_5, T_7)
|
||||
REDUCE2(R_0, R_1, R_2, M0, M1, M2, M3, M4, R5_1, R5_2, M5, T_1)
|
||||
VZERO R5_1
|
||||
VZERO R5_2
|
||||
VMSLG T_0, R_1, R5_1, R5_1
|
||||
VMSLG T_0, R_2, R5_2, R5_2
|
||||
|
||||
// skip r**4 calculation if 3 blocks or less
|
||||
CMPBLE R3, $48, b4
|
||||
|
||||
// calculate r**4 and 20*(r**4)
|
||||
VZERO T_8
|
||||
VZERO T_9
|
||||
VZERO T_10
|
||||
SQUARE(R_0, R_1, R_2, R5_2, T_8, T_9, T_10, T_1, T_5, T_7)
|
||||
REDUCE2(T_8, T_9, T_10, M0, M1, M2, M3, M4, T_2, T_3, M5, T_1)
|
||||
VZERO T_2
|
||||
VZERO T_3
|
||||
VMSLG T_0, T_9, T_2, T_2
|
||||
VMSLG T_0, T_10, T_3, T_3
|
||||
|
||||
// put r**2 to the right and r**4 to the left of R_0, R_1, R_2
|
||||
VSLDB $8, T_8, T_8, T_8
|
||||
VSLDB $8, T_9, T_9, T_9
|
||||
VSLDB $8, T_10, T_10, T_10
|
||||
VSLDB $8, T_2, T_2, T_2
|
||||
VSLDB $8, T_3, T_3, T_3
|
||||
|
||||
VO T_8, R_0, R_0
|
||||
VO T_9, R_1, R_1
|
||||
VO T_10, R_2, R_2
|
||||
VO T_2, R5_1, R5_1
|
||||
VO T_3, R5_2, R5_2
|
||||
|
||||
CMPBLE R3, $80, load // less than or equal to 5 blocks in message
|
||||
|
||||
// 6(or 5+1) blocks
|
||||
SUB $81, R3
|
||||
VLM (R2), M0, M4
|
||||
VLL R3, 80(R2), M5
|
||||
ADD $1, R3
|
||||
MOVBZ $1, R0
|
||||
CMPBGE R3, $16, 2(PC)
|
||||
VLVGB R3, R0, M5
|
||||
MOVD $96(R2), R2
|
||||
EXPACC(M0, M1, H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_0, T_1, T_2, T_3)
|
||||
EXPACC(M2, M3, H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_0, T_1, T_2, T_3)
|
||||
VLEIB $2, $1, H2_0
|
||||
VLEIB $2, $1, H2_1
|
||||
VLEIB $10, $1, H2_0
|
||||
VLEIB $10, $1, H2_1
|
||||
|
||||
VZERO M0
|
||||
VZERO M1
|
||||
VZERO M2
|
||||
VZERO M3
|
||||
VZERO T_4
|
||||
VZERO T_10
|
||||
EXPACC(M4, M5, M0, M1, M2, M3, T_4, T_10, T_0, T_1, T_2, T_3)
|
||||
VLR T_4, M4
|
||||
VLEIB $10, $1, M2
|
||||
CMPBLT R3, $16, 2(PC)
|
||||
VLEIB $10, $1, T_10
|
||||
MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, T_10, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
||||
REDUCE(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_10, M0, M1, M2, M3, M4, T_4, T_5, T_2, T_7, T_8, T_9)
|
||||
VMRHG V0, H0_1, H0_0
|
||||
VMRHG V0, H1_1, H1_0
|
||||
VMRHG V0, H2_1, H2_0
|
||||
VMRLG V0, H0_1, H0_1
|
||||
VMRLG V0, H1_1, H1_1
|
||||
VMRLG V0, H2_1, H2_1
|
||||
|
||||
SUB $16, R3
|
||||
CMPBLE R3, $0, square
|
||||
|
||||
load:
|
||||
// load EX0, EX1 and EX2
|
||||
MOVD $·c<>(SB), R5
|
||||
VLM (R5), EX0, EX2
|
||||
|
||||
loop:
|
||||
CMPBLE R3, $64, add // b4 // last 4 or less blocks left
|
||||
|
||||
// next 4 full blocks
|
||||
VLM (R2), M2, M5
|
||||
SUB $64, R3
|
||||
MOVD $64(R2), R2
|
||||
REDUCE(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_10, M0, M1, T_0, T_1, T_3, T_4, T_5, T_2, T_7, T_8, T_9)
|
||||
|
||||
// expacc in-lined to create [m2, m3] limbs
|
||||
VGBM $0x3f3f, T_0 // 44 bit clear mask
|
||||
VGBM $0x1f1f, T_1 // 40 bit clear mask
|
||||
VPERM M2, M3, EX0, T_3
|
||||
VESRLG $4, T_0, T_0 // 44 bit clear mask ready
|
||||
VPERM M2, M3, EX1, T_4
|
||||
VPERM M2, M3, EX2, T_5
|
||||
VN T_0, T_3, T_3
|
||||
VESRLG $4, T_4, T_4
|
||||
VN T_1, T_5, T_5
|
||||
VN T_0, T_4, T_4
|
||||
VMRHG H0_1, T_3, H0_0
|
||||
VMRHG H1_1, T_4, H1_0
|
||||
VMRHG H2_1, T_5, H2_0
|
||||
VMRLG H0_1, T_3, H0_1
|
||||
VMRLG H1_1, T_4, H1_1
|
||||
VMRLG H2_1, T_5, H2_1
|
||||
VLEIB $10, $1, H2_0
|
||||
VLEIB $10, $1, H2_1
|
||||
VPERM M4, M5, EX0, T_3
|
||||
VPERM M4, M5, EX1, T_4
|
||||
VPERM M4, M5, EX2, T_5
|
||||
VN T_0, T_3, T_3
|
||||
VESRLG $4, T_4, T_4
|
||||
VN T_1, T_5, T_5
|
||||
VN T_0, T_4, T_4
|
||||
VMRHG V0, T_3, M0
|
||||
VMRHG V0, T_4, M1
|
||||
VMRHG V0, T_5, M2
|
||||
VMRLG V0, T_3, M3
|
||||
VMRLG V0, T_4, M4
|
||||
VMRLG V0, T_5, M5
|
||||
VLEIB $10, $1, M2
|
||||
VLEIB $10, $1, M5
|
||||
|
||||
MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, M5, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
||||
CMPBNE R3, $0, loop
|
||||
REDUCE(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_10, M0, M1, M3, M4, M5, T_4, T_5, T_2, T_7, T_8, T_9)
|
||||
VMRHG V0, H0_1, H0_0
|
||||
VMRHG V0, H1_1, H1_0
|
||||
VMRHG V0, H2_1, H2_0
|
||||
VMRLG V0, H0_1, H0_1
|
||||
VMRLG V0, H1_1, H1_1
|
||||
VMRLG V0, H2_1, H2_1
|
||||
|
||||
// load EX0, EX1, EX2
|
||||
MOVD $·constants<>(SB), R5
|
||||
VLM (R5), EX0, EX2
|
||||
|
||||
// sum vectors
|
||||
VAQ H0_0, H0_1, H0_0
|
||||
VAQ H1_0, H1_1, H1_0
|
||||
VAQ H2_0, H2_1, H2_0
|
||||
|
||||
// h may be >= 2*(2**130-5) so we need to reduce it again
|
||||
// M0...M4 are used as temps here
|
||||
REDUCE2(H0_0, H1_0, H2_0, M0, M1, M2, M3, M4, T_9, T_10, H0_1, M5)
|
||||
|
||||
next: // carry h1->h2
|
||||
VLEIB $7, $0x28, T_1
|
||||
VREPIB $4, T_2
|
||||
VGBM $0x003F, T_3
|
||||
VESRLG $4, T_3
|
||||
|
||||
// byte shift
|
||||
VSRLB T_1, H1_0, T_4
|
||||
|
||||
// bit shift
|
||||
VSRL T_2, T_4, T_4
|
||||
|
||||
// clear h1 carry bits
|
||||
VN T_3, H1_0, H1_0
|
||||
|
||||
// add carry
|
||||
VAQ T_4, H2_0, H2_0
|
||||
|
||||
// h is now < 2*(2**130-5)
|
||||
// pack h into h1 (hi) and h0 (lo)
|
||||
PACK(H0_0, H1_0, H2_0)
|
||||
|
||||
// if h > 2**130-5 then h -= 2**130-5
|
||||
MOD(H0_0, H1_0, T_0, T_1, T_2)
|
||||
|
||||
// h += s
|
||||
MOVD $·bswapMask<>(SB), R5
|
||||
VL (R5), T_1
|
||||
VL 16(R4), T_0
|
||||
VPERM T_0, T_0, T_1, T_0 // reverse bytes (to big)
|
||||
VAQ T_0, H0_0, H0_0
|
||||
VPERM H0_0, H0_0, T_1, H0_0 // reverse bytes (to little)
|
||||
VST H0_0, (R1)
|
||||
RET
|
||||
|
||||
add:
|
||||
// load EX0, EX1, EX2
|
||||
MOVD $·constants<>(SB), R5
|
||||
VLM (R5), EX0, EX2
|
||||
|
||||
REDUCE(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_10, M0, M1, M3, M4, M5, T_4, T_5, T_2, T_7, T_8, T_9)
|
||||
VMRHG V0, H0_1, H0_0
|
||||
VMRHG V0, H1_1, H1_0
|
||||
VMRHG V0, H2_1, H2_0
|
||||
VMRLG V0, H0_1, H0_1
|
||||
VMRLG V0, H1_1, H1_1
|
||||
VMRLG V0, H2_1, H2_1
|
||||
CMPBLE R3, $64, b4
|
||||
|
||||
b4:
|
||||
CMPBLE R3, $48, b3 // 3 blocks or less
|
||||
|
||||
// 4(3+1) blocks remaining
|
||||
SUB $49, R3
|
||||
VLM (R2), M0, M2
|
||||
VLL R3, 48(R2), M3
|
||||
ADD $1, R3
|
||||
MOVBZ $1, R0
|
||||
CMPBEQ R3, $16, 2(PC)
|
||||
VLVGB R3, R0, M3
|
||||
MOVD $64(R2), R2
|
||||
EXPACC(M0, M1, H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_0, T_1, T_2, T_3)
|
||||
VLEIB $10, $1, H2_0
|
||||
VLEIB $10, $1, H2_1
|
||||
VZERO M0
|
||||
VZERO M1
|
||||
VZERO M4
|
||||
VZERO M5
|
||||
VZERO T_4
|
||||
VZERO T_10
|
||||
EXPACC(M2, M3, M0, M1, M4, M5, T_4, T_10, T_0, T_1, T_2, T_3)
|
||||
VLR T_4, M2
|
||||
VLEIB $10, $1, M4
|
||||
CMPBNE R3, $16, 2(PC)
|
||||
VLEIB $10, $1, T_10
|
||||
MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M4, M5, M2, T_10, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
||||
REDUCE(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_10, M0, M1, M3, M4, M5, T_4, T_5, T_2, T_7, T_8, T_9)
|
||||
VMRHG V0, H0_1, H0_0
|
||||
VMRHG V0, H1_1, H1_0
|
||||
VMRHG V0, H2_1, H2_0
|
||||
VMRLG V0, H0_1, H0_1
|
||||
VMRLG V0, H1_1, H1_1
|
||||
VMRLG V0, H2_1, H2_1
|
||||
SUB $16, R3
|
||||
CMPBLE R3, $0, square // this condition must always hold true!
|
||||
|
||||
b3:
|
||||
CMPBLE R3, $32, b2
|
||||
|
||||
// 3 blocks remaining
|
||||
|
||||
// setup [r²,r]
|
||||
VSLDB $8, R_0, R_0, R_0
|
||||
VSLDB $8, R_1, R_1, R_1
|
||||
VSLDB $8, R_2, R_2, R_2
|
||||
VSLDB $8, R5_1, R5_1, R5_1
|
||||
VSLDB $8, R5_2, R5_2, R5_2
|
||||
|
||||
VLVGG $1, RSAVE_0, R_0
|
||||
VLVGG $1, RSAVE_1, R_1
|
||||
VLVGG $1, RSAVE_2, R_2
|
||||
VLVGG $1, R5SAVE_1, R5_1
|
||||
VLVGG $1, R5SAVE_2, R5_2
|
||||
|
||||
// setup [h0, h1]
|
||||
VSLDB $8, H0_0, H0_0, H0_0
|
||||
VSLDB $8, H1_0, H1_0, H1_0
|
||||
VSLDB $8, H2_0, H2_0, H2_0
|
||||
VO H0_1, H0_0, H0_0
|
||||
VO H1_1, H1_0, H1_0
|
||||
VO H2_1, H2_0, H2_0
|
||||
VZERO H0_1
|
||||
VZERO H1_1
|
||||
VZERO H2_1
|
||||
|
||||
VZERO M0
|
||||
VZERO M1
|
||||
VZERO M2
|
||||
VZERO M3
|
||||
VZERO M4
|
||||
VZERO M5
|
||||
|
||||
// H*[r**2, r]
|
||||
MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, M5, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
||||
REDUCE2(H0_0, H1_0, H2_0, M0, M1, M2, M3, M4, H0_1, H1_1, T_10, M5)
|
||||
|
||||
SUB $33, R3
|
||||
VLM (R2), M0, M1
|
||||
VLL R3, 32(R2), M2
|
||||
ADD $1, R3
|
||||
MOVBZ $1, R0
|
||||
CMPBEQ R3, $16, 2(PC)
|
||||
VLVGB R3, R0, M2
|
||||
|
||||
// H += m0
|
||||
VZERO T_1
|
||||
VZERO T_2
|
||||
VZERO T_3
|
||||
EXPACC2(M0, T_1, T_2, T_3, T_4, T_5, T_6)
|
||||
VLEIB $10, $1, T_3
|
||||
VAG H0_0, T_1, H0_0
|
||||
VAG H1_0, T_2, H1_0
|
||||
VAG H2_0, T_3, H2_0
|
||||
|
||||
VZERO M0
|
||||
VZERO M3
|
||||
VZERO M4
|
||||
VZERO M5
|
||||
VZERO T_10
|
||||
|
||||
// (H+m0)*r
|
||||
MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M3, M4, M5, V0, T_10, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
||||
REDUCE2(H0_0, H1_0, H2_0, M0, M3, M4, M5, T_10, H0_1, H1_1, H2_1, T_9)
|
||||
|
||||
// H += m1
|
||||
VZERO V0
|
||||
VZERO T_1
|
||||
VZERO T_2
|
||||
VZERO T_3
|
||||
EXPACC2(M1, T_1, T_2, T_3, T_4, T_5, T_6)
|
||||
VLEIB $10, $1, T_3
|
||||
VAQ H0_0, T_1, H0_0
|
||||
VAQ H1_0, T_2, H1_0
|
||||
VAQ H2_0, T_3, H2_0
|
||||
REDUCE2(H0_0, H1_0, H2_0, M0, M3, M4, M5, T_9, H0_1, H1_1, H2_1, T_10)
|
||||
|
||||
// [H, m2] * [r**2, r]
|
||||
EXPACC2(M2, H0_0, H1_0, H2_0, T_1, T_2, T_3)
|
||||
CMPBNE R3, $16, 2(PC)
|
||||
VLEIB $10, $1, H2_0
|
||||
VZERO M0
|
||||
VZERO M1
|
||||
VZERO M2
|
||||
VZERO M3
|
||||
VZERO M4
|
||||
VZERO M5
|
||||
MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, M5, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
||||
REDUCE2(H0_0, H1_0, H2_0, M0, M1, M2, M3, M4, H0_1, H1_1, M5, T_10)
|
||||
SUB $16, R3
|
||||
CMPBLE R3, $0, next // this condition must always hold true!
|
||||
|
||||
b2:
|
||||
CMPBLE R3, $16, b1
|
||||
|
||||
// 2 blocks remaining
|
||||
|
||||
// setup [r²,r]
|
||||
VSLDB $8, R_0, R_0, R_0
|
||||
VSLDB $8, R_1, R_1, R_1
|
||||
VSLDB $8, R_2, R_2, R_2
|
||||
VSLDB $8, R5_1, R5_1, R5_1
|
||||
VSLDB $8, R5_2, R5_2, R5_2
|
||||
|
||||
VLVGG $1, RSAVE_0, R_0
|
||||
VLVGG $1, RSAVE_1, R_1
|
||||
VLVGG $1, RSAVE_2, R_2
|
||||
VLVGG $1, R5SAVE_1, R5_1
|
||||
VLVGG $1, R5SAVE_2, R5_2
|
||||
|
||||
// setup [h0, h1]
|
||||
VSLDB $8, H0_0, H0_0, H0_0
|
||||
VSLDB $8, H1_0, H1_0, H1_0
|
||||
VSLDB $8, H2_0, H2_0, H2_0
|
||||
VO H0_1, H0_0, H0_0
|
||||
VO H1_1, H1_0, H1_0
|
||||
VO H2_1, H2_0, H2_0
|
||||
VZERO H0_1
|
||||
VZERO H1_1
|
||||
VZERO H2_1
|
||||
|
||||
VZERO M0
|
||||
VZERO M1
|
||||
VZERO M2
|
||||
VZERO M3
|
||||
VZERO M4
|
||||
VZERO M5
|
||||
|
||||
// H*[r**2, r]
|
||||
MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, M5, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
||||
REDUCE(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, T_10, M0, M1, M2, M3, M4, T_4, T_5, T_2, T_7, T_8, T_9)
|
||||
VMRHG V0, H0_1, H0_0
|
||||
VMRHG V0, H1_1, H1_0
|
||||
VMRHG V0, H2_1, H2_0
|
||||
VMRLG V0, H0_1, H0_1
|
||||
VMRLG V0, H1_1, H1_1
|
||||
VMRLG V0, H2_1, H2_1
|
||||
|
||||
// move h to the left and 0s at the right
|
||||
VSLDB $8, H0_0, H0_0, H0_0
|
||||
VSLDB $8, H1_0, H1_0, H1_0
|
||||
VSLDB $8, H2_0, H2_0, H2_0
|
||||
|
||||
// get message blocks and append 1 to start
|
||||
SUB $17, R3
|
||||
VL (R2), M0
|
||||
VLL R3, 16(R2), M1
|
||||
ADD $1, R3
|
||||
MOVBZ $1, R0
|
||||
CMPBEQ R3, $16, 2(PC)
|
||||
VLVGB R3, R0, M1
|
||||
VZERO T_6
|
||||
VZERO T_7
|
||||
VZERO T_8
|
||||
EXPACC2(M0, T_6, T_7, T_8, T_1, T_2, T_3)
|
||||
EXPACC2(M1, T_6, T_7, T_8, T_1, T_2, T_3)
|
||||
VLEIB $2, $1, T_8
|
||||
CMPBNE R3, $16, 2(PC)
|
||||
VLEIB $10, $1, T_8
|
||||
|
||||
// add [m0, m1] to h
|
||||
VAG H0_0, T_6, H0_0
|
||||
VAG H1_0, T_7, H1_0
|
||||
VAG H2_0, T_8, H2_0
|
||||
|
||||
VZERO M2
|
||||
VZERO M3
|
||||
VZERO M4
|
||||
VZERO M5
|
||||
VZERO T_10
|
||||
VZERO M0
|
||||
|
||||
// at this point R_0 .. R5_2 look like [r**2, r]
|
||||
MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M2, M3, M4, M5, T_10, M0, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
||||
REDUCE2(H0_0, H1_0, H2_0, M2, M3, M4, M5, T_9, H0_1, H1_1, H2_1, T_10)
|
||||
SUB $16, R3, R3
|
||||
CMPBLE R3, $0, next
|
||||
|
||||
b1:
|
||||
CMPBLE R3, $0, next
|
||||
|
||||
// 1 block remaining
|
||||
|
||||
// setup [r²,r]
|
||||
VSLDB $8, R_0, R_0, R_0
|
||||
VSLDB $8, R_1, R_1, R_1
|
||||
VSLDB $8, R_2, R_2, R_2
|
||||
VSLDB $8, R5_1, R5_1, R5_1
|
||||
VSLDB $8, R5_2, R5_2, R5_2
|
||||
|
||||
VLVGG $1, RSAVE_0, R_0
|
||||
VLVGG $1, RSAVE_1, R_1
|
||||
VLVGG $1, RSAVE_2, R_2
|
||||
VLVGG $1, R5SAVE_1, R5_1
|
||||
VLVGG $1, R5SAVE_2, R5_2
|
||||
|
||||
// setup [h0, h1]
|
||||
VSLDB $8, H0_0, H0_0, H0_0
|
||||
VSLDB $8, H1_0, H1_0, H1_0
|
||||
VSLDB $8, H2_0, H2_0, H2_0
|
||||
VO H0_1, H0_0, H0_0
|
||||
VO H1_1, H1_0, H1_0
|
||||
VO H2_1, H2_0, H2_0
|
||||
VZERO H0_1
|
||||
VZERO H1_1
|
||||
VZERO H2_1
|
||||
|
||||
VZERO M0
|
||||
VZERO M1
|
||||
VZERO M2
|
||||
VZERO M3
|
||||
VZERO M4
|
||||
VZERO M5
|
||||
|
||||
// H*[r**2, r]
|
||||
MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, M5, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
||||
REDUCE2(H0_0, H1_0, H2_0, M0, M1, M2, M3, M4, T_9, T_10, H0_1, M5)
|
||||
|
||||
// set up [0, m0] limbs
|
||||
SUB $1, R3
|
||||
VLL R3, (R2), M0
|
||||
ADD $1, R3
|
||||
MOVBZ $1, R0
|
||||
CMPBEQ R3, $16, 2(PC)
|
||||
VLVGB R3, R0, M0
|
||||
VZERO T_1
|
||||
VZERO T_2
|
||||
VZERO T_3
|
||||
EXPACC2(M0, T_1, T_2, T_3, T_4, T_5, T_6)// limbs: [0, m]
|
||||
CMPBNE R3, $16, 2(PC)
|
||||
VLEIB $10, $1, T_3
|
||||
|
||||
// h+m0
|
||||
VAQ H0_0, T_1, H0_0
|
||||
VAQ H1_0, T_2, H1_0
|
||||
VAQ H2_0, T_3, H2_0
|
||||
|
||||
VZERO M0
|
||||
VZERO M1
|
||||
VZERO M2
|
||||
VZERO M3
|
||||
VZERO M4
|
||||
VZERO M5
|
||||
MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, M5, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
||||
REDUCE2(H0_0, H1_0, H2_0, M0, M1, M2, M3, M4, T_9, T_10, H0_1, M5)
|
||||
|
||||
BR next
|
||||
|
||||
square:
|
||||
// setup [r²,r]
|
||||
VSLDB $8, R_0, R_0, R_0
|
||||
VSLDB $8, R_1, R_1, R_1
|
||||
VSLDB $8, R_2, R_2, R_2
|
||||
VSLDB $8, R5_1, R5_1, R5_1
|
||||
VSLDB $8, R5_2, R5_2, R5_2
|
||||
|
||||
VLVGG $1, RSAVE_0, R_0
|
||||
VLVGG $1, RSAVE_1, R_1
|
||||
VLVGG $1, RSAVE_2, R_2
|
||||
VLVGG $1, R5SAVE_1, R5_1
|
||||
VLVGG $1, R5SAVE_2, R5_2
|
||||
|
||||
// setup [h0, h1]
|
||||
VSLDB $8, H0_0, H0_0, H0_0
|
||||
VSLDB $8, H1_0, H1_0, H1_0
|
||||
VSLDB $8, H2_0, H2_0, H2_0
|
||||
VO H0_1, H0_0, H0_0
|
||||
VO H1_1, H1_0, H1_0
|
||||
VO H2_1, H2_0, H2_0
|
||||
VZERO H0_1
|
||||
VZERO H1_1
|
||||
VZERO H2_1
|
||||
|
||||
VZERO M0
|
||||
VZERO M1
|
||||
VZERO M2
|
||||
VZERO M3
|
||||
VZERO M4
|
||||
VZERO M5
|
||||
|
||||
// (h0*r**2) + (h1*r)
|
||||
MULTIPLY(H0_0, H1_0, H2_0, H0_1, H1_1, H2_1, R_0, R_1, R_2, R5_1, R5_2, M0, M1, M2, M3, M4, M5, T_0, T_1, T_2, T_3, T_4, T_5, T_6, T_7, T_8, T_9)
|
||||
REDUCE2(H0_0, H1_0, H2_0, M0, M1, M2, M3, M4, T_9, T_10, H0_1, M5)
|
||||
BR next
|
||||
|
||||
TEXT ·hasVMSLFacility(SB), NOSPLIT, $24-1
|
||||
MOVD $x-24(SP), R1
|
||||
XC $24, 0(R1), 0(R1) // clear the storage
|
||||
MOVD $2, R0 // R0 is the number of double words stored -1
|
||||
WORD $0xB2B01000 // STFLE 0(R1)
|
||||
XOR R0, R0 // reset the value of R0
|
||||
MOVBZ z-8(SP), R1
|
||||
AND $0x01, R1
|
||||
BEQ novmsl
|
||||
|
||||
vectorinstalled:
|
||||
// check if the vector instruction has been enabled
|
||||
VLEIB $0, $0xF, V16
|
||||
VLGVB $0, V16, R1
|
||||
CMPBNE R1, $0xF, novmsl
|
||||
MOVB $1, ret+0(FP) // have vx
|
||||
RET
|
||||
|
||||
novmsl:
|
||||
MOVB $0, ret+0(FP) // no vx
|
||||
RET
|
||||
2943
vendor/golang.org/x/crypto/poly1305/vectors_test.go
generated
vendored
Normal file
2943
vendor/golang.org/x/crypto/poly1305/vectors_test.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6
vendor/golang.org/x/crypto/salsa20/salsa20.go
generated
vendored
6
vendor/golang.org/x/crypto/salsa20/salsa20.go
generated
vendored
@@ -24,6 +24,7 @@ package salsa20 // import "golang.org/x/crypto/salsa20"
|
||||
// TODO(agl): implement XORKeyStream12 and XORKeyStream8 - the reduced round variants of Salsa20.
|
||||
|
||||
import (
|
||||
"golang.org/x/crypto/internal/subtle"
|
||||
"golang.org/x/crypto/salsa20/salsa"
|
||||
)
|
||||
|
||||
@@ -32,7 +33,10 @@ import (
|
||||
// be either 8 or 24 bytes long.
|
||||
func XORKeyStream(out, in []byte, nonce []byte, key *[32]byte) {
|
||||
if len(out) < len(in) {
|
||||
in = in[:len(out)]
|
||||
panic("salsa20: output smaller than input")
|
||||
}
|
||||
if subtle.InexactOverlap(out[:len(in)], in) {
|
||||
panic("salsa20: invalid buffer overlap")
|
||||
}
|
||||
|
||||
var subNonce [16]byte
|
||||
|
||||
2
vendor/golang.org/x/crypto/scrypt/scrypt.go
generated
vendored
2
vendor/golang.org/x/crypto/scrypt/scrypt.go
generated
vendored
@@ -218,7 +218,7 @@ func smix(b []byte, r, N int, v, xy []uint32) {
|
||||
// For example, you can get a derived key for e.g. AES-256 (which needs a
|
||||
// 32-byte key) by doing:
|
||||
//
|
||||
// dk, err := scrypt.Key([]byte("some password"), salt, 16384, 8, 1, 32)
|
||||
// dk, err := scrypt.Key([]byte("some password"), salt, 32768, 8, 1, 32)
|
||||
//
|
||||
// The recommended parameters for interactive logins as of 2017 are N=32768, r=8
|
||||
// and p=1. The parameters N, r, and p should be increased as memory latency and
|
||||
|
||||
34
vendor/golang.org/x/crypto/sha3/hashes.go
generated
vendored
34
vendor/golang.org/x/crypto/sha3/hashes.go
generated
vendored
@@ -15,22 +15,48 @@ import (
|
||||
// New224 creates a new SHA3-224 hash.
|
||||
// Its generic security strength is 224 bits against preimage attacks,
|
||||
// and 112 bits against collision attacks.
|
||||
func New224() hash.Hash { return &state{rate: 144, outputLen: 28, dsbyte: 0x06} }
|
||||
func New224() hash.Hash {
|
||||
if h := new224Asm(); h != nil {
|
||||
return h
|
||||
}
|
||||
return &state{rate: 144, outputLen: 28, dsbyte: 0x06}
|
||||
}
|
||||
|
||||
// New256 creates a new SHA3-256 hash.
|
||||
// Its generic security strength is 256 bits against preimage attacks,
|
||||
// and 128 bits against collision attacks.
|
||||
func New256() hash.Hash { return &state{rate: 136, outputLen: 32, dsbyte: 0x06} }
|
||||
func New256() hash.Hash {
|
||||
if h := new256Asm(); h != nil {
|
||||
return h
|
||||
}
|
||||
return &state{rate: 136, outputLen: 32, dsbyte: 0x06}
|
||||
}
|
||||
|
||||
// New384 creates a new SHA3-384 hash.
|
||||
// Its generic security strength is 384 bits against preimage attacks,
|
||||
// and 192 bits against collision attacks.
|
||||
func New384() hash.Hash { return &state{rate: 104, outputLen: 48, dsbyte: 0x06} }
|
||||
func New384() hash.Hash {
|
||||
if h := new384Asm(); h != nil {
|
||||
return h
|
||||
}
|
||||
return &state{rate: 104, outputLen: 48, dsbyte: 0x06}
|
||||
}
|
||||
|
||||
// New512 creates a new SHA3-512 hash.
|
||||
// Its generic security strength is 512 bits against preimage attacks,
|
||||
// and 256 bits against collision attacks.
|
||||
func New512() hash.Hash { return &state{rate: 72, outputLen: 64, dsbyte: 0x06} }
|
||||
func New512() hash.Hash {
|
||||
if h := new512Asm(); h != nil {
|
||||
return h
|
||||
}
|
||||
return &state{rate: 72, outputLen: 64, dsbyte: 0x06}
|
||||
}
|
||||
|
||||
// NewLegacyKeccak256 creates a new Keccak-256 hash.
|
||||
//
|
||||
// Only use this function if you require compatibility with an existing cryptosystem
|
||||
// that uses non-standard padding. All other users should use New256 instead.
|
||||
func NewLegacyKeccak256() hash.Hash { return &state{rate: 136, outputLen: 32, dsbyte: 0x01} }
|
||||
|
||||
// Sum224 returns the SHA3-224 digest of the data.
|
||||
func Sum224(data []byte) (digest [28]byte) {
|
||||
|
||||
27
vendor/golang.org/x/crypto/sha3/hashes_generic.go
generated
vendored
Normal file
27
vendor/golang.org/x/crypto/sha3/hashes_generic.go
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//+build gccgo appengine !s390x
|
||||
|
||||
package sha3
|
||||
|
||||
import (
|
||||
"hash"
|
||||
)
|
||||
|
||||
// new224Asm returns an assembly implementation of SHA3-224 if available,
|
||||
// otherwise it returns nil.
|
||||
func new224Asm() hash.Hash { return nil }
|
||||
|
||||
// new256Asm returns an assembly implementation of SHA3-256 if available,
|
||||
// otherwise it returns nil.
|
||||
func new256Asm() hash.Hash { return nil }
|
||||
|
||||
// new384Asm returns an assembly implementation of SHA3-384 if available,
|
||||
// otherwise it returns nil.
|
||||
func new384Asm() hash.Hash { return nil }
|
||||
|
||||
// new512Asm returns an assembly implementation of SHA3-512 if available,
|
||||
// otherwise it returns nil.
|
||||
func new512Asm() hash.Hash { return nil }
|
||||
289
vendor/golang.org/x/crypto/sha3/sha3_s390x.go
generated
vendored
Normal file
289
vendor/golang.org/x/crypto/sha3/sha3_s390x.go
generated
vendored
Normal file
@@ -0,0 +1,289 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//+build !gccgo,!appengine
|
||||
|
||||
package sha3
|
||||
|
||||
// This file contains code for using the 'compute intermediate
|
||||
// message digest' (KIMD) and 'compute last message digest' (KLMD)
|
||||
// instructions to compute SHA-3 and SHAKE hashes on IBM Z.
|
||||
|
||||
import (
|
||||
"hash"
|
||||
)
|
||||
|
||||
// codes represent 7-bit KIMD/KLMD function codes as defined in
|
||||
// the Principles of Operation.
|
||||
type code uint64
|
||||
|
||||
const (
|
||||
// function codes for KIMD/KLMD
|
||||
sha3_224 code = 32
|
||||
sha3_256 = 33
|
||||
sha3_384 = 34
|
||||
sha3_512 = 35
|
||||
shake_128 = 36
|
||||
shake_256 = 37
|
||||
nopad = 0x100
|
||||
)
|
||||
|
||||
// hasMSA6 reports whether the machine supports the SHA-3 and SHAKE function
|
||||
// codes, as defined in message-security-assist extension 6.
|
||||
func hasMSA6() bool
|
||||
|
||||
// hasAsm caches the result of hasMSA6 (which might be expensive to call).
|
||||
var hasAsm = hasMSA6()
|
||||
|
||||
// kimd is a wrapper for the 'compute intermediate message digest' instruction.
|
||||
// src must be a multiple of the rate for the given function code.
|
||||
//go:noescape
|
||||
func kimd(function code, chain *[200]byte, src []byte)
|
||||
|
||||
// klmd is a wrapper for the 'compute last message digest' instruction.
|
||||
// src padding is handled by the instruction.
|
||||
//go:noescape
|
||||
func klmd(function code, chain *[200]byte, dst, src []byte)
|
||||
|
||||
type asmState struct {
|
||||
a [200]byte // 1600 bit state
|
||||
buf []byte // care must be taken to ensure cap(buf) is a multiple of rate
|
||||
rate int // equivalent to block size
|
||||
storage [3072]byte // underlying storage for buf
|
||||
outputLen int // output length if fixed, 0 if not
|
||||
function code // KIMD/KLMD function code
|
||||
state spongeDirection // whether the sponge is absorbing or squeezing
|
||||
}
|
||||
|
||||
func newAsmState(function code) *asmState {
|
||||
var s asmState
|
||||
s.function = function
|
||||
switch function {
|
||||
case sha3_224:
|
||||
s.rate = 144
|
||||
s.outputLen = 28
|
||||
case sha3_256:
|
||||
s.rate = 136
|
||||
s.outputLen = 32
|
||||
case sha3_384:
|
||||
s.rate = 104
|
||||
s.outputLen = 48
|
||||
case sha3_512:
|
||||
s.rate = 72
|
||||
s.outputLen = 64
|
||||
case shake_128:
|
||||
s.rate = 168
|
||||
case shake_256:
|
||||
s.rate = 136
|
||||
default:
|
||||
panic("sha3: unrecognized function code")
|
||||
}
|
||||
|
||||
// limit s.buf size to a multiple of s.rate
|
||||
s.resetBuf()
|
||||
return &s
|
||||
}
|
||||
|
||||
func (s *asmState) clone() *asmState {
|
||||
c := *s
|
||||
c.buf = c.storage[:len(s.buf):cap(s.buf)]
|
||||
return &c
|
||||
}
|
||||
|
||||
// copyIntoBuf copies b into buf. It will panic if there is not enough space to
|
||||
// store all of b.
|
||||
func (s *asmState) copyIntoBuf(b []byte) {
|
||||
bufLen := len(s.buf)
|
||||
s.buf = s.buf[:len(s.buf)+len(b)]
|
||||
copy(s.buf[bufLen:], b)
|
||||
}
|
||||
|
||||
// resetBuf points buf at storage, sets the length to 0 and sets cap to be a
|
||||
// multiple of the rate.
|
||||
func (s *asmState) resetBuf() {
|
||||
max := (cap(s.storage) / s.rate) * s.rate
|
||||
s.buf = s.storage[:0:max]
|
||||
}
|
||||
|
||||
// Write (via the embedded io.Writer interface) adds more data to the running hash.
|
||||
// It never returns an error.
|
||||
func (s *asmState) Write(b []byte) (int, error) {
|
||||
if s.state != spongeAbsorbing {
|
||||
panic("sha3: write to sponge after read")
|
||||
}
|
||||
length := len(b)
|
||||
for len(b) > 0 {
|
||||
if len(s.buf) == 0 && len(b) >= cap(s.buf) {
|
||||
// Hash the data directly and push any remaining bytes
|
||||
// into the buffer.
|
||||
remainder := len(s.buf) % s.rate
|
||||
kimd(s.function, &s.a, b[:len(b)-remainder])
|
||||
if remainder != 0 {
|
||||
s.copyIntoBuf(b[len(b)-remainder:])
|
||||
}
|
||||
return length, nil
|
||||
}
|
||||
|
||||
if len(s.buf) == cap(s.buf) {
|
||||
// flush the buffer
|
||||
kimd(s.function, &s.a, s.buf)
|
||||
s.buf = s.buf[:0]
|
||||
}
|
||||
|
||||
// copy as much as we can into the buffer
|
||||
n := len(b)
|
||||
if len(b) > cap(s.buf)-len(s.buf) {
|
||||
n = cap(s.buf) - len(s.buf)
|
||||
}
|
||||
s.copyIntoBuf(b[:n])
|
||||
b = b[n:]
|
||||
}
|
||||
return length, nil
|
||||
}
|
||||
|
||||
// Read squeezes an arbitrary number of bytes from the sponge.
|
||||
func (s *asmState) Read(out []byte) (n int, err error) {
|
||||
n = len(out)
|
||||
|
||||
// need to pad if we were absorbing
|
||||
if s.state == spongeAbsorbing {
|
||||
s.state = spongeSqueezing
|
||||
|
||||
// write hash directly into out if possible
|
||||
if len(out)%s.rate == 0 {
|
||||
klmd(s.function, &s.a, out, s.buf) // len(out) may be 0
|
||||
s.buf = s.buf[:0]
|
||||
return
|
||||
}
|
||||
|
||||
// write hash into buffer
|
||||
max := cap(s.buf)
|
||||
if max > len(out) {
|
||||
max = (len(out)/s.rate)*s.rate + s.rate
|
||||
}
|
||||
klmd(s.function, &s.a, s.buf[:max], s.buf)
|
||||
s.buf = s.buf[:max]
|
||||
}
|
||||
|
||||
for len(out) > 0 {
|
||||
// flush the buffer
|
||||
if len(s.buf) != 0 {
|
||||
c := copy(out, s.buf)
|
||||
out = out[c:]
|
||||
s.buf = s.buf[c:]
|
||||
continue
|
||||
}
|
||||
|
||||
// write hash directly into out if possible
|
||||
if len(out)%s.rate == 0 {
|
||||
klmd(s.function|nopad, &s.a, out, nil)
|
||||
return
|
||||
}
|
||||
|
||||
// write hash into buffer
|
||||
s.resetBuf()
|
||||
if cap(s.buf) > len(out) {
|
||||
s.buf = s.buf[:(len(out)/s.rate)*s.rate+s.rate]
|
||||
}
|
||||
klmd(s.function|nopad, &s.a, s.buf, nil)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Sum appends the current hash to b and returns the resulting slice.
|
||||
// It does not change the underlying hash state.
|
||||
func (s *asmState) Sum(b []byte) []byte {
|
||||
if s.outputLen == 0 {
|
||||
panic("sha3: cannot call Sum on SHAKE functions")
|
||||
}
|
||||
|
||||
// Copy the state to preserve the original.
|
||||
a := s.a
|
||||
|
||||
// Hash the buffer. Note that we don't clear it because we
|
||||
// aren't updating the state.
|
||||
klmd(s.function, &a, nil, s.buf)
|
||||
return append(b, a[:s.outputLen]...)
|
||||
}
|
||||
|
||||
// Reset resets the Hash to its initial state.
|
||||
func (s *asmState) Reset() {
|
||||
for i := range s.a {
|
||||
s.a[i] = 0
|
||||
}
|
||||
s.resetBuf()
|
||||
s.state = spongeAbsorbing
|
||||
}
|
||||
|
||||
// Size returns the number of bytes Sum will return.
|
||||
func (s *asmState) Size() int {
|
||||
return s.outputLen
|
||||
}
|
||||
|
||||
// BlockSize returns the hash's underlying block size.
|
||||
// The Write method must be able to accept any amount
|
||||
// of data, but it may operate more efficiently if all writes
|
||||
// are a multiple of the block size.
|
||||
func (s *asmState) BlockSize() int {
|
||||
return s.rate
|
||||
}
|
||||
|
||||
// Clone returns a copy of the ShakeHash in its current state.
|
||||
func (s *asmState) Clone() ShakeHash {
|
||||
return s.clone()
|
||||
}
|
||||
|
||||
// new224Asm returns an assembly implementation of SHA3-224 if available,
|
||||
// otherwise it returns nil.
|
||||
func new224Asm() hash.Hash {
|
||||
if hasAsm {
|
||||
return newAsmState(sha3_224)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// new256Asm returns an assembly implementation of SHA3-256 if available,
|
||||
// otherwise it returns nil.
|
||||
func new256Asm() hash.Hash {
|
||||
if hasAsm {
|
||||
return newAsmState(sha3_256)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// new384Asm returns an assembly implementation of SHA3-384 if available,
|
||||
// otherwise it returns nil.
|
||||
func new384Asm() hash.Hash {
|
||||
if hasAsm {
|
||||
return newAsmState(sha3_384)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// new512Asm returns an assembly implementation of SHA3-512 if available,
|
||||
// otherwise it returns nil.
|
||||
func new512Asm() hash.Hash {
|
||||
if hasAsm {
|
||||
return newAsmState(sha3_512)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// newShake128Asm returns an assembly implementation of SHAKE-128 if available,
|
||||
// otherwise it returns nil.
|
||||
func newShake128Asm() ShakeHash {
|
||||
if hasAsm {
|
||||
return newAsmState(shake_128)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// newShake256Asm returns an assembly implementation of SHAKE-256 if available,
|
||||
// otherwise it returns nil.
|
||||
func newShake256Asm() ShakeHash {
|
||||
if hasAsm {
|
||||
return newAsmState(shake_256)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
49
vendor/golang.org/x/crypto/sha3/sha3_s390x.s
generated
vendored
Normal file
49
vendor/golang.org/x/crypto/sha3/sha3_s390x.s
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//+build !gccgo,!appengine
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
TEXT ·hasMSA6(SB), NOSPLIT, $16-1
|
||||
MOVD $0, R0 // KIMD-Query function code
|
||||
MOVD $tmp-16(SP), R1 // parameter block
|
||||
XC $16, (R1), (R1) // clear the parameter block
|
||||
WORD $0xB93E0002 // KIMD --, --
|
||||
WORD $0x91FC1004 // TM 4(R1), 0xFC (test bits [32-37])
|
||||
BVS yes
|
||||
|
||||
no:
|
||||
MOVB $0, ret+0(FP)
|
||||
RET
|
||||
|
||||
yes:
|
||||
MOVB $1, ret+0(FP)
|
||||
RET
|
||||
|
||||
// func kimd(function code, params *[200]byte, src []byte)
|
||||
TEXT ·kimd(SB), NOFRAME|NOSPLIT, $0-40
|
||||
MOVD function+0(FP), R0
|
||||
MOVD params+8(FP), R1
|
||||
LMG src+16(FP), R2, R3 // R2=base, R3=len
|
||||
|
||||
continue:
|
||||
WORD $0xB93E0002 // KIMD --, R2
|
||||
BVS continue // continue if interrupted
|
||||
MOVD $0, R0 // reset R0 for pre-go1.8 compilers
|
||||
RET
|
||||
|
||||
// func klmd(function code, params *[200]byte, dst, src []byte)
|
||||
TEXT ·klmd(SB), NOFRAME|NOSPLIT, $0-64
|
||||
// TODO: SHAKE support
|
||||
MOVD function+0(FP), R0
|
||||
MOVD params+8(FP), R1
|
||||
LMG dst+16(FP), R2, R3 // R2=base, R3=len
|
||||
LMG src+40(FP), R4, R5 // R4=base, R5=len
|
||||
|
||||
continue:
|
||||
WORD $0xB93F0024 // KLMD R2, R4
|
||||
BVS continue // continue if interrupted
|
||||
MOVD $0, R0 // reset R0 for pre-go1.8 compilers
|
||||
RET
|
||||
44
vendor/golang.org/x/crypto/sha3/sha3_test.go
generated
vendored
44
vendor/golang.org/x/crypto/sha3/sha3_test.go
generated
vendored
@@ -36,15 +36,16 @@ func newHashShake256() hash.Hash {
|
||||
}
|
||||
|
||||
// testDigests contains functions returning hash.Hash instances
|
||||
// with output-length equal to the KAT length for both SHA-3 and
|
||||
// SHAKE instances.
|
||||
// with output-length equal to the KAT length for SHA-3, Keccak
|
||||
// and SHAKE instances.
|
||||
var testDigests = map[string]func() hash.Hash{
|
||||
"SHA3-224": New224,
|
||||
"SHA3-256": New256,
|
||||
"SHA3-384": New384,
|
||||
"SHA3-512": New512,
|
||||
"SHAKE128": newHashShake128,
|
||||
"SHAKE256": newHashShake256,
|
||||
"SHA3-224": New224,
|
||||
"SHA3-256": New256,
|
||||
"SHA3-384": New384,
|
||||
"SHA3-512": New512,
|
||||
"Keccak-256": NewLegacyKeccak256,
|
||||
"SHAKE128": newHashShake128,
|
||||
"SHAKE256": newHashShake256,
|
||||
}
|
||||
|
||||
// testShakes contains functions that return ShakeHash instances for
|
||||
@@ -124,9 +125,34 @@ func TestKeccakKats(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
// TestKeccak does a basic test of the non-standardized Keccak hash functions.
|
||||
func TestKeccak(t *testing.T) {
|
||||
tests := []struct {
|
||||
fn func() hash.Hash
|
||||
data []byte
|
||||
want string
|
||||
}{
|
||||
{
|
||||
NewLegacyKeccak256,
|
||||
[]byte("abc"),
|
||||
"4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45",
|
||||
},
|
||||
}
|
||||
|
||||
for _, u := range tests {
|
||||
h := u.fn()
|
||||
h.Write(u.data)
|
||||
got := h.Sum(nil)
|
||||
want := decodeHex(u.want)
|
||||
if !bytes.Equal(got, want) {
|
||||
t.Errorf("unexpected hash for size %d: got '%x' want '%s'", h.Size()*8, got, u.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestUnalignedWrite tests that writing data in an arbitrary pattern with
|
||||
// small input buffers.
|
||||
func testUnalignedWrite(t *testing.T) {
|
||||
func TestUnalignedWrite(t *testing.T) {
|
||||
testUnalignedAndGeneric(t, func(impl string) {
|
||||
buf := sequentialBytes(0x10000)
|
||||
for alg, df := range testDigests {
|
||||
|
||||
14
vendor/golang.org/x/crypto/sha3/shake.go
generated
vendored
14
vendor/golang.org/x/crypto/sha3/shake.go
generated
vendored
@@ -38,12 +38,22 @@ func (d *state) Clone() ShakeHash {
|
||||
// NewShake128 creates a new SHAKE128 variable-output-length ShakeHash.
|
||||
// Its generic security strength is 128 bits against all attacks if at
|
||||
// least 32 bytes of its output are used.
|
||||
func NewShake128() ShakeHash { return &state{rate: 168, dsbyte: 0x1f} }
|
||||
func NewShake128() ShakeHash {
|
||||
if h := newShake128Asm(); h != nil {
|
||||
return h
|
||||
}
|
||||
return &state{rate: 168, dsbyte: 0x1f}
|
||||
}
|
||||
|
||||
// NewShake256 creates a new SHAKE256 variable-output-length ShakeHash.
|
||||
// Its generic security strength is 256 bits against all attacks if
|
||||
// at least 64 bytes of its output are used.
|
||||
func NewShake256() ShakeHash { return &state{rate: 136, dsbyte: 0x1f} }
|
||||
func NewShake256() ShakeHash {
|
||||
if h := newShake256Asm(); h != nil {
|
||||
return h
|
||||
}
|
||||
return &state{rate: 136, dsbyte: 0x1f}
|
||||
}
|
||||
|
||||
// ShakeSum128 writes an arbitrary-length digest of data into hash.
|
||||
func ShakeSum128(hash, data []byte) {
|
||||
|
||||
19
vendor/golang.org/x/crypto/sha3/shake_generic.go
generated
vendored
Normal file
19
vendor/golang.org/x/crypto/sha3/shake_generic.go
generated
vendored
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.
|
||||
|
||||
//+build gccgo appengine !s390x
|
||||
|
||||
package sha3
|
||||
|
||||
// newShake128Asm returns an assembly implementation of SHAKE-128 if available,
|
||||
// otherwise it returns nil.
|
||||
func newShake128Asm() ShakeHash {
|
||||
return nil
|
||||
}
|
||||
|
||||
// newShake256Asm returns an assembly implementation of SHAKE-256 if available,
|
||||
// otherwise it returns nil.
|
||||
func newShake256Asm() ShakeHash {
|
||||
return nil
|
||||
}
|
||||
2
vendor/golang.org/x/crypto/ssh/agent/client.go
generated
vendored
2
vendor/golang.org/x/crypto/ssh/agent/client.go
generated
vendored
@@ -8,7 +8,7 @@
|
||||
// ssh-agent process using the sample server.
|
||||
//
|
||||
// References:
|
||||
// [PROTOCOL.agent]: http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.agent?rev=HEAD
|
||||
// [PROTOCOL.agent]: https://tools.ietf.org/html/draft-miller-ssh-agent-00
|
||||
package agent // import "golang.org/x/crypto/ssh/agent"
|
||||
|
||||
import (
|
||||
|
||||
2
vendor/golang.org/x/crypto/ssh/agent/keyring.go
generated
vendored
2
vendor/golang.org/x/crypto/ssh/agent/keyring.go
generated
vendored
@@ -102,7 +102,7 @@ func (r *keyring) Unlock(passphrase []byte) error {
|
||||
if !r.locked {
|
||||
return errors.New("agent: not locked")
|
||||
}
|
||||
if len(passphrase) != len(r.passphrase) || 1 != subtle.ConstantTimeCompare(passphrase, r.passphrase) {
|
||||
if 1 != subtle.ConstantTimeCompare(passphrase, r.passphrase) {
|
||||
return fmt.Errorf("agent: incorrect passphrase")
|
||||
}
|
||||
|
||||
|
||||
43
vendor/golang.org/x/crypto/ssh/cipher.go
generated
vendored
43
vendor/golang.org/x/crypto/ssh/cipher.go
generated
vendored
@@ -16,6 +16,7 @@ import (
|
||||
"hash"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math/bits"
|
||||
|
||||
"golang.org/x/crypto/internal/chacha20"
|
||||
"golang.org/x/crypto/poly1305"
|
||||
@@ -641,8 +642,8 @@ const chacha20Poly1305ID = "chacha20-poly1305@openssh.com"
|
||||
// the methods here also implement padding, which RFC4253 Section 6
|
||||
// also requires of stream ciphers.
|
||||
type chacha20Poly1305Cipher struct {
|
||||
lengthKey [32]byte
|
||||
contentKey [32]byte
|
||||
lengthKey [8]uint32
|
||||
contentKey [8]uint32
|
||||
buf []byte
|
||||
}
|
||||
|
||||
@@ -655,20 +656,21 @@ func newChaCha20Cipher(key, unusedIV, unusedMACKey []byte, unusedAlgs directionA
|
||||
buf: make([]byte, 256),
|
||||
}
|
||||
|
||||
copy(c.contentKey[:], key[:32])
|
||||
copy(c.lengthKey[:], key[32:])
|
||||
for i := range c.contentKey {
|
||||
c.contentKey[i] = binary.LittleEndian.Uint32(key[i*4 : (i+1)*4])
|
||||
}
|
||||
for i := range c.lengthKey {
|
||||
c.lengthKey[i] = binary.LittleEndian.Uint32(key[(i+8)*4 : (i+9)*4])
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// The Poly1305 key is obtained by encrypting 32 0-bytes.
|
||||
var chacha20PolyKeyInput [32]byte
|
||||
|
||||
func (c *chacha20Poly1305Cipher) readPacket(seqNum uint32, r io.Reader) ([]byte, error) {
|
||||
var counter [16]byte
|
||||
binary.BigEndian.PutUint64(counter[8:], uint64(seqNum))
|
||||
|
||||
nonce := [3]uint32{0, 0, bits.ReverseBytes32(seqNum)}
|
||||
s := chacha20.New(c.contentKey, nonce)
|
||||
var polyKey [32]byte
|
||||
chacha20.XORKeyStream(polyKey[:], chacha20PolyKeyInput[:], &counter, &c.contentKey)
|
||||
s.XORKeyStream(polyKey[:], polyKey[:])
|
||||
s.Advance() // skip next 32 bytes
|
||||
|
||||
encryptedLength := c.buf[:4]
|
||||
if _, err := io.ReadFull(r, encryptedLength); err != nil {
|
||||
@@ -676,7 +678,7 @@ func (c *chacha20Poly1305Cipher) readPacket(seqNum uint32, r io.Reader) ([]byte,
|
||||
}
|
||||
|
||||
var lenBytes [4]byte
|
||||
chacha20.XORKeyStream(lenBytes[:], encryptedLength, &counter, &c.lengthKey)
|
||||
chacha20.New(c.lengthKey, nonce).XORKeyStream(lenBytes[:], encryptedLength)
|
||||
|
||||
length := binary.BigEndian.Uint32(lenBytes[:])
|
||||
if length > maxPacket {
|
||||
@@ -702,10 +704,8 @@ func (c *chacha20Poly1305Cipher) readPacket(seqNum uint32, r io.Reader) ([]byte,
|
||||
return nil, errors.New("ssh: MAC failure")
|
||||
}
|
||||
|
||||
counter[0] = 1
|
||||
|
||||
plain := c.buf[4:contentEnd]
|
||||
chacha20.XORKeyStream(plain, plain, &counter, &c.contentKey)
|
||||
s.XORKeyStream(plain, plain)
|
||||
|
||||
padding := plain[0]
|
||||
if padding < 4 {
|
||||
@@ -724,11 +724,11 @@ func (c *chacha20Poly1305Cipher) readPacket(seqNum uint32, r io.Reader) ([]byte,
|
||||
}
|
||||
|
||||
func (c *chacha20Poly1305Cipher) writePacket(seqNum uint32, w io.Writer, rand io.Reader, payload []byte) error {
|
||||
var counter [16]byte
|
||||
binary.BigEndian.PutUint64(counter[8:], uint64(seqNum))
|
||||
|
||||
nonce := [3]uint32{0, 0, bits.ReverseBytes32(seqNum)}
|
||||
s := chacha20.New(c.contentKey, nonce)
|
||||
var polyKey [32]byte
|
||||
chacha20.XORKeyStream(polyKey[:], chacha20PolyKeyInput[:], &counter, &c.contentKey)
|
||||
s.XORKeyStream(polyKey[:], polyKey[:])
|
||||
s.Advance() // skip next 32 bytes
|
||||
|
||||
// There is no blocksize, so fall back to multiple of 8 byte
|
||||
// padding, as described in RFC 4253, Sec 6.
|
||||
@@ -748,7 +748,7 @@ func (c *chacha20Poly1305Cipher) writePacket(seqNum uint32, w io.Writer, rand io
|
||||
}
|
||||
|
||||
binary.BigEndian.PutUint32(c.buf, uint32(1+len(payload)+padding))
|
||||
chacha20.XORKeyStream(c.buf, c.buf[:4], &counter, &c.lengthKey)
|
||||
chacha20.New(c.lengthKey, nonce).XORKeyStream(c.buf, c.buf[:4])
|
||||
c.buf[4] = byte(padding)
|
||||
copy(c.buf[5:], payload)
|
||||
packetEnd := 5 + len(payload) + padding
|
||||
@@ -756,8 +756,7 @@ func (c *chacha20Poly1305Cipher) writePacket(seqNum uint32, w io.Writer, rand io
|
||||
return err
|
||||
}
|
||||
|
||||
counter[0] = 1
|
||||
chacha20.XORKeyStream(c.buf[4:], c.buf[4:packetEnd], &counter, &c.contentKey)
|
||||
s.XORKeyStream(c.buf[4:], c.buf[4:packetEnd])
|
||||
|
||||
var mac [poly1305.TagSize]byte
|
||||
poly1305.Sum(&mac, c.buf[:packetEnd], &polyKey)
|
||||
|
||||
4
vendor/golang.org/x/crypto/ssh/client.go
generated
vendored
4
vendor/golang.org/x/crypto/ssh/client.go
generated
vendored
@@ -19,6 +19,8 @@ import (
|
||||
type Client struct {
|
||||
Conn
|
||||
|
||||
handleForwardsOnce sync.Once // guards calling (*Client).handleForwards
|
||||
|
||||
forwards forwardList // forwarded tcpip connections from the remote side
|
||||
mu sync.Mutex
|
||||
channelHandlers map[string]chan NewChannel
|
||||
@@ -60,8 +62,6 @@ func NewClient(c Conn, chans <-chan NewChannel, reqs <-chan *Request) *Client {
|
||||
conn.Wait()
|
||||
conn.forwards.closeAll()
|
||||
}()
|
||||
go conn.forwards.handleChannels(conn.HandleChannelOpen("forwarded-tcpip"))
|
||||
go conn.forwards.handleChannels(conn.HandleChannelOpen("forwarded-streamlocal@openssh.com"))
|
||||
return conn
|
||||
}
|
||||
|
||||
|
||||
58
vendor/golang.org/x/crypto/ssh/knownhosts/knownhosts.go
generated
vendored
58
vendor/golang.org/x/crypto/ssh/knownhosts/knownhosts.go
generated
vendored
@@ -2,8 +2,9 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package knownhosts implements a parser for the OpenSSH
|
||||
// known_hosts host key database.
|
||||
// Package knownhosts implements a parser for the OpenSSH known_hosts
|
||||
// host key database, and provides utility functions for writing
|
||||
// OpenSSH compliant known_hosts files.
|
||||
package knownhosts
|
||||
|
||||
import (
|
||||
@@ -38,7 +39,7 @@ func (a *addr) String() string {
|
||||
}
|
||||
|
||||
type matcher interface {
|
||||
match([]addr) bool
|
||||
match(addr) bool
|
||||
}
|
||||
|
||||
type hostPattern struct {
|
||||
@@ -57,19 +58,16 @@ func (p *hostPattern) String() string {
|
||||
|
||||
type hostPatterns []hostPattern
|
||||
|
||||
func (ps hostPatterns) match(addrs []addr) bool {
|
||||
func (ps hostPatterns) match(a addr) bool {
|
||||
matched := false
|
||||
for _, p := range ps {
|
||||
for _, a := range addrs {
|
||||
m := p.match(a)
|
||||
if !m {
|
||||
continue
|
||||
}
|
||||
if p.negate {
|
||||
return false
|
||||
}
|
||||
matched = true
|
||||
if !p.match(a) {
|
||||
continue
|
||||
}
|
||||
if p.negate {
|
||||
return false
|
||||
}
|
||||
matched = true
|
||||
}
|
||||
return matched
|
||||
}
|
||||
@@ -122,8 +120,8 @@ func serialize(k ssh.PublicKey) string {
|
||||
return k.Type() + " " + base64.StdEncoding.EncodeToString(k.Marshal())
|
||||
}
|
||||
|
||||
func (l *keyDBLine) match(addrs []addr) bool {
|
||||
return l.matcher.match(addrs)
|
||||
func (l *keyDBLine) match(a addr) bool {
|
||||
return l.matcher.match(a)
|
||||
}
|
||||
|
||||
type hostKeyDB struct {
|
||||
@@ -153,7 +151,7 @@ func (db *hostKeyDB) IsHostAuthority(remote ssh.PublicKey, address string) bool
|
||||
a := addr{host: h, port: p}
|
||||
|
||||
for _, l := range db.lines {
|
||||
if l.cert && keyEq(l.knownKey.Key, remote) && l.match([]addr{a}) {
|
||||
if l.cert && keyEq(l.knownKey.Key, remote) && l.match(a) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -338,26 +336,24 @@ func (db *hostKeyDB) check(address string, remote net.Addr, remoteKey ssh.Public
|
||||
return fmt.Errorf("knownhosts: SplitHostPort(%s): %v", remote, err)
|
||||
}
|
||||
|
||||
addrs := []addr{
|
||||
{host, port},
|
||||
}
|
||||
|
||||
hostToCheck := addr{host, port}
|
||||
if address != "" {
|
||||
// Give preference to the hostname if available.
|
||||
host, port, err := net.SplitHostPort(address)
|
||||
if err != nil {
|
||||
return fmt.Errorf("knownhosts: SplitHostPort(%s): %v", address, err)
|
||||
}
|
||||
|
||||
addrs = append(addrs, addr{host, port})
|
||||
hostToCheck = addr{host, port}
|
||||
}
|
||||
|
||||
return db.checkAddrs(addrs, remoteKey)
|
||||
return db.checkAddr(hostToCheck, remoteKey)
|
||||
}
|
||||
|
||||
// checkAddrs checks if we can find the given public key for any of
|
||||
// the given addresses. If we only find an entry for the IP address,
|
||||
// or only the hostname, then this still succeeds.
|
||||
func (db *hostKeyDB) checkAddrs(addrs []addr, remoteKey ssh.PublicKey) error {
|
||||
func (db *hostKeyDB) checkAddr(a addr, remoteKey ssh.PublicKey) error {
|
||||
// TODO(hanwen): are these the right semantics? What if there
|
||||
// is just a key for the IP address, but not for the
|
||||
// hostname?
|
||||
@@ -365,7 +361,7 @@ func (db *hostKeyDB) checkAddrs(addrs []addr, remoteKey ssh.PublicKey) error {
|
||||
// Algorithm => key.
|
||||
knownKeys := map[string]KnownKey{}
|
||||
for _, l := range db.lines {
|
||||
if l.match(addrs) {
|
||||
if l.match(a) {
|
||||
typ := l.knownKey.Key.Type()
|
||||
if _, ok := knownKeys[typ]; !ok {
|
||||
knownKeys[typ] = l.knownKey
|
||||
@@ -414,7 +410,10 @@ func (db *hostKeyDB) Read(r io.Reader, filename string) error {
|
||||
|
||||
// New creates a host key callback from the given OpenSSH host key
|
||||
// files. The returned callback is for use in
|
||||
// ssh.ClientConfig.HostKeyCallback.
|
||||
// ssh.ClientConfig.HostKeyCallback. By preference, the key check
|
||||
// operates on the hostname if available, i.e. if a server changes its
|
||||
// IP address, the host key check will still succeed, even though a
|
||||
// record of the new IP address is not available.
|
||||
func New(files ...string) (ssh.HostKeyCallback, error) {
|
||||
db := newHostKeyDB()
|
||||
for _, fn := range files {
|
||||
@@ -536,11 +535,6 @@ func newHashedHost(encoded string) (*hashedHost, error) {
|
||||
return &hashedHost{salt: salt, hash: hash}, nil
|
||||
}
|
||||
|
||||
func (h *hashedHost) match(addrs []addr) bool {
|
||||
for _, a := range addrs {
|
||||
if bytes.Equal(hashHost(Normalize(a.String()), h.salt), h.hash) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
func (h *hashedHost) match(a addr) bool {
|
||||
return bytes.Equal(hashHost(Normalize(a.String()), h.salt), h.hash)
|
||||
}
|
||||
|
||||
29
vendor/golang.org/x/crypto/ssh/knownhosts/knownhosts_test.go
generated
vendored
29
vendor/golang.org/x/crypto/ssh/knownhosts/knownhosts_test.go
generated
vendored
@@ -166,7 +166,7 @@ func TestBasic(t *testing.T) {
|
||||
str := fmt.Sprintf("#comment\n\nserver.org,%s %s\notherhost %s", testAddr, edKeyStr, ecKeyStr)
|
||||
db := testDB(t, str)
|
||||
if err := db.check("server.org:22", testAddr, edKey); err != nil {
|
||||
t.Errorf("got error %q, want none", err)
|
||||
t.Errorf("got error %v, want none", err)
|
||||
}
|
||||
|
||||
want := KnownKey{
|
||||
@@ -185,6 +185,33 @@ func TestBasic(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestHostNamePrecedence(t *testing.T) {
|
||||
var evilAddr = &net.TCPAddr{
|
||||
IP: net.IP{66, 66, 66, 66},
|
||||
Port: 22,
|
||||
}
|
||||
|
||||
str := fmt.Sprintf("server.org,%s %s\nevil.org,%s %s", testAddr, edKeyStr, evilAddr, ecKeyStr)
|
||||
db := testDB(t, str)
|
||||
|
||||
if err := db.check("server.org:22", evilAddr, ecKey); err == nil {
|
||||
t.Errorf("check succeeded")
|
||||
} else if _, ok := err.(*KeyError); !ok {
|
||||
t.Errorf("got %T, want *KeyError", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDBOrderingPrecedenceKeyType(t *testing.T) {
|
||||
str := fmt.Sprintf("server.org,%s %s\nserver.org,%s %s", testAddr, edKeyStr, testAddr, alternateEdKeyStr)
|
||||
db := testDB(t, str)
|
||||
|
||||
if err := db.check("server.org:22", testAddr, alternateEdKey); err == nil {
|
||||
t.Errorf("check succeeded")
|
||||
} else if _, ok := err.(*KeyError); !ok {
|
||||
t.Errorf("got %T, want *KeyError", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNegate(t *testing.T) {
|
||||
str := fmt.Sprintf("%s,!server.org %s", testAddr, edKeyStr)
|
||||
db := testDB(t, str)
|
||||
|
||||
4
vendor/golang.org/x/crypto/ssh/mux_test.go
generated
vendored
4
vendor/golang.org/x/crypto/ssh/mux_test.go
generated
vendored
@@ -108,10 +108,6 @@ func TestMuxReadWrite(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("Write: %v", err)
|
||||
}
|
||||
err = s.Close()
|
||||
if err != nil {
|
||||
t.Fatalf("Close: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
var buf [1024]byte
|
||||
|
||||
1
vendor/golang.org/x/crypto/ssh/streamlocal.go
generated
vendored
1
vendor/golang.org/x/crypto/ssh/streamlocal.go
generated
vendored
@@ -32,6 +32,7 @@ type streamLocalChannelForwardMsg struct {
|
||||
|
||||
// ListenUnix is similar to ListenTCP but uses a Unix domain socket.
|
||||
func (c *Client) ListenUnix(socketPath string) (net.Listener, error) {
|
||||
c.handleForwardsOnce.Do(c.handleForwards)
|
||||
m := streamLocalChannelForwardMsg{
|
||||
socketPath,
|
||||
}
|
||||
|
||||
9
vendor/golang.org/x/crypto/ssh/tcpip.go
generated
vendored
9
vendor/golang.org/x/crypto/ssh/tcpip.go
generated
vendored
@@ -90,10 +90,19 @@ type channelForwardMsg struct {
|
||||
rport uint32
|
||||
}
|
||||
|
||||
// handleForwards starts goroutines handling forwarded connections.
|
||||
// It's called on first use by (*Client).ListenTCP to not launch
|
||||
// goroutines until needed.
|
||||
func (c *Client) handleForwards() {
|
||||
go c.forwards.handleChannels(c.HandleChannelOpen("forwarded-tcpip"))
|
||||
go c.forwards.handleChannels(c.HandleChannelOpen("forwarded-streamlocal@openssh.com"))
|
||||
}
|
||||
|
||||
// ListenTCP requests the remote peer open a listening socket
|
||||
// on laddr. Incoming connections will be available by calling
|
||||
// Accept on the returned net.Listener.
|
||||
func (c *Client) ListenTCP(laddr *net.TCPAddr) (net.Listener, error) {
|
||||
c.handleForwardsOnce.Do(c.handleForwards)
|
||||
if laddr.Port == 0 && isBrokenOpenSSHVersion(string(c.ServerVersion())) {
|
||||
return c.autoPortListenWorkaround(laddr)
|
||||
}
|
||||
|
||||
8
vendor/golang.org/x/crypto/ssh/terminal/terminal_test.go
generated
vendored
8
vendor/golang.org/x/crypto/ssh/terminal/terminal_test.go
generated
vendored
@@ -2,12 +2,15 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build darwin dragonfly freebsd linux,!appengine netbsd openbsd windows plan9 solaris
|
||||
|
||||
package terminal
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"os"
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@@ -324,6 +327,11 @@ func TestMakeRawState(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get terminal state from GetState: %s", err)
|
||||
}
|
||||
|
||||
if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") {
|
||||
t.Skip("MakeRaw not allowed on iOS; skipping test")
|
||||
}
|
||||
|
||||
defer Restore(fd, st)
|
||||
raw, err := MakeRaw(fd)
|
||||
if err != nil {
|
||||
|
||||
7
vendor/golang.org/x/crypto/ssh/test/test_unix_test.go
generated
vendored
7
vendor/golang.org/x/crypto/ssh/test/test_unix_test.go
generated
vendored
@@ -302,6 +302,13 @@ func newServerForConfig(t *testing.T, config string, configVars map[string]strin
|
||||
if testing.Short() {
|
||||
t.Skip("skipping test due to -short")
|
||||
}
|
||||
u, err := user.Current()
|
||||
if err != nil {
|
||||
t.Fatalf("user.Current: %v", err)
|
||||
}
|
||||
if u.Name == "root" {
|
||||
t.Skip("skipping test because current user is root")
|
||||
}
|
||||
dir, err := ioutil.TempDir("", "sshtest")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
||||
8
vendor/golang.org/x/crypto/xts/xts.go
generated
vendored
8
vendor/golang.org/x/crypto/xts/xts.go
generated
vendored
@@ -25,6 +25,8 @@ import (
|
||||
"crypto/cipher"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
|
||||
"golang.org/x/crypto/internal/subtle"
|
||||
)
|
||||
|
||||
// Cipher contains an expanded key structure. It doesn't contain mutable state
|
||||
@@ -64,6 +66,9 @@ func (c *Cipher) Encrypt(ciphertext, plaintext []byte, sectorNum uint64) {
|
||||
if len(plaintext)%blockSize != 0 {
|
||||
panic("xts: plaintext is not a multiple of the block size")
|
||||
}
|
||||
if subtle.InexactOverlap(ciphertext[:len(plaintext)], plaintext) {
|
||||
panic("xts: invalid buffer overlap")
|
||||
}
|
||||
|
||||
var tweak [blockSize]byte
|
||||
binary.LittleEndian.PutUint64(tweak[:8], sectorNum)
|
||||
@@ -95,6 +100,9 @@ func (c *Cipher) Decrypt(plaintext, ciphertext []byte, sectorNum uint64) {
|
||||
if len(ciphertext)%blockSize != 0 {
|
||||
panic("xts: ciphertext is not a multiple of the block size")
|
||||
}
|
||||
if subtle.InexactOverlap(plaintext[:len(ciphertext)], ciphertext) {
|
||||
panic("xts: invalid buffer overlap")
|
||||
}
|
||||
|
||||
var tweak [blockSize]byte
|
||||
binary.LittleEndian.PutUint64(tweak[:8], sectorNum)
|
||||
|
||||
144
vendor/golang.org/x/net/dns/dnsmessage/message.go
generated
vendored
144
vendor/golang.org/x/net/dns/dnsmessage/message.go
generated
vendored
@@ -5,6 +5,9 @@
|
||||
// Package dnsmessage provides a mostly RFC 1035 compliant implementation of
|
||||
// DNS message packing and unpacking.
|
||||
//
|
||||
// The package also supports messages with Extension Mechanisms for DNS
|
||||
// (EDNS(0)) as defined in RFC 6891.
|
||||
//
|
||||
// This implementation is designed to minimize heap allocations and avoid
|
||||
// unnecessary packing and unpacking as much as possible.
|
||||
package dnsmessage
|
||||
@@ -39,6 +42,7 @@ const (
|
||||
TypeTXT Type = 16
|
||||
TypeAAAA Type = 28
|
||||
TypeSRV Type = 33
|
||||
TypeOPT Type = 41
|
||||
|
||||
// Question.Type
|
||||
TypeWKS Type = 11
|
||||
@@ -802,6 +806,24 @@ func (p *Parser) AAAAResource() (AAAAResource, error) {
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// OPTResource parses a single OPTResource.
|
||||
//
|
||||
// One of the XXXHeader methods must have been called before calling this
|
||||
// method.
|
||||
func (p *Parser) OPTResource() (OPTResource, error) {
|
||||
if !p.resHeaderValid || p.resHeader.Type != TypeOPT {
|
||||
return OPTResource{}, ErrNotStarted
|
||||
}
|
||||
r, err := unpackOPTResource(p.msg, p.off, p.resHeader.Length)
|
||||
if err != nil {
|
||||
return OPTResource{}, err
|
||||
}
|
||||
p.off += int(p.resHeader.Length)
|
||||
p.resHeaderValid = false
|
||||
p.index++
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// Unpack parses a full Message.
|
||||
func (m *Message) Unpack(msg []byte) error {
|
||||
var p Parser
|
||||
@@ -1278,6 +1300,30 @@ func (b *Builder) AAAAResource(h ResourceHeader, r AAAAResource) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// OPTResource adds a single OPTResource.
|
||||
func (b *Builder) OPTResource(h ResourceHeader, r OPTResource) error {
|
||||
if err := b.checkResourceSection(); err != nil {
|
||||
return err
|
||||
}
|
||||
h.Type = r.realType()
|
||||
msg, length, err := h.pack(b.msg, b.compression, b.start)
|
||||
if err != nil {
|
||||
return &nestedError{"ResourceHeader", err}
|
||||
}
|
||||
preLen := len(msg)
|
||||
if msg, err = r.pack(msg, b.compression, b.start); err != nil {
|
||||
return &nestedError{"OPTResource body", err}
|
||||
}
|
||||
if err := h.fixLen(msg, length, preLen); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := b.incrementSectionCount(); err != nil {
|
||||
return err
|
||||
}
|
||||
b.msg = msg
|
||||
return nil
|
||||
}
|
||||
|
||||
// Finish ends message building and generates a binary message.
|
||||
func (b *Builder) Finish() ([]byte, error) {
|
||||
if b.section < sectionHeader {
|
||||
@@ -1366,6 +1412,44 @@ func (h *ResourceHeader) fixLen(msg []byte, length []byte, preLen int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// EDNS(0) wire costants.
|
||||
const (
|
||||
edns0Version = 0
|
||||
|
||||
edns0DNSSECOK = 0x00008000
|
||||
ednsVersionMask = 0x00ff0000
|
||||
edns0DNSSECOKMask = 0x00ff8000
|
||||
)
|
||||
|
||||
// SetEDNS0 configures h for EDNS(0).
|
||||
//
|
||||
// The provided extRCode must be an extedned RCode.
|
||||
func (h *ResourceHeader) SetEDNS0(udpPayloadLen int, extRCode RCode, dnssecOK bool) error {
|
||||
h.Name = Name{Data: [nameLen]byte{'.'}, Length: 1} // RFC 6891 section 6.1.2
|
||||
h.Type = TypeOPT
|
||||
h.Class = Class(udpPayloadLen)
|
||||
h.TTL = uint32(extRCode) >> 4 << 24
|
||||
if dnssecOK {
|
||||
h.TTL |= edns0DNSSECOK
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DNSSECAllowed reports whether the DNSSEC OK bit is set.
|
||||
func (h *ResourceHeader) DNSSECAllowed() bool {
|
||||
return h.TTL&edns0DNSSECOKMask == edns0DNSSECOK // RFC 6891 section 6.1.3
|
||||
}
|
||||
|
||||
// ExtendedRCode returns an extended RCode.
|
||||
//
|
||||
// The provided rcode must be the RCode in DNS message header.
|
||||
func (h *ResourceHeader) ExtendedRCode(rcode RCode) RCode {
|
||||
if h.TTL&ednsVersionMask == edns0Version { // RFC 6891 section 6.1.3
|
||||
return RCode(h.TTL>>24<<4) | rcode
|
||||
}
|
||||
return rcode
|
||||
}
|
||||
|
||||
func skipResource(msg []byte, off int) (int, error) {
|
||||
newOff, err := skipName(msg, off)
|
||||
if err != nil {
|
||||
@@ -1794,6 +1878,11 @@ func unpackResourceBody(msg []byte, off int, hdr ResourceHeader) (ResourceBody,
|
||||
rb, err = unpackSRVResource(msg, off)
|
||||
r = &rb
|
||||
name = "SRV"
|
||||
case TypeOPT:
|
||||
var rb OPTResource
|
||||
rb, err = unpackOPTResource(msg, off, hdr.Length)
|
||||
r = &rb
|
||||
name = "OPT"
|
||||
}
|
||||
if err != nil {
|
||||
return nil, off, &nestedError{name + " record", err}
|
||||
@@ -2101,3 +2190,58 @@ func unpackAAAAResource(msg []byte, off int) (AAAAResource, error) {
|
||||
}
|
||||
return AAAAResource{aaaa}, nil
|
||||
}
|
||||
|
||||
// An OPTResource is an OPT pseudo Resource record.
|
||||
//
|
||||
// The pseudo resource record is part of the extension mechanisms for DNS
|
||||
// as defined in RFC 6891.
|
||||
type OPTResource struct {
|
||||
Options []Option
|
||||
}
|
||||
|
||||
// An Option represents a DNS message option within OPTResource.
|
||||
//
|
||||
// The message option is part of the extension mechanisms for DNS as
|
||||
// defined in RFC 6891.
|
||||
type Option struct {
|
||||
Code uint16 // option code
|
||||
Data []byte
|
||||
}
|
||||
|
||||
func (r *OPTResource) realType() Type {
|
||||
return TypeOPT
|
||||
}
|
||||
|
||||
func (r *OPTResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
|
||||
for _, opt := range r.Options {
|
||||
msg = packUint16(msg, opt.Code)
|
||||
l := uint16(len(opt.Data))
|
||||
msg = packUint16(msg, l)
|
||||
msg = packBytes(msg, opt.Data)
|
||||
}
|
||||
return msg, nil
|
||||
}
|
||||
|
||||
func unpackOPTResource(msg []byte, off int, length uint16) (OPTResource, error) {
|
||||
var opts []Option
|
||||
for oldOff := off; off < oldOff+int(length); {
|
||||
var err error
|
||||
var o Option
|
||||
o.Code, off, err = unpackUint16(msg, off)
|
||||
if err != nil {
|
||||
return OPTResource{}, &nestedError{"Code", err}
|
||||
}
|
||||
var l uint16
|
||||
l, off, err = unpackUint16(msg, off)
|
||||
if err != nil {
|
||||
return OPTResource{}, &nestedError{"Data", err}
|
||||
}
|
||||
o.Data = make([]byte, l)
|
||||
if copy(o.Data, msg[off:]) != int(l) {
|
||||
return OPTResource{}, &nestedError{"Data", errCalcLen}
|
||||
}
|
||||
off += int(l)
|
||||
opts = append(opts, o)
|
||||
}
|
||||
return OPTResource{opts}, nil
|
||||
}
|
||||
|
||||
359
vendor/golang.org/x/net/dns/dnsmessage/message_test.go
generated
vendored
359
vendor/golang.org/x/net/dns/dnsmessage/message_test.go
generated
vendored
@@ -20,6 +20,14 @@ func mustNewName(name string) Name {
|
||||
return n
|
||||
}
|
||||
|
||||
func mustEDNS0ResourceHeader(l int, extrc RCode, do bool) ResourceHeader {
|
||||
h := ResourceHeader{Class: ClassINET}
|
||||
if err := h.SetEDNS0(l, extrc, do); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
||||
func (m *Message) String() string {
|
||||
s := fmt.Sprintf("Message: %#v\n", &m.Header)
|
||||
if len(m.Questions) > 0 {
|
||||
@@ -65,7 +73,7 @@ func TestQuestionPackUnpack(t *testing.T) {
|
||||
}
|
||||
buf, err := want.pack(make([]byte, 1, 50), map[string]int{}, 1)
|
||||
if err != nil {
|
||||
t.Fatal("Packing failed:", err)
|
||||
t.Fatal("Question.pack() =", err)
|
||||
}
|
||||
var p Parser
|
||||
p.msg = buf
|
||||
@@ -74,13 +82,13 @@ func TestQuestionPackUnpack(t *testing.T) {
|
||||
p.off = 1
|
||||
got, err := p.Question()
|
||||
if err != nil {
|
||||
t.Fatalf("Unpacking failed: %v\n%s", err, string(buf[1:]))
|
||||
t.Fatalf("Parser{%q}.Question() = %v", string(buf[1:]), err)
|
||||
}
|
||||
if p.off != len(buf) {
|
||||
t.Errorf("Unpacked different amount than packed: got n = %d, want = %d", p.off, len(buf))
|
||||
t.Errorf("unpacked different amount than packed: got = %d, want = %d", p.off, len(buf))
|
||||
}
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Errorf("Got = %+v, want = %+v", got, want)
|
||||
t.Errorf("got from Parser.Question() = %+v, want = %+v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,11 +108,11 @@ func TestName(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
n, err := NewName(test)
|
||||
if err != nil {
|
||||
t.Errorf("Creating name for %q: %v", test, err)
|
||||
t.Errorf("NewName(%q) = %v", test, err)
|
||||
continue
|
||||
}
|
||||
if ns := n.String(); ns != test {
|
||||
t.Errorf("Got %#v.String() = %q, want = %q", n, ns, test)
|
||||
t.Errorf("got %#v.String() = %q, want = %q", n, ns, test)
|
||||
continue
|
||||
}
|
||||
}
|
||||
@@ -132,7 +140,7 @@ func TestNamePackUnpack(t *testing.T) {
|
||||
want := mustNewName(test.want)
|
||||
buf, err := in.pack(make([]byte, 0, 30), map[string]int{}, 0)
|
||||
if err != test.err {
|
||||
t.Errorf("Packing of %q: got err = %v, want err = %v", test.in, err, test.err)
|
||||
t.Errorf("got %q.pack() = %v, want = %v", test.in, err, test.err)
|
||||
continue
|
||||
}
|
||||
if test.err != nil {
|
||||
@@ -141,19 +149,19 @@ func TestNamePackUnpack(t *testing.T) {
|
||||
var got Name
|
||||
n, err := got.unpack(buf, 0)
|
||||
if err != nil {
|
||||
t.Errorf("Unpacking for %q failed: %v", test.in, err)
|
||||
t.Errorf("%q.unpack() = %v", test.in, err)
|
||||
continue
|
||||
}
|
||||
if n != len(buf) {
|
||||
t.Errorf(
|
||||
"Unpacked different amount than packed for %q: got n = %d, want = %d",
|
||||
"unpacked different amount than packed for %q: got = %d, want = %d",
|
||||
test.in,
|
||||
n,
|
||||
len(buf),
|
||||
)
|
||||
}
|
||||
if got != want {
|
||||
t.Errorf("Unpacking packing of %q: got = %#v, want = %#v", test.in, got, want)
|
||||
t.Errorf("unpacking packing of %q: got = %#v, want = %#v", test.in, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -163,20 +171,20 @@ func TestIncompressibleName(t *testing.T) {
|
||||
compression := map[string]int{}
|
||||
buf, err := name.pack(make([]byte, 0, 100), compression, 0)
|
||||
if err != nil {
|
||||
t.Fatal("First packing failed:", err)
|
||||
t.Fatal("first Name.pack() =", err)
|
||||
}
|
||||
buf, err = name.pack(buf, compression, 0)
|
||||
if err != nil {
|
||||
t.Fatal("Second packing failed:", err)
|
||||
t.Fatal("second Name.pack() =", err)
|
||||
}
|
||||
var n1 Name
|
||||
off, err := n1.unpackCompressed(buf, 0, false /* allowCompression */)
|
||||
if err != nil {
|
||||
t.Fatal("Unpacking incompressible name without pointers failed:", err)
|
||||
t.Fatal("unpacking incompressible name without pointers failed:", err)
|
||||
}
|
||||
var n2 Name
|
||||
if _, err := n2.unpackCompressed(buf, off, false /* allowCompression */); err != errCompressedSRV {
|
||||
t.Errorf("Unpacking compressed incompressible name with pointers: got err = %v, want = %v", err, errCompressedSRV)
|
||||
t.Errorf("unpacking compressed incompressible name with pointers: got %v, want = %v", err, errCompressedSRV)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,7 +207,7 @@ func TestHeaderUnpackError(t *testing.T) {
|
||||
for _, want := range wants {
|
||||
n, err := h.unpack(buf, 0)
|
||||
if n != 0 || !checkErrorPrefix(err, want) {
|
||||
t.Errorf("got h.unpack([%d]byte, 0) = %d, %v, want = 0, %s", len(buf), n, err, want)
|
||||
t.Errorf("got header.unpack([%d]byte, 0) = %d, %v, want = 0, %s", len(buf), n, err, want)
|
||||
}
|
||||
buf = append(buf, 0, 0)
|
||||
}
|
||||
@@ -211,7 +219,7 @@ func TestParserStart(t *testing.T) {
|
||||
for i := 0; i <= 1; i++ {
|
||||
_, err := p.Start([]byte{})
|
||||
if !checkErrorPrefix(err, want) {
|
||||
t.Errorf("got p.Start(nil) = _, %v, want = _, %s", err, want)
|
||||
t.Errorf("got Parser.Start(nil) = _, %v, want = _, %s", err, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -234,7 +242,7 @@ func TestResourceNotStarted(t *testing.T) {
|
||||
|
||||
for _, test := range tests {
|
||||
if err := test.fn(&Parser{}); err != ErrNotStarted {
|
||||
t.Errorf("got _, %v = p.%s(), want = _, %v", err, test.name, ErrNotStarted)
|
||||
t.Errorf("got Parser.%s() = _ , %v, want = _, %v", test.name, err, ErrNotStarted)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -258,15 +266,15 @@ func TestDNSPackUnpack(t *testing.T) {
|
||||
for i, want := range wants {
|
||||
b, err := want.Pack()
|
||||
if err != nil {
|
||||
t.Fatalf("%d: packing failed: %v", i, err)
|
||||
t.Fatalf("%d: Message.Pack() = %v", i, err)
|
||||
}
|
||||
var got Message
|
||||
err = got.Unpack(b)
|
||||
if err != nil {
|
||||
t.Fatalf("%d: unpacking failed: %v", i, err)
|
||||
t.Fatalf("%d: Message.Unapck() = %v", i, err)
|
||||
}
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Errorf("%d: got = %+v, want = %+v", i, &got, &want)
|
||||
t.Errorf("%d: Message.Pack/Unpack() roundtrip: got = %+v, want = %+v", i, &got, &want)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -291,16 +299,16 @@ func TestDNSAppendPackUnpack(t *testing.T) {
|
||||
b := make([]byte, 2, 514)
|
||||
b, err := want.AppendPack(b)
|
||||
if err != nil {
|
||||
t.Fatalf("%d: packing failed: %v", i, err)
|
||||
t.Fatalf("%d: Message.AppendPack() = %v", i, err)
|
||||
}
|
||||
b = b[2:]
|
||||
var got Message
|
||||
err = got.Unpack(b)
|
||||
if err != nil {
|
||||
t.Fatalf("%d: unpacking failed: %v", i, err)
|
||||
t.Fatalf("%d: Message.Unapck() = %v", i, err)
|
||||
}
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Errorf("%d: got = %+v, want = %+v", i, &got, &want)
|
||||
t.Errorf("%d: Message.AppendPack/Unpack() roundtrip: got = %+v, want = %+v", i, &got, &want)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -309,11 +317,11 @@ func TestSkipAll(t *testing.T) {
|
||||
msg := largeTestMsg()
|
||||
buf, err := msg.Pack()
|
||||
if err != nil {
|
||||
t.Fatal("Packing large test message:", err)
|
||||
t.Fatal("Message.Pack() =", err)
|
||||
}
|
||||
var p Parser
|
||||
if _, err := p.Start(buf); err != nil {
|
||||
t.Fatal(err)
|
||||
t.Fatal("Parser.Start(non-nil) =", err)
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
@@ -328,7 +336,7 @@ func TestSkipAll(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
for i := 1; i <= 3; i++ {
|
||||
if err := test.f(); err != nil {
|
||||
t.Errorf("Call #%d to %s(): %v", i, test.name, err)
|
||||
t.Errorf("%d: Parser.%s() = %v", i, test.name, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -339,11 +347,11 @@ func TestSkipEach(t *testing.T) {
|
||||
|
||||
buf, err := msg.Pack()
|
||||
if err != nil {
|
||||
t.Fatal("Packing test message:", err)
|
||||
t.Fatal("Message.Pack() =", err)
|
||||
}
|
||||
var p Parser
|
||||
if _, err := p.Start(buf); err != nil {
|
||||
t.Fatal(err)
|
||||
t.Fatal("Parser.Start(non-nil) =", err)
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
@@ -357,10 +365,10 @@ func TestSkipEach(t *testing.T) {
|
||||
}
|
||||
for _, test := range tests {
|
||||
if err := test.f(); err != nil {
|
||||
t.Errorf("First call: got %s() = %v, want = %v", test.name, err, nil)
|
||||
t.Errorf("first Parser.%s() = %v, want = nil", test.name, err)
|
||||
}
|
||||
if err := test.f(); err != ErrSectionDone {
|
||||
t.Errorf("Second call: got %s() = %v, want = %v", test.name, err, ErrSectionDone)
|
||||
t.Errorf("second Parser.%s() = %v, want = %v", test.name, err, ErrSectionDone)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -370,11 +378,11 @@ func TestSkipAfterRead(t *testing.T) {
|
||||
|
||||
buf, err := msg.Pack()
|
||||
if err != nil {
|
||||
t.Fatal("Packing test message:", err)
|
||||
t.Fatal("Message.Pack() =", err)
|
||||
}
|
||||
var p Parser
|
||||
if _, err := p.Start(buf); err != nil {
|
||||
t.Fatal(err)
|
||||
t.Fatal("Parser.Srart(non-nil) =", err)
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
@@ -389,10 +397,10 @@ func TestSkipAfterRead(t *testing.T) {
|
||||
}
|
||||
for _, test := range tests {
|
||||
if err := test.read(); err != nil {
|
||||
t.Errorf("Got %s() = _, %v, want = _, %v", test.name, err, nil)
|
||||
t.Errorf("got Parser.%s() = _, %v, want = _, nil", test.name, err)
|
||||
}
|
||||
if err := test.skip(); err != ErrSectionDone {
|
||||
t.Errorf("Got Skip%s() = %v, want = %v", test.name, err, ErrSectionDone)
|
||||
t.Errorf("got Parser.Skip%s() = %v, want = %v", test.name, err, ErrSectionDone)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -411,7 +419,7 @@ func TestSkipNotStarted(t *testing.T) {
|
||||
}
|
||||
for _, test := range tests {
|
||||
if err := test.f(); err != ErrNotStarted {
|
||||
t.Errorf("Got %s() = %v, want = %v", test.name, err, ErrNotStarted)
|
||||
t.Errorf("got Parser.%s() = %v, want = %v", test.name, err, ErrNotStarted)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -455,7 +463,7 @@ func TestTooManyRecords(t *testing.T) {
|
||||
|
||||
for _, test := range tests {
|
||||
if _, got := test.msg.Pack(); got != test.want {
|
||||
t.Errorf("Packing %d %s: got = %v, want = %v", recs, test.name, got, test.want)
|
||||
t.Errorf("got Message.Pack() for %d %s = %v, want = %v", recs, test.name, got, test.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -479,30 +487,30 @@ func TestVeryLongTxt(t *testing.T) {
|
||||
}
|
||||
buf, err := want.pack(make([]byte, 0, 8000), map[string]int{}, 0)
|
||||
if err != nil {
|
||||
t.Fatal("Packing failed:", err)
|
||||
t.Fatal("Resource.pack() =", err)
|
||||
}
|
||||
var got Resource
|
||||
off, err := got.Header.unpack(buf, 0)
|
||||
if err != nil {
|
||||
t.Fatal("Unpacking ResourceHeader failed:", err)
|
||||
t.Fatal("ResourceHeader.unpack() =", err)
|
||||
}
|
||||
body, n, err := unpackResourceBody(buf, off, got.Header)
|
||||
if err != nil {
|
||||
t.Fatal("Unpacking failed:", err)
|
||||
t.Fatal("unpackResourceBody() =", err)
|
||||
}
|
||||
got.Body = body
|
||||
if n != len(buf) {
|
||||
t.Errorf("Unpacked different amount than packed: got n = %d, want = %d", n, len(buf))
|
||||
t.Errorf("unpacked different amount than packed: got = %d, want = %d", n, len(buf))
|
||||
}
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Errorf("Got = %#v, want = %#v", got, want)
|
||||
t.Errorf("Resource.pack/unpack() roundtrip: got = %#v, want = %#v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTooLongTxt(t *testing.T) {
|
||||
rb := TXTResource{[]string{strings.Repeat(".", 256)}}
|
||||
if _, err := rb.pack(make([]byte, 0, 8000), map[string]int{}, 0); err != errStringTooLong {
|
||||
t.Errorf("Packing TXTRecord with 256 character string: got err = %v, want = %v", err, errStringTooLong)
|
||||
t.Errorf("packing TXTResource with 256 character string: got err = %v, want = %v", err, errStringTooLong)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -516,13 +524,13 @@ func TestStartAppends(t *testing.T) {
|
||||
|
||||
buf, err := b.Finish()
|
||||
if err != nil {
|
||||
t.Fatal("Building failed:", err)
|
||||
t.Fatal("Builder.Finish() =", err)
|
||||
}
|
||||
if got, want := len(buf), headerLen+2; got != want {
|
||||
t.Errorf("Got len(buf} = %d, want = %d", got, want)
|
||||
t.Errorf("got len(buf) = %d, want = %d", got, want)
|
||||
}
|
||||
if string(buf[:2]) != string(wantBuf) {
|
||||
t.Errorf("Original data not preserved, got = %v, want = %v", buf[:2], wantBuf)
|
||||
t.Errorf("original data not preserved, got = %#v, want = %#v", buf[:2], wantBuf)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -549,7 +557,7 @@ func TestStartError(t *testing.T) {
|
||||
for _, env := range envs {
|
||||
for _, test := range tests {
|
||||
if got := test.fn(env.fn()); got != env.want {
|
||||
t.Errorf("got Builder{%s}.Start%s = %v, want = %v", env.name, test.name, got, env.want)
|
||||
t.Errorf("got Builder{%s}.Start%s() = %v, want = %v", env.name, test.name, got, env.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -569,6 +577,7 @@ func TestBuilderResourceError(t *testing.T) {
|
||||
{"SRVResource", func(b *Builder) error { return b.SRVResource(ResourceHeader{}, SRVResource{}) }},
|
||||
{"AResource", func(b *Builder) error { return b.AResource(ResourceHeader{}, AResource{}) }},
|
||||
{"AAAAResource", func(b *Builder) error { return b.AAAAResource(ResourceHeader{}, AAAAResource{}) }},
|
||||
{"OPTResource", func(b *Builder) error { return b.OPTResource(ResourceHeader{}, OPTResource{}) }},
|
||||
}
|
||||
|
||||
envs := []struct {
|
||||
@@ -585,7 +594,7 @@ func TestBuilderResourceError(t *testing.T) {
|
||||
for _, env := range envs {
|
||||
for _, test := range tests {
|
||||
if got := test.fn(env.fn()); got != env.want {
|
||||
t.Errorf("got Builder{%s}.%s = %v, want = %v", env.name, test.name, got, env.want)
|
||||
t.Errorf("got Builder{%s}.%s() = %v, want = %v", env.name, test.name, got, env.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -595,7 +604,7 @@ func TestFinishError(t *testing.T) {
|
||||
var b Builder
|
||||
want := ErrNotStarted
|
||||
if _, got := b.Finish(); got != want {
|
||||
t.Errorf("got Builder{}.Finish() = %v, want = %v", got, want)
|
||||
t.Errorf("got Builder.Finish() = %v, want = %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -603,89 +612,96 @@ func TestBuilder(t *testing.T) {
|
||||
msg := largeTestMsg()
|
||||
want, err := msg.Pack()
|
||||
if err != nil {
|
||||
t.Fatal("Packing without builder:", err)
|
||||
t.Fatal("Message.Pack() =", err)
|
||||
}
|
||||
|
||||
b := NewBuilder(nil, msg.Header)
|
||||
b.EnableCompression()
|
||||
|
||||
if err := b.StartQuestions(); err != nil {
|
||||
t.Fatal("b.StartQuestions():", err)
|
||||
t.Fatal("Builder.StartQuestions() =", err)
|
||||
}
|
||||
for _, q := range msg.Questions {
|
||||
if err := b.Question(q); err != nil {
|
||||
t.Fatalf("b.Question(%#v): %v", q, err)
|
||||
t.Fatalf("Builder.Question(%#v) = %v", q, err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := b.StartAnswers(); err != nil {
|
||||
t.Fatal("b.StartAnswers():", err)
|
||||
t.Fatal("Builder.StartAnswers() =", err)
|
||||
}
|
||||
for _, a := range msg.Answers {
|
||||
switch a.Header.Type {
|
||||
case TypeA:
|
||||
if err := b.AResource(a.Header, *a.Body.(*AResource)); err != nil {
|
||||
t.Fatalf("b.AResource(%#v): %v", a, err)
|
||||
t.Fatalf("Builder.AResource(%#v) = %v", a, err)
|
||||
}
|
||||
case TypeNS:
|
||||
if err := b.NSResource(a.Header, *a.Body.(*NSResource)); err != nil {
|
||||
t.Fatalf("b.NSResource(%#v): %v", a, err)
|
||||
t.Fatalf("Builder.NSResource(%#v) = %v", a, err)
|
||||
}
|
||||
case TypeCNAME:
|
||||
if err := b.CNAMEResource(a.Header, *a.Body.(*CNAMEResource)); err != nil {
|
||||
t.Fatalf("b.CNAMEResource(%#v): %v", a, err)
|
||||
t.Fatalf("Builder.CNAMEResource(%#v) = %v", a, err)
|
||||
}
|
||||
case TypeSOA:
|
||||
if err := b.SOAResource(a.Header, *a.Body.(*SOAResource)); err != nil {
|
||||
t.Fatalf("b.SOAResource(%#v): %v", a, err)
|
||||
t.Fatalf("Builder.SOAResource(%#v) = %v", a, err)
|
||||
}
|
||||
case TypePTR:
|
||||
if err := b.PTRResource(a.Header, *a.Body.(*PTRResource)); err != nil {
|
||||
t.Fatalf("b.PTRResource(%#v): %v", a, err)
|
||||
t.Fatalf("Builder.PTRResource(%#v) = %v", a, err)
|
||||
}
|
||||
case TypeMX:
|
||||
if err := b.MXResource(a.Header, *a.Body.(*MXResource)); err != nil {
|
||||
t.Fatalf("b.MXResource(%#v): %v", a, err)
|
||||
t.Fatalf("Builder.MXResource(%#v) = %v", a, err)
|
||||
}
|
||||
case TypeTXT:
|
||||
if err := b.TXTResource(a.Header, *a.Body.(*TXTResource)); err != nil {
|
||||
t.Fatalf("b.TXTResource(%#v): %v", a, err)
|
||||
t.Fatalf("Builder.TXTResource(%#v) = %v", a, err)
|
||||
}
|
||||
case TypeAAAA:
|
||||
if err := b.AAAAResource(a.Header, *a.Body.(*AAAAResource)); err != nil {
|
||||
t.Fatalf("b.AAAAResource(%#v): %v", a, err)
|
||||
t.Fatalf("Builder.AAAAResource(%#v) = %v", a, err)
|
||||
}
|
||||
case TypeSRV:
|
||||
if err := b.SRVResource(a.Header, *a.Body.(*SRVResource)); err != nil {
|
||||
t.Fatalf("b.SRVResource(%#v): %v", a, err)
|
||||
t.Fatalf("Builder.SRVResource(%#v) = %v", a, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := b.StartAuthorities(); err != nil {
|
||||
t.Fatal("b.StartAuthorities():", err)
|
||||
t.Fatal("Builder.StartAuthorities() =", err)
|
||||
}
|
||||
for _, a := range msg.Authorities {
|
||||
if err := b.NSResource(a.Header, *a.Body.(*NSResource)); err != nil {
|
||||
t.Fatalf("b.NSResource(%#v): %v", a, err)
|
||||
t.Fatalf("Builder.NSResource(%#v) = %v", a, err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := b.StartAdditionals(); err != nil {
|
||||
t.Fatal("b.StartAdditionals():", err)
|
||||
t.Fatal("Builder.StartAdditionals() =", err)
|
||||
}
|
||||
for _, a := range msg.Additionals {
|
||||
if err := b.TXTResource(a.Header, *a.Body.(*TXTResource)); err != nil {
|
||||
t.Fatalf("b.TXTResource(%#v): %v", a, err)
|
||||
switch a.Body.(type) {
|
||||
case *TXTResource:
|
||||
if err := b.TXTResource(a.Header, *a.Body.(*TXTResource)); err != nil {
|
||||
t.Fatalf("Builder.TXTResource(%#v) = %v", a, err)
|
||||
}
|
||||
case *OPTResource:
|
||||
if err := b.OPTResource(a.Header, *a.Body.(*OPTResource)); err != nil {
|
||||
t.Fatalf("Builder.OPTResource(%#v) = %v", a, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
got, err := b.Finish()
|
||||
if err != nil {
|
||||
t.Fatal("b.Finish():", err)
|
||||
t.Fatal("Builder.Finish() =", err)
|
||||
}
|
||||
if !bytes.Equal(got, want) {
|
||||
t.Fatalf("Got from Builder: %#v\nwant = %#v", got, want)
|
||||
t.Fatalf("got from Builder.Finish() = %#v\nwant = %#v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -740,7 +756,146 @@ func TestResourcePack(t *testing.T) {
|
||||
} {
|
||||
_, err := tt.m.Pack()
|
||||
if !reflect.DeepEqual(err, tt.err) {
|
||||
t.Errorf("got %v for %v; want %v", err, tt.m, tt.err)
|
||||
t.Errorf("got Message{%v}.Pack() = %v, want %v", tt.m, err, tt.err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestOptionPackUnpack(t *testing.T) {
|
||||
for _, tt := range []struct {
|
||||
name string
|
||||
w []byte // wire format of m.Additionals
|
||||
m Message
|
||||
dnssecOK bool
|
||||
extRCode RCode
|
||||
}{
|
||||
{
|
||||
name: "without EDNS(0) options",
|
||||
w: []byte{
|
||||
0x00, 0x00, 0x29, 0x10, 0x00, 0xfe, 0x00, 0x80,
|
||||
0x00, 0x00, 0x00,
|
||||
},
|
||||
m: Message{
|
||||
Header: Header{RCode: RCodeFormatError},
|
||||
Questions: []Question{
|
||||
{
|
||||
Name: mustNewName("."),
|
||||
Type: TypeA,
|
||||
Class: ClassINET,
|
||||
},
|
||||
},
|
||||
Additionals: []Resource{
|
||||
{
|
||||
mustEDNS0ResourceHeader(4096, 0xfe0|RCodeFormatError, true),
|
||||
&OPTResource{},
|
||||
},
|
||||
},
|
||||
},
|
||||
dnssecOK: true,
|
||||
extRCode: 0xfe0 | RCodeFormatError,
|
||||
},
|
||||
{
|
||||
name: "with EDNS(0) options",
|
||||
w: []byte{
|
||||
0x00, 0x00, 0x29, 0x10, 0x00, 0xff, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x02, 0x00,
|
||||
0x00, 0x00, 0x0b, 0x00, 0x02, 0x12, 0x34,
|
||||
},
|
||||
m: Message{
|
||||
Header: Header{RCode: RCodeServerFailure},
|
||||
Questions: []Question{
|
||||
{
|
||||
Name: mustNewName("."),
|
||||
Type: TypeAAAA,
|
||||
Class: ClassINET,
|
||||
},
|
||||
},
|
||||
Additionals: []Resource{
|
||||
{
|
||||
mustEDNS0ResourceHeader(4096, 0xff0|RCodeServerFailure, false),
|
||||
&OPTResource{
|
||||
Options: []Option{
|
||||
{
|
||||
Code: 12, // see RFC 7828
|
||||
Data: []byte{0x00, 0x00},
|
||||
},
|
||||
{
|
||||
Code: 11, // see RFC 7830
|
||||
Data: []byte{0x12, 0x34},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
dnssecOK: false,
|
||||
extRCode: 0xff0 | RCodeServerFailure,
|
||||
},
|
||||
{
|
||||
// Containing multiple OPT resources in a
|
||||
// message is invalid, but it's necessary for
|
||||
// protocol conformance testing.
|
||||
name: "with multiple OPT resources",
|
||||
w: []byte{
|
||||
0x00, 0x00, 0x29, 0x10, 0x00, 0xff, 0x00, 0x00,
|
||||
0x00, 0x00, 0x06, 0x00, 0x0b, 0x00, 0x02, 0x12,
|
||||
0x34, 0x00, 0x00, 0x29, 0x10, 0x00, 0xff, 0x00,
|
||||
0x00, 0x00, 0x00, 0x06, 0x00, 0x0c, 0x00, 0x02,
|
||||
0x00, 0x00,
|
||||
},
|
||||
m: Message{
|
||||
Header: Header{RCode: RCodeNameError},
|
||||
Questions: []Question{
|
||||
{
|
||||
Name: mustNewName("."),
|
||||
Type: TypeAAAA,
|
||||
Class: ClassINET,
|
||||
},
|
||||
},
|
||||
Additionals: []Resource{
|
||||
{
|
||||
mustEDNS0ResourceHeader(4096, 0xff0|RCodeNameError, false),
|
||||
&OPTResource{
|
||||
Options: []Option{
|
||||
{
|
||||
Code: 11, // see RFC 7830
|
||||
Data: []byte{0x12, 0x34},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
mustEDNS0ResourceHeader(4096, 0xff0|RCodeNameError, false),
|
||||
&OPTResource{
|
||||
Options: []Option{
|
||||
{
|
||||
Code: 12, // see RFC 7828
|
||||
Data: []byte{0x00, 0x00},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} {
|
||||
w, err := tt.m.Pack()
|
||||
if err != nil {
|
||||
t.Errorf("Message.Pack() for %s = %v", tt.name, err)
|
||||
continue
|
||||
}
|
||||
if !bytes.Equal(w[len(w)-len(tt.w):], tt.w) {
|
||||
t.Errorf("got Message.Pack() for %s = %#v, want %#v", tt.name, w[len(w)-len(tt.w):], tt.w)
|
||||
continue
|
||||
}
|
||||
var m Message
|
||||
if err := m.Unpack(w); err != nil {
|
||||
t.Errorf("Message.Unpack() for %s = %v", tt.name, err)
|
||||
continue
|
||||
}
|
||||
if !reflect.DeepEqual(m.Additionals, tt.m.Additionals) {
|
||||
t.Errorf("got Message.Pack/Unpack() roundtrip for %s = %+v, want %+v", tt.name, m, tt.m)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -790,7 +945,7 @@ func benchmarkParsingSetup() ([]byte, error) {
|
||||
|
||||
buf, err := msg.Pack()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("msg.Pack(): %v", err)
|
||||
return nil, fmt.Errorf("Message.Pack() = %v", err)
|
||||
}
|
||||
return buf, nil
|
||||
}
|
||||
@@ -798,7 +953,7 @@ func benchmarkParsingSetup() ([]byte, error) {
|
||||
func benchmarkParsing(tb testing.TB, buf []byte) {
|
||||
var p Parser
|
||||
if _, err := p.Start(buf); err != nil {
|
||||
tb.Fatal("p.Start(buf):", err)
|
||||
tb.Fatal("Parser.Start(non-nil) =", err)
|
||||
}
|
||||
|
||||
for {
|
||||
@@ -807,7 +962,7 @@ func benchmarkParsing(tb testing.TB, buf []byte) {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
tb.Fatal("p.Question():", err)
|
||||
tb.Fatal("Parser.Question() =", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -817,28 +972,32 @@ func benchmarkParsing(tb testing.TB, buf []byte) {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
panic(err)
|
||||
tb.Fatal("Parser.AnswerHeader() =", err)
|
||||
}
|
||||
|
||||
switch h.Type {
|
||||
case TypeA:
|
||||
if _, err := p.AResource(); err != nil {
|
||||
tb.Fatal("p.AResource():", err)
|
||||
tb.Fatal("Parser.AResource() =", err)
|
||||
}
|
||||
case TypeAAAA:
|
||||
if _, err := p.AAAAResource(); err != nil {
|
||||
tb.Fatal("p.AAAAResource():", err)
|
||||
tb.Fatal("Parser.AAAAResource() =", err)
|
||||
}
|
||||
case TypeCNAME:
|
||||
if _, err := p.CNAMEResource(); err != nil {
|
||||
tb.Fatal("p.CNAMEResource():", err)
|
||||
tb.Fatal("Parser.CNAMEResource() =", err)
|
||||
}
|
||||
case TypeNS:
|
||||
if _, err := p.NSResource(); err != nil {
|
||||
tb.Fatal("p.NSResource():", err)
|
||||
tb.Fatal("Parser.NSResource() =", err)
|
||||
}
|
||||
case TypeOPT:
|
||||
if _, err := p.OPTResource(); err != nil {
|
||||
tb.Fatal("Parser.OPTResource() =", err)
|
||||
}
|
||||
default:
|
||||
tb.Fatalf("unknown type: %T", h)
|
||||
tb.Fatalf("got unknown type: %T", h)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -862,7 +1021,7 @@ func TestParsingAllocs(t *testing.T) {
|
||||
}
|
||||
|
||||
if allocs := testing.AllocsPerRun(100, func() { benchmarkParsing(t, buf) }); allocs > 0.5 {
|
||||
t.Errorf("Allocations during parsing: got = %f, want ~0", allocs)
|
||||
t.Errorf("allocations during parsing: got = %f, want ~0", allocs)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -876,7 +1035,7 @@ func benchmarkBuilding(tb testing.TB, name Name, buf []byte) {
|
||||
bld := NewBuilder(buf, Header{Response: true, Authoritative: true})
|
||||
|
||||
if err := bld.StartQuestions(); err != nil {
|
||||
tb.Fatal("bld.StartQuestions():", err)
|
||||
tb.Fatal("Builder.StartQuestions() =", err)
|
||||
}
|
||||
q := Question{
|
||||
Name: name,
|
||||
@@ -884,7 +1043,7 @@ func benchmarkBuilding(tb testing.TB, name Name, buf []byte) {
|
||||
Class: ClassINET,
|
||||
}
|
||||
if err := bld.Question(q); err != nil {
|
||||
tb.Fatalf("bld.Question(%+v): %v", q, err)
|
||||
tb.Fatalf("Builder.Question(%+v) = %v", q, err)
|
||||
}
|
||||
|
||||
hdr := ResourceHeader{
|
||||
@@ -892,31 +1051,40 @@ func benchmarkBuilding(tb testing.TB, name Name, buf []byte) {
|
||||
Class: ClassINET,
|
||||
}
|
||||
if err := bld.StartAnswers(); err != nil {
|
||||
tb.Fatal("bld.StartQuestions():", err)
|
||||
tb.Fatal("Builder.StartQuestions() =", err)
|
||||
}
|
||||
|
||||
ar := AResource{[4]byte{}}
|
||||
if err := bld.AResource(hdr, ar); err != nil {
|
||||
tb.Fatalf("bld.AResource(%+v, %+v): %v", hdr, ar, err)
|
||||
tb.Fatalf("Builder.AResource(%+v, %+v) = %v", hdr, ar, err)
|
||||
}
|
||||
|
||||
aaar := AAAAResource{[16]byte{}}
|
||||
if err := bld.AAAAResource(hdr, aaar); err != nil {
|
||||
tb.Fatalf("bld.AAAAResource(%+v, %+v): %v", hdr, aaar, err)
|
||||
tb.Fatalf("Builder.AAAAResource(%+v, %+v) = %v", hdr, aaar, err)
|
||||
}
|
||||
|
||||
cnr := CNAMEResource{name}
|
||||
if err := bld.CNAMEResource(hdr, cnr); err != nil {
|
||||
tb.Fatalf("bld.CNAMEResource(%+v, %+v): %v", hdr, cnr, err)
|
||||
tb.Fatalf("Builder.CNAMEResource(%+v, %+v) = %v", hdr, cnr, err)
|
||||
}
|
||||
|
||||
nsr := NSResource{name}
|
||||
if err := bld.NSResource(hdr, nsr); err != nil {
|
||||
tb.Fatalf("bld.NSResource(%+v, %+v): %v", hdr, nsr, err)
|
||||
tb.Fatalf("Builder.NSResource(%+v, %+v) = %v", hdr, nsr, err)
|
||||
}
|
||||
|
||||
extrc := 0xfe0 | RCodeNotImplemented
|
||||
if err := (&hdr).SetEDNS0(4096, extrc, true); err != nil {
|
||||
tb.Fatalf("ResourceHeader.SetEDNS0(4096, %#x, true) = %v", extrc, err)
|
||||
}
|
||||
optr := OPTResource{}
|
||||
if err := bld.OPTResource(hdr, optr); err != nil {
|
||||
tb.Fatalf("Builder.OPTResource(%+v, %+v) = %v", hdr, optr, err)
|
||||
}
|
||||
|
||||
if _, err := bld.Finish(); err != nil {
|
||||
tb.Fatal("bld.Finish():", err)
|
||||
tb.Fatal("Builder.Finish() =", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -931,7 +1099,7 @@ func BenchmarkBuilding(b *testing.B) {
|
||||
func TestBuildingAllocs(t *testing.T) {
|
||||
name, buf := benchmarkBuildingSetup()
|
||||
if allocs := testing.AllocsPerRun(100, func() { benchmarkBuilding(t, name, buf) }); allocs > 0.5 {
|
||||
t.Errorf("Allocations during building: got = %f, want ~0", allocs)
|
||||
t.Errorf("allocations during building: got = %f, want ~0", allocs)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -986,7 +1154,7 @@ func BenchmarkPack(b *testing.B) {
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
if _, err := msg.Pack(); err != nil {
|
||||
b.Fatal(err)
|
||||
b.Fatal("Message.Pack() =", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -999,7 +1167,7 @@ func BenchmarkAppendPack(b *testing.B) {
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
if _, err := msg.AppendPack(buf[:0]); err != nil {
|
||||
b.Fatal(err)
|
||||
b.Fatal("Message.AppendPack() = ", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1132,6 +1300,17 @@ func largeTestMsg() Message {
|
||||
},
|
||||
&TXTResource{[]string{"Hamster Huey and the Gooey Kablooie"}},
|
||||
},
|
||||
{
|
||||
mustEDNS0ResourceHeader(4096, 0xfe0|RCodeSuccess, false),
|
||||
&OPTResource{
|
||||
Options: []Option{
|
||||
{
|
||||
Code: 10, // see RFC 7873
|
||||
Data: []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
4
vendor/golang.org/x/net/html/atom/gen.go
generated
vendored
4
vendor/golang.org/x/net/html/atom/gen.go
generated
vendored
@@ -306,7 +306,7 @@ func (t *table) push(i uint32, depth int) bool {
|
||||
|
||||
// The lists of element names and attribute keys were taken from
|
||||
// https://html.spec.whatwg.org/multipage/indices.html#index
|
||||
// as of the "HTML Living Standard - Last Updated 18 September 2017" version.
|
||||
// as of the "HTML Living Standard - Last Updated 16 April 2018" version.
|
||||
|
||||
// "command", "keygen" and "menuitem" have been removed from the spec,
|
||||
// but are kept here for backwards compatibility.
|
||||
@@ -701,6 +701,8 @@ var extra = []string{
|
||||
"plaintext",
|
||||
"prompt",
|
||||
"public",
|
||||
"rb",
|
||||
"rtc",
|
||||
"spacer",
|
||||
"strike",
|
||||
"svg",
|
||||
|
||||
1100
vendor/golang.org/x/net/html/atom/table.go
generated
vendored
1100
vendor/golang.org/x/net/html/atom/table.go
generated
vendored
File diff suppressed because it is too large
Load Diff
2
vendor/golang.org/x/net/html/atom/table_test.go
generated
vendored
2
vendor/golang.org/x/net/html/atom/table_test.go
generated
vendored
@@ -296,6 +296,7 @@ var testAtomList = []string{
|
||||
"public",
|
||||
"q",
|
||||
"radiogroup",
|
||||
"rb",
|
||||
"readonly",
|
||||
"referrerpolicy",
|
||||
"rel",
|
||||
@@ -305,6 +306,7 @@ var testAtomList = []string{
|
||||
"rowspan",
|
||||
"rp",
|
||||
"rt",
|
||||
"rtc",
|
||||
"ruby",
|
||||
"s",
|
||||
"samp",
|
||||
|
||||
4154
vendor/golang.org/x/net/html/entity.go
generated
vendored
4154
vendor/golang.org/x/net/html/entity.go
generated
vendored
File diff suppressed because it is too large
Load Diff
26
vendor/golang.org/x/net/html/node.go
generated
vendored
26
vendor/golang.org/x/net/html/node.go
generated
vendored
@@ -174,6 +174,16 @@ func (s *nodeStack) index(n *Node) int {
|
||||
return -1
|
||||
}
|
||||
|
||||
// contains returns whether a is within s.
|
||||
func (s *nodeStack) contains(a atom.Atom) bool {
|
||||
for _, n := range *s {
|
||||
if n.DataAtom == a {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// insert inserts a node at the given index.
|
||||
func (s *nodeStack) insert(i int, n *Node) {
|
||||
(*s) = append(*s, nil)
|
||||
@@ -192,3 +202,19 @@ func (s *nodeStack) remove(n *Node) {
|
||||
(*s)[j] = nil
|
||||
*s = (*s)[:j]
|
||||
}
|
||||
|
||||
type insertionModeStack []insertionMode
|
||||
|
||||
func (s *insertionModeStack) pop() (im insertionMode) {
|
||||
i := len(*s)
|
||||
im = (*s)[i-1]
|
||||
*s = (*s)[:i-1]
|
||||
return im
|
||||
}
|
||||
|
||||
func (s *insertionModeStack) top() insertionMode {
|
||||
if i := len(*s); i > 0 {
|
||||
return (*s)[i-1]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
285
vendor/golang.org/x/net/html/parse.go
generated
vendored
285
vendor/golang.org/x/net/html/parse.go
generated
vendored
@@ -32,6 +32,8 @@ type parser struct {
|
||||
head, form *Node
|
||||
// Other parsing state flags (section 12.2.4.5).
|
||||
scripting, framesetOK bool
|
||||
// The stack of template insertion modes
|
||||
templateStack insertionModeStack
|
||||
// im is the current insertion mode.
|
||||
im insertionMode
|
||||
// originalIM is the insertion mode to go back to after completing a text
|
||||
@@ -126,7 +128,7 @@ func (p *parser) indexOfElementInScope(s scope, matchTags ...a.Atom) int {
|
||||
return -1
|
||||
}
|
||||
case tableScope:
|
||||
if tagAtom == a.Html || tagAtom == a.Table {
|
||||
if tagAtom == a.Html || tagAtom == a.Table || tagAtom == a.Template {
|
||||
return -1
|
||||
}
|
||||
case selectScope:
|
||||
@@ -162,17 +164,17 @@ func (p *parser) clearStackToContext(s scope) {
|
||||
tagAtom := p.oe[i].DataAtom
|
||||
switch s {
|
||||
case tableScope:
|
||||
if tagAtom == a.Html || tagAtom == a.Table {
|
||||
if tagAtom == a.Html || tagAtom == a.Table || tagAtom == a.Template {
|
||||
p.oe = p.oe[:i+1]
|
||||
return
|
||||
}
|
||||
case tableRowScope:
|
||||
if tagAtom == a.Html || tagAtom == a.Tr {
|
||||
if tagAtom == a.Html || tagAtom == a.Tr || tagAtom == a.Template {
|
||||
p.oe = p.oe[:i+1]
|
||||
return
|
||||
}
|
||||
case tableBodyScope:
|
||||
if tagAtom == a.Html || tagAtom == a.Tbody || tagAtom == a.Tfoot || tagAtom == a.Thead {
|
||||
if tagAtom == a.Html || tagAtom == a.Tbody || tagAtom == a.Tfoot || tagAtom == a.Thead || tagAtom == a.Template {
|
||||
p.oe = p.oe[:i+1]
|
||||
return
|
||||
}
|
||||
@@ -183,7 +185,7 @@ func (p *parser) clearStackToContext(s scope) {
|
||||
}
|
||||
|
||||
// generateImpliedEndTags pops nodes off the stack of open elements as long as
|
||||
// the top node has a tag name of dd, dt, li, option, optgroup, p, rp, or rt.
|
||||
// the top node has a tag name of dd, dt, li, optgroup, option, p, rb, rp, rt or rtc.
|
||||
// If exceptions are specified, nodes with that name will not be popped off.
|
||||
func (p *parser) generateImpliedEndTags(exceptions ...string) {
|
||||
var i int
|
||||
@@ -192,7 +194,7 @@ loop:
|
||||
n := p.oe[i]
|
||||
if n.Type == ElementNode {
|
||||
switch n.DataAtom {
|
||||
case a.Dd, a.Dt, a.Li, a.Option, a.Optgroup, a.P, a.Rp, a.Rt:
|
||||
case a.Dd, a.Dt, a.Li, a.Optgroup, a.Option, a.P, a.Rb, a.Rp, a.Rt, a.Rtc:
|
||||
for _, except := range exceptions {
|
||||
if n.Data == except {
|
||||
break loop
|
||||
@@ -207,6 +209,27 @@ loop:
|
||||
p.oe = p.oe[:i+1]
|
||||
}
|
||||
|
||||
// generateAllImpliedEndTags pops nodes off the stack of open elements as long as
|
||||
// the top node has a tag name of caption, colgroup, dd, div, dt, li, optgroup, option, p, rb,
|
||||
// rp, rt, rtc, span, tbody, td, tfoot, th, thead or tr.
|
||||
func (p *parser) generateAllImpliedEndTags() {
|
||||
var i int
|
||||
for i = len(p.oe) - 1; i >= 0; i-- {
|
||||
n := p.oe[i]
|
||||
if n.Type == ElementNode {
|
||||
switch n.DataAtom {
|
||||
// TODO: remove this divergence from the HTML5 spec
|
||||
case a.Caption, a.Colgroup, a.Dd, a.Div, a.Dt, a.Li, a.Optgroup, a.Option, a.P, a.Rb,
|
||||
a.Rp, a.Rt, a.Rtc, a.Span, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr:
|
||||
continue
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
p.oe = p.oe[:i+1]
|
||||
}
|
||||
|
||||
// addChild adds a child node n to the top element, and pushes n onto the stack
|
||||
// of open elements if it is an element node.
|
||||
func (p *parser) addChild(n *Node) {
|
||||
@@ -236,7 +259,7 @@ func (p *parser) shouldFosterParent() bool {
|
||||
// fosterParent adds a child node according to the foster parenting rules.
|
||||
// Section 12.2.6.1, "foster parenting".
|
||||
func (p *parser) fosterParent(n *Node) {
|
||||
var table, parent, prev *Node
|
||||
var table, parent, prev, template *Node
|
||||
var i int
|
||||
for i = len(p.oe) - 1; i >= 0; i-- {
|
||||
if p.oe[i].DataAtom == a.Table {
|
||||
@@ -245,6 +268,19 @@ func (p *parser) fosterParent(n *Node) {
|
||||
}
|
||||
}
|
||||
|
||||
var j int
|
||||
for j = len(p.oe) - 1; j >= 0; j-- {
|
||||
if p.oe[j].DataAtom == a.Template {
|
||||
template = p.oe[j]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if template != nil && (table == nil || j < i) {
|
||||
template.AppendChild(n)
|
||||
return
|
||||
}
|
||||
|
||||
if table == nil {
|
||||
// The foster parent is the html element.
|
||||
parent = p.oe[0]
|
||||
@@ -415,14 +451,34 @@ func (p *parser) setOriginalIM() {
|
||||
func (p *parser) resetInsertionMode() {
|
||||
for i := len(p.oe) - 1; i >= 0; i-- {
|
||||
n := p.oe[i]
|
||||
if i == 0 && p.context != nil {
|
||||
last := i == 0
|
||||
if last && p.context != nil {
|
||||
n = p.context
|
||||
}
|
||||
|
||||
switch n.DataAtom {
|
||||
case a.Select:
|
||||
if !last {
|
||||
for ancestor, first := n, p.oe[0]; ancestor != first; {
|
||||
if ancestor == first {
|
||||
break
|
||||
}
|
||||
ancestor = p.oe[p.oe.index(ancestor)-1]
|
||||
switch ancestor.DataAtom {
|
||||
case a.Template:
|
||||
p.im = inSelectIM
|
||||
return
|
||||
case a.Table:
|
||||
p.im = inSelectInTableIM
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
p.im = inSelectIM
|
||||
case a.Td, a.Th:
|
||||
// TODO: remove this divergence from the HTML5 spec.
|
||||
//
|
||||
// See https://bugs.chromium.org/p/chromium/issues/detail?id=829668
|
||||
p.im = inCellIM
|
||||
case a.Tr:
|
||||
p.im = inRowIM
|
||||
@@ -434,20 +490,32 @@ func (p *parser) resetInsertionMode() {
|
||||
p.im = inColumnGroupIM
|
||||
case a.Table:
|
||||
p.im = inTableIM
|
||||
case a.Template:
|
||||
p.im = p.templateStack.top()
|
||||
case a.Head:
|
||||
p.im = inBodyIM
|
||||
// TODO: remove this divergence from the HTML5 spec.
|
||||
//
|
||||
// See https://bugs.chromium.org/p/chromium/issues/detail?id=829668
|
||||
p.im = inHeadIM
|
||||
case a.Body:
|
||||
p.im = inBodyIM
|
||||
case a.Frameset:
|
||||
p.im = inFramesetIM
|
||||
case a.Html:
|
||||
p.im = beforeHeadIM
|
||||
if p.head == nil {
|
||||
p.im = beforeHeadIM
|
||||
} else {
|
||||
p.im = afterHeadIM
|
||||
}
|
||||
default:
|
||||
if last {
|
||||
p.im = inBodyIM
|
||||
return
|
||||
}
|
||||
continue
|
||||
}
|
||||
return
|
||||
}
|
||||
p.im = inBodyIM
|
||||
}
|
||||
|
||||
const whitespace = " \t\r\n\f"
|
||||
@@ -590,19 +658,36 @@ func inHeadIM(p *parser) bool {
|
||||
case a.Head:
|
||||
// Ignore the token.
|
||||
return true
|
||||
case a.Template:
|
||||
p.addElement()
|
||||
p.afe = append(p.afe, &scopeMarker)
|
||||
p.framesetOK = false
|
||||
p.im = inTemplateIM
|
||||
p.templateStack = append(p.templateStack, inTemplateIM)
|
||||
return true
|
||||
}
|
||||
case EndTagToken:
|
||||
switch p.tok.DataAtom {
|
||||
case a.Head:
|
||||
n := p.oe.pop()
|
||||
if n.DataAtom != a.Head {
|
||||
panic("html: bad parser state: <head> element not found, in the in-head insertion mode")
|
||||
}
|
||||
p.oe.pop()
|
||||
p.im = afterHeadIM
|
||||
return true
|
||||
case a.Body, a.Html, a.Br:
|
||||
p.parseImpliedToken(EndTagToken, a.Head, a.Head.String())
|
||||
return false
|
||||
case a.Template:
|
||||
if !p.oe.contains(a.Template) {
|
||||
return true
|
||||
}
|
||||
p.generateAllImpliedEndTags()
|
||||
if n := p.oe.top(); n.DataAtom != a.Template {
|
||||
return true
|
||||
}
|
||||
p.popUntil(defaultScope, a.Template)
|
||||
p.clearActiveFormattingElements()
|
||||
p.templateStack.pop()
|
||||
p.resetInsertionMode()
|
||||
return true
|
||||
default:
|
||||
// Ignore the token.
|
||||
return true
|
||||
@@ -648,7 +733,7 @@ func afterHeadIM(p *parser) bool {
|
||||
p.addElement()
|
||||
p.im = inFramesetIM
|
||||
return true
|
||||
case a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Title:
|
||||
case a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Template, a.Title:
|
||||
p.oe = append(p.oe, p.head)
|
||||
defer p.oe.remove(p.head)
|
||||
return inHeadIM(p)
|
||||
@@ -660,6 +745,8 @@ func afterHeadIM(p *parser) bool {
|
||||
switch p.tok.DataAtom {
|
||||
case a.Body, a.Html, a.Br:
|
||||
// Drop down to creating an implied <body> tag.
|
||||
case a.Template:
|
||||
return inHeadIM(p)
|
||||
default:
|
||||
// Ignore the token.
|
||||
return true
|
||||
@@ -727,10 +814,16 @@ func inBodyIM(p *parser) bool {
|
||||
case StartTagToken:
|
||||
switch p.tok.DataAtom {
|
||||
case a.Html:
|
||||
if p.oe.contains(a.Template) {
|
||||
return true
|
||||
}
|
||||
copyAttributes(p.oe[0], p.tok)
|
||||
case a.Base, a.Basefont, a.Bgsound, a.Command, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Title:
|
||||
case a.Base, a.Basefont, a.Bgsound, a.Command, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Template, a.Title:
|
||||
return inHeadIM(p)
|
||||
case a.Body:
|
||||
if p.oe.contains(a.Template) {
|
||||
return true
|
||||
}
|
||||
if len(p.oe) >= 2 {
|
||||
body := p.oe[1]
|
||||
if body.Type == ElementNode && body.DataAtom == a.Body {
|
||||
@@ -767,7 +860,7 @@ func inBodyIM(p *parser) bool {
|
||||
// The newline, if any, will be dealt with by the TextToken case.
|
||||
p.framesetOK = false
|
||||
case a.Form:
|
||||
if p.form == nil {
|
||||
if p.oe.contains(a.Template) || p.form == nil {
|
||||
p.popUntil(buttonScope, a.P)
|
||||
p.addElement()
|
||||
p.form = p.top()
|
||||
@@ -952,11 +1045,16 @@ func inBodyIM(p *parser) bool {
|
||||
}
|
||||
p.reconstructActiveFormattingElements()
|
||||
p.addElement()
|
||||
case a.Rp, a.Rt:
|
||||
case a.Rb, a.Rtc:
|
||||
if p.elementInScope(defaultScope, a.Ruby) {
|
||||
p.generateImpliedEndTags()
|
||||
}
|
||||
p.addElement()
|
||||
case a.Rp, a.Rt:
|
||||
if p.elementInScope(defaultScope, a.Ruby) {
|
||||
p.generateImpliedEndTags("rtc")
|
||||
}
|
||||
p.addElement()
|
||||
case a.Math, a.Svg:
|
||||
p.reconstructActiveFormattingElements()
|
||||
if p.tok.DataAtom == a.Math {
|
||||
@@ -972,7 +1070,13 @@ func inBodyIM(p *parser) bool {
|
||||
p.acknowledgeSelfClosingTag()
|
||||
}
|
||||
return true
|
||||
case a.Caption, a.Col, a.Colgroup, a.Frame, a.Head, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr:
|
||||
case a.Frame:
|
||||
// TODO: remove this divergence from the HTML5 spec.
|
||||
if p.oe.contains(a.Template) {
|
||||
p.addElement()
|
||||
return true
|
||||
}
|
||||
case a.Caption, a.Col, a.Colgroup, a.Head, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr:
|
||||
// Ignore the token.
|
||||
default:
|
||||
p.reconstructActiveFormattingElements()
|
||||
@@ -993,15 +1097,28 @@ func inBodyIM(p *parser) bool {
|
||||
case a.Address, a.Article, a.Aside, a.Blockquote, a.Button, a.Center, a.Details, a.Dir, a.Div, a.Dl, a.Fieldset, a.Figcaption, a.Figure, a.Footer, a.Header, a.Hgroup, a.Listing, a.Menu, a.Nav, a.Ol, a.Pre, a.Section, a.Summary, a.Ul:
|
||||
p.popUntil(defaultScope, p.tok.DataAtom)
|
||||
case a.Form:
|
||||
node := p.form
|
||||
p.form = nil
|
||||
i := p.indexOfElementInScope(defaultScope, a.Form)
|
||||
if node == nil || i == -1 || p.oe[i] != node {
|
||||
// Ignore the token.
|
||||
return true
|
||||
if p.oe.contains(a.Template) {
|
||||
if !p.oe.contains(a.Form) {
|
||||
// Ignore the token.
|
||||
return true
|
||||
}
|
||||
p.generateImpliedEndTags()
|
||||
if p.tok.DataAtom == a.Form {
|
||||
// Ignore the token.
|
||||
return true
|
||||
}
|
||||
p.popUntil(defaultScope, a.Form)
|
||||
} else {
|
||||
node := p.form
|
||||
p.form = nil
|
||||
i := p.indexOfElementInScope(defaultScope, a.Form)
|
||||
if node == nil || i == -1 || p.oe[i] != node {
|
||||
// Ignore the token.
|
||||
return true
|
||||
}
|
||||
p.generateImpliedEndTags()
|
||||
p.oe.remove(node)
|
||||
}
|
||||
p.generateImpliedEndTags()
|
||||
p.oe.remove(node)
|
||||
case a.P:
|
||||
if !p.elementInScope(buttonScope, a.P) {
|
||||
p.parseImpliedToken(StartTagToken, a.P, a.P.String())
|
||||
@@ -1022,6 +1139,8 @@ func inBodyIM(p *parser) bool {
|
||||
case a.Br:
|
||||
p.tok.Type = StartTagToken
|
||||
return false
|
||||
case a.Template:
|
||||
return inHeadIM(p)
|
||||
default:
|
||||
p.inBodyEndTagOther(p.tok.DataAtom)
|
||||
}
|
||||
@@ -1030,6 +1149,21 @@ func inBodyIM(p *parser) bool {
|
||||
Type: CommentNode,
|
||||
Data: p.tok.Data,
|
||||
})
|
||||
case ErrorToken:
|
||||
// TODO: remove this divergence from the HTML5 spec.
|
||||
if len(p.templateStack) > 0 {
|
||||
p.im = inTemplateIM
|
||||
return false
|
||||
} else {
|
||||
for _, e := range p.oe {
|
||||
switch e.DataAtom {
|
||||
case a.Dd, a.Dt, a.Li, a.Optgroup, a.Option, a.P, a.Rb, a.Rp, a.Rt, a.Rtc, a.Tbody, a.Td, a.Tfoot, a.Th,
|
||||
a.Thead, a.Tr, a.Body, a.Html:
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
@@ -1135,6 +1269,12 @@ func (p *parser) inBodyEndTagFormatting(tagAtom a.Atom) {
|
||||
switch commonAncestor.DataAtom {
|
||||
case a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr:
|
||||
p.fosterParent(lastNode)
|
||||
case a.Template:
|
||||
// TODO: remove namespace checking
|
||||
if commonAncestor.Namespace == "html" {
|
||||
commonAncestor = commonAncestor.LastChild
|
||||
}
|
||||
fallthrough
|
||||
default:
|
||||
commonAncestor.AppendChild(lastNode)
|
||||
}
|
||||
@@ -1249,7 +1389,7 @@ func inTableIM(p *parser) bool {
|
||||
}
|
||||
// Ignore the token.
|
||||
return true
|
||||
case a.Style, a.Script:
|
||||
case a.Style, a.Script, a.Template:
|
||||
return inHeadIM(p)
|
||||
case a.Input:
|
||||
for _, t := range p.tok.Attr {
|
||||
@@ -1261,7 +1401,7 @@ func inTableIM(p *parser) bool {
|
||||
}
|
||||
// Otherwise drop down to the default action.
|
||||
case a.Form:
|
||||
if p.form != nil {
|
||||
if p.oe.contains(a.Template) || p.form != nil {
|
||||
// Ignore the token.
|
||||
return true
|
||||
}
|
||||
@@ -1291,6 +1431,8 @@ func inTableIM(p *parser) bool {
|
||||
case a.Body, a.Caption, a.Col, a.Colgroup, a.Html, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr:
|
||||
// Ignore the token.
|
||||
return true
|
||||
case a.Template:
|
||||
return inHeadIM(p)
|
||||
}
|
||||
case CommentToken:
|
||||
p.addChild(&Node{
|
||||
@@ -1386,11 +1528,13 @@ func inColumnGroupIM(p *parser) bool {
|
||||
p.oe.pop()
|
||||
p.acknowledgeSelfClosingTag()
|
||||
return true
|
||||
case a.Template:
|
||||
return inHeadIM(p)
|
||||
}
|
||||
case EndTagToken:
|
||||
switch p.tok.DataAtom {
|
||||
case a.Colgroup:
|
||||
if p.oe.top().DataAtom != a.Html {
|
||||
if p.oe.top().DataAtom == a.Colgroup {
|
||||
p.oe.pop()
|
||||
p.im = inTableIM
|
||||
}
|
||||
@@ -1398,14 +1542,16 @@ func inColumnGroupIM(p *parser) bool {
|
||||
case a.Col:
|
||||
// Ignore the token.
|
||||
return true
|
||||
case a.Template:
|
||||
return inHeadIM(p)
|
||||
}
|
||||
}
|
||||
if p.oe.top().DataAtom != a.Html {
|
||||
p.oe.pop()
|
||||
p.im = inTableIM
|
||||
return false
|
||||
if p.oe.top().DataAtom != a.Colgroup {
|
||||
return true
|
||||
}
|
||||
return true
|
||||
p.oe.pop()
|
||||
p.im = inTableIM
|
||||
return false
|
||||
}
|
||||
|
||||
// Section 12.2.6.4.13.
|
||||
@@ -1597,7 +1743,7 @@ func inSelectIM(p *parser) bool {
|
||||
p.tokenizer.NextIsNotRawText()
|
||||
// Ignore the token.
|
||||
return true
|
||||
case a.Script:
|
||||
case a.Script, a.Template:
|
||||
return inHeadIM(p)
|
||||
}
|
||||
case EndTagToken:
|
||||
@@ -1618,6 +1764,8 @@ func inSelectIM(p *parser) bool {
|
||||
if p.popUntil(selectScope, a.Select) {
|
||||
p.resetInsertionMode()
|
||||
}
|
||||
case a.Template:
|
||||
return inHeadIM(p)
|
||||
}
|
||||
case CommentToken:
|
||||
p.addChild(&Node{
|
||||
@@ -1650,6 +1798,61 @@ func inSelectInTableIM(p *parser) bool {
|
||||
return inSelectIM(p)
|
||||
}
|
||||
|
||||
// Section 12.2.6.4.18.
|
||||
func inTemplateIM(p *parser) bool {
|
||||
switch p.tok.Type {
|
||||
case TextToken, CommentToken, DoctypeToken:
|
||||
return inBodyIM(p)
|
||||
case StartTagToken:
|
||||
switch p.tok.DataAtom {
|
||||
case a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Template, a.Title:
|
||||
return inHeadIM(p)
|
||||
case a.Caption, a.Colgroup, a.Tbody, a.Tfoot, a.Thead:
|
||||
p.templateStack.pop()
|
||||
p.templateStack = append(p.templateStack, inTableIM)
|
||||
p.im = inTableIM
|
||||
return false
|
||||
case a.Col:
|
||||
p.templateStack.pop()
|
||||
p.templateStack = append(p.templateStack, inColumnGroupIM)
|
||||
p.im = inColumnGroupIM
|
||||
return false
|
||||
case a.Tr:
|
||||
p.templateStack.pop()
|
||||
p.templateStack = append(p.templateStack, inTableBodyIM)
|
||||
p.im = inTableBodyIM
|
||||
return false
|
||||
case a.Td, a.Th:
|
||||
p.templateStack.pop()
|
||||
p.templateStack = append(p.templateStack, inRowIM)
|
||||
p.im = inRowIM
|
||||
return false
|
||||
default:
|
||||
p.templateStack.pop()
|
||||
p.templateStack = append(p.templateStack, inBodyIM)
|
||||
p.im = inBodyIM
|
||||
return false
|
||||
}
|
||||
case EndTagToken:
|
||||
switch p.tok.DataAtom {
|
||||
case a.Template:
|
||||
return inHeadIM(p)
|
||||
default:
|
||||
// Ignore the token.
|
||||
return true
|
||||
}
|
||||
}
|
||||
if !p.oe.contains(a.Template) {
|
||||
// Ignore the token.
|
||||
return true
|
||||
}
|
||||
p.popUntil(defaultScope, a.Template)
|
||||
p.clearActiveFormattingElements()
|
||||
p.templateStack.pop()
|
||||
p.resetInsertionMode()
|
||||
return false
|
||||
}
|
||||
|
||||
// Section 12.2.6.4.19.
|
||||
func afterBodyIM(p *parser) bool {
|
||||
switch p.tok.Type {
|
||||
@@ -1720,6 +1923,11 @@ func inFramesetIM(p *parser) bool {
|
||||
p.acknowledgeSelfClosingTag()
|
||||
case a.Noframes:
|
||||
return inHeadIM(p)
|
||||
case a.Template:
|
||||
// TODO: remove this divergence from the HTML5 spec.
|
||||
//
|
||||
// See https://bugs.chromium.org/p/chromium/issues/detail?id=829668
|
||||
return inTemplateIM(p)
|
||||
}
|
||||
case EndTagToken:
|
||||
switch p.tok.DataAtom {
|
||||
@@ -2064,6 +2272,9 @@ func ParseFragment(r io.Reader, context *Node) ([]*Node, error) {
|
||||
}
|
||||
p.doc.AppendChild(root)
|
||||
p.oe = nodeStack{root}
|
||||
if context != nil && context.DataAtom == a.Template {
|
||||
p.templateStack = append(p.templateStack, inTemplateIM)
|
||||
}
|
||||
p.resetInsertionMode()
|
||||
|
||||
for n := context; n != nil; n = n.Parent {
|
||||
|
||||
16
vendor/golang.org/x/net/html/parse_test.go
generated
vendored
16
vendor/golang.org/x/net/html/parse_test.go
generated
vendored
@@ -125,6 +125,7 @@ func (a sortedAttributes) Swap(i, j int) {
|
||||
|
||||
func dumpLevel(w io.Writer, n *Node, level int) error {
|
||||
dumpIndent(w, level)
|
||||
level++
|
||||
switch n.Type {
|
||||
case ErrorNode:
|
||||
return errors.New("unexpected ErrorNode")
|
||||
@@ -140,13 +141,19 @@ func dumpLevel(w io.Writer, n *Node, level int) error {
|
||||
sort.Sort(attr)
|
||||
for _, a := range attr {
|
||||
io.WriteString(w, "\n")
|
||||
dumpIndent(w, level+1)
|
||||
dumpIndent(w, level)
|
||||
if a.Namespace != "" {
|
||||
fmt.Fprintf(w, `%s %s="%s"`, a.Namespace, a.Key, a.Val)
|
||||
} else {
|
||||
fmt.Fprintf(w, `%s="%s"`, a.Key, a.Val)
|
||||
}
|
||||
}
|
||||
if n.Namespace == "" && n.DataAtom == atom.Template {
|
||||
io.WriteString(w, "\n")
|
||||
dumpIndent(w, level)
|
||||
level++
|
||||
io.WriteString(w, "content")
|
||||
}
|
||||
case TextNode:
|
||||
fmt.Fprintf(w, `"%s"`, n.Data)
|
||||
case CommentNode:
|
||||
@@ -176,7 +183,7 @@ func dumpLevel(w io.Writer, n *Node, level int) error {
|
||||
}
|
||||
io.WriteString(w, "\n")
|
||||
for c := n.FirstChild; c != nil; c = c.NextSibling {
|
||||
if err := dumpLevel(w, c, level+1); err != nil {
|
||||
if err := dumpLevel(w, c, level); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -373,6 +380,11 @@ func TestNodeConsistency(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseFragmentWithNilContext(t *testing.T) {
|
||||
// This shouldn't panic.
|
||||
ParseFragment(strings.NewReader("<p>hello</p>"), nil)
|
||||
}
|
||||
|
||||
func BenchmarkParser(b *testing.B) {
|
||||
buf, err := ioutil.ReadFile("testdata/go1.html")
|
||||
if err != nil {
|
||||
|
||||
298
vendor/golang.org/x/net/html/testdata/webkit/ruby.dat
generated
vendored
Normal file
298
vendor/golang.org/x/net/html/testdata/webkit/ruby.dat
generated
vendored
Normal file
@@ -0,0 +1,298 @@
|
||||
#data
|
||||
<html><ruby>a<rb>b<rb></ruby></html>
|
||||
#errors
|
||||
(1,6): expected-doctype-but-got-start-tag
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <ruby>
|
||||
| "a"
|
||||
| <rb>
|
||||
| "b"
|
||||
| <rb>
|
||||
|
||||
#data
|
||||
<html><ruby>a<rb>b<rt></ruby></html>
|
||||
#errors
|
||||
(1,6): expected-doctype-but-got-start-tag
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <ruby>
|
||||
| "a"
|
||||
| <rb>
|
||||
| "b"
|
||||
| <rt>
|
||||
|
||||
#data
|
||||
<html><ruby>a<rb>b<rtc></ruby></html>
|
||||
#errors
|
||||
(1,6): expected-doctype-but-got-start-tag
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <ruby>
|
||||
| "a"
|
||||
| <rb>
|
||||
| "b"
|
||||
| <rtc>
|
||||
|
||||
#data
|
||||
<html><ruby>a<rb>b<rp></ruby></html>
|
||||
#errors
|
||||
(1,6): expected-doctype-but-got-start-tag
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <ruby>
|
||||
| "a"
|
||||
| <rb>
|
||||
| "b"
|
||||
| <rp>
|
||||
|
||||
#data
|
||||
<html><ruby>a<rb>b<span></ruby></html>
|
||||
#errors
|
||||
(1,6): expected-doctype-but-got-start-tag
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <ruby>
|
||||
| "a"
|
||||
| <rb>
|
||||
| "b"
|
||||
| <span>
|
||||
|
||||
#data
|
||||
<html><ruby>a<rt>b<rb></ruby></html>
|
||||
#errors
|
||||
(1,6): expected-doctype-but-got-start-tag
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <ruby>
|
||||
| "a"
|
||||
| <rt>
|
||||
| "b"
|
||||
| <rb>
|
||||
|
||||
#data
|
||||
<html><ruby>a<rt>b<rt></ruby></html>
|
||||
#errors
|
||||
(1,6): expected-doctype-but-got-start-tag
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <ruby>
|
||||
| "a"
|
||||
| <rt>
|
||||
| "b"
|
||||
| <rt>
|
||||
|
||||
#data
|
||||
<html><ruby>a<rt>b<rtc></ruby></html>
|
||||
#errors
|
||||
(1,6): expected-doctype-but-got-start-tag
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <ruby>
|
||||
| "a"
|
||||
| <rt>
|
||||
| "b"
|
||||
| <rtc>
|
||||
|
||||
#data
|
||||
<html><ruby>a<rt>b<rp></ruby></html>
|
||||
#errors
|
||||
(1,6): expected-doctype-but-got-start-tag
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <ruby>
|
||||
| "a"
|
||||
| <rt>
|
||||
| "b"
|
||||
| <rp>
|
||||
|
||||
#data
|
||||
<html><ruby>a<rt>b<span></ruby></html>
|
||||
#errors
|
||||
(1,6): expected-doctype-but-got-start-tag
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <ruby>
|
||||
| "a"
|
||||
| <rt>
|
||||
| "b"
|
||||
| <span>
|
||||
|
||||
#data
|
||||
<html><ruby>a<rtc>b<rb></ruby></html>
|
||||
#errors
|
||||
(1,6): expected-doctype-but-got-start-tag
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <ruby>
|
||||
| "a"
|
||||
| <rtc>
|
||||
| "b"
|
||||
| <rb>
|
||||
|
||||
#data
|
||||
<html><ruby>a<rtc>b<rt>c<rt>d</ruby></html>
|
||||
#errors
|
||||
(1,6): expected-doctype-but-got-start-tag
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <ruby>
|
||||
| "a"
|
||||
| <rtc>
|
||||
| "b"
|
||||
| <rt>
|
||||
| "c"
|
||||
| <rt>
|
||||
| "d"
|
||||
|
||||
#data
|
||||
<html><ruby>a<rtc>b<rtc></ruby></html>
|
||||
#errors
|
||||
(1,6): expected-doctype-but-got-start-tag
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <ruby>
|
||||
| "a"
|
||||
| <rtc>
|
||||
| "b"
|
||||
| <rtc>
|
||||
|
||||
#data
|
||||
<html><ruby>a<rtc>b<rp></ruby></html>
|
||||
#errors
|
||||
(1,6): expected-doctype-but-got-start-tag
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <ruby>
|
||||
| "a"
|
||||
| <rtc>
|
||||
| "b"
|
||||
| <rp>
|
||||
|
||||
#data
|
||||
<html><ruby>a<rtc>b<span></ruby></html>
|
||||
#errors
|
||||
(1,6): expected-doctype-but-got-start-tag
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <ruby>
|
||||
| "a"
|
||||
| <rtc>
|
||||
| "b"
|
||||
| <span>
|
||||
|
||||
#data
|
||||
<html><ruby>a<rp>b<rb></ruby></html>
|
||||
#errors
|
||||
(1,6): expected-doctype-but-got-start-tag
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <ruby>
|
||||
| "a"
|
||||
| <rp>
|
||||
| "b"
|
||||
| <rb>
|
||||
|
||||
#data
|
||||
<html><ruby>a<rp>b<rt></ruby></html>
|
||||
#errors
|
||||
(1,6): expected-doctype-but-got-start-tag
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <ruby>
|
||||
| "a"
|
||||
| <rp>
|
||||
| "b"
|
||||
| <rt>
|
||||
|
||||
#data
|
||||
<html><ruby>a<rp>b<rtc></ruby></html>
|
||||
#errors
|
||||
(1,6): expected-doctype-but-got-start-tag
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <ruby>
|
||||
| "a"
|
||||
| <rp>
|
||||
| "b"
|
||||
| <rtc>
|
||||
|
||||
#data
|
||||
<html><ruby>a<rp>b<rp></ruby></html>
|
||||
#errors
|
||||
(1,6): expected-doctype-but-got-start-tag
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <ruby>
|
||||
| "a"
|
||||
| <rp>
|
||||
| "b"
|
||||
| <rp>
|
||||
|
||||
#data
|
||||
<html><ruby>a<rp>b<span></ruby></html>
|
||||
#errors
|
||||
(1,6): expected-doctype-but-got-start-tag
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <ruby>
|
||||
| "a"
|
||||
| <rp>
|
||||
| "b"
|
||||
| <span>
|
||||
|
||||
#data
|
||||
<html><ruby><rtc><ruby>a<rb>b<rt></ruby></ruby></html>
|
||||
#errors
|
||||
(1,6): expected-doctype-but-got-start-tag
|
||||
#document
|
||||
| <html>
|
||||
| <head>
|
||||
| <body>
|
||||
| <ruby>
|
||||
| <rtc>
|
||||
| <ruby>
|
||||
| "a"
|
||||
| <rb>
|
||||
| "b"
|
||||
| <rt>
|
||||
1117
vendor/golang.org/x/net/html/testdata/webkit/template.dat
generated
vendored
Normal file
1117
vendor/golang.org/x/net/html/testdata/webkit/template.dat
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
28
vendor/golang.org/x/net/html/token_test.go
generated
vendored
28
vendor/golang.org/x/net/html/token_test.go
generated
vendored
@@ -589,20 +589,20 @@ func TestConvertNewlines(t *testing.T) {
|
||||
"Mac\rDOS\r\nUnix\n": "Mac\nDOS\nUnix\n",
|
||||
"Unix\nMac\rDOS\r\n": "Unix\nMac\nDOS\n",
|
||||
"DOS\r\nDOS\r\nDOS\r\n": "DOS\nDOS\nDOS\n",
|
||||
"": "",
|
||||
"\n": "\n",
|
||||
"\n\r": "\n\n",
|
||||
"\r": "\n",
|
||||
"\r\n": "\n",
|
||||
"\r\n\n": "\n\n",
|
||||
"\r\n\r": "\n\n",
|
||||
"\r\n\r\n": "\n\n",
|
||||
"\r\r": "\n\n",
|
||||
"\r\r\n": "\n\n",
|
||||
"\r\r\n\n": "\n\n\n",
|
||||
"\r\r\r\n": "\n\n\n",
|
||||
"\r \n": "\n \n",
|
||||
"xyz": "xyz",
|
||||
"": "",
|
||||
"\n": "\n",
|
||||
"\n\r": "\n\n",
|
||||
"\r": "\n",
|
||||
"\r\n": "\n",
|
||||
"\r\n\n": "\n\n",
|
||||
"\r\n\r": "\n\n",
|
||||
"\r\n\r\n": "\n\n",
|
||||
"\r\r": "\n\n",
|
||||
"\r\r\n": "\n\n",
|
||||
"\r\r\n\n": "\n\n\n",
|
||||
"\r\r\r\n": "\n\n\n",
|
||||
"\r \n": "\n \n",
|
||||
"xyz": "xyz",
|
||||
}
|
||||
for in, want := range testCases {
|
||||
if got := string(convertNewlines([]byte(in))); got != want {
|
||||
|
||||
50
vendor/golang.org/x/net/http/httpguts/guts.go
generated
vendored
Normal file
50
vendor/golang.org/x/net/http/httpguts/guts.go
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
// 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 httpguts provides functions implementing various details
|
||||
// of the HTTP specification.
|
||||
//
|
||||
// This package is shared by the standard library (which vendors it)
|
||||
// and x/net/http2. It comes with no API stability promise.
|
||||
package httpguts
|
||||
|
||||
import (
|
||||
"net/textproto"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ValidTrailerHeader reports whether name is a valid header field name to appear
|
||||
// in trailers.
|
||||
// See RFC 7230, Section 4.1.2
|
||||
func ValidTrailerHeader(name string) bool {
|
||||
name = textproto.CanonicalMIMEHeaderKey(name)
|
||||
if strings.HasPrefix(name, "If-") || badTrailer[name] {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
var badTrailer = map[string]bool{
|
||||
"Authorization": true,
|
||||
"Cache-Control": true,
|
||||
"Connection": true,
|
||||
"Content-Encoding": true,
|
||||
"Content-Length": true,
|
||||
"Content-Range": true,
|
||||
"Content-Type": true,
|
||||
"Expect": true,
|
||||
"Host": true,
|
||||
"Keep-Alive": true,
|
||||
"Max-Forwards": true,
|
||||
"Pragma": true,
|
||||
"Proxy-Authenticate": true,
|
||||
"Proxy-Authorization": true,
|
||||
"Proxy-Connection": true,
|
||||
"Range": true,
|
||||
"Realm": true,
|
||||
"Te": true,
|
||||
"Trailer": true,
|
||||
"Transfer-Encoding": true,
|
||||
"Www-Authenticate": true,
|
||||
}
|
||||
@@ -2,12 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package httplex contains rules around lexical matters of various
|
||||
// HTTP-related specifications.
|
||||
//
|
||||
// This package is shared by the standard library (which vendors it)
|
||||
// and x/net/http2. It comes with no API stability promise.
|
||||
package httplex
|
||||
package httpguts
|
||||
|
||||
import (
|
||||
"net"
|
||||
@@ -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 httplex
|
||||
package httpguts
|
||||
|
||||
import (
|
||||
"testing"
|
||||
4
vendor/golang.org/x/net/http2/frame.go
generated
vendored
4
vendor/golang.org/x/net/http2/frame.go
generated
vendored
@@ -14,8 +14,8 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/net/http/httpguts"
|
||||
"golang.org/x/net/http2/hpack"
|
||||
"golang.org/x/net/lex/httplex"
|
||||
)
|
||||
|
||||
const frameHeaderLen = 9
|
||||
@@ -1462,7 +1462,7 @@ func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) {
|
||||
if VerboseLogs && fr.logReads {
|
||||
fr.debugReadLoggerf("http2: decoded hpack field %+v", hf)
|
||||
}
|
||||
if !httplex.ValidHeaderFieldValue(hf.Value) {
|
||||
if !httpguts.ValidHeaderFieldValue(hf.Value) {
|
||||
invalid = headerFieldValueError(hf.Value)
|
||||
}
|
||||
isPseudo := strings.HasPrefix(hf.Name, ":")
|
||||
|
||||
6
vendor/golang.org/x/net/http2/hpack/hpack.go
generated
vendored
6
vendor/golang.org/x/net/http2/hpack/hpack.go
generated
vendored
@@ -389,6 +389,12 @@ func (d *Decoder) callEmit(hf HeaderField) error {
|
||||
|
||||
// (same invariants and behavior as parseHeaderFieldRepr)
|
||||
func (d *Decoder) parseDynamicTableSizeUpdate() error {
|
||||
// RFC 7541, sec 4.2: This dynamic table size update MUST occur at the
|
||||
// beginning of the first header block following the change to the dynamic table size.
|
||||
if d.dynTab.size > 0 {
|
||||
return DecodingError{errors.New("dynamic table size update MUST occur at the beginning of a header block")}
|
||||
}
|
||||
|
||||
buf := d.buf
|
||||
size, buf, err := readVarInt(5, buf)
|
||||
if err != nil {
|
||||
|
||||
19
vendor/golang.org/x/net/http2/hpack/hpack_test.go
generated
vendored
19
vendor/golang.org/x/net/http2/hpack/hpack_test.go
generated
vendored
@@ -720,3 +720,22 @@ func TestSaveBufLimit(t *testing.T) {
|
||||
t.Fatalf("Write error = %v; want ErrStringLength", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDynamicSizeUpdate(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
enc := NewEncoder(&buf)
|
||||
enc.SetMaxDynamicTableSize(255)
|
||||
enc.WriteField(HeaderField{Name: "foo", Value: "bar"})
|
||||
|
||||
d := NewDecoder(4096, nil)
|
||||
_, err := d.DecodeFull(buf.Bytes())
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: got = %v", err)
|
||||
}
|
||||
|
||||
// must fail since the dynamic table update must be at the beginning
|
||||
_, err = d.DecodeFull(buf.Bytes())
|
||||
if err == nil {
|
||||
t.Fatalf("dynamic table size update not at the beginning of a header block")
|
||||
}
|
||||
}
|
||||
|
||||
6
vendor/golang.org/x/net/http2/http2.go
generated
vendored
6
vendor/golang.org/x/net/http2/http2.go
generated
vendored
@@ -29,7 +29,7 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/net/lex/httplex"
|
||||
"golang.org/x/net/http/httpguts"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -179,7 +179,7 @@ var (
|
||||
)
|
||||
|
||||
// validWireHeaderFieldName reports whether v is a valid header field
|
||||
// name (key). See httplex.ValidHeaderName for the base rules.
|
||||
// name (key). See httpguts.ValidHeaderName for the base rules.
|
||||
//
|
||||
// Further, http2 says:
|
||||
// "Just as in HTTP/1.x, header field names are strings of ASCII
|
||||
@@ -191,7 +191,7 @@ func validWireHeaderFieldName(v string) bool {
|
||||
return false
|
||||
}
|
||||
for _, r := range v {
|
||||
if !httplex.IsTokenRune(r) {
|
||||
if !httpguts.IsTokenRune(r) {
|
||||
return false
|
||||
}
|
||||
if 'A' <= r && r <= 'Z' {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user