Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
00fd4ff485 | ||
|
|
018c28f8a1 | ||
|
|
9cd0187c09 | ||
|
|
c6a20f9984 | ||
|
|
776e461a4e | ||
|
|
ebe92624d1 | ||
|
|
a9f661cb6e | ||
|
|
310bfa40f1 | ||
|
|
59ff47295c | ||
|
|
3d872d0428 | ||
|
|
bc7d1d1eb5 | ||
|
|
7e3ac2043e | ||
|
|
23edec0b38 | ||
|
|
f495dc37d5 | ||
|
|
eb2c406296 | ||
|
|
2c476679df | ||
|
|
0ec7e8322c | ||
|
|
6fad3dfc18 | ||
|
|
21d60a1521 | ||
|
|
183a9b70cc | ||
|
|
334521b960 | ||
|
|
a3485e1740 |
+9
-22
@@ -354,11 +354,12 @@ func TestWaitAuthorization(t *testing.T) {
|
||||
})
|
||||
}
|
||||
t.Run("context cancel", func(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
_, err := runWaitAuthorization(ctx, t, func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Retry-After", "60")
|
||||
fmt.Fprintf(w, `{"status":"pending"}`)
|
||||
time.AfterFunc(1*time.Millisecond, cancel)
|
||||
})
|
||||
if err == nil {
|
||||
t.Error("err is nil")
|
||||
@@ -373,28 +374,14 @@ func runWaitAuthorization(ctx context.Context, t *testing.T, h http.HandlerFunc)
|
||||
h(w, r)
|
||||
}))
|
||||
defer ts.Close()
|
||||
type res struct {
|
||||
authz *Authorization
|
||||
err error
|
||||
|
||||
client := &Client{
|
||||
Key: testKey,
|
||||
DirectoryURL: ts.URL,
|
||||
dir: &Directory{},
|
||||
KID: "some-key-id", // set to avoid lookup attempt
|
||||
}
|
||||
ch := make(chan res, 1)
|
||||
go func() {
|
||||
client := &Client{
|
||||
Key: testKey,
|
||||
DirectoryURL: ts.URL,
|
||||
dir: &Directory{},
|
||||
KID: "some-key-id", // set to avoid lookup attempt
|
||||
}
|
||||
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")
|
||||
return client.WaitAuthorization(ctx, ts.URL)
|
||||
}
|
||||
|
||||
func TestRevokeAuthorization(t *testing.T) {
|
||||
|
||||
@@ -427,18 +427,7 @@ func TestGetCertificate(t *testing.T) {
|
||||
|
||||
man.Client = &acme.Client{DirectoryURL: s.URL()}
|
||||
|
||||
var tlscert *tls.Certificate
|
||||
var err error
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
tlscert, err = man.GetCertificate(tt.hello)
|
||||
close(done)
|
||||
}()
|
||||
select {
|
||||
case <-time.After(time.Minute):
|
||||
t.Fatal("man.GetCertificate took too long to return")
|
||||
case <-done:
|
||||
}
|
||||
tlscert, err := man.GetCertificate(tt.hello)
|
||||
if tt.expectError != "" {
|
||||
if err == nil {
|
||||
t.Fatal("expected error, got certificate")
|
||||
@@ -515,15 +504,12 @@ func TestGetCertificate_failedAttempt(t *testing.T) {
|
||||
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", exampleCertKey)
|
||||
case <-done:
|
||||
man.stateMu.Lock()
|
||||
defer man.stateMu.Unlock()
|
||||
if v, exist := man.state[exampleCertKey]; exist {
|
||||
t.Errorf("state exists for %v: %+v", exampleCertKey, v)
|
||||
}
|
||||
|
||||
<-done
|
||||
man.stateMu.Lock()
|
||||
defer man.stateMu.Unlock()
|
||||
if v, exist := man.state[exampleCertKey]; exist {
|
||||
t.Errorf("state exists for %v: %+v", exampleCertKey, v)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -542,8 +528,9 @@ func TestRevokeFailedAuthz(t *testing.T) {
|
||||
t.Fatal("expected GetCertificate to fail")
|
||||
}
|
||||
|
||||
start := time.Now()
|
||||
for time.Since(start) < 3*time.Second {
|
||||
logTicker := time.NewTicker(3 * time.Second)
|
||||
defer logTicker.Stop()
|
||||
for {
|
||||
authz, err := m.Client.GetAuthorization(context.Background(), ca.URL()+"/authz/0")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -551,10 +538,14 @@ func TestRevokeFailedAuthz(t *testing.T) {
|
||||
if authz.Status == acme.StatusDeactivated {
|
||||
return
|
||||
}
|
||||
|
||||
select {
|
||||
case <-logTicker.C:
|
||||
t.Logf("still waiting on revocations")
|
||||
default:
|
||||
}
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
}
|
||||
t.Error("revocations took too long")
|
||||
|
||||
}
|
||||
|
||||
func TestHTTPHandlerDefaultFallback(t *testing.T) {
|
||||
|
||||
+1
-1
@@ -117,7 +117,7 @@ func (c *Client) updateRegRFC(ctx context.Context, a *Account) (*Account, error)
|
||||
return responseAccount(res)
|
||||
}
|
||||
|
||||
// getGegRFC is equivalent to c.GetReg but for CAs implementing RFC 8555.
|
||||
// getRegRFC is equivalent to c.GetReg but for CAs implementing RFC 8555.
|
||||
// It expects c.Discover to have already been called.
|
||||
func (c *Client) getRegRFC(ctx context.Context) (*Account, error) {
|
||||
req := json.RawMessage(`{"onlyReturnExisting": true}`)
|
||||
|
||||
+25
-50
@@ -177,8 +177,7 @@ func TestRFC_postKID(t *testing.T) {
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
ctx := context.Background()
|
||||
cl := &Client{
|
||||
Key: testKey,
|
||||
DirectoryURL: ts.URL,
|
||||
@@ -316,8 +315,7 @@ func TestRFC_Register(t *testing.T) {
|
||||
s.start()
|
||||
defer s.close()
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
ctx := context.Background()
|
||||
cl := &Client{
|
||||
Key: testKeyEC,
|
||||
DirectoryURL: s.url("/"),
|
||||
@@ -454,8 +452,7 @@ func TestRFC_RegisterExternalAccountBinding(t *testing.T) {
|
||||
s.start()
|
||||
defer s.close()
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
ctx := context.Background()
|
||||
cl := &Client{
|
||||
Key: testKeyEC,
|
||||
DirectoryURL: s.url("/"),
|
||||
@@ -867,24 +864,13 @@ func testWaitOrderStatus(t *testing.T, okStatus string) {
|
||||
s.start()
|
||||
defer s.close()
|
||||
|
||||
var order *Order
|
||||
var err error
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
cl := &Client{Key: testKeyEC, DirectoryURL: s.url("/")}
|
||||
order, err = cl.WaitOrder(context.Background(), s.url("/orders/1"))
|
||||
close(done)
|
||||
}()
|
||||
select {
|
||||
case <-time.After(3 * time.Second):
|
||||
t.Fatal("WaitOrder took too long to return")
|
||||
case <-done:
|
||||
if err != nil {
|
||||
t.Fatalf("WaitOrder: %v", err)
|
||||
}
|
||||
if order.Status != okStatus {
|
||||
t.Errorf("order.Status = %q; want %q", order.Status, okStatus)
|
||||
}
|
||||
cl := &Client{Key: testKeyEC, DirectoryURL: s.url("/")}
|
||||
order, err := cl.WaitOrder(context.Background(), s.url("/orders/1"))
|
||||
if err != nil {
|
||||
t.Fatalf("WaitOrder: %v", err)
|
||||
}
|
||||
if order.Status != okStatus {
|
||||
t.Errorf("order.Status = %q; want %q", order.Status, okStatus)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -909,30 +895,20 @@ func TestRFC_WaitOrderError(t *testing.T) {
|
||||
s.start()
|
||||
defer s.close()
|
||||
|
||||
var err error
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
cl := &Client{Key: testKeyEC, DirectoryURL: s.url("/")}
|
||||
_, err = cl.WaitOrder(context.Background(), s.url("/orders/1"))
|
||||
close(done)
|
||||
}()
|
||||
select {
|
||||
case <-time.After(3 * time.Second):
|
||||
t.Fatal("WaitOrder took too long to return")
|
||||
case <-done:
|
||||
if err == nil {
|
||||
t.Fatal("WaitOrder returned nil error")
|
||||
}
|
||||
e, ok := err.(*OrderError)
|
||||
if !ok {
|
||||
t.Fatalf("err = %v (%T); want OrderError", err, err)
|
||||
}
|
||||
if e.OrderURL != s.url("/orders/1") {
|
||||
t.Errorf("e.OrderURL = %q; want %q", e.OrderURL, s.url("/orders/1"))
|
||||
}
|
||||
if e.Status != StatusInvalid {
|
||||
t.Errorf("e.Status = %q; want %q", e.Status, StatusInvalid)
|
||||
}
|
||||
cl := &Client{Key: testKeyEC, DirectoryURL: s.url("/")}
|
||||
_, err := cl.WaitOrder(context.Background(), s.url("/orders/1"))
|
||||
if err == nil {
|
||||
t.Fatal("WaitOrder returned nil error")
|
||||
}
|
||||
e, ok := err.(*OrderError)
|
||||
if !ok {
|
||||
t.Fatalf("err = %v (%T); want OrderError", err, err)
|
||||
}
|
||||
if e.OrderURL != s.url("/orders/1") {
|
||||
t.Errorf("e.OrderURL = %q; want %q", e.OrderURL, s.url("/orders/1"))
|
||||
}
|
||||
if e.Status != StatusInvalid {
|
||||
t.Errorf("e.Status = %q; want %q", e.Status, StatusInvalid)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -972,8 +948,7 @@ func TestRFC_CreateOrderCert(t *testing.T) {
|
||||
})
|
||||
s.start()
|
||||
defer s.close()
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
ctx := context.Background()
|
||||
|
||||
cl := &Client{Key: testKeyEC, DirectoryURL: s.url("/")}
|
||||
cert, curl, err := cl.CreateOrderCert(ctx, s.url("/pleaseissue"), csr, true)
|
||||
|
||||
+10
-1
@@ -50,7 +50,7 @@ func (ih InvalidHashPrefixError) Error() string {
|
||||
type InvalidCostError int
|
||||
|
||||
func (ic InvalidCostError) Error() string {
|
||||
return fmt.Sprintf("crypto/bcrypt: cost %d is outside allowed range (%d,%d)", int(ic), int(MinCost), int(MaxCost))
|
||||
return fmt.Sprintf("crypto/bcrypt: cost %d is outside allowed range (%d,%d)", int(ic), MinCost, MaxCost)
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -82,11 +82,20 @@ type hashed struct {
|
||||
minor byte
|
||||
}
|
||||
|
||||
// ErrPasswordTooLong is returned when the password passed to
|
||||
// GenerateFromPassword is too long (i.e. > 72 bytes).
|
||||
var ErrPasswordTooLong = errors.New("bcrypt: password length exceeds 72 bytes")
|
||||
|
||||
// GenerateFromPassword returns the bcrypt hash of the password at the given
|
||||
// cost. If the cost given is less than MinCost, the cost will be set to
|
||||
// DefaultCost, instead. Use CompareHashAndPassword, as defined in this package,
|
||||
// to compare the returned hashed password with its cleartext version.
|
||||
// GenerateFromPassword does not accept passwords longer than 72 bytes, which
|
||||
// is the longest password bcrypt will operate on.
|
||||
func GenerateFromPassword(password []byte, cost int) ([]byte, error) {
|
||||
if len(password) > 72 {
|
||||
return nil, ErrPasswordTooLong
|
||||
}
|
||||
p, err := newFromPassword(password, cost)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -241,3 +241,10 @@ func TestNoSideEffectsFromCompare(t *testing.T) {
|
||||
t.Errorf("got=%q want=%q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPasswordTooLong(t *testing.T) {
|
||||
_, err := GenerateFromPassword(make([]byte, 73), 1)
|
||||
if err != ErrPasswordTooLong {
|
||||
t.Errorf("unexpected error: got %q, want %q", err, ErrPasswordTooLong)
|
||||
}
|
||||
}
|
||||
|
||||
+7
-4
@@ -13,7 +13,10 @@
|
||||
// golang.org/x/crypto/chacha20poly1305).
|
||||
package cast5 // import "golang.org/x/crypto/cast5"
|
||||
|
||||
import "errors"
|
||||
import (
|
||||
"errors"
|
||||
"math/bits"
|
||||
)
|
||||
|
||||
const BlockSize = 8
|
||||
const KeySize = 16
|
||||
@@ -241,19 +244,19 @@ func (c *Cipher) keySchedule(in []byte) {
|
||||
// These are the three 'f' functions. See RFC 2144, section 2.2.
|
||||
func f1(d, m uint32, r uint8) uint32 {
|
||||
t := m + d
|
||||
I := (t << r) | (t >> (32 - r))
|
||||
I := bits.RotateLeft32(t, int(r))
|
||||
return ((sBox[0][I>>24] ^ sBox[1][(I>>16)&0xff]) - sBox[2][(I>>8)&0xff]) + sBox[3][I&0xff]
|
||||
}
|
||||
|
||||
func f2(d, m uint32, r uint8) uint32 {
|
||||
t := m ^ d
|
||||
I := (t << r) | (t >> (32 - r))
|
||||
I := bits.RotateLeft32(t, int(r))
|
||||
return ((sBox[0][I>>24] - sBox[1][(I>>16)&0xff]) + sBox[2][(I>>8)&0xff]) ^ sBox[3][I&0xff]
|
||||
}
|
||||
|
||||
func f3(d, m uint32, r uint8) uint32 {
|
||||
t := m - d
|
||||
I := (t << r) | (t >> (32 - r))
|
||||
I := bits.RotateLeft32(t, int(r))
|
||||
return ((sBox[0][I>>24] + sBox[1][(I>>16)&0xff]) ^ sBox[2][(I>>8)&0xff]) - sBox[3][I&0xff]
|
||||
}
|
||||
|
||||
|
||||
+43
-36
@@ -264,36 +264,35 @@ func (s *String) ReadASN1Boolean(out *bool) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
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 reports whether the
|
||||
// read was successful.
|
||||
// not point to an integer, to a big.Int, or to a []byte it panics. Only
|
||||
// positive and zero values can be decoded into []byte, and they are returned as
|
||||
// big-endian binary values that share memory with s. Positive values will have
|
||||
// no leading zeroes, and zero will be returned as a single zero byte.
|
||||
// ReadASN1Integer 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")
|
||||
}
|
||||
switch reflect.ValueOf(out).Elem().Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
switch out := out.(type) {
|
||||
case *int, *int8, *int16, *int32, *int64:
|
||||
var i int64
|
||||
if !s.readASN1Int64(&i) || reflect.ValueOf(out).Elem().OverflowInt(i) {
|
||||
return false
|
||||
}
|
||||
reflect.ValueOf(out).Elem().SetInt(i)
|
||||
return true
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
case *uint, *uint8, *uint16, *uint32, *uint64:
|
||||
var u uint64
|
||||
if !s.readASN1Uint64(&u) || reflect.ValueOf(out).Elem().OverflowUint(u) {
|
||||
return false
|
||||
}
|
||||
reflect.ValueOf(out).Elem().SetUint(u)
|
||||
return true
|
||||
case reflect.Struct:
|
||||
if reflect.TypeOf(out).Elem() == bigIntType {
|
||||
return s.readASN1BigInt(out.(*big.Int))
|
||||
}
|
||||
case *big.Int:
|
||||
return s.readASN1BigInt(out)
|
||||
case *[]byte:
|
||||
return s.readASN1Bytes(out)
|
||||
default:
|
||||
panic("out does not point to an integer type")
|
||||
}
|
||||
panic("out does not point to an integer type")
|
||||
}
|
||||
|
||||
func checkASN1Integer(bytes []byte) bool {
|
||||
@@ -333,6 +332,21 @@ func (s *String) readASN1BigInt(out *big.Int) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *String) readASN1Bytes(out *[]byte) bool {
|
||||
var bytes String
|
||||
if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) {
|
||||
return false
|
||||
}
|
||||
if bytes[0]&0x80 == 0x80 {
|
||||
return false
|
||||
}
|
||||
for len(bytes) > 1 && bytes[0] == 0 {
|
||||
bytes = bytes[1:]
|
||||
}
|
||||
*out = bytes
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *String) readASN1Int64(out *int64) bool {
|
||||
var bytes String
|
||||
if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) || !asn1Signed(out, bytes) {
|
||||
@@ -532,7 +546,7 @@ func (s *String) ReadASN1BitString(out *encoding_asn1.BitString) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
paddingBits := uint8(bytes[0])
|
||||
paddingBits := bytes[0]
|
||||
bytes = bytes[1:]
|
||||
if paddingBits > 7 ||
|
||||
len(bytes) == 0 && paddingBits != 0 ||
|
||||
@@ -545,7 +559,7 @@ func (s *String) ReadASN1BitString(out *encoding_asn1.BitString) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// ReadASN1BitString decodes an ASN.1 BIT STRING into out and advances. It is
|
||||
// ReadASN1BitStringAsBytes 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. It reports
|
||||
// whether the read was successful.
|
||||
func (s *String) ReadASN1BitStringAsBytes(out *[]byte) bool {
|
||||
@@ -554,7 +568,7 @@ func (s *String) ReadASN1BitStringAsBytes(out *[]byte) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
paddingBits := uint8(bytes[0])
|
||||
paddingBits := bytes[0]
|
||||
if paddingBits != 0 {
|
||||
return false
|
||||
}
|
||||
@@ -654,34 +668,27 @@ func (s *String) SkipOptionalASN1(tag asn1.Tag) bool {
|
||||
return s.ReadASN1(&unused, tag)
|
||||
}
|
||||
|
||||
// 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 reports
|
||||
// whether the read was successful.
|
||||
// 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. Otherwise, it behaves like
|
||||
// ReadASN1Integer.
|
||||
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")
|
||||
}
|
||||
var present bool
|
||||
var i String
|
||||
if !s.ReadOptionalASN1(&i, &present, tag) {
|
||||
return false
|
||||
}
|
||||
if !present {
|
||||
switch reflect.ValueOf(out).Elem().Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
|
||||
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
switch out.(type) {
|
||||
case *int, *int8, *int16, *int32, *int64,
|
||||
*uint, *uint8, *uint16, *uint32, *uint64, *[]byte:
|
||||
reflect.ValueOf(out).Elem().Set(reflect.ValueOf(defaultValue))
|
||||
case reflect.Struct:
|
||||
if reflect.TypeOf(out).Elem() != bigIntType {
|
||||
panic("invalid integer type")
|
||||
}
|
||||
if reflect.TypeOf(defaultValue).Kind() != reflect.Ptr ||
|
||||
reflect.TypeOf(defaultValue).Elem() != bigIntType {
|
||||
case *big.Int:
|
||||
if defaultValue, ok := defaultValue.(*big.Int); ok {
|
||||
out.(*big.Int).Set(defaultValue)
|
||||
} else {
|
||||
panic("out points to big.Int, but defaultValue does not")
|
||||
}
|
||||
out.(*big.Int).Set(defaultValue.(*big.Int))
|
||||
default:
|
||||
panic("invalid integer type")
|
||||
}
|
||||
|
||||
@@ -154,6 +154,32 @@ func TestReadASN1IntegerSigned(t *testing.T) {
|
||||
}
|
||||
})
|
||||
|
||||
// Repeat the same cases, reading into a []byte.
|
||||
t.Run("bytes", func(t *testing.T) {
|
||||
for i, test := range testData64 {
|
||||
in := String(test.in)
|
||||
var out []byte
|
||||
ok := in.ReadASN1Integer(&out)
|
||||
if test.out < 0 {
|
||||
if ok {
|
||||
t.Errorf("#%d: in.ReadASN1Integer(%d) = %v, want false", i, test.out, ok)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if !ok {
|
||||
t.Errorf("#%d: in.ReadASN1Integer() = %v, want true", i, ok)
|
||||
continue
|
||||
}
|
||||
n := new(big.Int).SetBytes(out).Int64()
|
||||
if n != test.out {
|
||||
t.Errorf("#%d: in.ReadASN1Integer() = %v, want true; out = %x, want %d", i, ok, out, test.out)
|
||||
}
|
||||
if out[0] == 0 && len(out) > 1 {
|
||||
t.Errorf("#%d: in.ReadASN1Integer() = %v; out = %x, has leading zeroes", i, ok, out)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// Repeat with the implicit-tagging functions
|
||||
t.Run("WithTag", func(t *testing.T) {
|
||||
for i, test := range testData64 {
|
||||
|
||||
@@ -303,9 +303,9 @@ func (b *Builder) add(bytes ...byte) {
|
||||
b.result = append(b.result, bytes...)
|
||||
}
|
||||
|
||||
// Unwrite rolls back n bytes written directly to the Builder. An attempt by a
|
||||
// child builder passed to a continuation to unwrite bytes from its parent will
|
||||
// panic.
|
||||
// Unwrite rolls back non-negative n bytes written directly to the Builder.
|
||||
// An attempt by a child builder passed to a continuation to unwrite bytes
|
||||
// from its parent will panic.
|
||||
func (b *Builder) Unwrite(n int) {
|
||||
if b.err != nil {
|
||||
return
|
||||
@@ -317,6 +317,9 @@ func (b *Builder) Unwrite(n int) {
|
||||
if length < 0 {
|
||||
panic("cryptobyte: internal error")
|
||||
}
|
||||
if n < 0 {
|
||||
panic("cryptobyte: attempted to unwrite negative number of bytes")
|
||||
}
|
||||
if n > length {
|
||||
panic("cryptobyte: attempted to unwrite more than was written")
|
||||
}
|
||||
|
||||
@@ -5,71 +5,18 @@
|
||||
// Package curve25519 provides an implementation of the X25519 function, which
|
||||
// performs scalar multiplication on the elliptic curve known as Curve25519.
|
||||
// See RFC 7748.
|
||||
//
|
||||
// Starting in Go 1.20, this package is a wrapper for the X25519 implementation
|
||||
// in the crypto/ecdh package.
|
||||
package curve25519 // import "golang.org/x/crypto/curve25519"
|
||||
|
||||
import (
|
||||
"crypto/subtle"
|
||||
"errors"
|
||||
"strconv"
|
||||
|
||||
"golang.org/x/crypto/curve25519/internal/field"
|
||||
)
|
||||
|
||||
// ScalarMult sets dst to the product scalar * point.
|
||||
//
|
||||
// Deprecated: when provided a low-order point, ScalarMult will set dst to all
|
||||
// zeroes, irrespective of the scalar. Instead, use the X25519 function, which
|
||||
// will return an error.
|
||||
func ScalarMult(dst, scalar, point *[32]byte) {
|
||||
var e [32]byte
|
||||
|
||||
copy(e[:], scalar[:])
|
||||
e[0] &= 248
|
||||
e[31] &= 127
|
||||
e[31] |= 64
|
||||
|
||||
var x1, x2, z2, x3, z3, tmp0, tmp1 field.Element
|
||||
x1.SetBytes(point[:])
|
||||
x2.One()
|
||||
x3.Set(&x1)
|
||||
z3.One()
|
||||
|
||||
swap := 0
|
||||
for pos := 254; pos >= 0; pos-- {
|
||||
b := e[pos/8] >> uint(pos&7)
|
||||
b &= 1
|
||||
swap ^= int(b)
|
||||
x2.Swap(&x3, swap)
|
||||
z2.Swap(&z3, swap)
|
||||
swap = int(b)
|
||||
|
||||
tmp0.Subtract(&x3, &z3)
|
||||
tmp1.Subtract(&x2, &z2)
|
||||
x2.Add(&x2, &z2)
|
||||
z2.Add(&x3, &z3)
|
||||
z3.Multiply(&tmp0, &x2)
|
||||
z2.Multiply(&z2, &tmp1)
|
||||
tmp0.Square(&tmp1)
|
||||
tmp1.Square(&x2)
|
||||
x3.Add(&z3, &z2)
|
||||
z2.Subtract(&z3, &z2)
|
||||
x2.Multiply(&tmp1, &tmp0)
|
||||
tmp1.Subtract(&tmp1, &tmp0)
|
||||
z2.Square(&z2)
|
||||
|
||||
z3.Mult32(&tmp1, 121666)
|
||||
x3.Square(&x3)
|
||||
tmp0.Add(&tmp0, &z3)
|
||||
z3.Multiply(&x1, &z2)
|
||||
z2.Multiply(&tmp1, &tmp0)
|
||||
}
|
||||
|
||||
x2.Swap(&x3, swap)
|
||||
z2.Swap(&z3, swap)
|
||||
|
||||
z2.Invert(&z2)
|
||||
x2.Multiply(&x2, &z2)
|
||||
copy(dst[:], x2.Bytes())
|
||||
scalarMult(dst, scalar, point)
|
||||
}
|
||||
|
||||
// ScalarBaseMult sets dst to the product scalar * base where base is the
|
||||
@@ -78,7 +25,7 @@ func ScalarMult(dst, scalar, point *[32]byte) {
|
||||
// It is recommended to use the X25519 function with Basepoint instead, as
|
||||
// copying into fixed size arrays can lead to unexpected bugs.
|
||||
func ScalarBaseMult(dst, scalar *[32]byte) {
|
||||
ScalarMult(dst, scalar, &basePoint)
|
||||
scalarBaseMult(dst, scalar)
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -91,21 +38,10 @@ const (
|
||||
// Basepoint is the canonical Curve25519 generator.
|
||||
var Basepoint []byte
|
||||
|
||||
var basePoint = [32]byte{9, 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}
|
||||
var basePoint = [32]byte{9}
|
||||
|
||||
func init() { Basepoint = basePoint[:] }
|
||||
|
||||
func checkBasepoint() {
|
||||
if subtle.ConstantTimeCompare(Basepoint, []byte{
|
||||
0x09, 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,
|
||||
}) != 1 {
|
||||
panic("curve25519: global Basepoint value was modified")
|
||||
}
|
||||
}
|
||||
|
||||
// X25519 returns the result of the scalar multiplication (scalar * point),
|
||||
// according to RFC 7748, Section 5. scalar, point and the return value are
|
||||
// slices of 32 bytes.
|
||||
@@ -121,26 +57,3 @@ func X25519(scalar, point []byte) ([]byte, error) {
|
||||
var dst [32]byte
|
||||
return x25519(&dst, scalar, point)
|
||||
}
|
||||
|
||||
func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) {
|
||||
var in [32]byte
|
||||
if l := len(scalar); l != 32 {
|
||||
return nil, errors.New("bad scalar length: " + strconv.Itoa(l) + ", expected 32")
|
||||
}
|
||||
if l := len(point); l != 32 {
|
||||
return nil, errors.New("bad point length: " + strconv.Itoa(l) + ", expected 32")
|
||||
}
|
||||
copy(in[:], scalar)
|
||||
if &point[0] == &Basepoint[0] {
|
||||
checkBasepoint()
|
||||
ScalarBaseMult(dst, &in)
|
||||
} else {
|
||||
var base, zero [32]byte
|
||||
copy(base[:], point)
|
||||
ScalarMult(dst, &in, &base)
|
||||
if subtle.ConstantTimeCompare(dst[:], zero[:]) == 1 {
|
||||
return nil, errors.New("bad input point: low order point")
|
||||
}
|
||||
}
|
||||
return dst[:], nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !go1.20
|
||||
|
||||
package curve25519
|
||||
|
||||
import (
|
||||
"crypto/subtle"
|
||||
"errors"
|
||||
"strconv"
|
||||
|
||||
"golang.org/x/crypto/curve25519/internal/field"
|
||||
)
|
||||
|
||||
func scalarMult(dst, scalar, point *[32]byte) {
|
||||
var e [32]byte
|
||||
|
||||
copy(e[:], scalar[:])
|
||||
e[0] &= 248
|
||||
e[31] &= 127
|
||||
e[31] |= 64
|
||||
|
||||
var x1, x2, z2, x3, z3, tmp0, tmp1 field.Element
|
||||
x1.SetBytes(point[:])
|
||||
x2.One()
|
||||
x3.Set(&x1)
|
||||
z3.One()
|
||||
|
||||
swap := 0
|
||||
for pos := 254; pos >= 0; pos-- {
|
||||
b := e[pos/8] >> uint(pos&7)
|
||||
b &= 1
|
||||
swap ^= int(b)
|
||||
x2.Swap(&x3, swap)
|
||||
z2.Swap(&z3, swap)
|
||||
swap = int(b)
|
||||
|
||||
tmp0.Subtract(&x3, &z3)
|
||||
tmp1.Subtract(&x2, &z2)
|
||||
x2.Add(&x2, &z2)
|
||||
z2.Add(&x3, &z3)
|
||||
z3.Multiply(&tmp0, &x2)
|
||||
z2.Multiply(&z2, &tmp1)
|
||||
tmp0.Square(&tmp1)
|
||||
tmp1.Square(&x2)
|
||||
x3.Add(&z3, &z2)
|
||||
z2.Subtract(&z3, &z2)
|
||||
x2.Multiply(&tmp1, &tmp0)
|
||||
tmp1.Subtract(&tmp1, &tmp0)
|
||||
z2.Square(&z2)
|
||||
|
||||
z3.Mult32(&tmp1, 121666)
|
||||
x3.Square(&x3)
|
||||
tmp0.Add(&tmp0, &z3)
|
||||
z3.Multiply(&x1, &z2)
|
||||
z2.Multiply(&tmp1, &tmp0)
|
||||
}
|
||||
|
||||
x2.Swap(&x3, swap)
|
||||
z2.Swap(&z3, swap)
|
||||
|
||||
z2.Invert(&z2)
|
||||
x2.Multiply(&x2, &z2)
|
||||
copy(dst[:], x2.Bytes())
|
||||
}
|
||||
|
||||
func scalarBaseMult(dst, scalar *[32]byte) {
|
||||
checkBasepoint()
|
||||
scalarMult(dst, scalar, &basePoint)
|
||||
}
|
||||
|
||||
func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) {
|
||||
var in [32]byte
|
||||
if l := len(scalar); l != 32 {
|
||||
return nil, errors.New("bad scalar length: " + strconv.Itoa(l) + ", expected 32")
|
||||
}
|
||||
if l := len(point); l != 32 {
|
||||
return nil, errors.New("bad point length: " + strconv.Itoa(l) + ", expected 32")
|
||||
}
|
||||
copy(in[:], scalar)
|
||||
if &point[0] == &Basepoint[0] {
|
||||
scalarBaseMult(dst, &in)
|
||||
} else {
|
||||
var base, zero [32]byte
|
||||
copy(base[:], point)
|
||||
scalarMult(dst, &in, &base)
|
||||
if subtle.ConstantTimeCompare(dst[:], zero[:]) == 1 {
|
||||
return nil, errors.New("bad input point: low order point")
|
||||
}
|
||||
}
|
||||
return dst[:], nil
|
||||
}
|
||||
|
||||
func checkBasepoint() {
|
||||
if subtle.ConstantTimeCompare(Basepoint, []byte{
|
||||
0x09, 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,
|
||||
}) != 1 {
|
||||
panic("curve25519: global Basepoint value was modified")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
// Copyright 2022 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build go1.20
|
||||
|
||||
package curve25519
|
||||
|
||||
import "crypto/ecdh"
|
||||
|
||||
func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) {
|
||||
curve := ecdh.X25519()
|
||||
pub, err := curve.NewPublicKey(point)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
priv, err := curve.NewPrivateKey(scalar)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out, err := priv.ECDH(pub)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
copy(dst[:], out)
|
||||
return dst[:], nil
|
||||
}
|
||||
|
||||
func scalarMult(dst, scalar, point *[32]byte) {
|
||||
if _, err := x25519(dst, scalar[:], point[:]); err != nil {
|
||||
// The only error condition for x25519 when the inputs are 32 bytes long
|
||||
// is if the output would have been the all-zero value.
|
||||
for i := range dst {
|
||||
dst[i] = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func scalarBaseMult(dst, scalar *[32]byte) {
|
||||
curve := ecdh.X25519()
|
||||
priv, err := curve.NewPrivateKey(scalar[:])
|
||||
if err != nil {
|
||||
panic("curve25519: internal error: scalarBaseMult was not 32 bytes")
|
||||
}
|
||||
copy(dst[:], priv.PublicKey().Bytes())
|
||||
}
|
||||
@@ -2,13 +2,15 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package curve25519
|
||||
package curve25519_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/crypto/curve25519"
|
||||
)
|
||||
|
||||
const expectedHex = "89161fde887b2b53de549af483940106ecc114d6982daa98256de23bdf77661a"
|
||||
@@ -19,7 +21,7 @@ func TestX25519Basepoint(t *testing.T) {
|
||||
|
||||
for i := 0; i < 200; i++ {
|
||||
var err error
|
||||
x, err = X25519(x, Basepoint)
|
||||
x, err = curve25519.X25519(x, curve25519.Basepoint)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -32,12 +34,12 @@ func TestX25519Basepoint(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLowOrderPoints(t *testing.T) {
|
||||
scalar := make([]byte, ScalarSize)
|
||||
scalar := make([]byte, curve25519.ScalarSize)
|
||||
if _, err := rand.Read(scalar); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for i, p := range lowOrderPoints {
|
||||
out, err := X25519(scalar, p)
|
||||
out, err := curve25519.X25519(scalar, p)
|
||||
if err == nil {
|
||||
t.Errorf("%d: expected error, got nil", i)
|
||||
}
|
||||
@@ -48,10 +50,10 @@ func TestLowOrderPoints(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestTestVectors(t *testing.T) {
|
||||
t.Run("Legacy", func(t *testing.T) { testTestVectors(t, ScalarMult) })
|
||||
t.Run("Legacy", func(t *testing.T) { testTestVectors(t, curve25519.ScalarMult) })
|
||||
t.Run("X25519", func(t *testing.T) {
|
||||
testTestVectors(t, func(dst, scalar, point *[32]byte) {
|
||||
out, err := X25519(scalar[:], point[:])
|
||||
out, err := curve25519.X25519(scalar[:], point[:])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -88,10 +90,10 @@ func TestHighBitIgnored(t *testing.T) {
|
||||
var hi0, hi1 [32]byte
|
||||
|
||||
u[31] &= 0x7f
|
||||
ScalarMult(&hi0, &s, &u)
|
||||
curve25519.ScalarMult(&hi0, &s, &u)
|
||||
|
||||
u[31] |= 0x80
|
||||
ScalarMult(&hi1, &s, &u)
|
||||
curve25519.ScalarMult(&hi1, &s, &u)
|
||||
|
||||
if !bytes.Equal(hi0[:], hi1[:]) {
|
||||
t.Errorf("high bit of group point should not affect result")
|
||||
@@ -101,14 +103,14 @@ func TestHighBitIgnored(t *testing.T) {
|
||||
var benchmarkSink byte
|
||||
|
||||
func BenchmarkX25519Basepoint(b *testing.B) {
|
||||
scalar := make([]byte, ScalarSize)
|
||||
scalar := make([]byte, curve25519.ScalarSize)
|
||||
if _, err := rand.Read(scalar); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
out, err := X25519(scalar, Basepoint)
|
||||
out, err := curve25519.X25519(scalar, curve25519.Basepoint)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
@@ -117,11 +119,11 @@ func BenchmarkX25519Basepoint(b *testing.B) {
|
||||
}
|
||||
|
||||
func BenchmarkX25519(b *testing.B) {
|
||||
scalar := make([]byte, ScalarSize)
|
||||
scalar := make([]byte, curve25519.ScalarSize)
|
||||
if _, err := rand.Read(scalar); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
point, err := X25519(scalar, Basepoint)
|
||||
point, err := curve25519.X25519(scalar, curve25519.Basepoint)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
@@ -131,7 +133,7 @@ func BenchmarkX25519(b *testing.B) {
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
out, err := X25519(scalar, point)
|
||||
out, err := curve25519.X25519(scalar, point)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -245,7 +245,7 @@ func feSquareGeneric(v, a *Element) {
|
||||
v.carryPropagate()
|
||||
}
|
||||
|
||||
// carryPropagate brings the limbs below 52 bits by applying the reduction
|
||||
// carryPropagateGeneric brings the limbs below 52 bits by applying the reduction
|
||||
// identity (a * 2²⁵⁵ + b = a * 19 + b) to the l4 carry. TODO inline
|
||||
func (v *Element) carryPropagateGeneric() *Element {
|
||||
c0 := v.l0 >> 51
|
||||
|
||||
@@ -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 curve25519
|
||||
package curve25519_test
|
||||
|
||||
// lowOrderPoints from libsodium.
|
||||
// https://github.com/jedisct1/libsodium/blob/65621a1059a37d/src/libsodium/crypto_scalarmult/curve25519/ref10/x25519_ref10.c#L11-L70
|
||||
|
||||
@@ -3,9 +3,9 @@ module golang.org/x/crypto
|
||||
go 1.17
|
||||
|
||||
require (
|
||||
golang.org/x/net v0.1.0
|
||||
golang.org/x/sys v0.1.0
|
||||
golang.org/x/term v0.1.0
|
||||
golang.org/x/net v0.9.0
|
||||
golang.org/x/sys v0.7.0
|
||||
golang.org/x/term v0.7.0
|
||||
)
|
||||
|
||||
require golang.org/x/text v0.4.0 // indirect
|
||||
require golang.org/x/text v0.9.0 // indirect
|
||||
|
||||
@@ -2,30 +2,37 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0=
|
||||
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
|
||||
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.1.0 h1:g6Z6vPFA9dYBAF7DWcH6sCcOntplXsDKcliusYijMlw=
|
||||
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ=
|
||||
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
||||
@@ -118,7 +118,7 @@ func TestECDHStdLib(t *testing.T) {
|
||||
}
|
||||
|
||||
shared := decodeHex(tt.Shared)
|
||||
x, err := curve.ECDH(priv, pub)
|
||||
x, err := priv.ECDH(pub)
|
||||
if err != nil {
|
||||
if tg.Curve == "curve25519" && !shouldPass {
|
||||
// ECDH is expected to only return an error when using X25519,
|
||||
|
||||
@@ -6,7 +6,11 @@ package wycheproof
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/crypto/cryptobyte"
|
||||
"golang.org/x/crypto/cryptobyte/asn1"
|
||||
)
|
||||
|
||||
func TestECDSA(t *testing.T) {
|
||||
@@ -76,9 +80,25 @@ func TestECDSA(t *testing.T) {
|
||||
h.Reset()
|
||||
h.Write(decodeHex(sig.Msg))
|
||||
hashed := h.Sum(nil)
|
||||
got := ecdsa.VerifyASN1(pub, hashed, decodeHex(sig.Sig))
|
||||
sigBytes := decodeHex(sig.Sig)
|
||||
got := ecdsa.VerifyASN1(pub, hashed, sigBytes)
|
||||
if want := shouldPass(sig.Result, sig.Flags, flagsShouldPass); got != want {
|
||||
t.Errorf("tcid: %d, type: %s, comment: %q, wanted success: %t", sig.TcID, sig.Result, sig.Comment, want)
|
||||
t.Errorf("tcid: %d, type: %s, comment: %q, VerifyASN1 wanted success: %t", sig.TcID, sig.Result, sig.Comment, want)
|
||||
}
|
||||
|
||||
var r, s big.Int
|
||||
var inner cryptobyte.String
|
||||
input := cryptobyte.String(sigBytes)
|
||||
if !input.ReadASN1(&inner, asn1.SEQUENCE) ||
|
||||
!input.Empty() ||
|
||||
!inner.ReadASN1Integer(&r) ||
|
||||
!inner.ReadASN1Integer(&s) ||
|
||||
!inner.Empty() {
|
||||
continue
|
||||
}
|
||||
got = ecdsa.Verify(pub, hashed, &r, &s)
|
||||
if want := shouldPass(sig.Result, sig.Flags, flagsShouldPass); got != want {
|
||||
t.Errorf("tcid: %d, type: %s, comment: %q, Verify wanted success: %t", sig.TcID, sig.Result, sig.Comment, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+8
-6
@@ -8,9 +8,11 @@
|
||||
|
||||
package md4
|
||||
|
||||
var shift1 = []uint{3, 7, 11, 19}
|
||||
var shift2 = []uint{3, 5, 9, 13}
|
||||
var shift3 = []uint{3, 9, 11, 15}
|
||||
import "math/bits"
|
||||
|
||||
var shift1 = []int{3, 7, 11, 19}
|
||||
var shift2 = []int{3, 5, 9, 13}
|
||||
var shift3 = []int{3, 9, 11, 15}
|
||||
|
||||
var xIndex2 = []uint{0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15}
|
||||
var xIndex3 = []uint{0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15}
|
||||
@@ -48,7 +50,7 @@ func _Block(dig *digest, p []byte) int {
|
||||
s := shift1[i%4]
|
||||
f := ((c ^ d) & b) ^ d
|
||||
a += f + X[x]
|
||||
a = a<<s | a>>(32-s)
|
||||
a = bits.RotateLeft32(a, s)
|
||||
a, b, c, d = d, a, b, c
|
||||
}
|
||||
|
||||
@@ -58,7 +60,7 @@ func _Block(dig *digest, p []byte) int {
|
||||
s := shift2[i%4]
|
||||
g := (b & c) | (b & d) | (c & d)
|
||||
a += g + X[x] + 0x5a827999
|
||||
a = a<<s | a>>(32-s)
|
||||
a = bits.RotateLeft32(a, s)
|
||||
a, b, c, d = d, a, b, c
|
||||
}
|
||||
|
||||
@@ -68,7 +70,7 @@ func _Block(dig *digest, p []byte) int {
|
||||
s := shift3[i%4]
|
||||
h := b ^ c ^ d
|
||||
a += h + X[x] + 0x6ed9eba1
|
||||
a = a<<s | a>>(32-s)
|
||||
a = bits.RotateLeft32(a, s)
|
||||
a, b, c, d = d, a, b, c
|
||||
}
|
||||
|
||||
|
||||
@@ -156,7 +156,7 @@ func (r *openpgpReader) Read(p []byte) (n int, err error) {
|
||||
n, err = r.b64Reader.Read(p)
|
||||
r.currentCRC = crc24(r.currentCRC, p[:n])
|
||||
|
||||
if err == io.EOF && r.lReader.crcSet && r.lReader.crc != uint32(r.currentCRC&crc24Mask) {
|
||||
if err == io.EOF && r.lReader.crcSet && r.lReader.crc != r.currentCRC&crc24Mask {
|
||||
return 0, ArmorCorrupt
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -61,7 +61,7 @@ type Key struct {
|
||||
type KeyRing interface {
|
||||
// KeysById returns the set of keys that have the given key id.
|
||||
KeysById(id uint64) []Key
|
||||
// KeysByIdAndUsage returns the set of keys with the given id
|
||||
// KeysByIdUsage returns the set of keys with the given id
|
||||
// that also meet the key usage given by requiredUsage.
|
||||
// The requiredUsage is expressed as the bitwise-OR of
|
||||
// packet.KeyFlag* values.
|
||||
@@ -183,7 +183,7 @@ func (el EntityList) KeysById(id uint64) (keys []Key) {
|
||||
return
|
||||
}
|
||||
|
||||
// KeysByIdAndUsage returns the set of keys with the given id that also meet
|
||||
// KeysByIdUsage returns the set of keys with the given id that also meet
|
||||
// the key usage given by requiredUsage. The requiredUsage is expressed as
|
||||
// the bitwise-OR of packet.KeyFlag* values.
|
||||
func (el EntityList) KeysByIdUsage(id uint64, requiredUsage byte) (keys []Key) {
|
||||
|
||||
@@ -60,7 +60,7 @@ func (c *Compressed) parse(r io.Reader) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// compressedWriterCloser represents the serialized compression stream
|
||||
// compressedWriteCloser represents the serialized compression stream
|
||||
// header and the compressor. Its Close() method ensures that both the
|
||||
// compressor and serialized stream header are closed. Its Write()
|
||||
// method writes to the compressor.
|
||||
|
||||
+25
-28
@@ -14,6 +14,7 @@ package rc2
|
||||
import (
|
||||
"crypto/cipher"
|
||||
"encoding/binary"
|
||||
"math/bits"
|
||||
)
|
||||
|
||||
// The rc2 block size in bytes
|
||||
@@ -80,10 +81,6 @@ func expandKey(key []byte, t1 int) [64]uint16 {
|
||||
return k
|
||||
}
|
||||
|
||||
func rotl16(x uint16, b uint) uint16 {
|
||||
return (x >> (16 - b)) | (x << b)
|
||||
}
|
||||
|
||||
func (c *rc2Cipher) Encrypt(dst, src []byte) {
|
||||
|
||||
r0 := binary.LittleEndian.Uint16(src[0:])
|
||||
@@ -96,22 +93,22 @@ func (c *rc2Cipher) Encrypt(dst, src []byte) {
|
||||
for j <= 16 {
|
||||
// mix r0
|
||||
r0 = r0 + c.k[j] + (r3 & r2) + ((^r3) & r1)
|
||||
r0 = rotl16(r0, 1)
|
||||
r0 = bits.RotateLeft16(r0, 1)
|
||||
j++
|
||||
|
||||
// mix r1
|
||||
r1 = r1 + c.k[j] + (r0 & r3) + ((^r0) & r2)
|
||||
r1 = rotl16(r1, 2)
|
||||
r1 = bits.RotateLeft16(r1, 2)
|
||||
j++
|
||||
|
||||
// mix r2
|
||||
r2 = r2 + c.k[j] + (r1 & r0) + ((^r1) & r3)
|
||||
r2 = rotl16(r2, 3)
|
||||
r2 = bits.RotateLeft16(r2, 3)
|
||||
j++
|
||||
|
||||
// mix r3
|
||||
r3 = r3 + c.k[j] + (r2 & r1) + ((^r2) & r0)
|
||||
r3 = rotl16(r3, 5)
|
||||
r3 = bits.RotateLeft16(r3, 5)
|
||||
j++
|
||||
|
||||
}
|
||||
@@ -124,22 +121,22 @@ func (c *rc2Cipher) Encrypt(dst, src []byte) {
|
||||
for j <= 40 {
|
||||
// mix r0
|
||||
r0 = r0 + c.k[j] + (r3 & r2) + ((^r3) & r1)
|
||||
r0 = rotl16(r0, 1)
|
||||
r0 = bits.RotateLeft16(r0, 1)
|
||||
j++
|
||||
|
||||
// mix r1
|
||||
r1 = r1 + c.k[j] + (r0 & r3) + ((^r0) & r2)
|
||||
r1 = rotl16(r1, 2)
|
||||
r1 = bits.RotateLeft16(r1, 2)
|
||||
j++
|
||||
|
||||
// mix r2
|
||||
r2 = r2 + c.k[j] + (r1 & r0) + ((^r1) & r3)
|
||||
r2 = rotl16(r2, 3)
|
||||
r2 = bits.RotateLeft16(r2, 3)
|
||||
j++
|
||||
|
||||
// mix r3
|
||||
r3 = r3 + c.k[j] + (r2 & r1) + ((^r2) & r0)
|
||||
r3 = rotl16(r3, 5)
|
||||
r3 = bits.RotateLeft16(r3, 5)
|
||||
j++
|
||||
|
||||
}
|
||||
@@ -152,22 +149,22 @@ func (c *rc2Cipher) Encrypt(dst, src []byte) {
|
||||
for j <= 60 {
|
||||
// mix r0
|
||||
r0 = r0 + c.k[j] + (r3 & r2) + ((^r3) & r1)
|
||||
r0 = rotl16(r0, 1)
|
||||
r0 = bits.RotateLeft16(r0, 1)
|
||||
j++
|
||||
|
||||
// mix r1
|
||||
r1 = r1 + c.k[j] + (r0 & r3) + ((^r0) & r2)
|
||||
r1 = rotl16(r1, 2)
|
||||
r1 = bits.RotateLeft16(r1, 2)
|
||||
j++
|
||||
|
||||
// mix r2
|
||||
r2 = r2 + c.k[j] + (r1 & r0) + ((^r1) & r3)
|
||||
r2 = rotl16(r2, 3)
|
||||
r2 = bits.RotateLeft16(r2, 3)
|
||||
j++
|
||||
|
||||
// mix r3
|
||||
r3 = r3 + c.k[j] + (r2 & r1) + ((^r2) & r0)
|
||||
r3 = rotl16(r3, 5)
|
||||
r3 = bits.RotateLeft16(r3, 5)
|
||||
j++
|
||||
}
|
||||
|
||||
@@ -188,22 +185,22 @@ func (c *rc2Cipher) Decrypt(dst, src []byte) {
|
||||
|
||||
for j >= 44 {
|
||||
// unmix r3
|
||||
r3 = rotl16(r3, 16-5)
|
||||
r3 = bits.RotateLeft16(r3, 16-5)
|
||||
r3 = r3 - c.k[j] - (r2 & r1) - ((^r2) & r0)
|
||||
j--
|
||||
|
||||
// unmix r2
|
||||
r2 = rotl16(r2, 16-3)
|
||||
r2 = bits.RotateLeft16(r2, 16-3)
|
||||
r2 = r2 - c.k[j] - (r1 & r0) - ((^r1) & r3)
|
||||
j--
|
||||
|
||||
// unmix r1
|
||||
r1 = rotl16(r1, 16-2)
|
||||
r1 = bits.RotateLeft16(r1, 16-2)
|
||||
r1 = r1 - c.k[j] - (r0 & r3) - ((^r0) & r2)
|
||||
j--
|
||||
|
||||
// unmix r0
|
||||
r0 = rotl16(r0, 16-1)
|
||||
r0 = bits.RotateLeft16(r0, 16-1)
|
||||
r0 = r0 - c.k[j] - (r3 & r2) - ((^r3) & r1)
|
||||
j--
|
||||
}
|
||||
@@ -215,22 +212,22 @@ func (c *rc2Cipher) Decrypt(dst, src []byte) {
|
||||
|
||||
for j >= 20 {
|
||||
// unmix r3
|
||||
r3 = rotl16(r3, 16-5)
|
||||
r3 = bits.RotateLeft16(r3, 16-5)
|
||||
r3 = r3 - c.k[j] - (r2 & r1) - ((^r2) & r0)
|
||||
j--
|
||||
|
||||
// unmix r2
|
||||
r2 = rotl16(r2, 16-3)
|
||||
r2 = bits.RotateLeft16(r2, 16-3)
|
||||
r2 = r2 - c.k[j] - (r1 & r0) - ((^r1) & r3)
|
||||
j--
|
||||
|
||||
// unmix r1
|
||||
r1 = rotl16(r1, 16-2)
|
||||
r1 = bits.RotateLeft16(r1, 16-2)
|
||||
r1 = r1 - c.k[j] - (r0 & r3) - ((^r0) & r2)
|
||||
j--
|
||||
|
||||
// unmix r0
|
||||
r0 = rotl16(r0, 16-1)
|
||||
r0 = bits.RotateLeft16(r0, 16-1)
|
||||
r0 = r0 - c.k[j] - (r3 & r2) - ((^r3) & r1)
|
||||
j--
|
||||
|
||||
@@ -243,22 +240,22 @@ func (c *rc2Cipher) Decrypt(dst, src []byte) {
|
||||
|
||||
for j >= 0 {
|
||||
// unmix r3
|
||||
r3 = rotl16(r3, 16-5)
|
||||
r3 = bits.RotateLeft16(r3, 16-5)
|
||||
r3 = r3 - c.k[j] - (r2 & r1) - ((^r2) & r0)
|
||||
j--
|
||||
|
||||
// unmix r2
|
||||
r2 = rotl16(r2, 16-3)
|
||||
r2 = bits.RotateLeft16(r2, 16-3)
|
||||
r2 = r2 - c.k[j] - (r1 & r0) - ((^r1) & r3)
|
||||
j--
|
||||
|
||||
// unmix r1
|
||||
r1 = rotl16(r1, 16-2)
|
||||
r1 = bits.RotateLeft16(r1, 16-2)
|
||||
r1 = r1 - c.k[j] - (r0 & r3) - ((^r0) & r2)
|
||||
j--
|
||||
|
||||
// unmix r0
|
||||
r0 = rotl16(r0, 16-1)
|
||||
r0 = bits.RotateLeft16(r0, 16-1)
|
||||
r0 = r0 - c.k[j] - (r3 & r2) - ((^r3) & r1)
|
||||
j--
|
||||
|
||||
|
||||
+34
-32
@@ -5,6 +5,8 @@
|
||||
// Package salsa provides low-level access to functions in the Salsa family.
|
||||
package salsa // import "golang.org/x/crypto/salsa20/salsa"
|
||||
|
||||
import "math/bits"
|
||||
|
||||
// Sigma is the Salsa20 constant for 256-bit keys.
|
||||
var Sigma = [16]byte{'e', 'x', 'p', 'a', 'n', 'd', ' ', '3', '2', '-', 'b', 'y', 't', 'e', ' ', 'k'}
|
||||
|
||||
@@ -31,76 +33,76 @@ func HSalsa20(out *[32]byte, in *[16]byte, k *[32]byte, c *[16]byte) {
|
||||
|
||||
for i := 0; i < 20; i += 2 {
|
||||
u := x0 + x12
|
||||
x4 ^= u<<7 | u>>(32-7)
|
||||
x4 ^= bits.RotateLeft32(u, 7)
|
||||
u = x4 + x0
|
||||
x8 ^= u<<9 | u>>(32-9)
|
||||
x8 ^= bits.RotateLeft32(u, 9)
|
||||
u = x8 + x4
|
||||
x12 ^= u<<13 | u>>(32-13)
|
||||
x12 ^= bits.RotateLeft32(u, 13)
|
||||
u = x12 + x8
|
||||
x0 ^= u<<18 | u>>(32-18)
|
||||
x0 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x5 + x1
|
||||
x9 ^= u<<7 | u>>(32-7)
|
||||
x9 ^= bits.RotateLeft32(u, 7)
|
||||
u = x9 + x5
|
||||
x13 ^= u<<9 | u>>(32-9)
|
||||
x13 ^= bits.RotateLeft32(u, 9)
|
||||
u = x13 + x9
|
||||
x1 ^= u<<13 | u>>(32-13)
|
||||
x1 ^= bits.RotateLeft32(u, 13)
|
||||
u = x1 + x13
|
||||
x5 ^= u<<18 | u>>(32-18)
|
||||
x5 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x10 + x6
|
||||
x14 ^= u<<7 | u>>(32-7)
|
||||
x14 ^= bits.RotateLeft32(u, 7)
|
||||
u = x14 + x10
|
||||
x2 ^= u<<9 | u>>(32-9)
|
||||
x2 ^= bits.RotateLeft32(u, 9)
|
||||
u = x2 + x14
|
||||
x6 ^= u<<13 | u>>(32-13)
|
||||
x6 ^= bits.RotateLeft32(u, 13)
|
||||
u = x6 + x2
|
||||
x10 ^= u<<18 | u>>(32-18)
|
||||
x10 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x15 + x11
|
||||
x3 ^= u<<7 | u>>(32-7)
|
||||
x3 ^= bits.RotateLeft32(u, 7)
|
||||
u = x3 + x15
|
||||
x7 ^= u<<9 | u>>(32-9)
|
||||
x7 ^= bits.RotateLeft32(u, 9)
|
||||
u = x7 + x3
|
||||
x11 ^= u<<13 | u>>(32-13)
|
||||
x11 ^= bits.RotateLeft32(u, 13)
|
||||
u = x11 + x7
|
||||
x15 ^= u<<18 | u>>(32-18)
|
||||
x15 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x0 + x3
|
||||
x1 ^= u<<7 | u>>(32-7)
|
||||
x1 ^= bits.RotateLeft32(u, 7)
|
||||
u = x1 + x0
|
||||
x2 ^= u<<9 | u>>(32-9)
|
||||
x2 ^= bits.RotateLeft32(u, 9)
|
||||
u = x2 + x1
|
||||
x3 ^= u<<13 | u>>(32-13)
|
||||
x3 ^= bits.RotateLeft32(u, 13)
|
||||
u = x3 + x2
|
||||
x0 ^= u<<18 | u>>(32-18)
|
||||
x0 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x5 + x4
|
||||
x6 ^= u<<7 | u>>(32-7)
|
||||
x6 ^= bits.RotateLeft32(u, 7)
|
||||
u = x6 + x5
|
||||
x7 ^= u<<9 | u>>(32-9)
|
||||
x7 ^= bits.RotateLeft32(u, 9)
|
||||
u = x7 + x6
|
||||
x4 ^= u<<13 | u>>(32-13)
|
||||
x4 ^= bits.RotateLeft32(u, 13)
|
||||
u = x4 + x7
|
||||
x5 ^= u<<18 | u>>(32-18)
|
||||
x5 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x10 + x9
|
||||
x11 ^= u<<7 | u>>(32-7)
|
||||
x11 ^= bits.RotateLeft32(u, 7)
|
||||
u = x11 + x10
|
||||
x8 ^= u<<9 | u>>(32-9)
|
||||
x8 ^= bits.RotateLeft32(u, 9)
|
||||
u = x8 + x11
|
||||
x9 ^= u<<13 | u>>(32-13)
|
||||
x9 ^= bits.RotateLeft32(u, 13)
|
||||
u = x9 + x8
|
||||
x10 ^= u<<18 | u>>(32-18)
|
||||
x10 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x15 + x14
|
||||
x12 ^= u<<7 | u>>(32-7)
|
||||
x12 ^= bits.RotateLeft32(u, 7)
|
||||
u = x12 + x15
|
||||
x13 ^= u<<9 | u>>(32-9)
|
||||
x13 ^= bits.RotateLeft32(u, 9)
|
||||
u = x13 + x12
|
||||
x14 ^= u<<13 | u>>(32-13)
|
||||
x14 ^= bits.RotateLeft32(u, 13)
|
||||
u = x14 + x13
|
||||
x15 ^= u<<18 | u>>(32-18)
|
||||
x15 ^= bits.RotateLeft32(u, 18)
|
||||
}
|
||||
out[0] = byte(x0)
|
||||
out[1] = byte(x0 >> 8)
|
||||
|
||||
+34
-32
@@ -4,6 +4,8 @@
|
||||
|
||||
package salsa
|
||||
|
||||
import "math/bits"
|
||||
|
||||
// Core208 applies the Salsa20/8 core function to the 64-byte array in and puts
|
||||
// the result into the 64-byte array out. The input and output may be the same array.
|
||||
func Core208(out *[64]byte, in *[64]byte) {
|
||||
@@ -29,76 +31,76 @@ func Core208(out *[64]byte, in *[64]byte) {
|
||||
|
||||
for i := 0; i < 8; i += 2 {
|
||||
u := x0 + x12
|
||||
x4 ^= u<<7 | u>>(32-7)
|
||||
x4 ^= bits.RotateLeft32(u, 7)
|
||||
u = x4 + x0
|
||||
x8 ^= u<<9 | u>>(32-9)
|
||||
x8 ^= bits.RotateLeft32(u, 9)
|
||||
u = x8 + x4
|
||||
x12 ^= u<<13 | u>>(32-13)
|
||||
x12 ^= bits.RotateLeft32(u, 13)
|
||||
u = x12 + x8
|
||||
x0 ^= u<<18 | u>>(32-18)
|
||||
x0 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x5 + x1
|
||||
x9 ^= u<<7 | u>>(32-7)
|
||||
x9 ^= bits.RotateLeft32(u, 7)
|
||||
u = x9 + x5
|
||||
x13 ^= u<<9 | u>>(32-9)
|
||||
x13 ^= bits.RotateLeft32(u, 9)
|
||||
u = x13 + x9
|
||||
x1 ^= u<<13 | u>>(32-13)
|
||||
x1 ^= bits.RotateLeft32(u, 13)
|
||||
u = x1 + x13
|
||||
x5 ^= u<<18 | u>>(32-18)
|
||||
x5 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x10 + x6
|
||||
x14 ^= u<<7 | u>>(32-7)
|
||||
x14 ^= bits.RotateLeft32(u, 7)
|
||||
u = x14 + x10
|
||||
x2 ^= u<<9 | u>>(32-9)
|
||||
x2 ^= bits.RotateLeft32(u, 9)
|
||||
u = x2 + x14
|
||||
x6 ^= u<<13 | u>>(32-13)
|
||||
x6 ^= bits.RotateLeft32(u, 13)
|
||||
u = x6 + x2
|
||||
x10 ^= u<<18 | u>>(32-18)
|
||||
x10 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x15 + x11
|
||||
x3 ^= u<<7 | u>>(32-7)
|
||||
x3 ^= bits.RotateLeft32(u, 7)
|
||||
u = x3 + x15
|
||||
x7 ^= u<<9 | u>>(32-9)
|
||||
x7 ^= bits.RotateLeft32(u, 9)
|
||||
u = x7 + x3
|
||||
x11 ^= u<<13 | u>>(32-13)
|
||||
x11 ^= bits.RotateLeft32(u, 13)
|
||||
u = x11 + x7
|
||||
x15 ^= u<<18 | u>>(32-18)
|
||||
x15 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x0 + x3
|
||||
x1 ^= u<<7 | u>>(32-7)
|
||||
x1 ^= bits.RotateLeft32(u, 7)
|
||||
u = x1 + x0
|
||||
x2 ^= u<<9 | u>>(32-9)
|
||||
x2 ^= bits.RotateLeft32(u, 9)
|
||||
u = x2 + x1
|
||||
x3 ^= u<<13 | u>>(32-13)
|
||||
x3 ^= bits.RotateLeft32(u, 13)
|
||||
u = x3 + x2
|
||||
x0 ^= u<<18 | u>>(32-18)
|
||||
x0 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x5 + x4
|
||||
x6 ^= u<<7 | u>>(32-7)
|
||||
x6 ^= bits.RotateLeft32(u, 7)
|
||||
u = x6 + x5
|
||||
x7 ^= u<<9 | u>>(32-9)
|
||||
x7 ^= bits.RotateLeft32(u, 9)
|
||||
u = x7 + x6
|
||||
x4 ^= u<<13 | u>>(32-13)
|
||||
x4 ^= bits.RotateLeft32(u, 13)
|
||||
u = x4 + x7
|
||||
x5 ^= u<<18 | u>>(32-18)
|
||||
x5 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x10 + x9
|
||||
x11 ^= u<<7 | u>>(32-7)
|
||||
x11 ^= bits.RotateLeft32(u, 7)
|
||||
u = x11 + x10
|
||||
x8 ^= u<<9 | u>>(32-9)
|
||||
x8 ^= bits.RotateLeft32(u, 9)
|
||||
u = x8 + x11
|
||||
x9 ^= u<<13 | u>>(32-13)
|
||||
x9 ^= bits.RotateLeft32(u, 13)
|
||||
u = x9 + x8
|
||||
x10 ^= u<<18 | u>>(32-18)
|
||||
x10 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x15 + x14
|
||||
x12 ^= u<<7 | u>>(32-7)
|
||||
x12 ^= bits.RotateLeft32(u, 7)
|
||||
u = x12 + x15
|
||||
x13 ^= u<<9 | u>>(32-9)
|
||||
x13 ^= bits.RotateLeft32(u, 9)
|
||||
u = x13 + x12
|
||||
x14 ^= u<<13 | u>>(32-13)
|
||||
x14 ^= bits.RotateLeft32(u, 13)
|
||||
u = x14 + x13
|
||||
x15 ^= u<<18 | u>>(32-18)
|
||||
x15 ^= bits.RotateLeft32(u, 18)
|
||||
}
|
||||
x0 += j0
|
||||
x1 += j1
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
package salsa
|
||||
|
||||
import "math/bits"
|
||||
|
||||
const rounds = 20
|
||||
|
||||
// core applies the Salsa20 core function to 16-byte input in, 32-byte key k,
|
||||
@@ -31,76 +33,76 @@ func core(out *[64]byte, in *[16]byte, k *[32]byte, c *[16]byte) {
|
||||
|
||||
for i := 0; i < rounds; i += 2 {
|
||||
u := x0 + x12
|
||||
x4 ^= u<<7 | u>>(32-7)
|
||||
x4 ^= bits.RotateLeft32(u, 7)
|
||||
u = x4 + x0
|
||||
x8 ^= u<<9 | u>>(32-9)
|
||||
x8 ^= bits.RotateLeft32(u, 9)
|
||||
u = x8 + x4
|
||||
x12 ^= u<<13 | u>>(32-13)
|
||||
x12 ^= bits.RotateLeft32(u, 13)
|
||||
u = x12 + x8
|
||||
x0 ^= u<<18 | u>>(32-18)
|
||||
x0 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x5 + x1
|
||||
x9 ^= u<<7 | u>>(32-7)
|
||||
x9 ^= bits.RotateLeft32(u, 7)
|
||||
u = x9 + x5
|
||||
x13 ^= u<<9 | u>>(32-9)
|
||||
x13 ^= bits.RotateLeft32(u, 9)
|
||||
u = x13 + x9
|
||||
x1 ^= u<<13 | u>>(32-13)
|
||||
x1 ^= bits.RotateLeft32(u, 13)
|
||||
u = x1 + x13
|
||||
x5 ^= u<<18 | u>>(32-18)
|
||||
x5 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x10 + x6
|
||||
x14 ^= u<<7 | u>>(32-7)
|
||||
x14 ^= bits.RotateLeft32(u, 7)
|
||||
u = x14 + x10
|
||||
x2 ^= u<<9 | u>>(32-9)
|
||||
x2 ^= bits.RotateLeft32(u, 9)
|
||||
u = x2 + x14
|
||||
x6 ^= u<<13 | u>>(32-13)
|
||||
x6 ^= bits.RotateLeft32(u, 13)
|
||||
u = x6 + x2
|
||||
x10 ^= u<<18 | u>>(32-18)
|
||||
x10 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x15 + x11
|
||||
x3 ^= u<<7 | u>>(32-7)
|
||||
x3 ^= bits.RotateLeft32(u, 7)
|
||||
u = x3 + x15
|
||||
x7 ^= u<<9 | u>>(32-9)
|
||||
x7 ^= bits.RotateLeft32(u, 9)
|
||||
u = x7 + x3
|
||||
x11 ^= u<<13 | u>>(32-13)
|
||||
x11 ^= bits.RotateLeft32(u, 13)
|
||||
u = x11 + x7
|
||||
x15 ^= u<<18 | u>>(32-18)
|
||||
x15 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x0 + x3
|
||||
x1 ^= u<<7 | u>>(32-7)
|
||||
x1 ^= bits.RotateLeft32(u, 7)
|
||||
u = x1 + x0
|
||||
x2 ^= u<<9 | u>>(32-9)
|
||||
x2 ^= bits.RotateLeft32(u, 9)
|
||||
u = x2 + x1
|
||||
x3 ^= u<<13 | u>>(32-13)
|
||||
x3 ^= bits.RotateLeft32(u, 13)
|
||||
u = x3 + x2
|
||||
x0 ^= u<<18 | u>>(32-18)
|
||||
x0 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x5 + x4
|
||||
x6 ^= u<<7 | u>>(32-7)
|
||||
x6 ^= bits.RotateLeft32(u, 7)
|
||||
u = x6 + x5
|
||||
x7 ^= u<<9 | u>>(32-9)
|
||||
x7 ^= bits.RotateLeft32(u, 9)
|
||||
u = x7 + x6
|
||||
x4 ^= u<<13 | u>>(32-13)
|
||||
x4 ^= bits.RotateLeft32(u, 13)
|
||||
u = x4 + x7
|
||||
x5 ^= u<<18 | u>>(32-18)
|
||||
x5 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x10 + x9
|
||||
x11 ^= u<<7 | u>>(32-7)
|
||||
x11 ^= bits.RotateLeft32(u, 7)
|
||||
u = x11 + x10
|
||||
x8 ^= u<<9 | u>>(32-9)
|
||||
x8 ^= bits.RotateLeft32(u, 9)
|
||||
u = x8 + x11
|
||||
x9 ^= u<<13 | u>>(32-13)
|
||||
x9 ^= bits.RotateLeft32(u, 13)
|
||||
u = x9 + x8
|
||||
x10 ^= u<<18 | u>>(32-18)
|
||||
x10 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x15 + x14
|
||||
x12 ^= u<<7 | u>>(32-7)
|
||||
x12 ^= bits.RotateLeft32(u, 7)
|
||||
u = x12 + x15
|
||||
x13 ^= u<<9 | u>>(32-9)
|
||||
x13 ^= bits.RotateLeft32(u, 9)
|
||||
u = x13 + x12
|
||||
x14 ^= u<<13 | u>>(32-13)
|
||||
x14 ^= bits.RotateLeft32(u, 13)
|
||||
u = x14 + x13
|
||||
x15 ^= u<<18 | u>>(32-18)
|
||||
x15 ^= bits.RotateLeft32(u, 18)
|
||||
}
|
||||
x0 += j0
|
||||
x1 += j1
|
||||
|
||||
+98
-96
@@ -7,6 +7,8 @@
|
||||
|
||||
package sha3
|
||||
|
||||
import "math/bits"
|
||||
|
||||
// rc stores the round constants for use in the ι step.
|
||||
var rc = [24]uint64{
|
||||
0x0000000000000001,
|
||||
@@ -60,13 +62,13 @@ func keccakF1600(a *[25]uint64) {
|
||||
|
||||
bc0 = a[0] ^ d0
|
||||
t = a[6] ^ d1
|
||||
bc1 = t<<44 | t>>(64-44)
|
||||
bc1 = bits.RotateLeft64(t, 44)
|
||||
t = a[12] ^ d2
|
||||
bc2 = t<<43 | t>>(64-43)
|
||||
bc2 = bits.RotateLeft64(t, 43)
|
||||
t = a[18] ^ d3
|
||||
bc3 = t<<21 | t>>(64-21)
|
||||
bc3 = bits.RotateLeft64(t, 21)
|
||||
t = a[24] ^ d4
|
||||
bc4 = t<<14 | t>>(64-14)
|
||||
bc4 = bits.RotateLeft64(t, 14)
|
||||
a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i]
|
||||
a[6] = bc1 ^ (bc3 &^ bc2)
|
||||
a[12] = bc2 ^ (bc4 &^ bc3)
|
||||
@@ -74,15 +76,15 @@ func keccakF1600(a *[25]uint64) {
|
||||
a[24] = bc4 ^ (bc1 &^ bc0)
|
||||
|
||||
t = a[10] ^ d0
|
||||
bc2 = t<<3 | t>>(64-3)
|
||||
bc2 = bits.RotateLeft64(t, 3)
|
||||
t = a[16] ^ d1
|
||||
bc3 = t<<45 | t>>(64-45)
|
||||
bc3 = bits.RotateLeft64(t, 45)
|
||||
t = a[22] ^ d2
|
||||
bc4 = t<<61 | t>>(64-61)
|
||||
bc4 = bits.RotateLeft64(t, 61)
|
||||
t = a[3] ^ d3
|
||||
bc0 = t<<28 | t>>(64-28)
|
||||
bc0 = bits.RotateLeft64(t, 28)
|
||||
t = a[9] ^ d4
|
||||
bc1 = t<<20 | t>>(64-20)
|
||||
bc1 = bits.RotateLeft64(t, 20)
|
||||
a[10] = bc0 ^ (bc2 &^ bc1)
|
||||
a[16] = bc1 ^ (bc3 &^ bc2)
|
||||
a[22] = bc2 ^ (bc4 &^ bc3)
|
||||
@@ -90,15 +92,15 @@ func keccakF1600(a *[25]uint64) {
|
||||
a[9] = bc4 ^ (bc1 &^ bc0)
|
||||
|
||||
t = a[20] ^ d0
|
||||
bc4 = t<<18 | t>>(64-18)
|
||||
bc4 = bits.RotateLeft64(t, 18)
|
||||
t = a[1] ^ d1
|
||||
bc0 = t<<1 | t>>(64-1)
|
||||
bc0 = bits.RotateLeft64(t, 1)
|
||||
t = a[7] ^ d2
|
||||
bc1 = t<<6 | t>>(64-6)
|
||||
bc1 = bits.RotateLeft64(t, 6)
|
||||
t = a[13] ^ d3
|
||||
bc2 = t<<25 | t>>(64-25)
|
||||
bc2 = bits.RotateLeft64(t, 25)
|
||||
t = a[19] ^ d4
|
||||
bc3 = t<<8 | t>>(64-8)
|
||||
bc3 = bits.RotateLeft64(t, 8)
|
||||
a[20] = bc0 ^ (bc2 &^ bc1)
|
||||
a[1] = bc1 ^ (bc3 &^ bc2)
|
||||
a[7] = bc2 ^ (bc4 &^ bc3)
|
||||
@@ -106,15 +108,15 @@ func keccakF1600(a *[25]uint64) {
|
||||
a[19] = bc4 ^ (bc1 &^ bc0)
|
||||
|
||||
t = a[5] ^ d0
|
||||
bc1 = t<<36 | t>>(64-36)
|
||||
bc1 = bits.RotateLeft64(t, 36)
|
||||
t = a[11] ^ d1
|
||||
bc2 = t<<10 | t>>(64-10)
|
||||
bc2 = bits.RotateLeft64(t, 10)
|
||||
t = a[17] ^ d2
|
||||
bc3 = t<<15 | t>>(64-15)
|
||||
bc3 = bits.RotateLeft64(t, 15)
|
||||
t = a[23] ^ d3
|
||||
bc4 = t<<56 | t>>(64-56)
|
||||
bc4 = bits.RotateLeft64(t, 56)
|
||||
t = a[4] ^ d4
|
||||
bc0 = t<<27 | t>>(64-27)
|
||||
bc0 = bits.RotateLeft64(t, 27)
|
||||
a[5] = bc0 ^ (bc2 &^ bc1)
|
||||
a[11] = bc1 ^ (bc3 &^ bc2)
|
||||
a[17] = bc2 ^ (bc4 &^ bc3)
|
||||
@@ -122,15 +124,15 @@ func keccakF1600(a *[25]uint64) {
|
||||
a[4] = bc4 ^ (bc1 &^ bc0)
|
||||
|
||||
t = a[15] ^ d0
|
||||
bc3 = t<<41 | t>>(64-41)
|
||||
bc3 = bits.RotateLeft64(t, 41)
|
||||
t = a[21] ^ d1
|
||||
bc4 = t<<2 | t>>(64-2)
|
||||
bc4 = bits.RotateLeft64(t, 2)
|
||||
t = a[2] ^ d2
|
||||
bc0 = t<<62 | t>>(64-62)
|
||||
bc0 = bits.RotateLeft64(t, 62)
|
||||
t = a[8] ^ d3
|
||||
bc1 = t<<55 | t>>(64-55)
|
||||
bc1 = bits.RotateLeft64(t, 55)
|
||||
t = a[14] ^ d4
|
||||
bc2 = t<<39 | t>>(64-39)
|
||||
bc2 = bits.RotateLeft64(t, 39)
|
||||
a[15] = bc0 ^ (bc2 &^ bc1)
|
||||
a[21] = bc1 ^ (bc3 &^ bc2)
|
||||
a[2] = bc2 ^ (bc4 &^ bc3)
|
||||
@@ -151,13 +153,13 @@ func keccakF1600(a *[25]uint64) {
|
||||
|
||||
bc0 = a[0] ^ d0
|
||||
t = a[16] ^ d1
|
||||
bc1 = t<<44 | t>>(64-44)
|
||||
bc1 = bits.RotateLeft64(t, 44)
|
||||
t = a[7] ^ d2
|
||||
bc2 = t<<43 | t>>(64-43)
|
||||
bc2 = bits.RotateLeft64(t, 43)
|
||||
t = a[23] ^ d3
|
||||
bc3 = t<<21 | t>>(64-21)
|
||||
bc3 = bits.RotateLeft64(t, 21)
|
||||
t = a[14] ^ d4
|
||||
bc4 = t<<14 | t>>(64-14)
|
||||
bc4 = bits.RotateLeft64(t, 14)
|
||||
a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i+1]
|
||||
a[16] = bc1 ^ (bc3 &^ bc2)
|
||||
a[7] = bc2 ^ (bc4 &^ bc3)
|
||||
@@ -165,15 +167,15 @@ func keccakF1600(a *[25]uint64) {
|
||||
a[14] = bc4 ^ (bc1 &^ bc0)
|
||||
|
||||
t = a[20] ^ d0
|
||||
bc2 = t<<3 | t>>(64-3)
|
||||
bc2 = bits.RotateLeft64(t, 3)
|
||||
t = a[11] ^ d1
|
||||
bc3 = t<<45 | t>>(64-45)
|
||||
bc3 = bits.RotateLeft64(t, 45)
|
||||
t = a[2] ^ d2
|
||||
bc4 = t<<61 | t>>(64-61)
|
||||
bc4 = bits.RotateLeft64(t, 61)
|
||||
t = a[18] ^ d3
|
||||
bc0 = t<<28 | t>>(64-28)
|
||||
bc0 = bits.RotateLeft64(t, 28)
|
||||
t = a[9] ^ d4
|
||||
bc1 = t<<20 | t>>(64-20)
|
||||
bc1 = bits.RotateLeft64(t, 20)
|
||||
a[20] = bc0 ^ (bc2 &^ bc1)
|
||||
a[11] = bc1 ^ (bc3 &^ bc2)
|
||||
a[2] = bc2 ^ (bc4 &^ bc3)
|
||||
@@ -181,15 +183,15 @@ func keccakF1600(a *[25]uint64) {
|
||||
a[9] = bc4 ^ (bc1 &^ bc0)
|
||||
|
||||
t = a[15] ^ d0
|
||||
bc4 = t<<18 | t>>(64-18)
|
||||
bc4 = bits.RotateLeft64(t, 18)
|
||||
t = a[6] ^ d1
|
||||
bc0 = t<<1 | t>>(64-1)
|
||||
bc0 = bits.RotateLeft64(t, 1)
|
||||
t = a[22] ^ d2
|
||||
bc1 = t<<6 | t>>(64-6)
|
||||
bc1 = bits.RotateLeft64(t, 6)
|
||||
t = a[13] ^ d3
|
||||
bc2 = t<<25 | t>>(64-25)
|
||||
bc2 = bits.RotateLeft64(t, 25)
|
||||
t = a[4] ^ d4
|
||||
bc3 = t<<8 | t>>(64-8)
|
||||
bc3 = bits.RotateLeft64(t, 8)
|
||||
a[15] = bc0 ^ (bc2 &^ bc1)
|
||||
a[6] = bc1 ^ (bc3 &^ bc2)
|
||||
a[22] = bc2 ^ (bc4 &^ bc3)
|
||||
@@ -197,15 +199,15 @@ func keccakF1600(a *[25]uint64) {
|
||||
a[4] = bc4 ^ (bc1 &^ bc0)
|
||||
|
||||
t = a[10] ^ d0
|
||||
bc1 = t<<36 | t>>(64-36)
|
||||
bc1 = bits.RotateLeft64(t, 36)
|
||||
t = a[1] ^ d1
|
||||
bc2 = t<<10 | t>>(64-10)
|
||||
bc2 = bits.RotateLeft64(t, 10)
|
||||
t = a[17] ^ d2
|
||||
bc3 = t<<15 | t>>(64-15)
|
||||
bc3 = bits.RotateLeft64(t, 15)
|
||||
t = a[8] ^ d3
|
||||
bc4 = t<<56 | t>>(64-56)
|
||||
bc4 = bits.RotateLeft64(t, 56)
|
||||
t = a[24] ^ d4
|
||||
bc0 = t<<27 | t>>(64-27)
|
||||
bc0 = bits.RotateLeft64(t, 27)
|
||||
a[10] = bc0 ^ (bc2 &^ bc1)
|
||||
a[1] = bc1 ^ (bc3 &^ bc2)
|
||||
a[17] = bc2 ^ (bc4 &^ bc3)
|
||||
@@ -213,15 +215,15 @@ func keccakF1600(a *[25]uint64) {
|
||||
a[24] = bc4 ^ (bc1 &^ bc0)
|
||||
|
||||
t = a[5] ^ d0
|
||||
bc3 = t<<41 | t>>(64-41)
|
||||
bc3 = bits.RotateLeft64(t, 41)
|
||||
t = a[21] ^ d1
|
||||
bc4 = t<<2 | t>>(64-2)
|
||||
bc4 = bits.RotateLeft64(t, 2)
|
||||
t = a[12] ^ d2
|
||||
bc0 = t<<62 | t>>(64-62)
|
||||
bc0 = bits.RotateLeft64(t, 62)
|
||||
t = a[3] ^ d3
|
||||
bc1 = t<<55 | t>>(64-55)
|
||||
bc1 = bits.RotateLeft64(t, 55)
|
||||
t = a[19] ^ d4
|
||||
bc2 = t<<39 | t>>(64-39)
|
||||
bc2 = bits.RotateLeft64(t, 39)
|
||||
a[5] = bc0 ^ (bc2 &^ bc1)
|
||||
a[21] = bc1 ^ (bc3 &^ bc2)
|
||||
a[12] = bc2 ^ (bc4 &^ bc3)
|
||||
@@ -242,13 +244,13 @@ func keccakF1600(a *[25]uint64) {
|
||||
|
||||
bc0 = a[0] ^ d0
|
||||
t = a[11] ^ d1
|
||||
bc1 = t<<44 | t>>(64-44)
|
||||
bc1 = bits.RotateLeft64(t, 44)
|
||||
t = a[22] ^ d2
|
||||
bc2 = t<<43 | t>>(64-43)
|
||||
bc2 = bits.RotateLeft64(t, 43)
|
||||
t = a[8] ^ d3
|
||||
bc3 = t<<21 | t>>(64-21)
|
||||
bc3 = bits.RotateLeft64(t, 21)
|
||||
t = a[19] ^ d4
|
||||
bc4 = t<<14 | t>>(64-14)
|
||||
bc4 = bits.RotateLeft64(t, 14)
|
||||
a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i+2]
|
||||
a[11] = bc1 ^ (bc3 &^ bc2)
|
||||
a[22] = bc2 ^ (bc4 &^ bc3)
|
||||
@@ -256,15 +258,15 @@ func keccakF1600(a *[25]uint64) {
|
||||
a[19] = bc4 ^ (bc1 &^ bc0)
|
||||
|
||||
t = a[15] ^ d0
|
||||
bc2 = t<<3 | t>>(64-3)
|
||||
bc2 = bits.RotateLeft64(t, 3)
|
||||
t = a[1] ^ d1
|
||||
bc3 = t<<45 | t>>(64-45)
|
||||
bc3 = bits.RotateLeft64(t, 45)
|
||||
t = a[12] ^ d2
|
||||
bc4 = t<<61 | t>>(64-61)
|
||||
bc4 = bits.RotateLeft64(t, 61)
|
||||
t = a[23] ^ d3
|
||||
bc0 = t<<28 | t>>(64-28)
|
||||
bc0 = bits.RotateLeft64(t, 28)
|
||||
t = a[9] ^ d4
|
||||
bc1 = t<<20 | t>>(64-20)
|
||||
bc1 = bits.RotateLeft64(t, 20)
|
||||
a[15] = bc0 ^ (bc2 &^ bc1)
|
||||
a[1] = bc1 ^ (bc3 &^ bc2)
|
||||
a[12] = bc2 ^ (bc4 &^ bc3)
|
||||
@@ -272,15 +274,15 @@ func keccakF1600(a *[25]uint64) {
|
||||
a[9] = bc4 ^ (bc1 &^ bc0)
|
||||
|
||||
t = a[5] ^ d0
|
||||
bc4 = t<<18 | t>>(64-18)
|
||||
bc4 = bits.RotateLeft64(t, 18)
|
||||
t = a[16] ^ d1
|
||||
bc0 = t<<1 | t>>(64-1)
|
||||
bc0 = bits.RotateLeft64(t, 1)
|
||||
t = a[2] ^ d2
|
||||
bc1 = t<<6 | t>>(64-6)
|
||||
bc1 = bits.RotateLeft64(t, 6)
|
||||
t = a[13] ^ d3
|
||||
bc2 = t<<25 | t>>(64-25)
|
||||
bc2 = bits.RotateLeft64(t, 25)
|
||||
t = a[24] ^ d4
|
||||
bc3 = t<<8 | t>>(64-8)
|
||||
bc3 = bits.RotateLeft64(t, 8)
|
||||
a[5] = bc0 ^ (bc2 &^ bc1)
|
||||
a[16] = bc1 ^ (bc3 &^ bc2)
|
||||
a[2] = bc2 ^ (bc4 &^ bc3)
|
||||
@@ -288,15 +290,15 @@ func keccakF1600(a *[25]uint64) {
|
||||
a[24] = bc4 ^ (bc1 &^ bc0)
|
||||
|
||||
t = a[20] ^ d0
|
||||
bc1 = t<<36 | t>>(64-36)
|
||||
bc1 = bits.RotateLeft64(t, 36)
|
||||
t = a[6] ^ d1
|
||||
bc2 = t<<10 | t>>(64-10)
|
||||
bc2 = bits.RotateLeft64(t, 10)
|
||||
t = a[17] ^ d2
|
||||
bc3 = t<<15 | t>>(64-15)
|
||||
bc3 = bits.RotateLeft64(t, 15)
|
||||
t = a[3] ^ d3
|
||||
bc4 = t<<56 | t>>(64-56)
|
||||
bc4 = bits.RotateLeft64(t, 56)
|
||||
t = a[14] ^ d4
|
||||
bc0 = t<<27 | t>>(64-27)
|
||||
bc0 = bits.RotateLeft64(t, 27)
|
||||
a[20] = bc0 ^ (bc2 &^ bc1)
|
||||
a[6] = bc1 ^ (bc3 &^ bc2)
|
||||
a[17] = bc2 ^ (bc4 &^ bc3)
|
||||
@@ -304,15 +306,15 @@ func keccakF1600(a *[25]uint64) {
|
||||
a[14] = bc4 ^ (bc1 &^ bc0)
|
||||
|
||||
t = a[10] ^ d0
|
||||
bc3 = t<<41 | t>>(64-41)
|
||||
bc3 = bits.RotateLeft64(t, 41)
|
||||
t = a[21] ^ d1
|
||||
bc4 = t<<2 | t>>(64-2)
|
||||
bc4 = bits.RotateLeft64(t, 2)
|
||||
t = a[7] ^ d2
|
||||
bc0 = t<<62 | t>>(64-62)
|
||||
bc0 = bits.RotateLeft64(t, 62)
|
||||
t = a[18] ^ d3
|
||||
bc1 = t<<55 | t>>(64-55)
|
||||
bc1 = bits.RotateLeft64(t, 55)
|
||||
t = a[4] ^ d4
|
||||
bc2 = t<<39 | t>>(64-39)
|
||||
bc2 = bits.RotateLeft64(t, 39)
|
||||
a[10] = bc0 ^ (bc2 &^ bc1)
|
||||
a[21] = bc1 ^ (bc3 &^ bc2)
|
||||
a[7] = bc2 ^ (bc4 &^ bc3)
|
||||
@@ -333,13 +335,13 @@ func keccakF1600(a *[25]uint64) {
|
||||
|
||||
bc0 = a[0] ^ d0
|
||||
t = a[1] ^ d1
|
||||
bc1 = t<<44 | t>>(64-44)
|
||||
bc1 = bits.RotateLeft64(t, 44)
|
||||
t = a[2] ^ d2
|
||||
bc2 = t<<43 | t>>(64-43)
|
||||
bc2 = bits.RotateLeft64(t, 43)
|
||||
t = a[3] ^ d3
|
||||
bc3 = t<<21 | t>>(64-21)
|
||||
bc3 = bits.RotateLeft64(t, 21)
|
||||
t = a[4] ^ d4
|
||||
bc4 = t<<14 | t>>(64-14)
|
||||
bc4 = bits.RotateLeft64(t, 14)
|
||||
a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i+3]
|
||||
a[1] = bc1 ^ (bc3 &^ bc2)
|
||||
a[2] = bc2 ^ (bc4 &^ bc3)
|
||||
@@ -347,15 +349,15 @@ func keccakF1600(a *[25]uint64) {
|
||||
a[4] = bc4 ^ (bc1 &^ bc0)
|
||||
|
||||
t = a[5] ^ d0
|
||||
bc2 = t<<3 | t>>(64-3)
|
||||
bc2 = bits.RotateLeft64(t, 3)
|
||||
t = a[6] ^ d1
|
||||
bc3 = t<<45 | t>>(64-45)
|
||||
bc3 = bits.RotateLeft64(t, 45)
|
||||
t = a[7] ^ d2
|
||||
bc4 = t<<61 | t>>(64-61)
|
||||
bc4 = bits.RotateLeft64(t, 61)
|
||||
t = a[8] ^ d3
|
||||
bc0 = t<<28 | t>>(64-28)
|
||||
bc0 = bits.RotateLeft64(t, 28)
|
||||
t = a[9] ^ d4
|
||||
bc1 = t<<20 | t>>(64-20)
|
||||
bc1 = bits.RotateLeft64(t, 20)
|
||||
a[5] = bc0 ^ (bc2 &^ bc1)
|
||||
a[6] = bc1 ^ (bc3 &^ bc2)
|
||||
a[7] = bc2 ^ (bc4 &^ bc3)
|
||||
@@ -363,15 +365,15 @@ func keccakF1600(a *[25]uint64) {
|
||||
a[9] = bc4 ^ (bc1 &^ bc0)
|
||||
|
||||
t = a[10] ^ d0
|
||||
bc4 = t<<18 | t>>(64-18)
|
||||
bc4 = bits.RotateLeft64(t, 18)
|
||||
t = a[11] ^ d1
|
||||
bc0 = t<<1 | t>>(64-1)
|
||||
bc0 = bits.RotateLeft64(t, 1)
|
||||
t = a[12] ^ d2
|
||||
bc1 = t<<6 | t>>(64-6)
|
||||
bc1 = bits.RotateLeft64(t, 6)
|
||||
t = a[13] ^ d3
|
||||
bc2 = t<<25 | t>>(64-25)
|
||||
bc2 = bits.RotateLeft64(t, 25)
|
||||
t = a[14] ^ d4
|
||||
bc3 = t<<8 | t>>(64-8)
|
||||
bc3 = bits.RotateLeft64(t, 8)
|
||||
a[10] = bc0 ^ (bc2 &^ bc1)
|
||||
a[11] = bc1 ^ (bc3 &^ bc2)
|
||||
a[12] = bc2 ^ (bc4 &^ bc3)
|
||||
@@ -379,15 +381,15 @@ func keccakF1600(a *[25]uint64) {
|
||||
a[14] = bc4 ^ (bc1 &^ bc0)
|
||||
|
||||
t = a[15] ^ d0
|
||||
bc1 = t<<36 | t>>(64-36)
|
||||
bc1 = bits.RotateLeft64(t, 36)
|
||||
t = a[16] ^ d1
|
||||
bc2 = t<<10 | t>>(64-10)
|
||||
bc2 = bits.RotateLeft64(t, 10)
|
||||
t = a[17] ^ d2
|
||||
bc3 = t<<15 | t>>(64-15)
|
||||
bc3 = bits.RotateLeft64(t, 15)
|
||||
t = a[18] ^ d3
|
||||
bc4 = t<<56 | t>>(64-56)
|
||||
bc4 = bits.RotateLeft64(t, 56)
|
||||
t = a[19] ^ d4
|
||||
bc0 = t<<27 | t>>(64-27)
|
||||
bc0 = bits.RotateLeft64(t, 27)
|
||||
a[15] = bc0 ^ (bc2 &^ bc1)
|
||||
a[16] = bc1 ^ (bc3 &^ bc2)
|
||||
a[17] = bc2 ^ (bc4 &^ bc3)
|
||||
@@ -395,15 +397,15 @@ func keccakF1600(a *[25]uint64) {
|
||||
a[19] = bc4 ^ (bc1 &^ bc0)
|
||||
|
||||
t = a[20] ^ d0
|
||||
bc3 = t<<41 | t>>(64-41)
|
||||
bc3 = bits.RotateLeft64(t, 41)
|
||||
t = a[21] ^ d1
|
||||
bc4 = t<<2 | t>>(64-2)
|
||||
bc4 = bits.RotateLeft64(t, 2)
|
||||
t = a[22] ^ d2
|
||||
bc0 = t<<62 | t>>(64-62)
|
||||
bc0 = bits.RotateLeft64(t, 62)
|
||||
t = a[23] ^ d3
|
||||
bc1 = t<<55 | t>>(64-55)
|
||||
bc1 = bits.RotateLeft64(t, 55)
|
||||
t = a[24] ^ d4
|
||||
bc2 = t<<39 | t>>(64-39)
|
||||
bc2 = bits.RotateLeft64(t, 39)
|
||||
a[20] = bc0 ^ (bc2 &^ bc1)
|
||||
a[21] = bc1 ^ (bc3 &^ bc2)
|
||||
a[22] = bc2 ^ (bc4 &^ bc3)
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ import (
|
||||
"golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
// Server wraps an Agent and uses it to implement the agent side of
|
||||
// server wraps an Agent and uses it to implement the agent side of
|
||||
// the SSH-agent, wire protocol.
|
||||
type server struct {
|
||||
agent Agent
|
||||
|
||||
+2
-1
@@ -114,7 +114,8 @@ var cipherModes = map[string]*cipherMode{
|
||||
"arcfour": {16, 0, streamCipherMode(0, newRC4)},
|
||||
|
||||
// AEAD ciphers
|
||||
gcmCipherID: {16, 12, newGCMCipher},
|
||||
gcm128CipherID: {16, 12, newGCMCipher},
|
||||
gcm256CipherID: {32, 12, newGCMCipher},
|
||||
chacha20Poly1305ID: {64, 0, newChaCha20Cipher},
|
||||
|
||||
// CBC mode is insecure and so is not included in the default config.
|
||||
|
||||
+1
-1
@@ -141,7 +141,7 @@ func TestCVE202143565(t *testing.T) {
|
||||
constructPacket func(packetCipher) io.Reader
|
||||
}{
|
||||
{
|
||||
cipher: gcmCipherID,
|
||||
cipher: gcm128CipherID,
|
||||
constructPacket: func(client packetCipher) io.Reader {
|
||||
internalCipher := client.(*gcmCipher)
|
||||
b := &bytes.Buffer{}
|
||||
|
||||
@@ -132,9 +132,7 @@ func TestClientAuthPublicKey(t *testing.T) {
|
||||
if err := tryAuth(t, config); err != nil {
|
||||
t.Fatalf("unable to dial remote side: %s", err)
|
||||
}
|
||||
// Once the server implements the server-sig-algs extension, this will turn
|
||||
// into KeyAlgoRSASHA256.
|
||||
if len(signer.used) != 1 || signer.used[0] != KeyAlgoRSA {
|
||||
if len(signer.used) != 1 || signer.used[0] != KeyAlgoRSASHA256 {
|
||||
t.Errorf("unexpected Sign/SignWithAlgorithm calls: %q", signer.used)
|
||||
}
|
||||
}
|
||||
|
||||
+20
-4
@@ -10,6 +10,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
_ "crypto/sha1"
|
||||
@@ -27,7 +28,7 @@ const (
|
||||
// supportedCiphers lists ciphers we support but might not recommend.
|
||||
var supportedCiphers = []string{
|
||||
"aes128-ctr", "aes192-ctr", "aes256-ctr",
|
||||
"aes128-gcm@openssh.com",
|
||||
"aes128-gcm@openssh.com", gcm256CipherID,
|
||||
chacha20Poly1305ID,
|
||||
"arcfour256", "arcfour128", "arcfour",
|
||||
aes128cbcID,
|
||||
@@ -36,7 +37,7 @@ var supportedCiphers = []string{
|
||||
|
||||
// preferredCiphers specifies the default preference for ciphers.
|
||||
var preferredCiphers = []string{
|
||||
"aes128-gcm@openssh.com",
|
||||
"aes128-gcm@openssh.com", gcm256CipherID,
|
||||
chacha20Poly1305ID,
|
||||
"aes128-ctr", "aes192-ctr", "aes256-ctr",
|
||||
}
|
||||
@@ -118,6 +119,20 @@ func algorithmsForKeyFormat(keyFormat string) []string {
|
||||
}
|
||||
}
|
||||
|
||||
// supportedPubKeyAuthAlgos specifies the supported client public key
|
||||
// authentication algorithms. Note that this doesn't include certificate types
|
||||
// since those use the underlying algorithm. This list is sent to the client if
|
||||
// it supports the server-sig-algs extension. Order is irrelevant.
|
||||
var supportedPubKeyAuthAlgos = []string{
|
||||
KeyAlgoED25519,
|
||||
KeyAlgoSKED25519, KeyAlgoSKECDSA256,
|
||||
KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521,
|
||||
KeyAlgoRSASHA256, KeyAlgoRSASHA512, KeyAlgoRSA,
|
||||
KeyAlgoDSA,
|
||||
}
|
||||
|
||||
var supportedPubKeyAuthAlgosList = strings.Join(supportedPubKeyAuthAlgos, ",")
|
||||
|
||||
// unexpectedMessageError results when the SSH message that we received didn't
|
||||
// match what we wanted.
|
||||
func unexpectedMessageError(expected, got uint8) error {
|
||||
@@ -153,7 +168,7 @@ func (a *directionAlgorithms) rekeyBytes() int64 {
|
||||
// 2^(BLOCKSIZE/4) blocks. For all AES flavors BLOCKSIZE is
|
||||
// 128.
|
||||
switch a.Cipher {
|
||||
case "aes128-ctr", "aes192-ctr", "aes256-ctr", gcmCipherID, aes128cbcID:
|
||||
case "aes128-ctr", "aes192-ctr", "aes256-ctr", gcm128CipherID, gcm256CipherID, aes128cbcID:
|
||||
return 16 * (1 << 32)
|
||||
|
||||
}
|
||||
@@ -163,7 +178,8 @@ func (a *directionAlgorithms) rekeyBytes() int64 {
|
||||
}
|
||||
|
||||
var aeadCiphers = map[string]bool{
|
||||
gcmCipherID: true,
|
||||
gcm128CipherID: true,
|
||||
gcm256CipherID: true,
|
||||
chacha20Poly1305ID: true,
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -97,7 +97,7 @@ func (c *connection) Close() error {
|
||||
return c.sshConn.conn.Close()
|
||||
}
|
||||
|
||||
// sshconn provides net.Conn metadata, but disallows direct reads and
|
||||
// sshConn provides net.Conn metadata, but disallows direct reads and
|
||||
// writes.
|
||||
type sshConn struct {
|
||||
conn net.Conn
|
||||
|
||||
+51
-20
@@ -58,11 +58,13 @@ type handshakeTransport struct {
|
||||
incoming chan []byte
|
||||
readError error
|
||||
|
||||
mu sync.Mutex
|
||||
writeError error
|
||||
sentInitPacket []byte
|
||||
sentInitMsg *kexInitMsg
|
||||
pendingPackets [][]byte // Used when a key exchange is in progress.
|
||||
mu sync.Mutex
|
||||
writeError error
|
||||
sentInitPacket []byte
|
||||
sentInitMsg *kexInitMsg
|
||||
pendingPackets [][]byte // Used when a key exchange is in progress.
|
||||
writePacketsLeft uint32
|
||||
writeBytesLeft int64
|
||||
|
||||
// If the read loop wants to schedule a kex, it pings this
|
||||
// channel, and the write loop will send out a kex
|
||||
@@ -71,7 +73,8 @@ type handshakeTransport struct {
|
||||
|
||||
// If the other side requests or confirms a kex, its kexInit
|
||||
// packet is sent here for the write loop to find it.
|
||||
startKex chan *pendingKex
|
||||
startKex chan *pendingKex
|
||||
kexLoopDone chan struct{} // closed (with writeError non-nil) when kexLoop exits
|
||||
|
||||
// data for host key checking
|
||||
hostKeyCallback HostKeyCallback
|
||||
@@ -86,12 +89,10 @@ type handshakeTransport struct {
|
||||
// Algorithms agreed in the last key exchange.
|
||||
algorithms *algorithms
|
||||
|
||||
// Counters exclusively owned by readLoop.
|
||||
readPacketsLeft uint32
|
||||
readBytesLeft int64
|
||||
|
||||
writePacketsLeft uint32
|
||||
writeBytesLeft int64
|
||||
|
||||
// The session ID or nil if first kex did not complete yet.
|
||||
sessionID []byte
|
||||
}
|
||||
@@ -108,7 +109,8 @@ func newHandshakeTransport(conn keyingTransport, config *Config, clientVersion,
|
||||
clientVersion: clientVersion,
|
||||
incoming: make(chan []byte, chanSize),
|
||||
requestKex: make(chan struct{}, 1),
|
||||
startKex: make(chan *pendingKex, 1),
|
||||
startKex: make(chan *pendingKex),
|
||||
kexLoopDone: make(chan struct{}),
|
||||
|
||||
config: config,
|
||||
}
|
||||
@@ -340,16 +342,17 @@ write:
|
||||
t.mu.Unlock()
|
||||
}
|
||||
|
||||
// drain startKex channel. We don't service t.requestKex
|
||||
// because nobody does blocking sends there.
|
||||
go func() {
|
||||
for init := range t.startKex {
|
||||
init.done <- t.writeError
|
||||
}
|
||||
}()
|
||||
|
||||
// Unblock reader.
|
||||
t.conn.Close()
|
||||
|
||||
// drain startKex channel. We don't service t.requestKex
|
||||
// because nobody does blocking sends there.
|
||||
for request := range t.startKex {
|
||||
request.done <- t.getWriteError()
|
||||
}
|
||||
|
||||
// Mark that the loop is done so that Close can return.
|
||||
close(t.kexLoopDone)
|
||||
}
|
||||
|
||||
// The protocol uses uint32 for packet counters, so we can't let them
|
||||
@@ -545,7 +548,16 @@ func (t *handshakeTransport) writePacket(p []byte) error {
|
||||
}
|
||||
|
||||
func (t *handshakeTransport) Close() error {
|
||||
return t.conn.Close()
|
||||
// Close the connection. This should cause the readLoop goroutine to wake up
|
||||
// and close t.startKex, which will shut down kexLoop if running.
|
||||
err := t.conn.Close()
|
||||
|
||||
// Wait for the kexLoop goroutine to complete.
|
||||
// At that point we know that the readLoop goroutine is complete too,
|
||||
// because kexLoop itself waits for readLoop to close the startKex channel.
|
||||
<-t.kexLoopDone
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error {
|
||||
@@ -615,7 +627,8 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if t.sessionID == nil {
|
||||
firstKeyExchange := t.sessionID == nil
|
||||
if firstKeyExchange {
|
||||
t.sessionID = result.H
|
||||
}
|
||||
result.SessionID = t.sessionID
|
||||
@@ -626,6 +639,24 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error {
|
||||
if err = t.conn.writePacket([]byte{msgNewKeys}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// On the server side, after the first SSH_MSG_NEWKEYS, send a SSH_MSG_EXT_INFO
|
||||
// message with the server-sig-algs extension if the client supports it. See
|
||||
// RFC 8308, Sections 2.4 and 3.1.
|
||||
if !isClient && firstKeyExchange && contains(clientInit.KexAlgos, "ext-info-c") {
|
||||
extInfo := &extInfoMsg{
|
||||
NumExtensions: 1,
|
||||
Payload: make([]byte, 0, 4+15+4+len(supportedPubKeyAuthAlgosList)),
|
||||
}
|
||||
extInfo.Payload = appendInt(extInfo.Payload, len("server-sig-algs"))
|
||||
extInfo.Payload = append(extInfo.Payload, "server-sig-algs"...)
|
||||
extInfo.Payload = appendInt(extInfo.Payload, len(supportedPubKeyAuthAlgosList))
|
||||
extInfo.Payload = append(extInfo.Payload, supportedPubKeyAuthAlgosList...)
|
||||
if err := t.conn.writePacket(Marshal(extInfo)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if packet, err := t.conn.readPacket(); err != nil {
|
||||
return err
|
||||
} else if packet[0] != msgNewKeys {
|
||||
|
||||
@@ -562,7 +562,7 @@ func TestHandshakeRekeyDefault(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestHandshakeAEADCipherNoMAC(t *testing.T) {
|
||||
for _, cipher := range []string{chacha20Poly1305ID, gcmCipherID} {
|
||||
for _, cipher := range []string{chacha20Poly1305ID, gcm128CipherID} {
|
||||
checker := &syncChecker{
|
||||
called: make(chan int, 1),
|
||||
}
|
||||
|
||||
+3
-3
@@ -1087,9 +1087,9 @@ func (*PassphraseMissingError) Error() string {
|
||||
return "ssh: this private key is passphrase protected"
|
||||
}
|
||||
|
||||
// ParseRawPrivateKey returns a private key from a PEM encoded private key. It
|
||||
// supports RSA (PKCS#1), PKCS#8, DSA (OpenSSL), and ECDSA private keys. If the
|
||||
// private key is encrypted, it will return a PassphraseMissingError.
|
||||
// ParseRawPrivateKey returns a private key from a PEM encoded private key. It supports
|
||||
// RSA, DSA, ECDSA, and Ed25519 private keys in PKCS#1, PKCS#8, OpenSSL, and OpenSSH
|
||||
// formats. If the private key is encrypted, it will return a PassphraseMissingError.
|
||||
func ParseRawPrivateKey(pemBytes []byte) (interface{}, error) {
|
||||
block, _ := pem.Decode(pemBytes)
|
||||
if block == nil {
|
||||
|
||||
@@ -142,7 +142,7 @@ func keyEq(a, b ssh.PublicKey) bool {
|
||||
return bytes.Equal(a.Marshal(), b.Marshal())
|
||||
}
|
||||
|
||||
// IsAuthorityForHost can be used as a callback in ssh.CertChecker
|
||||
// IsHostAuthority can be used as a callback in ssh.CertChecker
|
||||
func (db *hostKeyDB) IsHostAuthority(remote ssh.PublicKey, address string) bool {
|
||||
h, p, err := net.SplitHostPort(address)
|
||||
if err != nil {
|
||||
|
||||
+1
-1
@@ -68,7 +68,7 @@ type kexInitMsg struct {
|
||||
|
||||
// See RFC 4253, section 8.
|
||||
|
||||
// Diffie-Helman
|
||||
// Diffie-Hellman
|
||||
const msgKexDHInit = 30
|
||||
|
||||
type kexDHInitMsg struct {
|
||||
|
||||
+2
-11
@@ -291,15 +291,6 @@ func (s *connection) serverHandshake(config *ServerConfig) (*Permissions, error)
|
||||
return perms, err
|
||||
}
|
||||
|
||||
func isAcceptableAlgo(algo string) bool {
|
||||
switch algo {
|
||||
case KeyAlgoRSA, KeyAlgoRSASHA256, KeyAlgoRSASHA512, KeyAlgoDSA, KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521, KeyAlgoSKECDSA256, KeyAlgoED25519, KeyAlgoSKED25519,
|
||||
CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoSKECDSA256v01, CertAlgoED25519v01, CertAlgoSKED25519v01:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func checkSourceAddress(addr net.Addr, sourceAddrs string) error {
|
||||
if addr == nil {
|
||||
return errors.New("ssh: no address known for client, but source-address match required")
|
||||
@@ -514,7 +505,7 @@ userAuthLoop:
|
||||
return nil, parseError(msgUserAuthRequest)
|
||||
}
|
||||
algo := string(algoBytes)
|
||||
if !isAcceptableAlgo(algo) {
|
||||
if !contains(supportedPubKeyAuthAlgos, underlyingAlgo(algo)) {
|
||||
authErr = fmt.Errorf("ssh: algorithm %q not accepted", algo)
|
||||
break
|
||||
}
|
||||
@@ -572,7 +563,7 @@ userAuthLoop:
|
||||
// algorithm name that corresponds to algo with
|
||||
// sig.Format. This is usually the same, but
|
||||
// for certs, the names differ.
|
||||
if !isAcceptableAlgo(sig.Format) {
|
||||
if !contains(supportedPubKeyAuthAlgos, sig.Format) {
|
||||
authErr = fmt.Errorf("ssh: algorithm %q not accepted", sig.Format)
|
||||
break
|
||||
}
|
||||
|
||||
+2
-1
@@ -17,7 +17,8 @@ import (
|
||||
const debugTransport = false
|
||||
|
||||
const (
|
||||
gcmCipherID = "aes128-gcm@openssh.com"
|
||||
gcm128CipherID = "aes128-gcm@openssh.com"
|
||||
gcm256CipherID = "aes256-gcm@openssh.com"
|
||||
aes128cbcID = "aes128-cbc"
|
||||
tripledescbcID = "3des-cbc"
|
||||
)
|
||||
|
||||
+14
-21
@@ -18,7 +18,10 @@ package twofish // import "golang.org/x/crypto/twofish"
|
||||
// LibTomCrypt is free for all purposes under the public domain.
|
||||
// It was heavily inspired by the go blowfish package.
|
||||
|
||||
import "strconv"
|
||||
import (
|
||||
"math/bits"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// BlockSize is the constant block size of Twofish.
|
||||
const BlockSize = 16
|
||||
@@ -76,12 +79,12 @@ func NewCipher(key []byte) (*Cipher, error) {
|
||||
tmp[j] = 2*i + 1
|
||||
}
|
||||
B := h(tmp[:], key, 1)
|
||||
B = rol(B, 8)
|
||||
B = bits.RotateLeft32(B, 8)
|
||||
|
||||
c.k[2*i] = A + B
|
||||
|
||||
// K[2i+1] = (A + 2B) <<< 9
|
||||
c.k[2*i+1] = rol(2*B+A, 9)
|
||||
c.k[2*i+1] = bits.RotateLeft32(2*B+A, 9)
|
||||
}
|
||||
|
||||
// Calculate sboxes
|
||||
@@ -129,16 +132,6 @@ func load32l(src []byte) uint32 {
|
||||
return uint32(src[0]) | uint32(src[1])<<8 | uint32(src[2])<<16 | uint32(src[3])<<24
|
||||
}
|
||||
|
||||
// rol returns x after a left circular rotation of y bits.
|
||||
func rol(x, y uint32) uint32 {
|
||||
return (x << (y & 31)) | (x >> (32 - (y & 31)))
|
||||
}
|
||||
|
||||
// ror returns x after a right circular rotation of y bits.
|
||||
func ror(x, y uint32) uint32 {
|
||||
return (x >> (y & 31)) | (x << (32 - (y & 31)))
|
||||
}
|
||||
|
||||
// The RS matrix. See [TWOFISH] 4.3
|
||||
var rs = [4][8]byte{
|
||||
{0x01, 0xA4, 0x55, 0x87, 0x5A, 0x58, 0xDB, 0x9E},
|
||||
@@ -282,13 +275,13 @@ func (c *Cipher) Encrypt(dst, src []byte) {
|
||||
k := c.k[8+i*4 : 12+i*4]
|
||||
t2 := S2[byte(ib)] ^ S3[byte(ib>>8)] ^ S4[byte(ib>>16)] ^ S1[byte(ib>>24)]
|
||||
t1 := S1[byte(ia)] ^ S2[byte(ia>>8)] ^ S3[byte(ia>>16)] ^ S4[byte(ia>>24)] + t2
|
||||
ic = ror(ic^(t1+k[0]), 1)
|
||||
id = rol(id, 1) ^ (t2 + t1 + k[1])
|
||||
ic = bits.RotateLeft32(ic^(t1+k[0]), -1)
|
||||
id = bits.RotateLeft32(id, 1) ^ (t2 + t1 + k[1])
|
||||
|
||||
t2 = S2[byte(id)] ^ S3[byte(id>>8)] ^ S4[byte(id>>16)] ^ S1[byte(id>>24)]
|
||||
t1 = S1[byte(ic)] ^ S2[byte(ic>>8)] ^ S3[byte(ic>>16)] ^ S4[byte(ic>>24)] + t2
|
||||
ia = ror(ia^(t1+k[2]), 1)
|
||||
ib = rol(ib, 1) ^ (t2 + t1 + k[3])
|
||||
ia = bits.RotateLeft32(ia^(t1+k[2]), -1)
|
||||
ib = bits.RotateLeft32(ib, 1) ^ (t2 + t1 + k[3])
|
||||
}
|
||||
|
||||
// Output with "undo last swap"
|
||||
@@ -326,13 +319,13 @@ func (c *Cipher) Decrypt(dst, src []byte) {
|
||||
k := c.k[4+i*4 : 8+i*4]
|
||||
t2 := S2[byte(id)] ^ S3[byte(id>>8)] ^ S4[byte(id>>16)] ^ S1[byte(id>>24)]
|
||||
t1 := S1[byte(ic)] ^ S2[byte(ic>>8)] ^ S3[byte(ic>>16)] ^ S4[byte(ic>>24)] + t2
|
||||
ia = rol(ia, 1) ^ (t1 + k[2])
|
||||
ib = ror(ib^(t2+t1+k[3]), 1)
|
||||
ia = bits.RotateLeft32(ia, 1) ^ (t1 + k[2])
|
||||
ib = bits.RotateLeft32(ib^(t2+t1+k[3]), -1)
|
||||
|
||||
t2 = S2[byte(ib)] ^ S3[byte(ib>>8)] ^ S4[byte(ib>>16)] ^ S1[byte(ib>>24)]
|
||||
t1 = S1[byte(ia)] ^ S2[byte(ia>>8)] ^ S3[byte(ia>>16)] ^ S4[byte(ia>>24)] + t2
|
||||
ic = rol(ic, 1) ^ (t1 + k[0])
|
||||
id = ror(id^(t2+t1+k[1]), 1)
|
||||
ic = bits.RotateLeft32(ic, 1) ^ (t1 + k[0])
|
||||
id = bits.RotateLeft32(id^(t2+t1+k[1]), -1)
|
||||
}
|
||||
|
||||
// Undo pre-whitening
|
||||
|
||||
Reference in New Issue
Block a user