1
0
mirror of https://github.com/docker/docs.git synced 2026-10-29 20:39:05 +03:00

adding gotuf to notary

Signed-off-by: David Lawrence <david.lawrence@docker.com> (github: endophage)
This commit is contained in:
David Lawrence
2015-10-27 16:36:06 -07:00
parent 4036910a6a
commit 2833a88292
112 changed files with 6909 additions and 252 deletions

24
Godeps/Godeps.json generated
View File

@@ -94,10 +94,6 @@
"ImportPath": "github.com/dvsekhvalnov/jose2go",
"Rev": "5307afb3bb6169b0f68cdf519a5964c843344441"
},
{
"ImportPath": "github.com/endophage/gotuf",
"Rev": "e1345f72687ad0443c25b3c58d4502c717c4936a"
},
{
"ImportPath": "github.com/go-sql-driver/mysql",
"Comment": "v1.2-97-g0cc29e9",
@@ -200,6 +196,26 @@
"ImportPath": "golang.org/x/crypto/blowfish",
"Rev": "bfc286917c5fcb7420d7e3092b50bbfd31b38a98"
},
{
"ImportPath": "golang.org/x/crypto/nacl/secretbox",
"Rev": "bfc286917c5fcb7420d7e3092b50bbfd31b38a98"
},
{
"ImportPath": "golang.org/x/crypto/pbkdf2",
"Rev": "bfc286917c5fcb7420d7e3092b50bbfd31b38a98"
},
{
"ImportPath": "golang.org/x/crypto/poly1305",
"Rev": "bfc286917c5fcb7420d7e3092b50bbfd31b38a98"
},
{
"ImportPath": "golang.org/x/crypto/salsa20/salsa",
"Rev": "bfc286917c5fcb7420d7e3092b50bbfd31b38a98"
},
{
"ImportPath": "golang.org/x/crypto/scrypt",
"Rev": "bfc286917c5fcb7420d7e3092b50bbfd31b38a98"
},
{
"ImportPath": "golang.org/x/net/context",
"Rev": "47990a1ba55743e6ef1affd3a14e5bac8553615d"

View File

@@ -1,3 +0,0 @@
/db/
*.bkp
*.swp

View File

@@ -1,30 +0,0 @@
language: go
go:
- 1.4
- tip
sudo: false
before_install:
- go get golang.org/x/tools/cmd/cover
script:
- go test -race -cover ./...
notifications:
irc:
channels:
- "chat.freenode.net#flynn"
use_notice: true
skip_join: true
on_success: change
on_failure: always
template:
- "%{repository}/%{branch} - %{commit}: %{message} %{build_url}"
email:
on_success: never
on_failure: always
matrix:
allow_failures:
- go: tip

View File

@@ -1,71 +0,0 @@
{
"ImportPath": "github.com/endophage/gotuf",
"GoVersion": "go1.5.1",
"Packages": [
"./..."
],
"Deps": [
{
"ImportPath": "github.com/Sirupsen/logrus",
"Comment": "v0.7.3",
"Rev": "55eb11d21d2a31a3cc93838241d04800f52e823d"
},
{
"ImportPath": "github.com/agl/ed25519",
"Rev": "d2b94fd789ea21d12fac1a4443dd3a3f79cda72c"
},
{
"ImportPath": "github.com/docker/docker/pkg/term",
"Comment": "v1.7.1",
"Rev": "786b29d4db80a6175e72b47a794ee044918ba734"
},
{
"ImportPath": "github.com/docker/notary/pkg/passphrase",
"Comment": "docker-v1.8.0-rc1-229-ge646033",
"Rev": "e6460330bdbef7d9a7a9a3dc51df2be83861c1b0"
},
{
"ImportPath": "github.com/docker/notary/trustmanager",
"Comment": "docker-v1.8.0-rc1-229-ge646033",
"Rev": "e6460330bdbef7d9a7a9a3dc51df2be83861c1b0"
},
{
"ImportPath": "github.com/google/gofuzz",
"Rev": "bbcb9da2d746f8bdbd6a936686a0a6067ada0ec5"
},
{
"ImportPath": "github.com/jfrazelle/go/canonical/json",
"Rev": "6e461eb70cb4187b41a84e9a567d7137bdbe0f16"
},
{
"ImportPath": "github.com/mattn/go-sqlite3",
"Comment": "v1.0.0",
"Rev": "b4142c444a8941d0d92b0b7103a24df9cd815e42"
},
{
"ImportPath": "github.com/stretchr/testify/assert",
"Comment": "v1.0-40-g7c2b1e5",
"Rev": "7c2b1e5640dcf2631213ca962d892bffa1e08860"
},
{
"ImportPath": "golang.org/x/crypto/nacl/secretbox",
"Rev": "bfc286917c5fcb7420d7e3092b50bbfd31b38a98"
},
{
"ImportPath": "golang.org/x/crypto/pbkdf2",
"Rev": "bfc286917c5fcb7420d7e3092b50bbfd31b38a98"
},
{
"ImportPath": "golang.org/x/crypto/poly1305",
"Rev": "bfc286917c5fcb7420d7e3092b50bbfd31b38a98"
},
{
"ImportPath": "golang.org/x/crypto/salsa20/salsa",
"Rev": "bfc286917c5fcb7420d7e3092b50bbfd31b38a98"
},
{
"ImportPath": "golang.org/x/crypto/scrypt",
"Rev": "bfc286917c5fcb7420d7e3092b50bbfd31b38a98"
}
]
}

View File

@@ -1,5 +0,0 @@
This directory tree is generated automatically by godep.
Please do not edit.
See https://github.com/tools/godep for more information.

View File

@@ -1,34 +0,0 @@
# Set an output prefix, which is the local directory if not specified
PREFIX?=$(shell pwd)
vet:
@echo "+ $@"
@go vet ./...
fmt:
@echo "+ $@"
@test -z "$$(gofmt -s -l . | grep -v Godeps/_workspace/src/ | tee /dev/stderr)" || \
echo "+ please format Go code with 'gofmt -s'"
lint:
@echo "+ $@"
@test -z "$$(golint ./... | grep -v Godeps/_workspace/src/ | tee /dev/stderr)"
build:
@echo "+ $@"
@go build -v ${GO_LDFLAGS} ./...
test:
@echo "+ $@"
@go test -test.short ./...
test-full:
@echo "+ $@"
@go test ./...
binaries: ${PREFIX}/bin/registry ${PREFIX}/bin/registry-api-descriptor-template ${PREFIX}/bin/dist
@echo "+ $@"
clean:
@echo "+ $@"
@rm -rf "${PREFIX}/bin/registry" "${PREFIX}/bin/registry-api-descriptor-template"

View File

@@ -0,0 +1,149 @@
// Copyright 2012 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 secretbox encrypts and authenticates small messages.
Secretbox uses XSalsa20 and Poly1305 to encrypt and authenticate messages with
secret-key cryptography. The length of messages is not hidden.
It is the caller's responsibility to ensure the uniqueness of nonces—for
example, by using nonce 1 for the first message, nonce 2 for the second
message, etc. Nonces are long enough that randomly generated nonces have
negligible risk of collision.
This package is interoperable with NaCl: http://nacl.cr.yp.to/secretbox.html.
*/
package secretbox
import (
"golang.org/x/crypto/poly1305"
"golang.org/x/crypto/salsa20/salsa"
)
// Overhead is the number of bytes of overhead when boxing a message.
const Overhead = poly1305.TagSize
// setup produces a sub-key and Salsa20 counter given a nonce and key.
func setup(subKey *[32]byte, counter *[16]byte, nonce *[24]byte, key *[32]byte) {
// We use XSalsa20 for encryption so first we need to generate a
// key and nonce with HSalsa20.
var hNonce [16]byte
copy(hNonce[:], nonce[:])
salsa.HSalsa20(subKey, &hNonce, key, &salsa.Sigma)
// The final 8 bytes of the original nonce form the new nonce.
copy(counter[:], nonce[16:])
}
// sliceForAppend takes a slice and a requested number of bytes. It returns a
// slice with the contents of the given slice followed by that many bytes and a
// second slice that aliases into it and contains only the extra bytes. If the
// original slice has sufficient capacity then no allocation is performed.
func sliceForAppend(in []byte, n int) (head, tail []byte) {
if total := len(in) + n; cap(in) >= total {
head = in[:total]
} else {
head = make([]byte, total)
copy(head, in)
}
tail = head[len(in):]
return
}
// Seal appends an encrypted and authenticated copy of message to out, which
// must not overlap message. The key and nonce pair must be unique for each
// distinct message and the output will be Overhead bytes longer than message.
func Seal(out, message []byte, nonce *[24]byte, key *[32]byte) []byte {
var subKey [32]byte
var counter [16]byte
setup(&subKey, &counter, nonce, key)
// The Poly1305 key is generated by encrypting 32 bytes of zeros. Since
// Salsa20 works with 64-byte blocks, we also generate 32 bytes of
// keystream as a side effect.
var firstBlock [64]byte
salsa.XORKeyStream(firstBlock[:], firstBlock[:], &counter, &subKey)
var poly1305Key [32]byte
copy(poly1305Key[:], firstBlock[:])
ret, out := sliceForAppend(out, len(message)+poly1305.TagSize)
// We XOR up to 32 bytes of message with the keystream generated from
// the first block.
firstMessageBlock := message
if len(firstMessageBlock) > 32 {
firstMessageBlock = firstMessageBlock[:32]
}
tagOut := out
out = out[poly1305.TagSize:]
for i, x := range firstMessageBlock {
out[i] = firstBlock[32+i] ^ x
}
message = message[len(firstMessageBlock):]
ciphertext := out
out = out[len(firstMessageBlock):]
// Now encrypt the rest.
counter[8] = 1
salsa.XORKeyStream(out, message, &counter, &subKey)
var tag [poly1305.TagSize]byte
poly1305.Sum(&tag, ciphertext, &poly1305Key)
copy(tagOut, tag[:])
return ret
}
// 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) {
if len(box) < Overhead {
return nil, false
}
var subKey [32]byte
var counter [16]byte
setup(&subKey, &counter, nonce, key)
// The Poly1305 key is generated by encrypting 32 bytes of zeros. Since
// Salsa20 works with 64-byte blocks, we also generate 32 bytes of
// keystream as a side effect.
var firstBlock [64]byte
salsa.XORKeyStream(firstBlock[:], firstBlock[:], &counter, &subKey)
var poly1305Key [32]byte
copy(poly1305Key[:], firstBlock[:])
var tag [poly1305.TagSize]byte
copy(tag[:], box)
if !poly1305.Verify(&tag, box[poly1305.TagSize:], &poly1305Key) {
return nil, false
}
ret, out := sliceForAppend(out, len(box)-Overhead)
// We XOR up to 32 bytes of box with the keystream generated from
// the first block.
box = box[Overhead:]
firstMessageBlock := box
if len(firstMessageBlock) > 32 {
firstMessageBlock = firstMessageBlock[:32]
}
for i, x := range firstMessageBlock {
out[i] = firstBlock[32+i] ^ x
}
box = box[len(firstMessageBlock):]
out = out[len(firstMessageBlock):]
// Now decrypt the rest.
counter[8] = 1
salsa.XORKeyStream(out, box, &counter, &subKey)
return ret, true
}

View File

@@ -0,0 +1,91 @@
// Copyright 2012 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 secretbox
import (
"bytes"
"crypto/rand"
"encoding/hex"
"testing"
)
func TestSealOpen(t *testing.T) {
var key [32]byte
var nonce [24]byte
rand.Reader.Read(key[:])
rand.Reader.Read(nonce[:])
var box, opened []byte
for msgLen := 0; msgLen < 128; msgLen += 17 {
message := make([]byte, msgLen)
rand.Reader.Read(message)
box = Seal(box[:0], message, &nonce, &key)
var ok bool
opened, ok = Open(opened[:0], box, &nonce, &key)
if !ok {
t.Errorf("%d: failed to open box", msgLen)
continue
}
if !bytes.Equal(opened, message) {
t.Errorf("%d: got %x, expected %x", msgLen, opened, message)
continue
}
}
for i := range box {
box[i] ^= 0x20
_, ok := Open(opened[:0], box, &nonce, &key)
if ok {
t.Errorf("box was opened after corrupting byte %d", i)
}
box[i] ^= 0x20
}
}
func TestSecretBox(t *testing.T) {
var key [32]byte
var nonce [24]byte
var message [64]byte
for i := range key[:] {
key[i] = 1
}
for i := range nonce[:] {
nonce[i] = 2
}
for i := range message[:] {
message[i] = 3
}
box := Seal(nil, message[:], &nonce, &key)
// expected was generated using the C implementation of NaCl.
expected, _ := hex.DecodeString("8442bc313f4626f1359e3b50122b6ce6fe66ddfe7d39d14e637eb4fd5b45beadab55198df6ab5368439792a23c87db70acb6156dc5ef957ac04f6276cf6093b84be77ff0849cc33e34b7254d5a8f65ad")
if !bytes.Equal(box, expected) {
t.Fatalf("box didn't match, got\n%x\n, expected\n%x", box, expected)
}
}
func TestAppend(t *testing.T) {
var key [32]byte
var nonce [24]byte
var message [8]byte
out := make([]byte, 4)
box := Seal(out, message[:], &nonce, &key)
if !bytes.Equal(box[:4], out[:4]) {
t.Fatalf("Seal didn't correctly append")
}
out = make([]byte, 4, 100)
box = Seal(out, message[:], &nonce, &key)
if !bytes.Equal(box[:4], out[:4]) {
t.Fatalf("Seal didn't correctly append with sufficient capacity.")
}
}

View File

@@ -0,0 +1,77 @@
// Copyright 2012 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 pbkdf2 implements the key derivation function PBKDF2 as defined in RFC
2898 / PKCS #5 v2.0.
A key derivation function is useful when encrypting data based on a password
or any other not-fully-random data. It uses a pseudorandom function to derive
a secure encryption key based on the password.
While v2.0 of the standard defines only one pseudorandom function to use,
HMAC-SHA1, the drafted v2.1 specification allows use of all five FIPS Approved
Hash Functions SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512 for HMAC. To
choose, you can pass the `New` functions from the different SHA packages to
pbkdf2.Key.
*/
package pbkdf2
import (
"crypto/hmac"
"hash"
)
// Key derives a key from the password, salt and iteration count, returning a
// []byte of length keylen that can be used as cryptographic key. The key is
// derived based on the method described as PBKDF2 with the HMAC variant using
// the supplied hash function.
//
// For example, to use a HMAC-SHA-1 based PBKDF2 key derivation function, you
// can get a derived key for e.g. AES-256 (which needs a 32-byte key) by
// doing:
//
// dk := pbkdf2.Key([]byte("some password"), salt, 4096, 32, sha1.New)
//
// Remember to get a good random salt. At least 8 bytes is recommended by the
// RFC.
//
// Using a higher iteration count will increase the cost of an exhaustive
// search but will also make derivation proportionally slower.
func Key(password, salt []byte, iter, keyLen int, h func() hash.Hash) []byte {
prf := hmac.New(h, password)
hashLen := prf.Size()
numBlocks := (keyLen + hashLen - 1) / hashLen
var buf [4]byte
dk := make([]byte, 0, numBlocks*hashLen)
U := make([]byte, hashLen)
for block := 1; block <= numBlocks; block++ {
// N.B.: || means concatenation, ^ means XOR
// for each block T_i = U_1 ^ U_2 ^ ... ^ U_iter
// U_1 = PRF(password, salt || uint(i))
prf.Reset()
prf.Write(salt)
buf[0] = byte(block >> 24)
buf[1] = byte(block >> 16)
buf[2] = byte(block >> 8)
buf[3] = byte(block)
prf.Write(buf[:4])
dk = prf.Sum(dk)
T := dk[len(dk)-hashLen:]
copy(U, T)
// U_n = PRF(password, U_(n-1))
for n := 2; n <= iter; n++ {
prf.Reset()
prf.Write(U)
U = U[:0]
U = prf.Sum(U)
for x := range U {
T[x] ^= U[x]
}
}
}
return dk[:keyLen]
}

View File

@@ -0,0 +1,157 @@
// Copyright 2012 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 pbkdf2
import (
"bytes"
"crypto/sha1"
"crypto/sha256"
"hash"
"testing"
)
type testVector struct {
password string
salt string
iter int
output []byte
}
// Test vectors from RFC 6070, http://tools.ietf.org/html/rfc6070
var sha1TestVectors = []testVector{
{
"password",
"salt",
1,
[]byte{
0x0c, 0x60, 0xc8, 0x0f, 0x96, 0x1f, 0x0e, 0x71,
0xf3, 0xa9, 0xb5, 0x24, 0xaf, 0x60, 0x12, 0x06,
0x2f, 0xe0, 0x37, 0xa6,
},
},
{
"password",
"salt",
2,
[]byte{
0xea, 0x6c, 0x01, 0x4d, 0xc7, 0x2d, 0x6f, 0x8c,
0xcd, 0x1e, 0xd9, 0x2a, 0xce, 0x1d, 0x41, 0xf0,
0xd8, 0xde, 0x89, 0x57,
},
},
{
"password",
"salt",
4096,
[]byte{
0x4b, 0x00, 0x79, 0x01, 0xb7, 0x65, 0x48, 0x9a,
0xbe, 0xad, 0x49, 0xd9, 0x26, 0xf7, 0x21, 0xd0,
0x65, 0xa4, 0x29, 0xc1,
},
},
// // This one takes too long
// {
// "password",
// "salt",
// 16777216,
// []byte{
// 0xee, 0xfe, 0x3d, 0x61, 0xcd, 0x4d, 0xa4, 0xe4,
// 0xe9, 0x94, 0x5b, 0x3d, 0x6b, 0xa2, 0x15, 0x8c,
// 0x26, 0x34, 0xe9, 0x84,
// },
// },
{
"passwordPASSWORDpassword",
"saltSALTsaltSALTsaltSALTsaltSALTsalt",
4096,
[]byte{
0x3d, 0x2e, 0xec, 0x4f, 0xe4, 0x1c, 0x84, 0x9b,
0x80, 0xc8, 0xd8, 0x36, 0x62, 0xc0, 0xe4, 0x4a,
0x8b, 0x29, 0x1a, 0x96, 0x4c, 0xf2, 0xf0, 0x70,
0x38,
},
},
{
"pass\000word",
"sa\000lt",
4096,
[]byte{
0x56, 0xfa, 0x6a, 0xa7, 0x55, 0x48, 0x09, 0x9d,
0xcc, 0x37, 0xd7, 0xf0, 0x34, 0x25, 0xe0, 0xc3,
},
},
}
// Test vectors from
// http://stackoverflow.com/questions/5130513/pbkdf2-hmac-sha2-test-vectors
var sha256TestVectors = []testVector{
{
"password",
"salt",
1,
[]byte{
0x12, 0x0f, 0xb6, 0xcf, 0xfc, 0xf8, 0xb3, 0x2c,
0x43, 0xe7, 0x22, 0x52, 0x56, 0xc4, 0xf8, 0x37,
0xa8, 0x65, 0x48, 0xc9,
},
},
{
"password",
"salt",
2,
[]byte{
0xae, 0x4d, 0x0c, 0x95, 0xaf, 0x6b, 0x46, 0xd3,
0x2d, 0x0a, 0xdf, 0xf9, 0x28, 0xf0, 0x6d, 0xd0,
0x2a, 0x30, 0x3f, 0x8e,
},
},
{
"password",
"salt",
4096,
[]byte{
0xc5, 0xe4, 0x78, 0xd5, 0x92, 0x88, 0xc8, 0x41,
0xaa, 0x53, 0x0d, 0xb6, 0x84, 0x5c, 0x4c, 0x8d,
0x96, 0x28, 0x93, 0xa0,
},
},
{
"passwordPASSWORDpassword",
"saltSALTsaltSALTsaltSALTsaltSALTsalt",
4096,
[]byte{
0x34, 0x8c, 0x89, 0xdb, 0xcb, 0xd3, 0x2b, 0x2f,
0x32, 0xd8, 0x14, 0xb8, 0x11, 0x6e, 0x84, 0xcf,
0x2b, 0x17, 0x34, 0x7e, 0xbc, 0x18, 0x00, 0x18,
0x1c,
},
},
{
"pass\000word",
"sa\000lt",
4096,
[]byte{
0x89, 0xb6, 0x9d, 0x05, 0x16, 0xf8, 0x29, 0x89,
0x3c, 0x69, 0x62, 0x26, 0x65, 0x0a, 0x86, 0x87,
},
},
}
func testHash(t *testing.T, h func() hash.Hash, hashName string, vectors []testVector) {
for i, v := range vectors {
o := Key([]byte(v.password), []byte(v.salt), v.iter, len(v.output), h)
if !bytes.Equal(o, v.output) {
t.Errorf("%s %d: expected %x, got %x", hashName, i, v.output, o)
}
}
}
func TestWithHMACSHA1(t *testing.T) {
testHash(t, sha1.New, "SHA1", sha1TestVectors)
}
func TestWithHMACSHA256(t *testing.T) {
testHash(t, sha256.New, "SHA256", sha256TestVectors)
}

View File

@@ -0,0 +1,45 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This code was translated into a form compatible with 6a from the public
// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
// +build amd64,!gccgo
DATA ·SCALE(SB)/8, $0x37F4000000000000
GLOBL ·SCALE(SB), 8, $8
DATA ·TWO32(SB)/8, $0x41F0000000000000
GLOBL ·TWO32(SB), 8, $8
DATA ·TWO64(SB)/8, $0x43F0000000000000
GLOBL ·TWO64(SB), 8, $8
DATA ·TWO96(SB)/8, $0x45F0000000000000
GLOBL ·TWO96(SB), 8, $8
DATA ·ALPHA32(SB)/8, $0x45E8000000000000
GLOBL ·ALPHA32(SB), 8, $8
DATA ·ALPHA64(SB)/8, $0x47E8000000000000
GLOBL ·ALPHA64(SB), 8, $8
DATA ·ALPHA96(SB)/8, $0x49E8000000000000
GLOBL ·ALPHA96(SB), 8, $8
DATA ·ALPHA130(SB)/8, $0x4C08000000000000
GLOBL ·ALPHA130(SB), 8, $8
DATA ·DOFFSET0(SB)/8, $0x4330000000000000
GLOBL ·DOFFSET0(SB), 8, $8
DATA ·DOFFSET1(SB)/8, $0x4530000000000000
GLOBL ·DOFFSET1(SB), 8, $8
DATA ·DOFFSET2(SB)/8, $0x4730000000000000
GLOBL ·DOFFSET2(SB), 8, $8
DATA ·DOFFSET3(SB)/8, $0x4930000000000000
GLOBL ·DOFFSET3(SB), 8, $8
DATA ·DOFFSET3MINUSTWO128(SB)/8, $0x492FFFFE00000000
GLOBL ·DOFFSET3MINUSTWO128(SB), 8, $8
DATA ·HOFFSET0(SB)/8, $0x43300001FFFFFFFB
GLOBL ·HOFFSET0(SB), 8, $8
DATA ·HOFFSET1(SB)/8, $0x45300001FFFFFFFE
GLOBL ·HOFFSET1(SB), 8, $8
DATA ·HOFFSET2(SB)/8, $0x47300001FFFFFFFE
GLOBL ·HOFFSET2(SB), 8, $8
DATA ·HOFFSET3(SB)/8, $0x49300003FFFFFFFE
GLOBL ·HOFFSET3(SB), 8, $8
DATA ·ROUNDING(SB)/2, $0x137f
GLOBL ·ROUNDING(SB), 8, $2

View File

@@ -0,0 +1,32 @@
// Copyright 2012 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 poly1305 implements Poly1305 one-time message authentication code as specified in http://cr.yp.to/mac/poly1305-20050329.pdf.
Poly1305 is a fast, one-time authentication function. It is infeasible for an
attacker to generate an authenticator for a message without the key. However, a
key must only be used for a single message. Authenticating two different
messages with the same key allows an attacker to forge authenticators for other
messages with the same key.
Poly1305 was originally coupled with AES in order to make Poly1305-AES. AES was
used with a fixed key in order to generate one-time keys from an nonce.
However, in this package AES isn't used and the one-time key is specified
directly.
*/
package poly1305
import "crypto/subtle"
// TagSize is the size, in bytes, of a poly1305 authenticator.
const TagSize = 16
// Verify returns true if mac is a valid authenticator for m with the given
// key.
func Verify(mac *[16]byte, m []byte, key *[32]byte) bool {
var tmp [16]byte
Sum(&tmp, m, key)
return subtle.ConstantTimeCompare(tmp[:], mac[:]) == 1
}

View File

@@ -0,0 +1,497 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This code was translated into a form compatible with 6a from the public
// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
// +build amd64,!gccgo
// func poly1305(out *[16]byte, m *byte, mlen uint64, key *[32]key)
TEXT ·poly1305(SB),0,$224-32
MOVQ out+0(FP),DI
MOVQ m+8(FP),SI
MOVQ mlen+16(FP),DX
MOVQ key+24(FP),CX
MOVQ SP,R11
MOVQ $31,R9
NOTQ R9
ANDQ R9,SP
ADDQ $32,SP
MOVQ R11,32(SP)
MOVQ R12,40(SP)
MOVQ R13,48(SP)
MOVQ R14,56(SP)
MOVQ R15,64(SP)
MOVQ BX,72(SP)
MOVQ BP,80(SP)
FLDCW ·ROUNDING(SB)
MOVL 0(CX),R8
MOVL 4(CX),R9
MOVL 8(CX),AX
MOVL 12(CX),R10
MOVQ DI,88(SP)
MOVQ CX,96(SP)
MOVL $0X43300000,108(SP)
MOVL $0X45300000,116(SP)
MOVL $0X47300000,124(SP)
MOVL $0X49300000,132(SP)
ANDL $0X0FFFFFFF,R8
ANDL $0X0FFFFFFC,R9
ANDL $0X0FFFFFFC,AX
ANDL $0X0FFFFFFC,R10
MOVL R8,104(SP)
MOVL R9,112(SP)
MOVL AX,120(SP)
MOVL R10,128(SP)
FMOVD 104(SP), F0
FSUBD ·DOFFSET0(SB), F0
FMOVD 112(SP), F0
FSUBD ·DOFFSET1(SB), F0
FMOVD 120(SP), F0
FSUBD ·DOFFSET2(SB), F0
FMOVD 128(SP), F0
FSUBD ·DOFFSET3(SB), F0
FXCHD F0, F3
FMOVDP F0, 136(SP)
FXCHD F0, F1
FMOVD F0, 144(SP)
FMULD ·SCALE(SB), F0
FMOVDP F0, 152(SP)
FMOVD F0, 160(SP)
FMULD ·SCALE(SB), F0
FMOVDP F0, 168(SP)
FMOVD F0, 176(SP)
FMULD ·SCALE(SB), F0
FMOVDP F0, 184(SP)
FLDZ
FLDZ
FLDZ
FLDZ
CMPQ DX,$16
JB ADDATMOST15BYTES
INITIALATLEAST16BYTES:
MOVL 12(SI),DI
MOVL 8(SI),CX
MOVL 4(SI),R8
MOVL 0(SI),R9
MOVL DI,128(SP)
MOVL CX,120(SP)
MOVL R8,112(SP)
MOVL R9,104(SP)
ADDQ $16,SI
SUBQ $16,DX
FXCHD F0, F3
FADDD 128(SP), F0
FSUBD ·DOFFSET3MINUSTWO128(SB), F0
FXCHD F0, F1
FADDD 112(SP), F0
FSUBD ·DOFFSET1(SB), F0
FXCHD F0, F2
FADDD 120(SP), F0
FSUBD ·DOFFSET2(SB), F0
FXCHD F0, F3
FADDD 104(SP), F0
FSUBD ·DOFFSET0(SB), F0
CMPQ DX,$16
JB MULTIPLYADDATMOST15BYTES
MULTIPLYADDATLEAST16BYTES:
MOVL 12(SI),DI
MOVL 8(SI),CX
MOVL 4(SI),R8
MOVL 0(SI),R9
MOVL DI,128(SP)
MOVL CX,120(SP)
MOVL R8,112(SP)
MOVL R9,104(SP)
ADDQ $16,SI
SUBQ $16,DX
FMOVD ·ALPHA130(SB), F0
FADDD F2,F0
FSUBD ·ALPHA130(SB), F0
FSUBD F0,F2
FMULD ·SCALE(SB), F0
FMOVD ·ALPHA32(SB), F0
FADDD F2,F0
FSUBD ·ALPHA32(SB), F0
FSUBD F0,F2
FXCHD F0, F2
FADDDP F0,F1
FMOVD ·ALPHA64(SB), F0
FADDD F4,F0
FSUBD ·ALPHA64(SB), F0
FSUBD F0,F4
FMOVD ·ALPHA96(SB), F0
FADDD F6,F0
FSUBD ·ALPHA96(SB), F0
FSUBD F0,F6
FXCHD F0, F6
FADDDP F0,F1
FXCHD F0, F3
FADDDP F0,F5
FXCHD F0, F3
FADDDP F0,F1
FMOVD 176(SP), F0
FMULD F3,F0
FMOVD 160(SP), F0
FMULD F4,F0
FMOVD 144(SP), F0
FMULD F5,F0
FMOVD 136(SP), F0
FMULDP F0,F6
FMOVD 160(SP), F0
FMULD F4,F0
FADDDP F0,F3
FMOVD 144(SP), F0
FMULD F4,F0
FADDDP F0,F2
FMOVD 136(SP), F0
FMULD F4,F0
FADDDP F0,F1
FMOVD 184(SP), F0
FMULDP F0,F4
FXCHD F0, F3
FADDDP F0,F5
FMOVD 144(SP), F0
FMULD F4,F0
FADDDP F0,F2
FMOVD 136(SP), F0
FMULD F4,F0
FADDDP F0,F1
FMOVD 184(SP), F0
FMULD F4,F0
FADDDP F0,F3
FMOVD 168(SP), F0
FMULDP F0,F4
FXCHD F0, F3
FADDDP F0,F4
FMOVD 136(SP), F0
FMULD F5,F0
FADDDP F0,F1
FXCHD F0, F3
FMOVD 184(SP), F0
FMULD F5,F0
FADDDP F0,F3
FXCHD F0, F1
FMOVD 168(SP), F0
FMULD F5,F0
FADDDP F0,F1
FMOVD 152(SP), F0
FMULDP F0,F5
FXCHD F0, F4
FADDDP F0,F1
CMPQ DX,$16
FXCHD F0, F2
FMOVD 128(SP), F0
FSUBD ·DOFFSET3MINUSTWO128(SB), F0
FADDDP F0,F1
FXCHD F0, F1
FMOVD 120(SP), F0
FSUBD ·DOFFSET2(SB), F0
FADDDP F0,F1
FXCHD F0, F3
FMOVD 112(SP), F0
FSUBD ·DOFFSET1(SB), F0
FADDDP F0,F1
FXCHD F0, F2
FMOVD 104(SP), F0
FSUBD ·DOFFSET0(SB), F0
FADDDP F0,F1
JAE MULTIPLYADDATLEAST16BYTES
MULTIPLYADDATMOST15BYTES:
FMOVD ·ALPHA130(SB), F0
FADDD F2,F0
FSUBD ·ALPHA130(SB), F0
FSUBD F0,F2
FMULD ·SCALE(SB), F0
FMOVD ·ALPHA32(SB), F0
FADDD F2,F0
FSUBD ·ALPHA32(SB), F0
FSUBD F0,F2
FMOVD ·ALPHA64(SB), F0
FADDD F5,F0
FSUBD ·ALPHA64(SB), F0
FSUBD F0,F5
FMOVD ·ALPHA96(SB), F0
FADDD F7,F0
FSUBD ·ALPHA96(SB), F0
FSUBD F0,F7
FXCHD F0, F7
FADDDP F0,F1
FXCHD F0, F5
FADDDP F0,F1
FXCHD F0, F3
FADDDP F0,F5
FADDDP F0,F1
FMOVD 176(SP), F0
FMULD F1,F0
FMOVD 160(SP), F0
FMULD F2,F0
FMOVD 144(SP), F0
FMULD F3,F0
FMOVD 136(SP), F0
FMULDP F0,F4
FMOVD 160(SP), F0
FMULD F5,F0
FADDDP F0,F3
FMOVD 144(SP), F0
FMULD F5,F0
FADDDP F0,F2
FMOVD 136(SP), F0
FMULD F5,F0
FADDDP F0,F1
FMOVD 184(SP), F0
FMULDP F0,F5
FXCHD F0, F4
FADDDP F0,F3
FMOVD 144(SP), F0
FMULD F5,F0
FADDDP F0,F2
FMOVD 136(SP), F0
FMULD F5,F0
FADDDP F0,F1
FMOVD 184(SP), F0
FMULD F5,F0
FADDDP F0,F4
FMOVD 168(SP), F0
FMULDP F0,F5
FXCHD F0, F4
FADDDP F0,F2
FMOVD 136(SP), F0
FMULD F5,F0
FADDDP F0,F1
FMOVD 184(SP), F0
FMULD F5,F0
FADDDP F0,F4
FMOVD 168(SP), F0
FMULD F5,F0
FADDDP F0,F3
FMOVD 152(SP), F0
FMULDP F0,F5
FXCHD F0, F4
FADDDP F0,F1
ADDATMOST15BYTES:
CMPQ DX,$0
JE NOMOREBYTES
MOVL $0,0(SP)
MOVL $0, 4 (SP)
MOVL $0, 8 (SP)
MOVL $0, 12 (SP)
LEAQ 0(SP),DI
MOVQ DX,CX
REP; MOVSB
MOVB $1,0(DI)
MOVL 12 (SP),DI
MOVL 8 (SP),SI
MOVL 4 (SP),DX
MOVL 0(SP),CX
MOVL DI,128(SP)
MOVL SI,120(SP)
MOVL DX,112(SP)
MOVL CX,104(SP)
FXCHD F0, F3
FADDD 128(SP), F0
FSUBD ·DOFFSET3(SB), F0
FXCHD F0, F2
FADDD 120(SP), F0
FSUBD ·DOFFSET2(SB), F0
FXCHD F0, F1
FADDD 112(SP), F0
FSUBD ·DOFFSET1(SB), F0
FXCHD F0, F3
FADDD 104(SP), F0
FSUBD ·DOFFSET0(SB), F0
FMOVD ·ALPHA130(SB), F0
FADDD F3,F0
FSUBD ·ALPHA130(SB), F0
FSUBD F0,F3
FMULD ·SCALE(SB), F0
FMOVD ·ALPHA32(SB), F0
FADDD F2,F0
FSUBD ·ALPHA32(SB), F0
FSUBD F0,F2
FMOVD ·ALPHA64(SB), F0
FADDD F6,F0
FSUBD ·ALPHA64(SB), F0
FSUBD F0,F6
FMOVD ·ALPHA96(SB), F0
FADDD F5,F0
FSUBD ·ALPHA96(SB), F0
FSUBD F0,F5
FXCHD F0, F4
FADDDP F0,F3
FXCHD F0, F6
FADDDP F0,F1
FXCHD F0, F3
FADDDP F0,F5
FXCHD F0, F3
FADDDP F0,F1
FMOVD 176(SP), F0
FMULD F3,F0
FMOVD 160(SP), F0
FMULD F4,F0
FMOVD 144(SP), F0
FMULD F5,F0
FMOVD 136(SP), F0
FMULDP F0,F6
FMOVD 160(SP), F0
FMULD F5,F0
FADDDP F0,F3
FMOVD 144(SP), F0
FMULD F5,F0
FADDDP F0,F2
FMOVD 136(SP), F0
FMULD F5,F0
FADDDP F0,F1
FMOVD 184(SP), F0
FMULDP F0,F5
FXCHD F0, F4
FADDDP F0,F5
FMOVD 144(SP), F0
FMULD F6,F0
FADDDP F0,F2
FMOVD 136(SP), F0
FMULD F6,F0
FADDDP F0,F1
FMOVD 184(SP), F0
FMULD F6,F0
FADDDP F0,F4
FMOVD 168(SP), F0
FMULDP F0,F6
FXCHD F0, F5
FADDDP F0,F4
FMOVD 136(SP), F0
FMULD F2,F0
FADDDP F0,F1
FMOVD 184(SP), F0
FMULD F2,F0
FADDDP F0,F5
FMOVD 168(SP), F0
FMULD F2,F0
FADDDP F0,F3
FMOVD 152(SP), F0
FMULDP F0,F2
FXCHD F0, F1
FADDDP F0,F3
FXCHD F0, F3
FXCHD F0, F2
NOMOREBYTES:
MOVL $0,R10
FMOVD ·ALPHA130(SB), F0
FADDD F4,F0
FSUBD ·ALPHA130(SB), F0
FSUBD F0,F4
FMULD ·SCALE(SB), F0
FMOVD ·ALPHA32(SB), F0
FADDD F2,F0
FSUBD ·ALPHA32(SB), F0
FSUBD F0,F2
FMOVD ·ALPHA64(SB), F0
FADDD F4,F0
FSUBD ·ALPHA64(SB), F0
FSUBD F0,F4
FMOVD ·ALPHA96(SB), F0
FADDD F6,F0
FSUBD ·ALPHA96(SB), F0
FXCHD F0, F6
FSUBD F6,F0
FXCHD F0, F4
FADDDP F0,F3
FXCHD F0, F4
FADDDP F0,F1
FXCHD F0, F2
FADDDP F0,F3
FXCHD F0, F4
FADDDP F0,F3
FXCHD F0, F3
FADDD ·HOFFSET0(SB), F0
FXCHD F0, F3
FADDD ·HOFFSET1(SB), F0
FXCHD F0, F1
FADDD ·HOFFSET2(SB), F0
FXCHD F0, F2
FADDD ·HOFFSET3(SB), F0
FXCHD F0, F3
FMOVDP F0, 104(SP)
FMOVDP F0, 112(SP)
FMOVDP F0, 120(SP)
FMOVDP F0, 128(SP)
MOVL 108(SP),DI
ANDL $63,DI
MOVL 116(SP),SI
ANDL $63,SI
MOVL 124(SP),DX
ANDL $63,DX
MOVL 132(SP),CX
ANDL $63,CX
MOVL 112(SP),R8
ADDL DI,R8
MOVQ R8,112(SP)
MOVL 120(SP),DI
ADCL SI,DI
MOVQ DI,120(SP)
MOVL 128(SP),DI
ADCL DX,DI
MOVQ DI,128(SP)
MOVL R10,DI
ADCL CX,DI
MOVQ DI,136(SP)
MOVQ $5,DI
MOVL 104(SP),SI
ADDL SI,DI
MOVQ DI,104(SP)
MOVL R10,DI
MOVQ 112(SP),DX
ADCL DX,DI
MOVQ DI,112(SP)
MOVL R10,DI
MOVQ 120(SP),CX
ADCL CX,DI
MOVQ DI,120(SP)
MOVL R10,DI
MOVQ 128(SP),R8
ADCL R8,DI
MOVQ DI,128(SP)
MOVQ $0XFFFFFFFC,DI
MOVQ 136(SP),R9
ADCL R9,DI
SARL $16,DI
MOVQ DI,R9
XORL $0XFFFFFFFF,R9
ANDQ DI,SI
MOVQ 104(SP),AX
ANDQ R9,AX
ORQ AX,SI
ANDQ DI,DX
MOVQ 112(SP),AX
ANDQ R9,AX
ORQ AX,DX
ANDQ DI,CX
MOVQ 120(SP),AX
ANDQ R9,AX
ORQ AX,CX
ANDQ DI,R8
MOVQ 128(SP),DI
ANDQ R9,DI
ORQ DI,R8
MOVQ 88(SP),DI
MOVQ 96(SP),R9
ADDL 16(R9),SI
ADCL 20(R9),DX
ADCL 24(R9),CX
ADCL 28(R9),R8
MOVL SI,0(DI)
MOVL DX,4(DI)
MOVL CX,8(DI)
MOVL R8,12(DI)
MOVQ 32(SP),R11
MOVQ 40(SP),R12
MOVQ 48(SP),R13
MOVQ 56(SP),R14
MOVQ 64(SP),R15
MOVQ 72(SP),BX
MOVQ 80(SP),BP
MOVQ R11,SP
RET

View File

@@ -0,0 +1,74 @@
// Copyright 2012 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 poly1305
import (
"bytes"
"testing"
)
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),
},
}
func TestSum(t *testing.T) {
var out [16]byte
var key [32]byte
for i, v := range testData {
copy(key[:], v.k)
Sum(&out, v.in, &key)
if !bytes.Equal(out[:], v.correct) {
t.Errorf("%d: expected %x, got %x", i, v.correct, out[:])
}
}
}
func Benchmark1K(b *testing.B) {
b.StopTimer()
var out [16]byte
var key [32]byte
in := make([]byte, 1024)
b.SetBytes(int64(len(in)))
b.StartTimer()
for i := 0; i < b.N; i++ {
Sum(&out, in, &key)
}
}
func Benchmark64(b *testing.B) {
b.StopTimer()
var out [16]byte
var key [32]byte
in := make([]byte, 64)
b.SetBytes(int64(len(in)))
b.StartTimer()
for i := 0; i < b.N; i++ {
Sum(&out, in, &key)
}
}

View File

@@ -0,0 +1,24 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build amd64,!gccgo
package poly1305
// This function is implemented in poly1305_amd64.s
//go:noescape
func poly1305(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) {
var mPtr *byte
if len(m) > 0 {
mPtr = &m[0]
}
poly1305(out, mPtr, uint64(len(m)), key)
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,144 @@
// Copyright 2012 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 salsa provides low-level access to functions in the Salsa family.
package salsa
// 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'}
// HSalsa20 applies the HSalsa20 core function to a 16-byte input in, 32-byte
// key k, and 16-byte constant c, and puts the result into the 32-byte array
// out.
func HSalsa20(out *[32]byte, in *[16]byte, k *[32]byte, c *[16]byte) {
x0 := uint32(c[0]) | uint32(c[1])<<8 | uint32(c[2])<<16 | uint32(c[3])<<24
x1 := uint32(k[0]) | uint32(k[1])<<8 | uint32(k[2])<<16 | uint32(k[3])<<24
x2 := uint32(k[4]) | uint32(k[5])<<8 | uint32(k[6])<<16 | uint32(k[7])<<24
x3 := uint32(k[8]) | uint32(k[9])<<8 | uint32(k[10])<<16 | uint32(k[11])<<24
x4 := uint32(k[12]) | uint32(k[13])<<8 | uint32(k[14])<<16 | uint32(k[15])<<24
x5 := uint32(c[4]) | uint32(c[5])<<8 | uint32(c[6])<<16 | uint32(c[7])<<24
x6 := uint32(in[0]) | uint32(in[1])<<8 | uint32(in[2])<<16 | uint32(in[3])<<24
x7 := uint32(in[4]) | uint32(in[5])<<8 | uint32(in[6])<<16 | uint32(in[7])<<24
x8 := uint32(in[8]) | uint32(in[9])<<8 | uint32(in[10])<<16 | uint32(in[11])<<24
x9 := uint32(in[12]) | uint32(in[13])<<8 | uint32(in[14])<<16 | uint32(in[15])<<24
x10 := uint32(c[8]) | uint32(c[9])<<8 | uint32(c[10])<<16 | uint32(c[11])<<24
x11 := uint32(k[16]) | uint32(k[17])<<8 | uint32(k[18])<<16 | uint32(k[19])<<24
x12 := uint32(k[20]) | uint32(k[21])<<8 | uint32(k[22])<<16 | uint32(k[23])<<24
x13 := uint32(k[24]) | uint32(k[25])<<8 | uint32(k[26])<<16 | uint32(k[27])<<24
x14 := uint32(k[28]) | uint32(k[29])<<8 | uint32(k[30])<<16 | uint32(k[31])<<24
x15 := uint32(c[12]) | uint32(c[13])<<8 | uint32(c[14])<<16 | uint32(c[15])<<24
for i := 0; i < 20; i += 2 {
u := x0 + x12
x4 ^= u<<7 | u>>(32-7)
u = x4 + x0
x8 ^= u<<9 | u>>(32-9)
u = x8 + x4
x12 ^= u<<13 | u>>(32-13)
u = x12 + x8
x0 ^= u<<18 | u>>(32-18)
u = x5 + x1
x9 ^= u<<7 | u>>(32-7)
u = x9 + x5
x13 ^= u<<9 | u>>(32-9)
u = x13 + x9
x1 ^= u<<13 | u>>(32-13)
u = x1 + x13
x5 ^= u<<18 | u>>(32-18)
u = x10 + x6
x14 ^= u<<7 | u>>(32-7)
u = x14 + x10
x2 ^= u<<9 | u>>(32-9)
u = x2 + x14
x6 ^= u<<13 | u>>(32-13)
u = x6 + x2
x10 ^= u<<18 | u>>(32-18)
u = x15 + x11
x3 ^= u<<7 | u>>(32-7)
u = x3 + x15
x7 ^= u<<9 | u>>(32-9)
u = x7 + x3
x11 ^= u<<13 | u>>(32-13)
u = x11 + x7
x15 ^= u<<18 | u>>(32-18)
u = x0 + x3
x1 ^= u<<7 | u>>(32-7)
u = x1 + x0
x2 ^= u<<9 | u>>(32-9)
u = x2 + x1
x3 ^= u<<13 | u>>(32-13)
u = x3 + x2
x0 ^= u<<18 | u>>(32-18)
u = x5 + x4
x6 ^= u<<7 | u>>(32-7)
u = x6 + x5
x7 ^= u<<9 | u>>(32-9)
u = x7 + x6
x4 ^= u<<13 | u>>(32-13)
u = x4 + x7
x5 ^= u<<18 | u>>(32-18)
u = x10 + x9
x11 ^= u<<7 | u>>(32-7)
u = x11 + x10
x8 ^= u<<9 | u>>(32-9)
u = x8 + x11
x9 ^= u<<13 | u>>(32-13)
u = x9 + x8
x10 ^= u<<18 | u>>(32-18)
u = x15 + x14
x12 ^= u<<7 | u>>(32-7)
u = x12 + x15
x13 ^= u<<9 | u>>(32-9)
u = x13 + x12
x14 ^= u<<13 | u>>(32-13)
u = x14 + x13
x15 ^= u<<18 | u>>(32-18)
}
out[0] = byte(x0)
out[1] = byte(x0 >> 8)
out[2] = byte(x0 >> 16)
out[3] = byte(x0 >> 24)
out[4] = byte(x5)
out[5] = byte(x5 >> 8)
out[6] = byte(x5 >> 16)
out[7] = byte(x5 >> 24)
out[8] = byte(x10)
out[9] = byte(x10 >> 8)
out[10] = byte(x10 >> 16)
out[11] = byte(x10 >> 24)
out[12] = byte(x15)
out[13] = byte(x15 >> 8)
out[14] = byte(x15 >> 16)
out[15] = byte(x15 >> 24)
out[16] = byte(x6)
out[17] = byte(x6 >> 8)
out[18] = byte(x6 >> 16)
out[19] = byte(x6 >> 24)
out[20] = byte(x7)
out[21] = byte(x7 >> 8)
out[22] = byte(x7 >> 16)
out[23] = byte(x7 >> 24)
out[24] = byte(x8)
out[25] = byte(x8 >> 8)
out[26] = byte(x8 >> 16)
out[27] = byte(x8 >> 24)
out[28] = byte(x9)
out[29] = byte(x9 >> 8)
out[30] = byte(x9 >> 16)
out[31] = byte(x9 >> 24)
}

View File

@@ -0,0 +1,902 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build amd64,!appengine,!gccgo
// This code was translated into a form compatible with 6a from the public
// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
// func salsa2020XORKeyStream(out, in *byte, n uint64, nonce, key *byte)
TEXT ·salsa2020XORKeyStream(SB),0,$512-40
MOVQ out+0(FP),DI
MOVQ in+8(FP),SI
MOVQ n+16(FP),DX
MOVQ nonce+24(FP),CX
MOVQ key+32(FP),R8
MOVQ SP,R11
MOVQ $31,R9
NOTQ R9
ANDQ R9,SP
ADDQ $32,SP
MOVQ R11,352(SP)
MOVQ R12,360(SP)
MOVQ R13,368(SP)
MOVQ R14,376(SP)
MOVQ R15,384(SP)
MOVQ BX,392(SP)
MOVQ BP,400(SP)
MOVQ DX,R9
MOVQ CX,DX
MOVQ R8,R10
CMPQ R9,$0
JBE DONE
START:
MOVL 20(R10),CX
MOVL 0(R10),R8
MOVL 0(DX),AX
MOVL 16(R10),R11
MOVL CX,0(SP)
MOVL R8, 4 (SP)
MOVL AX, 8 (SP)
MOVL R11, 12 (SP)
MOVL 8(DX),CX
MOVL 24(R10),R8
MOVL 4(R10),AX
MOVL 4(DX),R11
MOVL CX,16(SP)
MOVL R8, 20 (SP)
MOVL AX, 24 (SP)
MOVL R11, 28 (SP)
MOVL 12(DX),CX
MOVL 12(R10),DX
MOVL 28(R10),R8
MOVL 8(R10),AX
MOVL DX,32(SP)
MOVL CX, 36 (SP)
MOVL R8, 40 (SP)
MOVL AX, 44 (SP)
MOVQ $1634760805,DX
MOVQ $857760878,CX
MOVQ $2036477234,R8
MOVQ $1797285236,AX
MOVL DX,48(SP)
MOVL CX, 52 (SP)
MOVL R8, 56 (SP)
MOVL AX, 60 (SP)
CMPQ R9,$256
JB BYTESBETWEEN1AND255
MOVOA 48(SP),X0
PSHUFL $0X55,X0,X1
PSHUFL $0XAA,X0,X2
PSHUFL $0XFF,X0,X3
PSHUFL $0X00,X0,X0
MOVOA X1,64(SP)
MOVOA X2,80(SP)
MOVOA X3,96(SP)
MOVOA X0,112(SP)
MOVOA 0(SP),X0
PSHUFL $0XAA,X0,X1
PSHUFL $0XFF,X0,X2
PSHUFL $0X00,X0,X3
PSHUFL $0X55,X0,X0
MOVOA X1,128(SP)
MOVOA X2,144(SP)
MOVOA X3,160(SP)
MOVOA X0,176(SP)
MOVOA 16(SP),X0
PSHUFL $0XFF,X0,X1
PSHUFL $0X55,X0,X2
PSHUFL $0XAA,X0,X0
MOVOA X1,192(SP)
MOVOA X2,208(SP)
MOVOA X0,224(SP)
MOVOA 32(SP),X0
PSHUFL $0X00,X0,X1
PSHUFL $0XAA,X0,X2
PSHUFL $0XFF,X0,X0
MOVOA X1,240(SP)
MOVOA X2,256(SP)
MOVOA X0,272(SP)
BYTESATLEAST256:
MOVL 16(SP),DX
MOVL 36 (SP),CX
MOVL DX,288(SP)
MOVL CX,304(SP)
ADDQ $1,DX
SHLQ $32,CX
ADDQ CX,DX
MOVQ DX,CX
SHRQ $32,CX
MOVL DX, 292 (SP)
MOVL CX, 308 (SP)
ADDQ $1,DX
SHLQ $32,CX
ADDQ CX,DX
MOVQ DX,CX
SHRQ $32,CX
MOVL DX, 296 (SP)
MOVL CX, 312 (SP)
ADDQ $1,DX
SHLQ $32,CX
ADDQ CX,DX
MOVQ DX,CX
SHRQ $32,CX
MOVL DX, 300 (SP)
MOVL CX, 316 (SP)
ADDQ $1,DX
SHLQ $32,CX
ADDQ CX,DX
MOVQ DX,CX
SHRQ $32,CX
MOVL DX,16(SP)
MOVL CX, 36 (SP)
MOVQ R9,408(SP)
MOVQ $20,DX
MOVOA 64(SP),X0
MOVOA 80(SP),X1
MOVOA 96(SP),X2
MOVOA 256(SP),X3
MOVOA 272(SP),X4
MOVOA 128(SP),X5
MOVOA 144(SP),X6
MOVOA 176(SP),X7
MOVOA 192(SP),X8
MOVOA 208(SP),X9
MOVOA 224(SP),X10
MOVOA 304(SP),X11
MOVOA 112(SP),X12
MOVOA 160(SP),X13
MOVOA 240(SP),X14
MOVOA 288(SP),X15
MAINLOOP1:
MOVOA X1,320(SP)
MOVOA X2,336(SP)
MOVOA X13,X1
PADDL X12,X1
MOVOA X1,X2
PSLLL $7,X1
PXOR X1,X14
PSRLL $25,X2
PXOR X2,X14
MOVOA X7,X1
PADDL X0,X1
MOVOA X1,X2
PSLLL $7,X1
PXOR X1,X11
PSRLL $25,X2
PXOR X2,X11
MOVOA X12,X1
PADDL X14,X1
MOVOA X1,X2
PSLLL $9,X1
PXOR X1,X15
PSRLL $23,X2
PXOR X2,X15
MOVOA X0,X1
PADDL X11,X1
MOVOA X1,X2
PSLLL $9,X1
PXOR X1,X9
PSRLL $23,X2
PXOR X2,X9
MOVOA X14,X1
PADDL X15,X1
MOVOA X1,X2
PSLLL $13,X1
PXOR X1,X13
PSRLL $19,X2
PXOR X2,X13
MOVOA X11,X1
PADDL X9,X1
MOVOA X1,X2
PSLLL $13,X1
PXOR X1,X7
PSRLL $19,X2
PXOR X2,X7
MOVOA X15,X1
PADDL X13,X1
MOVOA X1,X2
PSLLL $18,X1
PXOR X1,X12
PSRLL $14,X2
PXOR X2,X12
MOVOA 320(SP),X1
MOVOA X12,320(SP)
MOVOA X9,X2
PADDL X7,X2
MOVOA X2,X12
PSLLL $18,X2
PXOR X2,X0
PSRLL $14,X12
PXOR X12,X0
MOVOA X5,X2
PADDL X1,X2
MOVOA X2,X12
PSLLL $7,X2
PXOR X2,X3
PSRLL $25,X12
PXOR X12,X3
MOVOA 336(SP),X2
MOVOA X0,336(SP)
MOVOA X6,X0
PADDL X2,X0
MOVOA X0,X12
PSLLL $7,X0
PXOR X0,X4
PSRLL $25,X12
PXOR X12,X4
MOVOA X1,X0
PADDL X3,X0
MOVOA X0,X12
PSLLL $9,X0
PXOR X0,X10
PSRLL $23,X12
PXOR X12,X10
MOVOA X2,X0
PADDL X4,X0
MOVOA X0,X12
PSLLL $9,X0
PXOR X0,X8
PSRLL $23,X12
PXOR X12,X8
MOVOA X3,X0
PADDL X10,X0
MOVOA X0,X12
PSLLL $13,X0
PXOR X0,X5
PSRLL $19,X12
PXOR X12,X5
MOVOA X4,X0
PADDL X8,X0
MOVOA X0,X12
PSLLL $13,X0
PXOR X0,X6
PSRLL $19,X12
PXOR X12,X6
MOVOA X10,X0
PADDL X5,X0
MOVOA X0,X12
PSLLL $18,X0
PXOR X0,X1
PSRLL $14,X12
PXOR X12,X1
MOVOA 320(SP),X0
MOVOA X1,320(SP)
MOVOA X4,X1
PADDL X0,X1
MOVOA X1,X12
PSLLL $7,X1
PXOR X1,X7
PSRLL $25,X12
PXOR X12,X7
MOVOA X8,X1
PADDL X6,X1
MOVOA X1,X12
PSLLL $18,X1
PXOR X1,X2
PSRLL $14,X12
PXOR X12,X2
MOVOA 336(SP),X12
MOVOA X2,336(SP)
MOVOA X14,X1
PADDL X12,X1
MOVOA X1,X2
PSLLL $7,X1
PXOR X1,X5
PSRLL $25,X2
PXOR X2,X5
MOVOA X0,X1
PADDL X7,X1
MOVOA X1,X2
PSLLL $9,X1
PXOR X1,X10
PSRLL $23,X2
PXOR X2,X10
MOVOA X12,X1
PADDL X5,X1
MOVOA X1,X2
PSLLL $9,X1
PXOR X1,X8
PSRLL $23,X2
PXOR X2,X8
MOVOA X7,X1
PADDL X10,X1
MOVOA X1,X2
PSLLL $13,X1
PXOR X1,X4
PSRLL $19,X2
PXOR X2,X4
MOVOA X5,X1
PADDL X8,X1
MOVOA X1,X2
PSLLL $13,X1
PXOR X1,X14
PSRLL $19,X2
PXOR X2,X14
MOVOA X10,X1
PADDL X4,X1
MOVOA X1,X2
PSLLL $18,X1
PXOR X1,X0
PSRLL $14,X2
PXOR X2,X0
MOVOA 320(SP),X1
MOVOA X0,320(SP)
MOVOA X8,X0
PADDL X14,X0
MOVOA X0,X2
PSLLL $18,X0
PXOR X0,X12
PSRLL $14,X2
PXOR X2,X12
MOVOA X11,X0
PADDL X1,X0
MOVOA X0,X2
PSLLL $7,X0
PXOR X0,X6
PSRLL $25,X2
PXOR X2,X6
MOVOA 336(SP),X2
MOVOA X12,336(SP)
MOVOA X3,X0
PADDL X2,X0
MOVOA X0,X12
PSLLL $7,X0
PXOR X0,X13
PSRLL $25,X12
PXOR X12,X13
MOVOA X1,X0
PADDL X6,X0
MOVOA X0,X12
PSLLL $9,X0
PXOR X0,X15
PSRLL $23,X12
PXOR X12,X15
MOVOA X2,X0
PADDL X13,X0
MOVOA X0,X12
PSLLL $9,X0
PXOR X0,X9
PSRLL $23,X12
PXOR X12,X9
MOVOA X6,X0
PADDL X15,X0
MOVOA X0,X12
PSLLL $13,X0
PXOR X0,X11
PSRLL $19,X12
PXOR X12,X11
MOVOA X13,X0
PADDL X9,X0
MOVOA X0,X12
PSLLL $13,X0
PXOR X0,X3
PSRLL $19,X12
PXOR X12,X3
MOVOA X15,X0
PADDL X11,X0
MOVOA X0,X12
PSLLL $18,X0
PXOR X0,X1
PSRLL $14,X12
PXOR X12,X1
MOVOA X9,X0
PADDL X3,X0
MOVOA X0,X12
PSLLL $18,X0
PXOR X0,X2
PSRLL $14,X12
PXOR X12,X2
MOVOA 320(SP),X12
MOVOA 336(SP),X0
SUBQ $2,DX
JA MAINLOOP1
PADDL 112(SP),X12
PADDL 176(SP),X7
PADDL 224(SP),X10
PADDL 272(SP),X4
MOVD X12,DX
MOVD X7,CX
MOVD X10,R8
MOVD X4,R9
PSHUFL $0X39,X12,X12
PSHUFL $0X39,X7,X7
PSHUFL $0X39,X10,X10
PSHUFL $0X39,X4,X4
XORL 0(SI),DX
XORL 4(SI),CX
XORL 8(SI),R8
XORL 12(SI),R9
MOVL DX,0(DI)
MOVL CX,4(DI)
MOVL R8,8(DI)
MOVL R9,12(DI)
MOVD X12,DX
MOVD X7,CX
MOVD X10,R8
MOVD X4,R9
PSHUFL $0X39,X12,X12
PSHUFL $0X39,X7,X7
PSHUFL $0X39,X10,X10
PSHUFL $0X39,X4,X4
XORL 64(SI),DX
XORL 68(SI),CX
XORL 72(SI),R8
XORL 76(SI),R9
MOVL DX,64(DI)
MOVL CX,68(DI)
MOVL R8,72(DI)
MOVL R9,76(DI)
MOVD X12,DX
MOVD X7,CX
MOVD X10,R8
MOVD X4,R9
PSHUFL $0X39,X12,X12
PSHUFL $0X39,X7,X7
PSHUFL $0X39,X10,X10
PSHUFL $0X39,X4,X4
XORL 128(SI),DX
XORL 132(SI),CX
XORL 136(SI),R8
XORL 140(SI),R9
MOVL DX,128(DI)
MOVL CX,132(DI)
MOVL R8,136(DI)
MOVL R9,140(DI)
MOVD X12,DX
MOVD X7,CX
MOVD X10,R8
MOVD X4,R9
XORL 192(SI),DX
XORL 196(SI),CX
XORL 200(SI),R8
XORL 204(SI),R9
MOVL DX,192(DI)
MOVL CX,196(DI)
MOVL R8,200(DI)
MOVL R9,204(DI)
PADDL 240(SP),X14
PADDL 64(SP),X0
PADDL 128(SP),X5
PADDL 192(SP),X8
MOVD X14,DX
MOVD X0,CX
MOVD X5,R8
MOVD X8,R9
PSHUFL $0X39,X14,X14
PSHUFL $0X39,X0,X0
PSHUFL $0X39,X5,X5
PSHUFL $0X39,X8,X8
XORL 16(SI),DX
XORL 20(SI),CX
XORL 24(SI),R8
XORL 28(SI),R9
MOVL DX,16(DI)
MOVL CX,20(DI)
MOVL R8,24(DI)
MOVL R9,28(DI)
MOVD X14,DX
MOVD X0,CX
MOVD X5,R8
MOVD X8,R9
PSHUFL $0X39,X14,X14
PSHUFL $0X39,X0,X0
PSHUFL $0X39,X5,X5
PSHUFL $0X39,X8,X8
XORL 80(SI),DX
XORL 84(SI),CX
XORL 88(SI),R8
XORL 92(SI),R9
MOVL DX,80(DI)
MOVL CX,84(DI)
MOVL R8,88(DI)
MOVL R9,92(DI)
MOVD X14,DX
MOVD X0,CX
MOVD X5,R8
MOVD X8,R9
PSHUFL $0X39,X14,X14
PSHUFL $0X39,X0,X0
PSHUFL $0X39,X5,X5
PSHUFL $0X39,X8,X8
XORL 144(SI),DX
XORL 148(SI),CX
XORL 152(SI),R8
XORL 156(SI),R9
MOVL DX,144(DI)
MOVL CX,148(DI)
MOVL R8,152(DI)
MOVL R9,156(DI)
MOVD X14,DX
MOVD X0,CX
MOVD X5,R8
MOVD X8,R9
XORL 208(SI),DX
XORL 212(SI),CX
XORL 216(SI),R8
XORL 220(SI),R9
MOVL DX,208(DI)
MOVL CX,212(DI)
MOVL R8,216(DI)
MOVL R9,220(DI)
PADDL 288(SP),X15
PADDL 304(SP),X11
PADDL 80(SP),X1
PADDL 144(SP),X6
MOVD X15,DX
MOVD X11,CX
MOVD X1,R8
MOVD X6,R9
PSHUFL $0X39,X15,X15
PSHUFL $0X39,X11,X11
PSHUFL $0X39,X1,X1
PSHUFL $0X39,X6,X6
XORL 32(SI),DX
XORL 36(SI),CX
XORL 40(SI),R8
XORL 44(SI),R9
MOVL DX,32(DI)
MOVL CX,36(DI)
MOVL R8,40(DI)
MOVL R9,44(DI)
MOVD X15,DX
MOVD X11,CX
MOVD X1,R8
MOVD X6,R9
PSHUFL $0X39,X15,X15
PSHUFL $0X39,X11,X11
PSHUFL $0X39,X1,X1
PSHUFL $0X39,X6,X6
XORL 96(SI),DX
XORL 100(SI),CX
XORL 104(SI),R8
XORL 108(SI),R9
MOVL DX,96(DI)
MOVL CX,100(DI)
MOVL R8,104(DI)
MOVL R9,108(DI)
MOVD X15,DX
MOVD X11,CX
MOVD X1,R8
MOVD X6,R9
PSHUFL $0X39,X15,X15
PSHUFL $0X39,X11,X11
PSHUFL $0X39,X1,X1
PSHUFL $0X39,X6,X6
XORL 160(SI),DX
XORL 164(SI),CX
XORL 168(SI),R8
XORL 172(SI),R9
MOVL DX,160(DI)
MOVL CX,164(DI)
MOVL R8,168(DI)
MOVL R9,172(DI)
MOVD X15,DX
MOVD X11,CX
MOVD X1,R8
MOVD X6,R9
XORL 224(SI),DX
XORL 228(SI),CX
XORL 232(SI),R8
XORL 236(SI),R9
MOVL DX,224(DI)
MOVL CX,228(DI)
MOVL R8,232(DI)
MOVL R9,236(DI)
PADDL 160(SP),X13
PADDL 208(SP),X9
PADDL 256(SP),X3
PADDL 96(SP),X2
MOVD X13,DX
MOVD X9,CX
MOVD X3,R8
MOVD X2,R9
PSHUFL $0X39,X13,X13
PSHUFL $0X39,X9,X9
PSHUFL $0X39,X3,X3
PSHUFL $0X39,X2,X2
XORL 48(SI),DX
XORL 52(SI),CX
XORL 56(SI),R8
XORL 60(SI),R9
MOVL DX,48(DI)
MOVL CX,52(DI)
MOVL R8,56(DI)
MOVL R9,60(DI)
MOVD X13,DX
MOVD X9,CX
MOVD X3,R8
MOVD X2,R9
PSHUFL $0X39,X13,X13
PSHUFL $0X39,X9,X9
PSHUFL $0X39,X3,X3
PSHUFL $0X39,X2,X2
XORL 112(SI),DX
XORL 116(SI),CX
XORL 120(SI),R8
XORL 124(SI),R9
MOVL DX,112(DI)
MOVL CX,116(DI)
MOVL R8,120(DI)
MOVL R9,124(DI)
MOVD X13,DX
MOVD X9,CX
MOVD X3,R8
MOVD X2,R9
PSHUFL $0X39,X13,X13
PSHUFL $0X39,X9,X9
PSHUFL $0X39,X3,X3
PSHUFL $0X39,X2,X2
XORL 176(SI),DX
XORL 180(SI),CX
XORL 184(SI),R8
XORL 188(SI),R9
MOVL DX,176(DI)
MOVL CX,180(DI)
MOVL R8,184(DI)
MOVL R9,188(DI)
MOVD X13,DX
MOVD X9,CX
MOVD X3,R8
MOVD X2,R9
XORL 240(SI),DX
XORL 244(SI),CX
XORL 248(SI),R8
XORL 252(SI),R9
MOVL DX,240(DI)
MOVL CX,244(DI)
MOVL R8,248(DI)
MOVL R9,252(DI)
MOVQ 408(SP),R9
SUBQ $256,R9
ADDQ $256,SI
ADDQ $256,DI
CMPQ R9,$256
JAE BYTESATLEAST256
CMPQ R9,$0
JBE DONE
BYTESBETWEEN1AND255:
CMPQ R9,$64
JAE NOCOPY
MOVQ DI,DX
LEAQ 416(SP),DI
MOVQ R9,CX
REP; MOVSB
LEAQ 416(SP),DI
LEAQ 416(SP),SI
NOCOPY:
MOVQ R9,408(SP)
MOVOA 48(SP),X0
MOVOA 0(SP),X1
MOVOA 16(SP),X2
MOVOA 32(SP),X3
MOVOA X1,X4
MOVQ $20,CX
MAINLOOP2:
PADDL X0,X4
MOVOA X0,X5
MOVOA X4,X6
PSLLL $7,X4
PSRLL $25,X6
PXOR X4,X3
PXOR X6,X3
PADDL X3,X5
MOVOA X3,X4
MOVOA X5,X6
PSLLL $9,X5
PSRLL $23,X6
PXOR X5,X2
PSHUFL $0X93,X3,X3
PXOR X6,X2
PADDL X2,X4
MOVOA X2,X5
MOVOA X4,X6
PSLLL $13,X4
PSRLL $19,X6
PXOR X4,X1
PSHUFL $0X4E,X2,X2
PXOR X6,X1
PADDL X1,X5
MOVOA X3,X4
MOVOA X5,X6
PSLLL $18,X5
PSRLL $14,X6
PXOR X5,X0
PSHUFL $0X39,X1,X1
PXOR X6,X0
PADDL X0,X4
MOVOA X0,X5
MOVOA X4,X6
PSLLL $7,X4
PSRLL $25,X6
PXOR X4,X1
PXOR X6,X1
PADDL X1,X5
MOVOA X1,X4
MOVOA X5,X6
PSLLL $9,X5
PSRLL $23,X6
PXOR X5,X2
PSHUFL $0X93,X1,X1
PXOR X6,X2
PADDL X2,X4
MOVOA X2,X5
MOVOA X4,X6
PSLLL $13,X4
PSRLL $19,X6
PXOR X4,X3
PSHUFL $0X4E,X2,X2
PXOR X6,X3
PADDL X3,X5
MOVOA X1,X4
MOVOA X5,X6
PSLLL $18,X5
PSRLL $14,X6
PXOR X5,X0
PSHUFL $0X39,X3,X3
PXOR X6,X0
PADDL X0,X4
MOVOA X0,X5
MOVOA X4,X6
PSLLL $7,X4
PSRLL $25,X6
PXOR X4,X3
PXOR X6,X3
PADDL X3,X5
MOVOA X3,X4
MOVOA X5,X6
PSLLL $9,X5
PSRLL $23,X6
PXOR X5,X2
PSHUFL $0X93,X3,X3
PXOR X6,X2
PADDL X2,X4
MOVOA X2,X5
MOVOA X4,X6
PSLLL $13,X4
PSRLL $19,X6
PXOR X4,X1
PSHUFL $0X4E,X2,X2
PXOR X6,X1
PADDL X1,X5
MOVOA X3,X4
MOVOA X5,X6
PSLLL $18,X5
PSRLL $14,X6
PXOR X5,X0
PSHUFL $0X39,X1,X1
PXOR X6,X0
PADDL X0,X4
MOVOA X0,X5
MOVOA X4,X6
PSLLL $7,X4
PSRLL $25,X6
PXOR X4,X1
PXOR X6,X1
PADDL X1,X5
MOVOA X1,X4
MOVOA X5,X6
PSLLL $9,X5
PSRLL $23,X6
PXOR X5,X2
PSHUFL $0X93,X1,X1
PXOR X6,X2
PADDL X2,X4
MOVOA X2,X5
MOVOA X4,X6
PSLLL $13,X4
PSRLL $19,X6
PXOR X4,X3
PSHUFL $0X4E,X2,X2
PXOR X6,X3
SUBQ $4,CX
PADDL X3,X5
MOVOA X1,X4
MOVOA X5,X6
PSLLL $18,X5
PXOR X7,X7
PSRLL $14,X6
PXOR X5,X0
PSHUFL $0X39,X3,X3
PXOR X6,X0
JA MAINLOOP2
PADDL 48(SP),X0
PADDL 0(SP),X1
PADDL 16(SP),X2
PADDL 32(SP),X3
MOVD X0,CX
MOVD X1,R8
MOVD X2,R9
MOVD X3,AX
PSHUFL $0X39,X0,X0
PSHUFL $0X39,X1,X1
PSHUFL $0X39,X2,X2
PSHUFL $0X39,X3,X3
XORL 0(SI),CX
XORL 48(SI),R8
XORL 32(SI),R9
XORL 16(SI),AX
MOVL CX,0(DI)
MOVL R8,48(DI)
MOVL R9,32(DI)
MOVL AX,16(DI)
MOVD X0,CX
MOVD X1,R8
MOVD X2,R9
MOVD X3,AX
PSHUFL $0X39,X0,X0
PSHUFL $0X39,X1,X1
PSHUFL $0X39,X2,X2
PSHUFL $0X39,X3,X3
XORL 20(SI),CX
XORL 4(SI),R8
XORL 52(SI),R9
XORL 36(SI),AX
MOVL CX,20(DI)
MOVL R8,4(DI)
MOVL R9,52(DI)
MOVL AX,36(DI)
MOVD X0,CX
MOVD X1,R8
MOVD X2,R9
MOVD X3,AX
PSHUFL $0X39,X0,X0
PSHUFL $0X39,X1,X1
PSHUFL $0X39,X2,X2
PSHUFL $0X39,X3,X3
XORL 40(SI),CX
XORL 24(SI),R8
XORL 8(SI),R9
XORL 56(SI),AX
MOVL CX,40(DI)
MOVL R8,24(DI)
MOVL R9,8(DI)
MOVL AX,56(DI)
MOVD X0,CX
MOVD X1,R8
MOVD X2,R9
MOVD X3,AX
XORL 60(SI),CX
XORL 44(SI),R8
XORL 28(SI),R9
XORL 12(SI),AX
MOVL CX,60(DI)
MOVL R8,44(DI)
MOVL R9,28(DI)
MOVL AX,12(DI)
MOVQ 408(SP),R9
MOVL 16(SP),CX
MOVL 36 (SP),R8
ADDQ $1,CX
SHLQ $32,R8
ADDQ R8,CX
MOVQ CX,R8
SHRQ $32,R8
MOVL CX,16(SP)
MOVL R8, 36 (SP)
CMPQ R9,$64
JA BYTESATLEAST65
JAE BYTESATLEAST64
MOVQ DI,SI
MOVQ DX,DI
MOVQ R9,CX
REP; MOVSB
BYTESATLEAST64:
DONE:
MOVQ 352(SP),R11
MOVQ 360(SP),R12
MOVQ 368(SP),R13
MOVQ 376(SP),R14
MOVQ 384(SP),R15
MOVQ 392(SP),BX
MOVQ 400(SP),BP
MOVQ R11,SP
RET
BYTESATLEAST65:
SUBQ $64,R9
ADDQ $64,DI
ADDQ $64,SI
JMP BYTESBETWEEN1AND255

View File

@@ -0,0 +1,199 @@
// Copyright 2012 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 salsa
// 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) {
j0 := uint32(in[0]) | uint32(in[1])<<8 | uint32(in[2])<<16 | uint32(in[3])<<24
j1 := uint32(in[4]) | uint32(in[5])<<8 | uint32(in[6])<<16 | uint32(in[7])<<24
j2 := uint32(in[8]) | uint32(in[9])<<8 | uint32(in[10])<<16 | uint32(in[11])<<24
j3 := uint32(in[12]) | uint32(in[13])<<8 | uint32(in[14])<<16 | uint32(in[15])<<24
j4 := uint32(in[16]) | uint32(in[17])<<8 | uint32(in[18])<<16 | uint32(in[19])<<24
j5 := uint32(in[20]) | uint32(in[21])<<8 | uint32(in[22])<<16 | uint32(in[23])<<24
j6 := uint32(in[24]) | uint32(in[25])<<8 | uint32(in[26])<<16 | uint32(in[27])<<24
j7 := uint32(in[28]) | uint32(in[29])<<8 | uint32(in[30])<<16 | uint32(in[31])<<24
j8 := uint32(in[32]) | uint32(in[33])<<8 | uint32(in[34])<<16 | uint32(in[35])<<24
j9 := uint32(in[36]) | uint32(in[37])<<8 | uint32(in[38])<<16 | uint32(in[39])<<24
j10 := uint32(in[40]) | uint32(in[41])<<8 | uint32(in[42])<<16 | uint32(in[43])<<24
j11 := uint32(in[44]) | uint32(in[45])<<8 | uint32(in[46])<<16 | uint32(in[47])<<24
j12 := uint32(in[48]) | uint32(in[49])<<8 | uint32(in[50])<<16 | uint32(in[51])<<24
j13 := uint32(in[52]) | uint32(in[53])<<8 | uint32(in[54])<<16 | uint32(in[55])<<24
j14 := uint32(in[56]) | uint32(in[57])<<8 | uint32(in[58])<<16 | uint32(in[59])<<24
j15 := uint32(in[60]) | uint32(in[61])<<8 | uint32(in[62])<<16 | uint32(in[63])<<24
x0, x1, x2, x3, x4, x5, x6, x7, x8 := j0, j1, j2, j3, j4, j5, j6, j7, j8
x9, x10, x11, x12, x13, x14, x15 := j9, j10, j11, j12, j13, j14, j15
for i := 0; i < 8; i += 2 {
u := x0 + x12
x4 ^= u<<7 | u>>(32-7)
u = x4 + x0
x8 ^= u<<9 | u>>(32-9)
u = x8 + x4
x12 ^= u<<13 | u>>(32-13)
u = x12 + x8
x0 ^= u<<18 | u>>(32-18)
u = x5 + x1
x9 ^= u<<7 | u>>(32-7)
u = x9 + x5
x13 ^= u<<9 | u>>(32-9)
u = x13 + x9
x1 ^= u<<13 | u>>(32-13)
u = x1 + x13
x5 ^= u<<18 | u>>(32-18)
u = x10 + x6
x14 ^= u<<7 | u>>(32-7)
u = x14 + x10
x2 ^= u<<9 | u>>(32-9)
u = x2 + x14
x6 ^= u<<13 | u>>(32-13)
u = x6 + x2
x10 ^= u<<18 | u>>(32-18)
u = x15 + x11
x3 ^= u<<7 | u>>(32-7)
u = x3 + x15
x7 ^= u<<9 | u>>(32-9)
u = x7 + x3
x11 ^= u<<13 | u>>(32-13)
u = x11 + x7
x15 ^= u<<18 | u>>(32-18)
u = x0 + x3
x1 ^= u<<7 | u>>(32-7)
u = x1 + x0
x2 ^= u<<9 | u>>(32-9)
u = x2 + x1
x3 ^= u<<13 | u>>(32-13)
u = x3 + x2
x0 ^= u<<18 | u>>(32-18)
u = x5 + x4
x6 ^= u<<7 | u>>(32-7)
u = x6 + x5
x7 ^= u<<9 | u>>(32-9)
u = x7 + x6
x4 ^= u<<13 | u>>(32-13)
u = x4 + x7
x5 ^= u<<18 | u>>(32-18)
u = x10 + x9
x11 ^= u<<7 | u>>(32-7)
u = x11 + x10
x8 ^= u<<9 | u>>(32-9)
u = x8 + x11
x9 ^= u<<13 | u>>(32-13)
u = x9 + x8
x10 ^= u<<18 | u>>(32-18)
u = x15 + x14
x12 ^= u<<7 | u>>(32-7)
u = x12 + x15
x13 ^= u<<9 | u>>(32-9)
u = x13 + x12
x14 ^= u<<13 | u>>(32-13)
u = x14 + x13
x15 ^= u<<18 | u>>(32-18)
}
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
out[0] = byte(x0)
out[1] = byte(x0 >> 8)
out[2] = byte(x0 >> 16)
out[3] = byte(x0 >> 24)
out[4] = byte(x1)
out[5] = byte(x1 >> 8)
out[6] = byte(x1 >> 16)
out[7] = byte(x1 >> 24)
out[8] = byte(x2)
out[9] = byte(x2 >> 8)
out[10] = byte(x2 >> 16)
out[11] = byte(x2 >> 24)
out[12] = byte(x3)
out[13] = byte(x3 >> 8)
out[14] = byte(x3 >> 16)
out[15] = byte(x3 >> 24)
out[16] = byte(x4)
out[17] = byte(x4 >> 8)
out[18] = byte(x4 >> 16)
out[19] = byte(x4 >> 24)
out[20] = byte(x5)
out[21] = byte(x5 >> 8)
out[22] = byte(x5 >> 16)
out[23] = byte(x5 >> 24)
out[24] = byte(x6)
out[25] = byte(x6 >> 8)
out[26] = byte(x6 >> 16)
out[27] = byte(x6 >> 24)
out[28] = byte(x7)
out[29] = byte(x7 >> 8)
out[30] = byte(x7 >> 16)
out[31] = byte(x7 >> 24)
out[32] = byte(x8)
out[33] = byte(x8 >> 8)
out[34] = byte(x8 >> 16)
out[35] = byte(x8 >> 24)
out[36] = byte(x9)
out[37] = byte(x9 >> 8)
out[38] = byte(x9 >> 16)
out[39] = byte(x9 >> 24)
out[40] = byte(x10)
out[41] = byte(x10 >> 8)
out[42] = byte(x10 >> 16)
out[43] = byte(x10 >> 24)
out[44] = byte(x11)
out[45] = byte(x11 >> 8)
out[46] = byte(x11 >> 16)
out[47] = byte(x11 >> 24)
out[48] = byte(x12)
out[49] = byte(x12 >> 8)
out[50] = byte(x12 >> 16)
out[51] = byte(x12 >> 24)
out[52] = byte(x13)
out[53] = byte(x13 >> 8)
out[54] = byte(x13 >> 16)
out[55] = byte(x13 >> 24)
out[56] = byte(x14)
out[57] = byte(x14 >> 8)
out[58] = byte(x14 >> 16)
out[59] = byte(x14 >> 24)
out[60] = byte(x15)
out[61] = byte(x15 >> 8)
out[62] = byte(x15 >> 16)
out[63] = byte(x15 >> 24)
}

View File

@@ -0,0 +1,23 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build amd64,!appengine,!gccgo
package salsa
// This function is implemented in salsa2020_amd64.s.
//go:noescape
func salsa2020XORKeyStream(out, in *byte, n uint64, nonce, key *byte)
// XORKeyStream crypts bytes from in to out using the given key and counters.
// In and out may be the same slice but otherwise should not overlap. Counter
// contains the raw salsa20 counter bytes (both nonce and block counter).
func XORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) {
if len(in) == 0 {
return
}
salsa2020XORKeyStream(&out[0], &in[0], uint64(len(in)), &counter[0], &key[0])
}

View File

@@ -0,0 +1,234 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !amd64 appengine gccgo
package salsa
const rounds = 20
// core applies the Salsa20 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, c *[16]byte) {
j0 := uint32(c[0]) | uint32(c[1])<<8 | uint32(c[2])<<16 | uint32(c[3])<<24
j1 := uint32(k[0]) | uint32(k[1])<<8 | uint32(k[2])<<16 | uint32(k[3])<<24
j2 := uint32(k[4]) | uint32(k[5])<<8 | uint32(k[6])<<16 | uint32(k[7])<<24
j3 := uint32(k[8]) | uint32(k[9])<<8 | uint32(k[10])<<16 | uint32(k[11])<<24
j4 := uint32(k[12]) | uint32(k[13])<<8 | uint32(k[14])<<16 | uint32(k[15])<<24
j5 := uint32(c[4]) | uint32(c[5])<<8 | uint32(c[6])<<16 | uint32(c[7])<<24
j6 := uint32(in[0]) | uint32(in[1])<<8 | uint32(in[2])<<16 | uint32(in[3])<<24
j7 := uint32(in[4]) | uint32(in[5])<<8 | uint32(in[6])<<16 | uint32(in[7])<<24
j8 := uint32(in[8]) | uint32(in[9])<<8 | uint32(in[10])<<16 | uint32(in[11])<<24
j9 := uint32(in[12]) | uint32(in[13])<<8 | uint32(in[14])<<16 | uint32(in[15])<<24
j10 := uint32(c[8]) | uint32(c[9])<<8 | uint32(c[10])<<16 | uint32(c[11])<<24
j11 := uint32(k[16]) | uint32(k[17])<<8 | uint32(k[18])<<16 | uint32(k[19])<<24
j12 := uint32(k[20]) | uint32(k[21])<<8 | uint32(k[22])<<16 | uint32(k[23])<<24
j13 := uint32(k[24]) | uint32(k[25])<<8 | uint32(k[26])<<16 | uint32(k[27])<<24
j14 := uint32(k[28]) | uint32(k[29])<<8 | uint32(k[30])<<16 | uint32(k[31])<<24
j15 := uint32(c[12]) | uint32(c[13])<<8 | uint32(c[14])<<16 | uint32(c[15])<<24
x0, x1, x2, x3, x4, x5, x6, x7, x8 := j0, j1, j2, j3, j4, j5, j6, j7, j8
x9, x10, x11, x12, x13, x14, x15 := j9, j10, j11, j12, j13, j14, j15
for i := 0; i < rounds; i += 2 {
u := x0 + x12
x4 ^= u<<7 | u>>(32-7)
u = x4 + x0
x8 ^= u<<9 | u>>(32-9)
u = x8 + x4
x12 ^= u<<13 | u>>(32-13)
u = x12 + x8
x0 ^= u<<18 | u>>(32-18)
u = x5 + x1
x9 ^= u<<7 | u>>(32-7)
u = x9 + x5
x13 ^= u<<9 | u>>(32-9)
u = x13 + x9
x1 ^= u<<13 | u>>(32-13)
u = x1 + x13
x5 ^= u<<18 | u>>(32-18)
u = x10 + x6
x14 ^= u<<7 | u>>(32-7)
u = x14 + x10
x2 ^= u<<9 | u>>(32-9)
u = x2 + x14
x6 ^= u<<13 | u>>(32-13)
u = x6 + x2
x10 ^= u<<18 | u>>(32-18)
u = x15 + x11
x3 ^= u<<7 | u>>(32-7)
u = x3 + x15
x7 ^= u<<9 | u>>(32-9)
u = x7 + x3
x11 ^= u<<13 | u>>(32-13)
u = x11 + x7
x15 ^= u<<18 | u>>(32-18)
u = x0 + x3
x1 ^= u<<7 | u>>(32-7)
u = x1 + x0
x2 ^= u<<9 | u>>(32-9)
u = x2 + x1
x3 ^= u<<13 | u>>(32-13)
u = x3 + x2
x0 ^= u<<18 | u>>(32-18)
u = x5 + x4
x6 ^= u<<7 | u>>(32-7)
u = x6 + x5
x7 ^= u<<9 | u>>(32-9)
u = x7 + x6
x4 ^= u<<13 | u>>(32-13)
u = x4 + x7
x5 ^= u<<18 | u>>(32-18)
u = x10 + x9
x11 ^= u<<7 | u>>(32-7)
u = x11 + x10
x8 ^= u<<9 | u>>(32-9)
u = x8 + x11
x9 ^= u<<13 | u>>(32-13)
u = x9 + x8
x10 ^= u<<18 | u>>(32-18)
u = x15 + x14
x12 ^= u<<7 | u>>(32-7)
u = x12 + x15
x13 ^= u<<9 | u>>(32-9)
u = x13 + x12
x14 ^= u<<13 | u>>(32-13)
u = x14 + x13
x15 ^= u<<18 | u>>(32-18)
}
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
out[0] = byte(x0)
out[1] = byte(x0 >> 8)
out[2] = byte(x0 >> 16)
out[3] = byte(x0 >> 24)
out[4] = byte(x1)
out[5] = byte(x1 >> 8)
out[6] = byte(x1 >> 16)
out[7] = byte(x1 >> 24)
out[8] = byte(x2)
out[9] = byte(x2 >> 8)
out[10] = byte(x2 >> 16)
out[11] = byte(x2 >> 24)
out[12] = byte(x3)
out[13] = byte(x3 >> 8)
out[14] = byte(x3 >> 16)
out[15] = byte(x3 >> 24)
out[16] = byte(x4)
out[17] = byte(x4 >> 8)
out[18] = byte(x4 >> 16)
out[19] = byte(x4 >> 24)
out[20] = byte(x5)
out[21] = byte(x5 >> 8)
out[22] = byte(x5 >> 16)
out[23] = byte(x5 >> 24)
out[24] = byte(x6)
out[25] = byte(x6 >> 8)
out[26] = byte(x6 >> 16)
out[27] = byte(x6 >> 24)
out[28] = byte(x7)
out[29] = byte(x7 >> 8)
out[30] = byte(x7 >> 16)
out[31] = byte(x7 >> 24)
out[32] = byte(x8)
out[33] = byte(x8 >> 8)
out[34] = byte(x8 >> 16)
out[35] = byte(x8 >> 24)
out[36] = byte(x9)
out[37] = byte(x9 >> 8)
out[38] = byte(x9 >> 16)
out[39] = byte(x9 >> 24)
out[40] = byte(x10)
out[41] = byte(x10 >> 8)
out[42] = byte(x10 >> 16)
out[43] = byte(x10 >> 24)
out[44] = byte(x11)
out[45] = byte(x11 >> 8)
out[46] = byte(x11 >> 16)
out[47] = byte(x11 >> 24)
out[48] = byte(x12)
out[49] = byte(x12 >> 8)
out[50] = byte(x12 >> 16)
out[51] = byte(x12 >> 24)
out[52] = byte(x13)
out[53] = byte(x13 >> 8)
out[54] = byte(x13 >> 16)
out[55] = byte(x13 >> 24)
out[56] = byte(x14)
out[57] = byte(x14 >> 8)
out[58] = byte(x14 >> 16)
out[59] = byte(x14 >> 24)
out[60] = byte(x15)
out[61] = byte(x15 >> 8)
out[62] = byte(x15 >> 16)
out[63] = byte(x15 >> 24)
}
// XORKeyStream crypts bytes from in to out using the given key and counters.
// In and out may be the same slice but otherwise should not overlap. Counter
// contains the raw salsa20 counter bytes (both nonce and block counter).
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, &Sigma)
for i, x := range block {
out[i] = in[i] ^ x
}
u := uint32(1)
for i := 8; i < 16; 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, &Sigma)
for i, v := range in {
out[i] = v ^ block[i]
}
}
}

View File

@@ -0,0 +1,35 @@
// Copyright 2012 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 salsa
import "testing"
func TestCore208(t *testing.T) {
in := [64]byte{
0x7e, 0x87, 0x9a, 0x21, 0x4f, 0x3e, 0xc9, 0x86,
0x7c, 0xa9, 0x40, 0xe6, 0x41, 0x71, 0x8f, 0x26,
0xba, 0xee, 0x55, 0x5b, 0x8c, 0x61, 0xc1, 0xb5,
0x0d, 0xf8, 0x46, 0x11, 0x6d, 0xcd, 0x3b, 0x1d,
0xee, 0x24, 0xf3, 0x19, 0xdf, 0x9b, 0x3d, 0x85,
0x14, 0x12, 0x1e, 0x4b, 0x5a, 0xc5, 0xaa, 0x32,
0x76, 0x02, 0x1d, 0x29, 0x09, 0xc7, 0x48, 0x29,
0xed, 0xeb, 0xc6, 0x8d, 0xb8, 0xb8, 0xc2, 0x5e}
out := [64]byte{
0xa4, 0x1f, 0x85, 0x9c, 0x66, 0x08, 0xcc, 0x99,
0x3b, 0x81, 0xca, 0xcb, 0x02, 0x0c, 0xef, 0x05,
0x04, 0x4b, 0x21, 0x81, 0xa2, 0xfd, 0x33, 0x7d,
0xfd, 0x7b, 0x1c, 0x63, 0x96, 0x68, 0x2f, 0x29,
0xb4, 0x39, 0x31, 0x68, 0xe3, 0xc9, 0xe6, 0xbc,
0xfe, 0x6b, 0xc5, 0xb7, 0xa0, 0x6d, 0x96, 0xba,
0xe4, 0x24, 0xcc, 0x10, 0x2c, 0x91, 0x74, 0x5c,
0x24, 0xad, 0x67, 0x3d, 0xc7, 0x61, 0x8f, 0x81,
}
Core208(&in, &in)
if in != out {
t.Errorf("expected %x, got %x", out, in)
}
}

View File

@@ -0,0 +1,243 @@
// Copyright 2012 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 scrypt implements the scrypt key derivation function as defined in
// Colin Percival's paper "Stronger Key Derivation via Sequential Memory-Hard
// Functions" (http://www.tarsnap.com/scrypt/scrypt.pdf).
package scrypt
import (
"crypto/sha256"
"errors"
"golang.org/x/crypto/pbkdf2"
)
const maxInt = int(^uint(0) >> 1)
// blockCopy copies n numbers from src into dst.
func blockCopy(dst, src []uint32, n int) {
copy(dst, src[:n])
}
// blockXOR XORs numbers from dst with n numbers from src.
func blockXOR(dst, src []uint32, n int) {
for i, v := range src[:n] {
dst[i] ^= v
}
}
// salsaXOR applies Salsa20/8 to the XOR of 16 numbers from tmp and in,
// and puts the result into both both tmp and out.
func salsaXOR(tmp *[16]uint32, in, out []uint32) {
w0 := tmp[0] ^ in[0]
w1 := tmp[1] ^ in[1]
w2 := tmp[2] ^ in[2]
w3 := tmp[3] ^ in[3]
w4 := tmp[4] ^ in[4]
w5 := tmp[5] ^ in[5]
w6 := tmp[6] ^ in[6]
w7 := tmp[7] ^ in[7]
w8 := tmp[8] ^ in[8]
w9 := tmp[9] ^ in[9]
w10 := tmp[10] ^ in[10]
w11 := tmp[11] ^ in[11]
w12 := tmp[12] ^ in[12]
w13 := tmp[13] ^ in[13]
w14 := tmp[14] ^ in[14]
w15 := tmp[15] ^ in[15]
x0, x1, x2, x3, x4, x5, x6, x7, x8 := w0, w1, w2, w3, w4, w5, w6, w7, w8
x9, x10, x11, x12, x13, x14, x15 := w9, w10, w11, w12, w13, w14, w15
for i := 0; i < 8; i += 2 {
u := x0 + x12
x4 ^= u<<7 | u>>(32-7)
u = x4 + x0
x8 ^= u<<9 | u>>(32-9)
u = x8 + x4
x12 ^= u<<13 | u>>(32-13)
u = x12 + x8
x0 ^= u<<18 | u>>(32-18)
u = x5 + x1
x9 ^= u<<7 | u>>(32-7)
u = x9 + x5
x13 ^= u<<9 | u>>(32-9)
u = x13 + x9
x1 ^= u<<13 | u>>(32-13)
u = x1 + x13
x5 ^= u<<18 | u>>(32-18)
u = x10 + x6
x14 ^= u<<7 | u>>(32-7)
u = x14 + x10
x2 ^= u<<9 | u>>(32-9)
u = x2 + x14
x6 ^= u<<13 | u>>(32-13)
u = x6 + x2
x10 ^= u<<18 | u>>(32-18)
u = x15 + x11
x3 ^= u<<7 | u>>(32-7)
u = x3 + x15
x7 ^= u<<9 | u>>(32-9)
u = x7 + x3
x11 ^= u<<13 | u>>(32-13)
u = x11 + x7
x15 ^= u<<18 | u>>(32-18)
u = x0 + x3
x1 ^= u<<7 | u>>(32-7)
u = x1 + x0
x2 ^= u<<9 | u>>(32-9)
u = x2 + x1
x3 ^= u<<13 | u>>(32-13)
u = x3 + x2
x0 ^= u<<18 | u>>(32-18)
u = x5 + x4
x6 ^= u<<7 | u>>(32-7)
u = x6 + x5
x7 ^= u<<9 | u>>(32-9)
u = x7 + x6
x4 ^= u<<13 | u>>(32-13)
u = x4 + x7
x5 ^= u<<18 | u>>(32-18)
u = x10 + x9
x11 ^= u<<7 | u>>(32-7)
u = x11 + x10
x8 ^= u<<9 | u>>(32-9)
u = x8 + x11
x9 ^= u<<13 | u>>(32-13)
u = x9 + x8
x10 ^= u<<18 | u>>(32-18)
u = x15 + x14
x12 ^= u<<7 | u>>(32-7)
u = x12 + x15
x13 ^= u<<9 | u>>(32-9)
u = x13 + x12
x14 ^= u<<13 | u>>(32-13)
u = x14 + x13
x15 ^= u<<18 | u>>(32-18)
}
x0 += w0
x1 += w1
x2 += w2
x3 += w3
x4 += w4
x5 += w5
x6 += w6
x7 += w7
x8 += w8
x9 += w9
x10 += w10
x11 += w11
x12 += w12
x13 += w13
x14 += w14
x15 += w15
out[0], tmp[0] = x0, x0
out[1], tmp[1] = x1, x1
out[2], tmp[2] = x2, x2
out[3], tmp[3] = x3, x3
out[4], tmp[4] = x4, x4
out[5], tmp[5] = x5, x5
out[6], tmp[6] = x6, x6
out[7], tmp[7] = x7, x7
out[8], tmp[8] = x8, x8
out[9], tmp[9] = x9, x9
out[10], tmp[10] = x10, x10
out[11], tmp[11] = x11, x11
out[12], tmp[12] = x12, x12
out[13], tmp[13] = x13, x13
out[14], tmp[14] = x14, x14
out[15], tmp[15] = x15, x15
}
func blockMix(tmp *[16]uint32, in, out []uint32, r int) {
blockCopy(tmp[:], in[(2*r-1)*16:], 16)
for i := 0; i < 2*r; i += 2 {
salsaXOR(tmp, in[i*16:], out[i*8:])
salsaXOR(tmp, in[i*16+16:], out[i*8+r*16:])
}
}
func integer(b []uint32, r int) uint64 {
j := (2*r - 1) * 16
return uint64(b[j]) | uint64(b[j+1])<<32
}
func smix(b []byte, r, N int, v, xy []uint32) {
var tmp [16]uint32
x := xy
y := xy[32*r:]
j := 0
for i := 0; i < 32*r; i++ {
x[i] = uint32(b[j]) | uint32(b[j+1])<<8 | uint32(b[j+2])<<16 | uint32(b[j+3])<<24
j += 4
}
for i := 0; i < N; i += 2 {
blockCopy(v[i*(32*r):], x, 32*r)
blockMix(&tmp, x, y, r)
blockCopy(v[(i+1)*(32*r):], y, 32*r)
blockMix(&tmp, y, x, r)
}
for i := 0; i < N; i += 2 {
j := int(integer(x, r) & uint64(N-1))
blockXOR(x, v[j*(32*r):], 32*r)
blockMix(&tmp, x, y, r)
j = int(integer(y, r) & uint64(N-1))
blockXOR(y, v[j*(32*r):], 32*r)
blockMix(&tmp, y, x, r)
}
j = 0
for _, v := range x[:32*r] {
b[j+0] = byte(v >> 0)
b[j+1] = byte(v >> 8)
b[j+2] = byte(v >> 16)
b[j+3] = byte(v >> 24)
j += 4
}
}
// Key derives a key from the password, salt, and cost parameters, returning
// a byte slice of length keyLen that can be used as cryptographic key.
//
// N is a CPU/memory cost parameter, which must be a power of two greater than 1.
// r and p must satisfy r * p < 2³⁰. If the parameters do not satisfy the
// limits, the function returns a nil byte slice and an error.
//
// For example, you can get a derived key for e.g. AES-256 (which needs a
// 32-byte key) by doing:
//
// dk := scrypt.Key([]byte("some password"), salt, 16384, 8, 1, 32)
//
// The recommended parameters for interactive logins as of 2009 are N=16384,
// r=8, p=1. They should be increased as memory latency and CPU parallelism
// increases. Remember to get a good random salt.
func Key(password, salt []byte, N, r, p, keyLen int) ([]byte, error) {
if N <= 1 || N&(N-1) != 0 {
return nil, errors.New("scrypt: N must be > 1 and a power of 2")
}
if uint64(r)*uint64(p) >= 1<<30 || r > maxInt/128/p || r > maxInt/256 || N > maxInt/128/r {
return nil, errors.New("scrypt: parameters are too large")
}
xy := make([]uint32, 64*r)
v := make([]uint32, 32*N*r)
b := pbkdf2.Key(password, salt, 1, p*128*r, sha256.New)
for i := 0; i < p; i++ {
smix(b[i*128*r:], r, N, v, xy)
}
return pbkdf2.Key(password, b, 1, keyLen, sha256.New), nil
}

View File

@@ -0,0 +1,160 @@
// Copyright 2012 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 scrypt
import (
"bytes"
"testing"
)
type testVector struct {
password string
salt string
N, r, p int
output []byte
}
var good = []testVector{
{
"password",
"salt",
2, 10, 10,
[]byte{
0x48, 0x2c, 0x85, 0x8e, 0x22, 0x90, 0x55, 0xe6, 0x2f,
0x41, 0xe0, 0xec, 0x81, 0x9a, 0x5e, 0xe1, 0x8b, 0xdb,
0x87, 0x25, 0x1a, 0x53, 0x4f, 0x75, 0xac, 0xd9, 0x5a,
0xc5, 0xe5, 0xa, 0xa1, 0x5f,
},
},
{
"password",
"salt",
16, 100, 100,
[]byte{
0x88, 0xbd, 0x5e, 0xdb, 0x52, 0xd1, 0xdd, 0x0, 0x18,
0x87, 0x72, 0xad, 0x36, 0x17, 0x12, 0x90, 0x22, 0x4e,
0x74, 0x82, 0x95, 0x25, 0xb1, 0x8d, 0x73, 0x23, 0xa5,
0x7f, 0x91, 0x96, 0x3c, 0x37,
},
},
{
"this is a long \000 password",
"and this is a long \000 salt",
16384, 8, 1,
[]byte{
0xc3, 0xf1, 0x82, 0xee, 0x2d, 0xec, 0x84, 0x6e, 0x70,
0xa6, 0x94, 0x2f, 0xb5, 0x29, 0x98, 0x5a, 0x3a, 0x09,
0x76, 0x5e, 0xf0, 0x4c, 0x61, 0x29, 0x23, 0xb1, 0x7f,
0x18, 0x55, 0x5a, 0x37, 0x07, 0x6d, 0xeb, 0x2b, 0x98,
0x30, 0xd6, 0x9d, 0xe5, 0x49, 0x26, 0x51, 0xe4, 0x50,
0x6a, 0xe5, 0x77, 0x6d, 0x96, 0xd4, 0x0f, 0x67, 0xaa,
0xee, 0x37, 0xe1, 0x77, 0x7b, 0x8a, 0xd5, 0xc3, 0x11,
0x14, 0x32, 0xbb, 0x3b, 0x6f, 0x7e, 0x12, 0x64, 0x40,
0x18, 0x79, 0xe6, 0x41, 0xae,
},
},
{
"p",
"s",
2, 1, 1,
[]byte{
0x48, 0xb0, 0xd2, 0xa8, 0xa3, 0x27, 0x26, 0x11, 0x98,
0x4c, 0x50, 0xeb, 0xd6, 0x30, 0xaf, 0x52,
},
},
{
"",
"",
16, 1, 1,
[]byte{
0x77, 0xd6, 0x57, 0x62, 0x38, 0x65, 0x7b, 0x20, 0x3b,
0x19, 0xca, 0x42, 0xc1, 0x8a, 0x04, 0x97, 0xf1, 0x6b,
0x48, 0x44, 0xe3, 0x07, 0x4a, 0xe8, 0xdf, 0xdf, 0xfa,
0x3f, 0xed, 0xe2, 0x14, 0x42, 0xfc, 0xd0, 0x06, 0x9d,
0xed, 0x09, 0x48, 0xf8, 0x32, 0x6a, 0x75, 0x3a, 0x0f,
0xc8, 0x1f, 0x17, 0xe8, 0xd3, 0xe0, 0xfb, 0x2e, 0x0d,
0x36, 0x28, 0xcf, 0x35, 0xe2, 0x0c, 0x38, 0xd1, 0x89,
0x06,
},
},
{
"password",
"NaCl",
1024, 8, 16,
[]byte{
0xfd, 0xba, 0xbe, 0x1c, 0x9d, 0x34, 0x72, 0x00, 0x78,
0x56, 0xe7, 0x19, 0x0d, 0x01, 0xe9, 0xfe, 0x7c, 0x6a,
0xd7, 0xcb, 0xc8, 0x23, 0x78, 0x30, 0xe7, 0x73, 0x76,
0x63, 0x4b, 0x37, 0x31, 0x62, 0x2e, 0xaf, 0x30, 0xd9,
0x2e, 0x22, 0xa3, 0x88, 0x6f, 0xf1, 0x09, 0x27, 0x9d,
0x98, 0x30, 0xda, 0xc7, 0x27, 0xaf, 0xb9, 0x4a, 0x83,
0xee, 0x6d, 0x83, 0x60, 0xcb, 0xdf, 0xa2, 0xcc, 0x06,
0x40,
},
},
{
"pleaseletmein", "SodiumChloride",
16384, 8, 1,
[]byte{
0x70, 0x23, 0xbd, 0xcb, 0x3a, 0xfd, 0x73, 0x48, 0x46,
0x1c, 0x06, 0xcd, 0x81, 0xfd, 0x38, 0xeb, 0xfd, 0xa8,
0xfb, 0xba, 0x90, 0x4f, 0x8e, 0x3e, 0xa9, 0xb5, 0x43,
0xf6, 0x54, 0x5d, 0xa1, 0xf2, 0xd5, 0x43, 0x29, 0x55,
0x61, 0x3f, 0x0f, 0xcf, 0x62, 0xd4, 0x97, 0x05, 0x24,
0x2a, 0x9a, 0xf9, 0xe6, 0x1e, 0x85, 0xdc, 0x0d, 0x65,
0x1e, 0x40, 0xdf, 0xcf, 0x01, 0x7b, 0x45, 0x57, 0x58,
0x87,
},
},
/*
// Disabled: needs 1 GiB RAM and takes too long for a simple test.
{
"pleaseletmein", "SodiumChloride",
1048576, 8, 1,
[]byte{
0x21, 0x01, 0xcb, 0x9b, 0x6a, 0x51, 0x1a, 0xae, 0xad,
0xdb, 0xbe, 0x09, 0xcf, 0x70, 0xf8, 0x81, 0xec, 0x56,
0x8d, 0x57, 0x4a, 0x2f, 0xfd, 0x4d, 0xab, 0xe5, 0xee,
0x98, 0x20, 0xad, 0xaa, 0x47, 0x8e, 0x56, 0xfd, 0x8f,
0x4b, 0xa5, 0xd0, 0x9f, 0xfa, 0x1c, 0x6d, 0x92, 0x7c,
0x40, 0xf4, 0xc3, 0x37, 0x30, 0x40, 0x49, 0xe8, 0xa9,
0x52, 0xfb, 0xcb, 0xf4, 0x5c, 0x6f, 0xa7, 0x7a, 0x41,
0xa4,
},
},
*/
}
var bad = []testVector{
{"p", "s", 0, 1, 1, nil}, // N == 0
{"p", "s", 1, 1, 1, nil}, // N == 1
{"p", "s", 7, 8, 1, nil}, // N is not power of 2
{"p", "s", 16, maxInt / 2, maxInt / 2, nil}, // p * r too large
}
func TestKey(t *testing.T) {
for i, v := range good {
k, err := Key([]byte(v.password), []byte(v.salt), v.N, v.r, v.p, len(v.output))
if err != nil {
t.Errorf("%d: got unexpected error: %s", i, err)
}
if !bytes.Equal(k, v.output) {
t.Errorf("%d: expected %x, got %x", i, v.output, k)
}
}
for i, v := range bad {
_, err := Key([]byte(v.password), []byte(v.salt), v.N, v.r, v.p, 32)
if err == nil {
t.Errorf("%d: expected error, got nil", i)
}
}
}
func BenchmarkKey(b *testing.B) {
for i := 0; i < b.N; i++ {
Key([]byte("password"), []byte("salt"), 16384, 8, 1, 64)
}
}

View File

@@ -1,7 +1,7 @@
package changelist
import (
"github.com/endophage/gotuf/data"
"github.com/docker/notary/tuf/data"
)
// Scopes for TufChanges are simply the TUF roles.

View File

@@ -16,14 +16,14 @@ import (
"github.com/docker/notary/keystoremanager"
"github.com/docker/notary/pkg/passphrase"
"github.com/docker/notary/trustmanager"
"github.com/endophage/gotuf"
tufclient "github.com/endophage/gotuf/client"
"github.com/endophage/gotuf/data"
tuferrors "github.com/endophage/gotuf/errors"
"github.com/endophage/gotuf/keys"
"github.com/endophage/gotuf/signed"
"github.com/endophage/gotuf/store"
tufutils "github.com/endophage/gotuf/utils"
"github.com/docker/notary/tuf"
tufclient "github.com/docker/notary/tuf/client"
"github.com/docker/notary/tuf/data"
tuferrors "github.com/docker/notary/tuf/errors"
"github.com/docker/notary/tuf/keys"
"github.com/docker/notary/tuf/signed"
"github.com/docker/notary/tuf/store"
tufutils "github.com/docker/notary/tuf/utils"
)
const maxSize = 5 << 20

View File

@@ -11,7 +11,7 @@ import (
"github.com/Sirupsen/logrus"
"github.com/docker/notary/keystoremanager"
"github.com/endophage/gotuf/data"
"github.com/docker/notary/tuf/data"
"github.com/stretchr/testify/assert"
)

View File

@@ -18,7 +18,7 @@ import (
"github.com/docker/notary/server/storage"
"github.com/docker/notary/trustmanager"
"github.com/docker/notary/utils"
"github.com/endophage/gotuf/data"
"github.com/docker/notary/tuf/data"
"github.com/gorilla/mux"
"github.com/stretchr/testify/assert"
"golang.org/x/net/context"

View File

@@ -7,10 +7,10 @@ import (
"github.com/Sirupsen/logrus"
"github.com/docker/notary/client/changelist"
tuf "github.com/endophage/gotuf"
"github.com/endophage/gotuf/data"
"github.com/endophage/gotuf/keys"
"github.com/endophage/gotuf/store"
tuf "github.com/docker/notary/tuf"
"github.com/docker/notary/tuf/data"
"github.com/docker/notary/tuf/keys"
"github.com/docker/notary/tuf/store"
)
// Use this to initialize remote HTTPStores from the config settings

View File

@@ -6,9 +6,9 @@ import (
"testing"
"github.com/docker/notary/client/changelist"
tuf "github.com/endophage/gotuf"
"github.com/endophage/gotuf/data"
"github.com/endophage/gotuf/keys"
tuf "github.com/docker/notary/tuf"
"github.com/docker/notary/tuf/data"
"github.com/docker/notary/tuf/keys"
"github.com/stretchr/testify/assert"
)

View File

@@ -16,7 +16,7 @@ import (
"github.com/docker/distribution/health"
_ "github.com/docker/distribution/registry/auth/htpasswd"
_ "github.com/docker/distribution/registry/auth/token"
"github.com/endophage/gotuf/signed"
"github.com/docker/notary/tuf/signed"
_ "github.com/go-sql-driver/mysql"
"golang.org/x/net/context"

View File

@@ -22,7 +22,7 @@ import (
"github.com/docker/notary/signer/api"
"github.com/docker/notary/utils"
"github.com/docker/notary/version"
"github.com/endophage/gotuf/data"
"github.com/docker/notary/tuf/data"
_ "github.com/go-sql-driver/mysql"
"github.com/miekg/pkcs11"
"github.com/spf13/viper"

View File

@@ -13,7 +13,7 @@ import (
"github.com/Sirupsen/logrus"
"github.com/agl/ed25519"
"github.com/docker/notary/trustmanager"
"github.com/endophage/gotuf/data"
"github.com/docker/notary/tuf/data"
)
const (

View File

@@ -5,8 +5,8 @@ import (
"testing"
"github.com/docker/notary/trustmanager"
"github.com/endophage/gotuf/data"
"github.com/endophage/gotuf/signed"
"github.com/docker/notary/tuf/data"
"github.com/docker/notary/tuf/signed"
)
func TestCryptoService(t *testing.T) {

View File

@@ -9,8 +9,8 @@ import (
"fmt"
"github.com/docker/notary/trustmanager"
"github.com/endophage/gotuf/data"
"github.com/endophage/gotuf/signed"
"github.com/docker/notary/tuf/data"
"github.com/docker/notary/tuf/signed"
)
// UnlockedCryptoService encapsulates a private key and a cryptoservice that

View File

@@ -15,7 +15,7 @@ import (
"github.com/docker/notary/client"
"github.com/docker/notary/keystoremanager"
"github.com/docker/notary/trustmanager"
"github.com/endophage/gotuf/data"
"github.com/docker/notary/tuf/data"
"github.com/stretchr/testify/assert"
)

View File

@@ -13,8 +13,8 @@ import (
"github.com/docker/notary/cryptoservice"
"github.com/docker/notary/pkg/passphrase"
"github.com/docker/notary/trustmanager"
"github.com/endophage/gotuf/data"
"github.com/endophage/gotuf/signed"
"github.com/docker/notary/tuf/data"
"github.com/docker/notary/tuf/signed"
)
// KeyStoreManager is an abstraction around the root and non-root key stores,

View File

@@ -10,8 +10,8 @@ import (
"text/template"
"github.com/docker/notary/trustmanager"
"github.com/endophage/gotuf/data"
"github.com/endophage/gotuf/signed"
"github.com/docker/notary/tuf/data"
"github.com/docker/notary/tuf/signed"
"github.com/stretchr/testify/assert"
)

View File

@@ -7,8 +7,8 @@ import (
"net/http"
"strings"
"github.com/endophage/gotuf/data"
"github.com/endophage/gotuf/signed"
"github.com/docker/notary/tuf/data"
"github.com/docker/notary/tuf/signed"
"github.com/gorilla/mux"
"golang.org/x/net/context"

View File

@@ -7,7 +7,7 @@ import (
"golang.org/x/net/context"
"github.com/endophage/gotuf/signed"
"github.com/docker/notary/tuf/signed"
"github.com/docker/notary/utils"
)

View File

@@ -6,14 +6,14 @@ import (
"errors"
"fmt"
"github.com/endophage/gotuf"
"github.com/endophage/gotuf/data"
"github.com/docker/notary/tuf"
"github.com/docker/notary/tuf/data"
"github.com/Sirupsen/logrus"
"github.com/docker/notary/server/storage"
"github.com/endophage/gotuf/keys"
"github.com/endophage/gotuf/signed"
"github.com/endophage/gotuf/utils"
"github.com/docker/notary/tuf/keys"
"github.com/docker/notary/tuf/signed"
"github.com/docker/notary/tuf/utils"
)
// ErrValidation represents a general validation error

View File

@@ -3,9 +3,9 @@ package handlers
import (
"testing"
"github.com/endophage/gotuf/data"
"github.com/endophage/gotuf/signed"
"github.com/endophage/gotuf/testutils"
"github.com/docker/notary/tuf/data"
"github.com/docker/notary/tuf/signed"
"github.com/docker/notary/tuf/testutils"
"github.com/stretchr/testify/assert"
"github.com/docker/notary/server/storage"

View File

@@ -9,8 +9,8 @@ import (
"github.com/Sirupsen/logrus"
"github.com/docker/distribution/health"
"github.com/docker/distribution/registry/auth"
"github.com/endophage/gotuf/data"
"github.com/endophage/gotuf/signed"
"github.com/docker/notary/tuf/data"
"github.com/docker/notary/tuf/signed"
"github.com/gorilla/mux"
"golang.org/x/net/context"

View File

@@ -6,7 +6,7 @@ import (
"testing"
_ "github.com/docker/distribution/registry/auth/silly"
"github.com/endophage/gotuf/signed"
"github.com/docker/notary/tuf/signed"
"golang.org/x/net/context"
)

View File

@@ -4,7 +4,7 @@ import (
"fmt"
"github.com/Sirupsen/logrus"
"github.com/endophage/gotuf/data"
"github.com/docker/notary/tuf/data"
"github.com/go-sql-driver/mysql"
"github.com/jinzhu/gorm"
"github.com/mattn/go-sqlite3"

View File

@@ -5,7 +5,7 @@ import (
"os"
"testing"
"github.com/endophage/gotuf/data"
"github.com/docker/notary/tuf/data"
"github.com/jinzhu/gorm"
_ "github.com/mattn/go-sqlite3"
"github.com/stretchr/testify/assert"

View File

@@ -1,6 +1,6 @@
package storage
import "github.com/endophage/gotuf/data"
import "github.com/docker/notary/tuf/data"
// MetaStore holds the methods that are used for a Metadata Store
type MetaStore interface {

View File

@@ -5,7 +5,7 @@ import (
"strings"
"sync"
"github.com/endophage/gotuf/data"
"github.com/docker/notary/tuf/data"
)
type key struct {

View File

@@ -3,7 +3,7 @@ package storage
import (
"testing"
"github.com/endophage/gotuf/data"
"github.com/docker/notary/tuf/data"
"github.com/stretchr/testify/assert"
)

View File

@@ -3,8 +3,8 @@ package timestamp
import (
"bytes"
"github.com/endophage/gotuf/data"
"github.com/endophage/gotuf/signed"
"github.com/docker/notary/tuf/data"
"github.com/docker/notary/tuf/signed"
"github.com/jfrazelle/go/canonical/json"
"github.com/Sirupsen/logrus"

View File

@@ -5,8 +5,8 @@ import (
"testing"
"time"
"github.com/endophage/gotuf/data"
"github.com/endophage/gotuf/signed"
"github.com/docker/notary/tuf/data"
"github.com/docker/notary/tuf/signed"
"github.com/stretchr/testify/assert"
"github.com/docker/notary/server/storage"

View File

@@ -6,8 +6,8 @@ import (
"github.com/docker/notary/signer"
"github.com/docker/notary/signer/keys"
"github.com/endophage/gotuf/data"
"github.com/endophage/gotuf/signed"
"github.com/docker/notary/tuf/data"
"github.com/docker/notary/tuf/signed"
"github.com/gorilla/mux"
pb "github.com/docker/notary/proto"

View File

@@ -15,7 +15,7 @@ import (
"github.com/docker/notary/signer"
"github.com/docker/notary/signer/api"
"github.com/docker/notary/trustmanager"
"github.com/endophage/gotuf/data"
"github.com/docker/notary/tuf/data"
"github.com/miekg/pkcs11"
"github.com/stretchr/testify/assert"

View File

@@ -3,8 +3,8 @@ package api
import (
"github.com/docker/notary/signer"
"github.com/docker/notary/signer/keys"
"github.com/endophage/gotuf/data"
"github.com/endophage/gotuf/signed"
"github.com/docker/notary/tuf/data"
"github.com/docker/notary/tuf/signed"
pb "github.com/docker/notary/proto"
)

View File

@@ -6,7 +6,7 @@ import (
ctxu "github.com/docker/distribution/context"
"github.com/docker/notary/signer"
"github.com/docker/notary/signer/keys"
"github.com/endophage/gotuf/data"
"github.com/docker/notary/tuf/data"
"golang.org/x/net/context"
"google.golang.org/grpc"

View File

@@ -11,7 +11,7 @@ import (
"github.com/docker/notary/signer"
"github.com/docker/notary/signer/api"
"github.com/docker/notary/trustmanager"
"github.com/endophage/gotuf/data"
"github.com/docker/notary/tuf/data"
"github.com/stretchr/testify/assert"
"golang.org/x/net/context"
"google.golang.org/grpc"

View File

@@ -11,7 +11,7 @@ import (
"math/big"
"github.com/docker/notary/signer/keys"
"github.com/endophage/gotuf/data"
"github.com/docker/notary/tuf/data"
"github.com/miekg/pkcs11"
)

View File

@@ -8,7 +8,7 @@ import (
"github.com/docker/notary/pkg/passphrase"
"github.com/docker/notary/trustmanager"
jose "github.com/dvsekhvalnov/jose2go"
"github.com/endophage/gotuf/data"
"github.com/docker/notary/tuf/data"
"github.com/jinzhu/gorm"
)

View File

@@ -3,7 +3,7 @@ package keys
import (
"errors"
"github.com/endophage/gotuf/data"
"github.com/docker/notary/tuf/data"
"github.com/miekg/pkcs11"
)

View File

@@ -2,8 +2,8 @@ package signer
import (
pb "github.com/docker/notary/proto"
"github.com/endophage/gotuf/data"
"github.com/endophage/gotuf/signed"
"github.com/docker/notary/tuf/data"
"github.com/docker/notary/tuf/signed"
)
// SigningService is the interface to implement a key management and signing service

View File

@@ -8,7 +8,7 @@ import (
"github.com/Sirupsen/logrus"
pb "github.com/docker/notary/proto"
"github.com/docker/notary/utils"
"github.com/endophage/gotuf/data"
"github.com/docker/notary/tuf/data"
"golang.org/x/net/context"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"

View File

@@ -6,7 +6,7 @@ import (
"sync"
"github.com/docker/notary/pkg/passphrase"
"github.com/endophage/gotuf/data"
"github.com/docker/notary/tuf/data"
)
// KeyFileStore persists and manages private keys on disk

View File

@@ -3,7 +3,7 @@ package trustmanager
import (
"fmt"
"github.com/endophage/gotuf/data"
"github.com/docker/notary/tuf/data"
)
// ErrAttemptsExceeded is returned when too many attempts have been made to decrypt a key

View File

@@ -20,7 +20,7 @@ import (
"github.com/Sirupsen/logrus"
"github.com/agl/ed25519"
"github.com/endophage/gotuf/data"
"github.com/docker/notary/tuf/data"
)
// GetCertFromURL tries to get a X509 certificate given a HTTPS URL

View File

@@ -10,7 +10,7 @@ import (
"testing"
"time"
"github.com/endophage/gotuf/data"
"github.com/docker/notary/tuf/data"
"github.com/stretchr/testify/assert"
)

View File

@@ -12,12 +12,12 @@ import (
"strings"
"github.com/Sirupsen/logrus"
tuf "github.com/endophage/gotuf"
"github.com/endophage/gotuf/data"
"github.com/endophage/gotuf/keys"
"github.com/endophage/gotuf/signed"
"github.com/endophage/gotuf/store"
"github.com/endophage/gotuf/utils"
tuf "github.com/docker/notary/tuf"
"github.com/docker/notary/tuf/data"
"github.com/docker/notary/tuf/keys"
"github.com/docker/notary/tuf/signed"
"github.com/docker/notary/tuf/store"
"github.com/docker/notary/tuf/utils"
)
const maxSize int64 = 5 << 20

588
tuf/client/client_test.go Normal file
View File

@@ -0,0 +1,588 @@
package client
import (
"crypto/sha256"
"encoding/json"
"testing"
"time"
"github.com/Sirupsen/logrus"
tuf "github.com/docker/notary/tuf"
"github.com/docker/notary/tuf/testutils"
"github.com/stretchr/testify/assert"
"github.com/docker/notary/tuf/data"
"github.com/docker/notary/tuf/keys"
"github.com/docker/notary/tuf/signed"
"github.com/docker/notary/tuf/store"
)
func TestRotation(t *testing.T) {
kdb := keys.NewDB()
signer := signed.NewEd25519()
repo := tuf.NewRepo(kdb, signer)
remote := store.NewMemoryStore(nil, nil)
cache := store.NewMemoryStore(nil, nil)
// Generate initial root key and role and add to key DB
rootKey, err := signer.Create("root", data.ED25519Key)
assert.NoError(t, err, "Error creating root key")
rootRole, err := data.NewRole("root", 1, []string{rootKey.ID()}, nil, nil)
assert.NoError(t, err, "Error creating root role")
kdb.AddKey(rootKey)
err = kdb.AddRole(rootRole)
assert.NoError(t, err, "Error adding root role to db")
// Generate new key and role. These will appear in the root.json
// but will not be added to the keyDB.
replacementKey, err := signer.Create("root", data.ED25519Key)
assert.NoError(t, err, "Error creating replacement root key")
replacementRole, err := data.NewRole("root", 1, []string{replacementKey.ID()}, nil, nil)
assert.NoError(t, err, "Error creating replacement root role")
// Generate a new root with the replacement key and role
testRoot, err := data.NewRoot(
map[string]data.PublicKey{replacementKey.ID(): replacementKey},
map[string]*data.RootRole{"root": &replacementRole.RootRole},
false,
)
assert.NoError(t, err, "Failed to create new root")
// Sign testRoot with both old and new keys
signedRoot, err := testRoot.ToSigned()
err = signed.Sign(signer, signedRoot, rootKey, replacementKey)
assert.NoError(t, err, "Failed to sign root")
var origKeySig bool
var replKeySig bool
for _, sig := range signedRoot.Signatures {
if sig.KeyID == rootKey.ID() {
origKeySig = true
} else if sig.KeyID == replacementKey.ID() {
replKeySig = true
}
}
assert.True(t, origKeySig, "Original root key signature not present")
assert.True(t, replKeySig, "Replacement root key signature not present")
client := NewClient(repo, remote, kdb, cache)
err = client.verifyRoot("root", signedRoot, 0)
assert.NoError(t, err, "Failed to verify key rotated root")
}
func TestRotationNewSigMissing(t *testing.T) {
logrus.SetLevel(logrus.DebugLevel)
kdb := keys.NewDB()
signer := signed.NewEd25519()
repo := tuf.NewRepo(kdb, signer)
remote := store.NewMemoryStore(nil, nil)
cache := store.NewMemoryStore(nil, nil)
// Generate initial root key and role and add to key DB
rootKey, err := signer.Create("root", data.ED25519Key)
assert.NoError(t, err, "Error creating root key")
rootRole, err := data.NewRole("root", 1, []string{rootKey.ID()}, nil, nil)
assert.NoError(t, err, "Error creating root role")
kdb.AddKey(rootKey)
err = kdb.AddRole(rootRole)
assert.NoError(t, err, "Error adding root role to db")
// Generate new key and role. These will appear in the root.json
// but will not be added to the keyDB.
replacementKey, err := signer.Create("root", data.ED25519Key)
assert.NoError(t, err, "Error creating replacement root key")
replacementRole, err := data.NewRole("root", 1, []string{replacementKey.ID()}, nil, nil)
assert.NoError(t, err, "Error creating replacement root role")
assert.NotEqual(t, rootKey.ID(), replacementKey.ID(), "Key IDs are the same")
// Generate a new root with the replacement key and role
testRoot, err := data.NewRoot(
map[string]data.PublicKey{replacementKey.ID(): replacementKey},
map[string]*data.RootRole{"root": &replacementRole.RootRole},
false,
)
assert.NoError(t, err, "Failed to create new root")
_, ok := testRoot.Signed.Keys[rootKey.ID()]
assert.False(t, ok, "Old root key appeared in test root")
// Sign testRoot with both old and new keys
signedRoot, err := testRoot.ToSigned()
err = signed.Sign(signer, signedRoot, rootKey)
assert.NoError(t, err, "Failed to sign root")
var origKeySig bool
var replKeySig bool
for _, sig := range signedRoot.Signatures {
if sig.KeyID == rootKey.ID() {
origKeySig = true
} else if sig.KeyID == replacementKey.ID() {
replKeySig = true
}
}
assert.True(t, origKeySig, "Original root key signature not present")
assert.False(t, replKeySig, "Replacement root key signature was present and shouldn't be")
client := NewClient(repo, remote, kdb, cache)
err = client.verifyRoot("root", signedRoot, 0)
assert.Error(t, err, "Should have errored on verify as replacement signature was missing.")
}
func TestRotationOldSigMissing(t *testing.T) {
logrus.SetLevel(logrus.DebugLevel)
kdb := keys.NewDB()
signer := signed.NewEd25519()
repo := tuf.NewRepo(kdb, signer)
remote := store.NewMemoryStore(nil, nil)
cache := store.NewMemoryStore(nil, nil)
// Generate initial root key and role and add to key DB
rootKey, err := signer.Create("root", data.ED25519Key)
assert.NoError(t, err, "Error creating root key")
rootRole, err := data.NewRole("root", 1, []string{rootKey.ID()}, nil, nil)
assert.NoError(t, err, "Error creating root role")
kdb.AddKey(rootKey)
err = kdb.AddRole(rootRole)
assert.NoError(t, err, "Error adding root role to db")
// Generate new key and role. These will appear in the root.json
// but will not be added to the keyDB.
replacementKey, err := signer.Create("root", data.ED25519Key)
assert.NoError(t, err, "Error creating replacement root key")
replacementRole, err := data.NewRole("root", 1, []string{replacementKey.ID()}, nil, nil)
assert.NoError(t, err, "Error creating replacement root role")
assert.NotEqual(t, rootKey.ID(), replacementKey.ID(), "Key IDs are the same")
// Generate a new root with the replacement key and role
testRoot, err := data.NewRoot(
map[string]data.PublicKey{replacementKey.ID(): replacementKey},
map[string]*data.RootRole{"root": &replacementRole.RootRole},
false,
)
assert.NoError(t, err, "Failed to create new root")
_, ok := testRoot.Signed.Keys[rootKey.ID()]
assert.False(t, ok, "Old root key appeared in test root")
// Sign testRoot with both old and new keys
signedRoot, err := testRoot.ToSigned()
err = signed.Sign(signer, signedRoot, replacementKey)
assert.NoError(t, err, "Failed to sign root")
var origKeySig bool
var replKeySig bool
for _, sig := range signedRoot.Signatures {
if sig.KeyID == rootKey.ID() {
origKeySig = true
} else if sig.KeyID == replacementKey.ID() {
replKeySig = true
}
}
assert.False(t, origKeySig, "Original root key signature was present and shouldn't be")
assert.True(t, replKeySig, "Replacement root key signature was not present")
client := NewClient(repo, remote, kdb, cache)
err = client.verifyRoot("root", signedRoot, 0)
assert.Error(t, err, "Should have errored on verify as replacement signature was missing.")
}
func TestCheckRootExpired(t *testing.T) {
repo := tuf.NewRepo(nil, nil)
storage := store.NewMemoryStore(nil, nil)
client := NewClient(repo, storage, nil, storage)
root := &data.SignedRoot{}
root.Signed.Expires = time.Now().AddDate(-1, 0, 0)
signedRoot, err := root.ToSigned()
assert.NoError(t, err)
rootJSON, err := json.Marshal(signedRoot)
assert.NoError(t, err)
rootHash := sha256.Sum256(rootJSON)
testSnap := &data.SignedSnapshot{
Signed: data.Snapshot{
Meta: map[string]data.FileMeta{
"root": {
Length: int64(len(rootJSON)),
Hashes: map[string][]byte{
"sha256": rootHash[:],
},
},
},
},
}
repo.SetRoot(root)
repo.SetSnapshot(testSnap)
storage.SetMeta("root", rootJSON)
err = client.checkRoot()
assert.Error(t, err)
assert.IsType(t, tuf.ErrLocalRootExpired{}, err)
}
func TestChecksumMismatch(t *testing.T) {
repo := tuf.NewRepo(nil, nil)
localStorage := store.NewMemoryStore(nil, nil)
remoteStorage := store.NewMemoryStore(nil, nil)
client := NewClient(repo, remoteStorage, nil, localStorage)
sampleTargets := data.NewTargets()
orig, err := json.Marshal(sampleTargets)
origSha256 := sha256.Sum256(orig)
orig[0] = '}' // corrupt data, should be a {
assert.NoError(t, err)
remoteStorage.SetMeta("targets", orig)
_, _, err = client.downloadSigned("targets", int64(len(orig)), origSha256[:])
assert.IsType(t, ErrChecksumMismatch{}, err)
}
func TestChecksumMatch(t *testing.T) {
repo := tuf.NewRepo(nil, nil)
localStorage := store.NewMemoryStore(nil, nil)
remoteStorage := store.NewMemoryStore(nil, nil)
client := NewClient(repo, remoteStorage, nil, localStorage)
sampleTargets := data.NewTargets()
orig, err := json.Marshal(sampleTargets)
origSha256 := sha256.Sum256(orig)
assert.NoError(t, err)
remoteStorage.SetMeta("targets", orig)
_, _, err = client.downloadSigned("targets", int64(len(orig)), origSha256[:])
assert.NoError(t, err)
}
func TestSizeMismatchLong(t *testing.T) {
repo := tuf.NewRepo(nil, nil)
localStorage := store.NewMemoryStore(nil, nil)
remoteStorage := store.NewMemoryStore(nil, nil)
client := NewClient(repo, remoteStorage, nil, localStorage)
sampleTargets := data.NewTargets()
orig, err := json.Marshal(sampleTargets)
origSha256 := sha256.Sum256(orig)
assert.NoError(t, err)
l := int64(len(orig))
orig = append([]byte(" "), orig...)
assert.Equal(t, l+1, int64(len(orig)))
remoteStorage.SetMeta("targets", orig)
_, _, err = client.downloadSigned("targets", l, origSha256[:])
// size just limits the data received, the error is caught
// either during checksum verification or during json deserialization
assert.IsType(t, ErrChecksumMismatch{}, err)
}
func TestSizeMismatchShort(t *testing.T) {
repo := tuf.NewRepo(nil, nil)
localStorage := store.NewMemoryStore(nil, nil)
remoteStorage := store.NewMemoryStore(nil, nil)
client := NewClient(repo, remoteStorage, nil, localStorage)
sampleTargets := data.NewTargets()
orig, err := json.Marshal(sampleTargets)
origSha256 := sha256.Sum256(orig)
assert.NoError(t, err)
l := int64(len(orig))
orig = orig[1:]
remoteStorage.SetMeta("targets", orig)
_, _, err = client.downloadSigned("targets", l, origSha256[:])
// size just limits the data received, the error is caught
// either during checksum verification or during json deserialization
assert.IsType(t, ErrChecksumMismatch{}, err)
}
func TestDownloadTargetsHappy(t *testing.T) {
kdb, repo, _ := testutils.EmptyRepo()
localStorage := store.NewMemoryStore(nil, nil)
remoteStorage := store.NewMemoryStore(nil, nil)
client := NewClient(repo, remoteStorage, kdb, localStorage)
signedOrig, err := repo.SignTargets("targets", data.DefaultExpires("targets"), nil)
assert.NoError(t, err)
orig, err := json.Marshal(signedOrig)
assert.NoError(t, err)
err = remoteStorage.SetMeta("targets", orig)
assert.NoError(t, err)
// call repo.SignSnapshot to update the targets role in the snapshot
repo.SignSnapshot(data.DefaultExpires("snapshot"), nil)
err = client.downloadTargets("targets")
assert.NoError(t, err)
}
func TestDownloadTargetChecksumMismatch(t *testing.T) {
kdb, repo, _ := testutils.EmptyRepo()
localStorage := store.NewMemoryStore(nil, nil)
remoteStorage := store.NewMemoryStore(nil, nil)
client := NewClient(repo, remoteStorage, kdb, localStorage)
// create and "upload" sample targets
signedOrig, err := repo.SignTargets("targets", data.DefaultExpires("targets"), nil)
assert.NoError(t, err)
orig, err := json.Marshal(signedOrig)
assert.NoError(t, err)
origSha256 := sha256.Sum256(orig)
orig[0] = '}' // corrupt data, should be a {
err = remoteStorage.SetMeta("targets", orig)
assert.NoError(t, err)
// create local snapshot with targets file
// It's necessary to do it this way rather than calling repo.SignSnapshot
// so that we have the wrong sha256 in the snapshot.
snap := data.SignedSnapshot{
Signed: data.Snapshot{
Meta: data.Files{
"targets": data.FileMeta{
Length: int64(len(orig)),
Hashes: data.Hashes{
"sha256": origSha256[:],
},
},
},
},
}
repo.Snapshot = &snap
err = client.downloadTargets("targets")
assert.IsType(t, ErrChecksumMismatch{}, err)
}
// TestDownloadTargetsNoChecksum: it's never valid to download any targets
// role (incl. delegations) when a checksum is not available.
func TestDownloadTargetsNoChecksum(t *testing.T) {
kdb, repo, _ := testutils.EmptyRepo()
localStorage := store.NewMemoryStore(nil, nil)
remoteStorage := store.NewMemoryStore(nil, nil)
client := NewClient(repo, remoteStorage, kdb, localStorage)
// create and "upload" sample targets
signedOrig, err := repo.SignTargets("targets", data.DefaultExpires("targets"), nil)
assert.NoError(t, err)
orig, err := json.Marshal(signedOrig)
assert.NoError(t, err)
err = remoteStorage.SetMeta("targets", orig)
assert.NoError(t, err)
delete(repo.Snapshot.Signed.Meta["targets"].Hashes, "sha256")
err = client.downloadTargets("targets")
assert.IsType(t, ErrMissingMeta{}, err)
}
// TestDownloadTargetsNoSnapshot: it's never valid to download any targets
// role (incl. delegations) when a checksum is not available.
func TestDownloadTargetsNoSnapshot(t *testing.T) {
kdb, repo, _ := testutils.EmptyRepo()
localStorage := store.NewMemoryStore(nil, nil)
remoteStorage := store.NewMemoryStore(nil, nil)
client := NewClient(repo, remoteStorage, kdb, localStorage)
// create and "upload" sample targets
signedOrig, err := repo.SignTargets("targets", data.DefaultExpires("targets"), nil)
assert.NoError(t, err)
orig, err := json.Marshal(signedOrig)
assert.NoError(t, err)
err = remoteStorage.SetMeta("targets", orig)
assert.NoError(t, err)
repo.Snapshot = nil
err = client.downloadTargets("targets")
assert.IsType(t, ErrMissingMeta{}, err)
}
func TestBootstrapDownloadRootHappy(t *testing.T) {
kdb, repo, _ := testutils.EmptyRepo()
localStorage := store.NewMemoryStore(nil, nil)
remoteStorage := store.NewMemoryStore(nil, nil)
client := NewClient(repo, remoteStorage, kdb, localStorage)
// create and "upload" sample root
signedOrig, err := repo.SignRoot(data.DefaultExpires("root"), nil)
assert.NoError(t, err)
orig, err := json.Marshal(signedOrig)
assert.NoError(t, err)
err = remoteStorage.SetMeta("root", orig)
assert.NoError(t, err)
// unset snapshot as if we're bootstrapping from nothing
repo.Snapshot = nil
err = client.downloadRoot()
assert.NoError(t, err)
}
func TestUpdateDownloadRootHappy(t *testing.T) {
kdb, repo, _ := testutils.EmptyRepo()
localStorage := store.NewMemoryStore(nil, nil)
remoteStorage := store.NewMemoryStore(nil, nil)
client := NewClient(repo, remoteStorage, kdb, localStorage)
// create and "upload" sample root, snapshot, and timestamp
signedOrig, err := repo.SignRoot(data.DefaultExpires("root"), nil)
assert.NoError(t, err)
orig, err := json.Marshal(signedOrig)
assert.NoError(t, err)
err = remoteStorage.SetMeta("root", orig)
assert.NoError(t, err)
// sign snapshot to make root meta in snapshot get updated
signedOrig, err = repo.SignSnapshot(data.DefaultExpires("snapshot"), nil)
err = client.downloadRoot()
assert.NoError(t, err)
}
func TestUpdateDownloadRootBadChecksum(t *testing.T) {
kdb, repo, _ := testutils.EmptyRepo()
localStorage := store.NewMemoryStore(nil, nil)
remoteStorage := store.NewMemoryStore(nil, nil)
client := NewClient(repo, remoteStorage, kdb, localStorage)
// sign snapshot to make sure we have a checksum for root
_, err := repo.SignSnapshot(data.DefaultExpires("snapshot"), nil)
assert.NoError(t, err)
// create and "upload" sample root, snapshot, and timestamp
signedOrig, err := repo.SignRoot(data.DefaultExpires("root"), nil)
assert.NoError(t, err)
orig, err := json.Marshal(signedOrig)
assert.NoError(t, err)
err = remoteStorage.SetMeta("root", orig)
assert.NoError(t, err)
// don't sign snapshot again to ensure checksum is out of date (bad)
err = client.downloadRoot()
assert.IsType(t, ErrChecksumMismatch{}, err)
}
func TestDownloadTimestampHappy(t *testing.T) {
kdb, repo, _ := testutils.EmptyRepo()
localStorage := store.NewMemoryStore(nil, nil)
remoteStorage := store.NewMemoryStore(nil, nil)
client := NewClient(repo, remoteStorage, kdb, localStorage)
// create and "upload" sample timestamp
signedOrig, err := repo.SignTimestamp(data.DefaultExpires("timestamp"), nil)
assert.NoError(t, err)
orig, err := json.Marshal(signedOrig)
assert.NoError(t, err)
err = remoteStorage.SetMeta("timestamp", orig)
assert.NoError(t, err)
err = client.downloadTimestamp()
assert.NoError(t, err)
}
func TestDownloadSnapshotHappy(t *testing.T) {
kdb, repo, _ := testutils.EmptyRepo()
localStorage := store.NewMemoryStore(nil, nil)
remoteStorage := store.NewMemoryStore(nil, nil)
client := NewClient(repo, remoteStorage, kdb, localStorage)
// create and "upload" sample snapshot and timestamp
signedOrig, err := repo.SignSnapshot(data.DefaultExpires("snapshot"), nil)
assert.NoError(t, err)
orig, err := json.Marshal(signedOrig)
assert.NoError(t, err)
err = remoteStorage.SetMeta("snapshot", orig)
assert.NoError(t, err)
signedOrig, err = repo.SignTimestamp(data.DefaultExpires("timestamp"), nil)
assert.NoError(t, err)
orig, err = json.Marshal(signedOrig)
assert.NoError(t, err)
err = remoteStorage.SetMeta("timestamp", orig)
assert.NoError(t, err)
err = client.downloadSnapshot()
assert.NoError(t, err)
}
// TestDownloadSnapshotNoChecksum: It should never be valid to download a
// snapshot if we don't have a checksum
func TestDownloadSnapshotNoTimestamp(t *testing.T) {
kdb, repo, _ := testutils.EmptyRepo()
localStorage := store.NewMemoryStore(nil, nil)
remoteStorage := store.NewMemoryStore(nil, nil)
client := NewClient(repo, remoteStorage, kdb, localStorage)
// create and "upload" sample snapshot and timestamp
signedOrig, err := repo.SignSnapshot(data.DefaultExpires("snapshot"), nil)
assert.NoError(t, err)
orig, err := json.Marshal(signedOrig)
assert.NoError(t, err)
err = remoteStorage.SetMeta("snapshot", orig)
assert.NoError(t, err)
repo.Timestamp = nil
err = client.downloadSnapshot()
assert.IsType(t, ErrMissingMeta{}, err)
}
func TestDownloadSnapshotNoChecksum(t *testing.T) {
kdb, repo, _ := testutils.EmptyRepo()
localStorage := store.NewMemoryStore(nil, nil)
remoteStorage := store.NewMemoryStore(nil, nil)
client := NewClient(repo, remoteStorage, kdb, localStorage)
// create and "upload" sample snapshot and timestamp
signedOrig, err := repo.SignSnapshot(data.DefaultExpires("snapshot"), nil)
assert.NoError(t, err)
orig, err := json.Marshal(signedOrig)
assert.NoError(t, err)
err = remoteStorage.SetMeta("snapshot", orig)
assert.NoError(t, err)
delete(repo.Timestamp.Signed.Meta["snapshot"].Hashes, "sha256")
err = client.downloadSnapshot()
assert.IsType(t, ErrMissingMeta{}, err)
}
func TestDownloadSnapshotBadChecksum(t *testing.T) {
kdb, repo, _ := testutils.EmptyRepo()
localStorage := store.NewMemoryStore(nil, nil)
remoteStorage := store.NewMemoryStore(nil, nil)
client := NewClient(repo, remoteStorage, kdb, localStorage)
// sign timestamp to ensure it has a checksum for snapshot
_, err := repo.SignTimestamp(data.DefaultExpires("timestamp"), nil)
assert.NoError(t, err)
// create and "upload" sample snapshot and timestamp
signedOrig, err := repo.SignSnapshot(data.DefaultExpires("snapshot"), nil)
assert.NoError(t, err)
orig, err := json.Marshal(signedOrig)
assert.NoError(t, err)
err = remoteStorage.SetMeta("snapshot", orig)
assert.NoError(t, err)
// by not signing timestamp again we ensure it has the wrong checksum
err = client.downloadSnapshot()
assert.IsType(t, ErrChecksumMismatch{}, err)
}

View File

@@ -4,7 +4,7 @@ import (
"fmt"
"strings"
"github.com/endophage/gotuf/errors"
"github.com/docker/notary/tuf/errors"
)
// Canonical base role names

52
tuf/data/roles_test.go Normal file
View File

@@ -0,0 +1,52 @@
package data
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestCanonicalRole(t *testing.T) {
testRoles := map[string]string{
CanonicalRootRole: "testRoot",
CanonicalTargetsRole: "testTargets",
CanonicalSnapshotRole: "testSnapshot",
CanonicalTimestampRole: "testTimestamp",
"garbageRole": "testGarbageRole",
}
SetValidRoles(testRoles)
// make sure roles were set correctly
assert.Equal(t, "testRoot", ValidRoles[CanonicalRootRole])
assert.Equal(t, "testTargets", ValidRoles[CanonicalTargetsRole])
assert.Equal(t, "testSnapshot", ValidRoles[CanonicalSnapshotRole])
assert.Equal(t, "testTimestamp", ValidRoles[CanonicalTimestampRole])
// check SetValidRoles doesn't allow non-valid roles in
assert.Equal(t, "", ValidRoles["garbageRole"])
// check when looking up CanonicalRole from configured role
assert.Equal(t, CanonicalRootRole, CanonicalRole("testRoot"))
assert.Equal(t, CanonicalTargetsRole, CanonicalRole("testTargets"))
assert.Equal(t, CanonicalSnapshotRole, CanonicalRole("testSnapshot"))
assert.Equal(t, CanonicalTimestampRole, CanonicalRole("testTimestamp"))
assert.Equal(t, "", CanonicalRole("testGarbageRole"))
// check when looking up CanonicalRole with canonical role
assert.Equal(t, CanonicalRootRole, CanonicalRole(CanonicalRootRole))
assert.Equal(t, CanonicalTargetsRole, CanonicalRole(CanonicalTargetsRole))
assert.Equal(t, CanonicalSnapshotRole, CanonicalRole(CanonicalSnapshotRole))
assert.Equal(t, CanonicalTimestampRole, CanonicalRole(CanonicalTimestampRole))
assert.Equal(t, "", CanonicalRole("garbageRole"))
assert.Equal(t, "", CanonicalRole("not found"))
// reset ValidRoles so other tests aren't messed up
ValidRoles = map[string]string{
CanonicalRootRole: CanonicalRootRole,
CanonicalTargetsRole: CanonicalTargetsRole,
CanonicalSnapshotRole: CanonicalSnapshotRole,
CanonicalTimestampRole: CanonicalTimestampRole,
}
}

55
tuf/data/types_test.go Normal file
View File

@@ -0,0 +1,55 @@
package data
import (
"bytes"
"encoding/hex"
"testing"
"github.com/jfrazelle/go/canonical/json"
"github.com/stretchr/testify/assert"
)
func TestGenerateFileMetaDefault(t *testing.T) {
// default is sha512
r := bytes.NewReader([]byte("foo"))
meta, err := NewFileMeta(r, "sha512")
assert.NoError(t, err, "Unexpected error.")
assert.Equal(t, meta.Length, int64(3), "Meta did not have expected Length field value")
hashes := meta.Hashes
assert.Len(t, hashes, 1, "Only expected one hash to be present")
hash, ok := hashes["sha512"]
if !ok {
t.Fatal("missing sha512 hash")
}
assert.Equal(t, "f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382d624741d0dc6638326e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7", hex.EncodeToString(hash), "Hashes not equal")
}
func TestGenerateFileMetaExplicit(t *testing.T) {
r := bytes.NewReader([]byte("foo"))
meta, err := NewFileMeta(r, "sha256", "sha512")
assert.NoError(t, err)
assert.Equal(t, meta.Length, int64(3))
hashes := meta.Hashes
assert.Len(t, hashes, 2)
for name, val := range map[string]string{
"sha256": "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae",
"sha512": "f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382d624741d0dc6638326e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7",
} {
hash, ok := hashes[name]
if !ok {
t.Fatalf("missing %s hash", name)
}
assert.Equal(t, hex.EncodeToString(hash), val)
}
}
func TestSignatureUnmarshalJSON(t *testing.T) {
signatureJSON := `{"keyid":"97e8e1b51b6e7cf8720a56b5334bd8692ac5b28233c590b89fab0b0cd93eeedc","method":"RSA","sig":"2230cba525e4f5f8fc744f234221ca9a92924da4cc5faf69a778848882fcf7a20dbb57296add87f600891f2569a9c36706314c240f9361c60fd36f5a915a0e9712fc437b761e8f480868d7a4444724daa0d29a2669c0edbd4046046649a506b3d711d0aa5e70cb9d09dec7381e7de27a3168e77731e08f6ed56fcce2478855e837816fb69aff53412477748cd198dce783850080d37aeb929ad0f81460ebd31e61b772b6c7aa56977c787d4281fa45dbdefbb38d449eb5bccb2702964a52c78811545939712c8280dee0b23b2fa9fbbdd6a0c42476689ace655eba0745b4a21ba108bcd03ad00fdefff416dc74e08486a0538f8fd24989e1b9fc89e675141b7c"}`
var sig Signature
err := json.Unmarshal([]byte(signatureJSON), &sig)
assert.NoError(t, err)
// Check that the method string is lowercased
assert.Equal(t, sig.Method.String(), "rsa")
}

BIN
tuf/db/files.db Normal file

Binary file not shown.

View File

@@ -0,0 +1,57 @@
package encrypted
import (
"encoding/json"
"testing"
"github.com/stretchr/testify/assert"
)
var plaintext = []byte("reallyimportant")
func TestRoundtrip(t *testing.T) {
passphrase := []byte("supersecret")
enc, err := Encrypt(plaintext, passphrase)
assert.NoError(t, err)
// successful decrypt
dec, err := Decrypt(enc, passphrase)
assert.NoError(t, err)
assert.Equal(t, dec, plaintext)
// wrong passphrase
passphrase[0] = 0
dec, err = Decrypt(enc, passphrase)
assert.Error(t, err)
assert.Nil(t, dec)
}
func TestTamperedRoundtrip(t *testing.T) {
passphrase := []byte("supersecret")
enc, err := Encrypt(plaintext, passphrase)
assert.NoError(t, err)
data := &data{}
err = json.Unmarshal(enc, data)
assert.NoError(t, err)
data.Ciphertext[0] = 0
data.Ciphertext[1] = 0
enc, _ = json.Marshal(data)
dec, err := Decrypt(enc, passphrase)
assert.Error(t, err)
assert.Nil(t, dec)
}
func TestDecrypt(t *testing.T) {
enc := []byte(`{"kdf":{"name":"scrypt","params":{"N":32768,"r":8,"p":1},"salt":"N9a7x5JFGbrtB2uBR81jPwp0eiLR4A7FV3mjVAQrg1g="},"cipher":{"name":"nacl/secretbox","nonce":"2h8HxMmgRfuYdpswZBQaU3xJ1nkA/5Ik"},"ciphertext":"SEW6sUh0jf2wfdjJGPNS9+bkk2uB+Cxamf32zR8XkQ=="}`)
passphrase := []byte("supersecret")
dec, err := Decrypt(enc, passphrase)
assert.NoError(t, err)
assert.Equal(t, dec, plaintext)
}

View File

@@ -3,7 +3,7 @@ package keys
import (
"errors"
"github.com/endophage/gotuf/data"
"github.com/docker/notary/tuf/data"
)
// Various basic key database errors

View File

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 56 KiB

View File

@@ -5,7 +5,7 @@ import (
"errors"
"github.com/agl/ed25519"
"github.com/endophage/gotuf/data"
"github.com/docker/notary/tuf/data"
)
// Ed25519 implements a simple in memory cryptosystem for ED25519 keys

View File

@@ -1,7 +1,7 @@
package signed
import (
"github.com/endophage/gotuf/data"
"github.com/docker/notary/tuf/data"
)
// SigningService defines the necessary functions to determine

View File

@@ -15,9 +15,9 @@ import (
"fmt"
"github.com/Sirupsen/logrus"
"github.com/endophage/gotuf/data"
"github.com/endophage/gotuf/errors"
"github.com/endophage/gotuf/utils"
"github.com/docker/notary/tuf/data"
"github.com/docker/notary/tuf/errors"
"github.com/docker/notary/tuf/utils"
)
type idPair struct {

230
tuf/signed/sign_test.go Normal file
View File

@@ -0,0 +1,230 @@
package signed
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"testing"
"github.com/docker/notary/trustmanager"
"github.com/docker/notary/tuf/data"
"github.com/stretchr/testify/assert"
)
const (
testKeyPEM1 = "-----BEGIN PUBLIC KEY-----\nMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAnKuXZeefa2LmgxaL5NsM\nzKOHNe+x/nL6ik+lDBCTV6OdcwAhHQS+PONGhrChIUVR6Vth3hUCrreLzPO73Oo5\nVSCuRJ53UronENl6lsa5mFKP8StYLvIDITNvkoT3j52BJIjyNUK9UKY9As2TNqDf\nBEPIRp28ev/NViwGOEkBu2UAbwCIdnDXm8JQErCZA0Ydm7PKGgjLbFsFGrVzqXHK\n6pdzJXlhr9yap3UpgQ/iO9JtoEYB2EXsnSrPc9JRjR30bNHHtnVql3fvinXrAEwq\n3xmN4p+R4VGzfdQN+8Kl/IPjqWB535twhFYEG/B7Ze8IwbygBjK3co/KnOPqMUrM\nBI8ztvPiogz+MvXb8WvarZ6TMTh8ifZI96r7zzqyzjR1hJulEy3IsMGvz8XS2J0X\n7sXoaqszEtXdq5ef5zKVxkiyIQZcbPgmpHLq4MgfdryuVVc/RPASoRIXG4lKaTJj\n1ANMFPxDQpHudCLxwCzjCb+sVa20HBRPTnzo8LSZkI6jAgMBAAE=\n-----END PUBLIC KEY-----"
testKeyID1 = "51324b59d4888faa91219ebbe5a3876bb4efb21f0602ddf363cd4c3996ded3d4"
testKeyPEM2 = "-----BEGIN PUBLIC KEY-----\nMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEArvqUPYb6JJROPJQglPTj\n5uDrsxQKl34Mo+3pSlBVuD6puE4lDnG649a2YksJy+C8ZIPJgokn5w+C3alh+dMe\nzbdWHHxrY1h9CLpYz5cbMlE16303ubkt1rvwDqEezG0HDBzPaKj4oP9YJ9x7wbsq\ndvFcy+Qc3wWd7UWcieo6E0ihbJkYcY8chRXVLg1rL7EfZ+e3bq5+ojA2ECM5JqzZ\nzgDpqCv5hTCYYZp72MZcG7dfSPAHrcSGIrwg7whzz2UsEtCOpsJTuCl96FPN7kAu\n4w/WyM3+SPzzr4/RQXuY1SrLCFD8ebM2zHt/3ATLhPnGmyG5I0RGYoegFaZ2AViw\nlqZDOYnBtgDvKP0zakMtFMbkh2XuNBUBO7Sjs0YcZMjLkh9gYUHL1yWS3Aqus1Lw\nlI0gHS22oyGObVBWkZEgk/Foy08sECLGao+5VvhmGpfVuiz9OKFUmtPVjWzRE4ng\niekEu4drSxpH41inLGSvdByDWLpcTvWQI9nkgclh3AT/AgMBAAE=\n-----END PUBLIC KEY-----"
testKeyID2 = "26f2f5c0fbfa98823bf1ad39d5f3b32575895793baf80f1df675597d5b95dba8"
)
type FailingCryptoService struct {
testKey data.PublicKey
}
func (mts *FailingCryptoService) Sign(keyIDs []string, _ []byte) ([]data.Signature, error) {
sigs := make([]data.Signature, 0, len(keyIDs))
return sigs, nil
}
func (mts *FailingCryptoService) Create(_ string, _ data.KeyAlgorithm) (data.PublicKey, error) {
return mts.testKey, nil
}
func (mts *FailingCryptoService) GetKey(keyID string) data.PublicKey {
if keyID == "testID" {
return mts.testKey
}
return nil
}
func (mts *FailingCryptoService) RemoveKey(keyID string) error {
return nil
}
type MockCryptoService struct {
testKey data.PublicKey
}
func (mts *MockCryptoService) Sign(keyIDs []string, _ []byte) ([]data.Signature, error) {
sigs := make([]data.Signature, 0, len(keyIDs))
for _, keyID := range keyIDs {
sigs = append(sigs, data.Signature{KeyID: keyID})
}
return sigs, nil
}
func (mts *MockCryptoService) Create(_ string, _ data.KeyAlgorithm) (data.PublicKey, error) {
return mts.testKey, nil
}
func (mts *MockCryptoService) GetKey(keyID string) data.PublicKey {
if keyID == "testID" {
return mts.testKey
}
return nil
}
func (mts *MockCryptoService) RemoveKey(keyID string) error {
return nil
}
var _ CryptoService = &MockCryptoService{}
type StrictMockCryptoService struct {
MockCryptoService
}
func (mts *StrictMockCryptoService) Sign(keyIDs []string, _ []byte) ([]data.Signature, error) {
sigs := make([]data.Signature, 0, len(keyIDs))
for _, keyID := range keyIDs {
if keyID == mts.testKey.ID() {
sigs = append(sigs, data.Signature{KeyID: keyID})
}
}
return sigs, nil
}
func (mts *StrictMockCryptoService) GetKey(keyID string) data.PublicKey {
if keyID == mts.testKey.ID() {
return mts.testKey
}
return nil
}
// Test signing and ensure the expected signature is added
func TestBasicSign(t *testing.T) {
testKey, _ := pem.Decode([]byte(testKeyPEM1))
k := data.NewPublicKey(data.RSAKey, testKey.Bytes)
mockCryptoService := &MockCryptoService{testKey: k}
key, err := mockCryptoService.Create("root", data.ED25519Key)
if err != nil {
t.Fatal(err)
}
testData := data.Signed{}
Sign(mockCryptoService, &testData, key)
if len(testData.Signatures) != 1 {
t.Fatalf("Incorrect number of signatures: %d", len(testData.Signatures))
}
if testData.Signatures[0].KeyID != testKeyID1 {
t.Fatalf("Wrong signature ID returned: %s", testData.Signatures[0].KeyID)
}
}
// Test signing with the same key multiple times only registers a single signature
// for the key (N.B. MockCryptoService.Sign will still be called again, but Signer.Sign
// should be cleaning previous signatures by the KeyID when asked to sign again)
func TestReSign(t *testing.T) {
testKey, _ := pem.Decode([]byte(testKeyPEM1))
k := data.NewPublicKey(data.RSAKey, testKey.Bytes)
mockCryptoService := &MockCryptoService{testKey: k}
testData := data.Signed{}
Sign(mockCryptoService, &testData, k)
Sign(mockCryptoService, &testData, k)
if len(testData.Signatures) != 1 {
t.Fatalf("Incorrect number of signatures: %d", len(testData.Signatures))
}
if testData.Signatures[0].KeyID != testKeyID1 {
t.Fatalf("Wrong signature ID returned: %s", testData.Signatures[0].KeyID)
}
}
func TestMultiSign(t *testing.T) {
mockCryptoService := &MockCryptoService{}
testData := data.Signed{}
testKey, _ := pem.Decode([]byte(testKeyPEM1))
key := data.NewPublicKey(data.RSAKey, testKey.Bytes)
Sign(mockCryptoService, &testData, key)
testKey, _ = pem.Decode([]byte(testKeyPEM2))
key = data.NewPublicKey(data.RSAKey, testKey.Bytes)
Sign(mockCryptoService, &testData, key)
if len(testData.Signatures) != 2 {
t.Fatalf("Incorrect number of signatures: %d", len(testData.Signatures))
}
keyIDs := map[string]struct{}{testKeyID1: struct{}{}, testKeyID2: struct{}{}}
for _, sig := range testData.Signatures {
if _, ok := keyIDs[sig.KeyID]; !ok {
t.Fatalf("Got a signature we didn't expect: %s", sig.KeyID)
}
}
}
func TestSignReturnsNoSigs(t *testing.T) {
failingCryptoService := &FailingCryptoService{}
testData := data.Signed{}
testKey, _ := pem.Decode([]byte(testKeyPEM1))
key := data.NewPublicKey(data.RSAKey, testKey.Bytes)
err := Sign(failingCryptoService, &testData, key)
if err == nil {
t.Fatalf("Expected failure due to no signature being returned by the crypto service")
}
if len(testData.Signatures) != 0 {
t.Fatalf("Incorrect number of signatures, expected 0: %d", len(testData.Signatures))
}
}
func TestCreate(t *testing.T) {
testKey, _ := pem.Decode([]byte(testKeyPEM1))
k := data.NewPublicKey(data.RSAKey, testKey.Bytes)
mockCryptoService := &MockCryptoService{testKey: k}
key, err := mockCryptoService.Create("root", data.ED25519Key)
if err != nil {
t.Fatal(err)
}
if key.ID() != testKeyID1 {
t.Fatalf("Expected key ID not found: %s", key.ID())
}
}
func TestSignWithX509(t *testing.T) {
// generate a key becase we need a cert
privKey, err := rsa.GenerateKey(rand.Reader, 1024)
assert.NoError(t, err)
// make a RSA x509 key
template, err := trustmanager.NewCertificate("test")
assert.NoError(t, err)
derBytes, err := x509.CreateCertificate(
rand.Reader, template, template, &privKey.PublicKey, privKey)
assert.NoError(t, err)
cert, err := x509.ParseCertificate(derBytes)
assert.NoError(t, err)
tufRSAx509Key := trustmanager.CertToKey(cert)
assert.NoError(t, err)
// make a data.PublicKey from the generated private key
pubBytes, err := x509.MarshalPKIXPublicKey(&privKey.PublicKey)
assert.NoError(t, err)
tufRSAKey := data.NewPublicKey(data.RSAKey, pubBytes)
// test signing against a service that only recognizes a RSAKey (not
// RSAx509 key)
mockCryptoService := &StrictMockCryptoService{MockCryptoService{tufRSAKey}}
testData := data.Signed{}
err = Sign(mockCryptoService, &testData, tufRSAx509Key)
assert.NoError(t, err)
assert.Len(t, testData.Signatures, 1)
assert.Equal(t, tufRSAx509Key.ID(), testData.Signatures[0].KeyID)
}

View File

@@ -13,7 +13,7 @@ import (
"github.com/Sirupsen/logrus"
"github.com/agl/ed25519"
"github.com/endophage/gotuf/data"
"github.com/docker/notary/tuf/data"
)
const (

File diff suppressed because one or more lines are too long

View File

@@ -6,8 +6,8 @@ import (
"time"
"github.com/Sirupsen/logrus"
"github.com/endophage/gotuf/data"
"github.com/endophage/gotuf/keys"
"github.com/docker/notary/tuf/data"
"github.com/docker/notary/tuf/keys"
"github.com/jfrazelle/go/canonical/json"
)

202
tuf/signed/verify_test.go Normal file
View File

@@ -0,0 +1,202 @@
package signed
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/docker/notary/tuf/data"
"github.com/docker/notary/tuf/keys"
"github.com/jfrazelle/go/canonical/json"
)
func Test(t *testing.T) {
cryptoService := NewEd25519()
type test struct {
name string
keys []data.PublicKey
roles map[string]*data.Role
s *data.Signed
ver int
exp *time.Time
typ string
role string
err error
mut func(*test)
}
expiredTime := time.Now().Add(-time.Hour)
minVer := 10
tests := []test{
{
name: "no signatures",
mut: func(t *test) { t.s.Signatures = []data.Signature{} },
err: ErrNoSignatures,
},
{
name: "unknown role",
role: "foo",
err: ErrUnknownRole,
},
//{
// name: "wrong signature method",
// mut: func(t *test) { t.s.Signatures[0].Method = "foo" },
// err: ErrWrongMethod,
//},
// {
// name: "signature wrong length",
// mut: func(t *test) { t.s.Signatures[0].Signature = []byte{0} },
// err: ErrInvalid,
// },
{
name: "key missing from role",
mut: func(t *test) { t.roles["root"].KeyIDs = nil },
err: ErrRoleThreshold{},
},
// {
// name: "invalid signature",
// mut: func(t *test) { t.s.Signatures[0].Signature = make([]byte, ed25519.SignatureSize) },
// err: ErrInvalid,
// },
{
name: "not enough signatures",
mut: func(t *test) { t.roles["root"].Threshold = 2 },
err: ErrRoleThreshold{},
},
{
name: "exactly enough signatures",
},
{
name: "more than enough signatures",
mut: func(t *test) {
k, _ := cryptoService.Create("root", data.ED25519Key)
Sign(cryptoService, t.s, k)
t.keys = append(t.keys, k)
t.roles["root"].KeyIDs = append(t.roles["root"].KeyIDs, k.ID())
},
},
{
name: "duplicate key id",
mut: func(t *test) {
t.roles["root"].Threshold = 2
t.s.Signatures = append(t.s.Signatures, t.s.Signatures[0])
},
err: ErrRoleThreshold{},
},
{
name: "unknown key",
mut: func(t *test) {
k, _ := cryptoService.Create("root", data.ED25519Key)
Sign(cryptoService, t.s, k)
},
},
{
name: "unknown key below threshold",
mut: func(t *test) {
k, _ := cryptoService.Create("root", data.ED25519Key)
Sign(cryptoService, t.s, k)
t.roles["root"].Threshold = 2
},
err: ErrRoleThreshold{},
},
{
name: "unknown keys in db",
mut: func(t *test) {
k, _ := cryptoService.Create("root", data.ED25519Key)
Sign(cryptoService, t.s, k)
t.keys = append(t.keys, k)
},
},
{
name: "unknown keys in db below threshold",
mut: func(t *test) {
k, _ := cryptoService.Create("root", data.ED25519Key)
Sign(cryptoService, t.s, k)
t.keys = append(t.keys, k)
t.roles["root"].Threshold = 2
},
err: ErrRoleThreshold{},
},
{
name: "wrong type",
typ: "bar",
err: ErrWrongType,
},
{
name: "low version",
ver: minVer - 1,
err: ErrLowVersion{minVer - 1, minVer},
},
{
role: "root",
name: "expired",
exp: &expiredTime,
err: ErrExpired{"root", expiredTime.Format("Mon Jan 2 15:04:05 MST 2006")},
},
}
for _, run := range tests {
if run.role == "" {
run.role = "root"
}
if run.ver == 0 {
run.ver = minVer
}
if run.exp == nil {
expires := time.Now().Add(time.Hour)
run.exp = &expires
}
if run.typ == "" {
run.typ = data.TUFTypes[run.role]
}
if run.keys == nil && run.s == nil {
k, _ := cryptoService.Create("root", data.ED25519Key)
meta := &data.SignedCommon{Type: run.typ, Version: run.ver, Expires: *run.exp}
b, err := json.MarshalCanonical(meta)
assert.NoError(t, err)
s := &data.Signed{Signed: b}
Sign(cryptoService, s, k)
run.s = s
run.keys = []data.PublicKey{k}
}
if run.roles == nil {
run.roles = map[string]*data.Role{
"root": &data.Role{
RootRole: data.RootRole{
KeyIDs: []string{run.keys[0].ID()},
Threshold: 1,
},
Name: "root",
},
}
}
if run.mut != nil {
run.mut(&run)
}
db := keys.NewDB()
for _, k := range run.keys {
db.AddKey(k)
}
for _, r := range run.roles {
err := db.AddRole(r)
assert.NoError(t, err)
}
err := Verify(run.s, run.role, minVer, db)
if e, ok := run.err.(ErrExpired); ok {
assertErrExpired(t, err, e)
} else {
assert.Equal(t, run.err, err)
}
}
}
func assertErrExpired(t *testing.T, err error, expected ErrExpired) {
actual, ok := err.(ErrExpired)
if !ok {
t.Fatalf("expected err to have type ErrExpired, got %T", err)
}
assert.Equal(t, actual.Expired, expected.Expired)
}

View File

@@ -0,0 +1,58 @@
package store
import (
"io/ioutil"
"os"
"path"
"testing"
"github.com/stretchr/testify/assert"
)
const testDir = "/tmp/testFilesystemStore/"
func TestNewFilesystemStore(t *testing.T) {
_, err := NewFilesystemStore(testDir, "metadata", "json", "targets")
assert.Nil(t, err, "Initializing FilesystemStore returned unexpected error: %v", err)
defer os.RemoveAll(testDir)
info, err := os.Stat(path.Join(testDir, "metadata"))
assert.Nil(t, err, "Error attempting to stat metadata dir: %v", err)
assert.NotNil(t, info, "Nil FileInfo from stat on metadata dir")
assert.True(t, 0700&info.Mode() != 0, "Metadata directory is not writable")
info, err = os.Stat(path.Join(testDir, "targets"))
assert.Nil(t, err, "Error attempting to stat targets dir: %v", err)
assert.NotNil(t, info, "Nil FileInfo from stat on targets dir")
assert.True(t, 0700&info.Mode() != 0, "Targets directory is not writable")
}
func TestSetMeta(t *testing.T) {
s, err := NewFilesystemStore(testDir, "metadata", "json", "targets")
assert.Nil(t, err, "Initializing FilesystemStore returned unexpected error: %v", err)
defer os.RemoveAll(testDir)
testContent := []byte("test data")
err = s.SetMeta("testMeta", testContent)
assert.Nil(t, err, "SetMeta returned unexpected error: %v", err)
content, err := ioutil.ReadFile(path.Join(testDir, "metadata", "testMeta.json"))
assert.Nil(t, err, "Error reading file: %v", err)
assert.Equal(t, testContent, content, "Content written to file was corrupted.")
}
func TestGetMeta(t *testing.T) {
s, err := NewFilesystemStore(testDir, "metadata", "json", "targets")
assert.Nil(t, err, "Initializing FilesystemStore returned unexpected error: %v", err)
defer os.RemoveAll(testDir)
testContent := []byte("test data")
ioutil.WriteFile(path.Join(testDir, "metadata", "testMeta.json"), testContent, 0600)
content, err := s.GetMeta("testMeta", int64(len(testContent)))
assert.Nil(t, err, "GetMeta returned unexpected error: %v", err)
assert.Equal(t, testContent, content, "Content read from file was corrupted.")
}

Some files were not shown because too many files have changed in this diff Show More