Rename crypto functions and constants

This commit is contained in:
Alexander Neumann 2015-04-12 09:41:47 +02:00
parent 3a2525809c
commit 21dc6dd3db
6 changed files with 54 additions and 54 deletions

View File

@ -18,14 +18,14 @@ import (
) )
const ( const (
AESKeySize = 32 // for AES256 aesKeySize = 32 // for AES256
MACKeySizeK = 16 // for AES-128 macKeySizeK = 16 // for AES-128
MACKeySizeR = 16 // for Poly1305 macKeySizeR = 16 // for Poly1305
MACKeySize = MACKeySizeK + MACKeySizeR // for Poly1305-AES128 macKeySize = macKeySizeK + macKeySizeR // for Poly1305-AES128
ivSize = aes.BlockSize ivSize = aes.BlockSize
macSize = poly1305.TagSize // Poly1305 size is 16 byte macSize = poly1305.TagSize // Poly1305 size is 16 byte
CiphertextExtension = ivSize + macSize Extension = ivSize + macSize
) )
var ( var (
@ -37,11 +37,11 @@ var (
ErrBufferTooSmall = errors.New("destination buffer too small") ErrBufferTooSmall = errors.New("destination buffer too small")
) )
// MasterKeys holds signing and encryption keys for a repository. It is stored // Key holds signing and encryption keys for a repository. It is stored
// encrypted and signed as a JSON data structure in the Data field of the Key // encrypted and signed as a JSON data structure in the Data field of the Key
// structure. For the master key, the secret random polynomial used for content // structure. For the master key, the secret random polynomial used for content
// defined chunking is included. // defined chunking is included.
type MasterKeys struct { type Key struct {
Sign MACKey `json:"sign"` Sign MACKey `json:"sign"`
Encrypt AESKey `json:"encrypt"` Encrypt AESKey `json:"encrypt"`
ChunkerPolynomial chunker.Pol `json:"chunker_polynomial,omitempty"` ChunkerPolynomial chunker.Pol `json:"chunker_polynomial,omitempty"`
@ -141,21 +141,21 @@ func poly1305_verify(msg []byte, nonce []byte, key *MACKey, mac []byte) bool {
return poly1305.Verify(&m, msg, &k) return poly1305.Verify(&m, msg, &k)
} }
// returns new encryption and mac keys. k.MACKey.R is already masked. // GenerateKey returns new encryption and signing keys.
func GenerateRandomKeys() (k *MasterKeys) { func GenerateKey() (k *Key) {
k = &MasterKeys{} k = &Key{}
n, err := rand.Read(k.Encrypt[:]) n, err := rand.Read(k.Encrypt[:])
if n != AESKeySize || err != nil { if n != aesKeySize || err != nil {
panic("unable to read enough random bytes for encryption key") panic("unable to read enough random bytes for encryption key")
} }
n, err = rand.Read(k.Sign.K[:]) n, err = rand.Read(k.Sign.K[:])
if n != MACKeySizeK || err != nil { if n != macKeySizeK || err != nil {
panic("unable to read enough random bytes for mac encryption key") panic("unable to read enough random bytes for mac encryption key")
} }
n, err = rand.Read(k.Sign.R[:]) n, err = rand.Read(k.Sign.R[:])
if n != MACKeySizeR || err != nil { if n != macKeySizeR || err != nil {
panic("unable to read enough random bytes for mac signing key") panic("unable to read enough random bytes for mac signing key")
} }
// mask r // mask r
@ -198,7 +198,7 @@ func (k *AESKey) MarshalJSON() ([]byte, error) {
} }
func (k *AESKey) UnmarshalJSON(data []byte) error { func (k *AESKey) UnmarshalJSON(data []byte) error {
d := make([]byte, AESKeySize) d := make([]byte, aesKeySize)
err := json.Unmarshal(data, &d) err := json.Unmarshal(data, &d)
if err != nil { if err != nil {
return err return err
@ -210,7 +210,7 @@ func (k *AESKey) UnmarshalJSON(data []byte) error {
// Encrypt encrypts and signs data. Stored in ciphertext is IV || Ciphertext || // Encrypt encrypts and signs data. Stored in ciphertext is IV || Ciphertext ||
// MAC. Encrypt returns the ciphertext's length. // MAC. Encrypt returns the ciphertext's length.
func Encrypt(ks *MasterKeys, ciphertext, plaintext []byte) (int, error) { func Encrypt(ks *Key, ciphertext, plaintext []byte) (int, error) {
if cap(ciphertext) < len(plaintext)+ivSize+macSize { if cap(ciphertext) < len(plaintext)+ivSize+macSize {
return 0, ErrBufferTooSmall return 0, ErrBufferTooSmall
} }
@ -236,7 +236,7 @@ func Encrypt(ks *MasterKeys, ciphertext, plaintext []byte) (int, error) {
// Decrypt verifies and decrypts the ciphertext. Ciphertext must be in the form // Decrypt verifies and decrypts the ciphertext. Ciphertext must be in the form
// IV || Ciphertext || MAC. // IV || Ciphertext || MAC.
func Decrypt(ks *MasterKeys, plaintext, ciphertext []byte) ([]byte, error) { func Decrypt(ks *Key, plaintext, ciphertext []byte) ([]byte, error) {
// check for plausible length // check for plausible length
if len(ciphertext) < ivSize+macSize { if len(ciphertext) < ivSize+macSize {
panic("trying to decrypt invalid data: ciphertext too small") panic("trying to decrypt invalid data: ciphertext too small")
@ -275,14 +275,14 @@ func Decrypt(ks *MasterKeys, plaintext, ciphertext []byte) ([]byte, error) {
// KDF derives encryption and signing keys from the password using the supplied // KDF derives encryption and signing keys from the password using the supplied
// parameters N, R and P and the Salt. // parameters N, R and P and the Salt.
func KDF(N, R, P int, salt []byte, password string) (*MasterKeys, error) { func KDF(N, R, P int, salt []byte, password string) (*Key, error) {
if len(salt) == 0 { if len(salt) == 0 {
return nil, fmt.Errorf("scrypt() called with empty salt") return nil, fmt.Errorf("scrypt() called with empty salt")
} }
derKeys := &MasterKeys{} derKeys := &Key{}
keybytes := MACKeySize + AESKeySize keybytes := macKeySize + aesKeySize
scryptKeys, err := scrypt.Key([]byte(password), salt, N, R, P, keybytes) scryptKeys, err := scrypt.Key([]byte(password), salt, N, R, P, keybytes)
if err != nil { if err != nil {
return nil, fmt.Errorf("error deriving keys from password: %v", err) return nil, fmt.Errorf("error deriving keys from password: %v", err)
@ -293,10 +293,10 @@ func KDF(N, R, P int, salt []byte, password string) (*MasterKeys, error) {
} }
// first 32 byte of scrypt output is the encryption key // first 32 byte of scrypt output is the encryption key
copy(derKeys.Encrypt[:], scryptKeys[:AESKeySize]) copy(derKeys.Encrypt[:], scryptKeys[:aesKeySize])
// next 32 byte of scrypt output is the mac key, in the form k||r // next 32 byte of scrypt output is the mac key, in the form k||r
macKeyFromSlice(&derKeys.Sign, scryptKeys[AESKeySize:]) macKeyFromSlice(&derKeys.Sign, scryptKeys[aesKeySize:])
return derKeys, nil return derKeys, nil
} }
@ -305,7 +305,7 @@ type encryptWriter struct {
iv IV iv IV
wroteIV bool wroteIV bool
data *bytes.Buffer data *bytes.Buffer
key *MasterKeys key *Key
s cipher.Stream s cipher.Stream
w io.Writer w io.Writer
origWr io.Writer origWr io.Writer
@ -376,7 +376,7 @@ func (e *encryptWriter) Write(p []byte) (int, error) {
// EncryptTo buffers data written to the returned io.WriteCloser. When Close() // EncryptTo buffers data written to the returned io.WriteCloser. When Close()
// is called, the data is encrypted an written to the underlying writer. // is called, the data is encrypted an written to the underlying writer.
func EncryptTo(ks *MasterKeys, wr io.Writer) io.WriteCloser { func EncryptTo(ks *Key, wr io.Writer) io.WriteCloser {
ew := &encryptWriter{ ew := &encryptWriter{
iv: generateRandomIV(), iv: generateRandomIV(),
data: bytes.NewBuffer(getBuffer()[:0]), data: bytes.NewBuffer(getBuffer()[:0]),
@ -462,7 +462,7 @@ func (d *decryptReader) Close() error {
// drained, locally buffered and made available on the returned Reader // drained, locally buffered and made available on the returned Reader
// afterwards. If a MAC verification failure is observed, it is returned // afterwards. If a MAC verification failure is observed, it is returned
// immediately. // immediately.
func DecryptFrom(ks *MasterKeys, rd io.Reader) (io.ReadCloser, error) { func DecryptFrom(ks *Key, rd io.Reader) (io.ReadCloser, error) {
ciphertext := getBuffer() ciphertext := getBuffer()
ciphertext = ciphertext[0:cap(ciphertext)] ciphertext = ciphertext[0:cap(ciphertext)]

View File

@ -100,7 +100,7 @@ func should_panic(f func()) (did_panic bool) {
func TestCrypto(t *testing.T) { func TestCrypto(t *testing.T) {
for _, tv := range test_values { for _, tv := range test_values {
// test encryption // test encryption
k := &MasterKeys{ k := &Key{
Encrypt: tv.ekey, Encrypt: tv.ekey,
Sign: tv.skey, Sign: tv.skey,
} }

View File

@ -17,7 +17,7 @@ import (
var testLargeCrypto = flag.Bool("test.largecrypto", false, "also test crypto functions with large payloads") var testLargeCrypto = flag.Bool("test.largecrypto", false, "also test crypto functions with large payloads")
func TestEncryptDecrypt(t *testing.T) { func TestEncryptDecrypt(t *testing.T) {
k := crypto.GenerateRandomKeys() k := crypto.GenerateKey()
tests := []int{5, 23, 2<<18 + 23, 1 << 20} tests := []int{5, 23, 2<<18 + 23, 1 << 20}
if *testLargeCrypto { if *testLargeCrypto {
@ -43,7 +43,7 @@ func TestEncryptDecrypt(t *testing.T) {
} }
func TestSmallBuffer(t *testing.T) { func TestSmallBuffer(t *testing.T) {
k := crypto.GenerateRandomKeys() k := crypto.GenerateKey()
size := 600 size := 600
data := make([]byte, size) data := make([]byte, size)
@ -65,7 +65,7 @@ func TestLargeEncrypt(t *testing.T) {
t.SkipNow() t.SkipNow()
} }
k := crypto.GenerateRandomKeys() k := crypto.GenerateKey()
for _, size := range []int{chunker.MaxSize, chunker.MaxSize + 1, chunker.MaxSize + 1<<20} { for _, size := range []int{chunker.MaxSize, chunker.MaxSize + 1, chunker.MaxSize + 1<<20} {
data := make([]byte, size) data := make([]byte, size)
@ -75,7 +75,7 @@ func TestLargeEncrypt(t *testing.T) {
_, err = io.ReadFull(f, data) _, err = io.ReadFull(f, data)
OK(t, err) OK(t, err)
ciphertext := make([]byte, size+crypto.CiphertextExtension) ciphertext := make([]byte, size+crypto.Extension)
n, err := crypto.Encrypt(k, ciphertext, data) n, err := crypto.Encrypt(k, ciphertext, data)
OK(t, err) OK(t, err)
@ -90,7 +90,7 @@ func BenchmarkEncryptWriter(b *testing.B) {
size := 8 << 20 // 8MiB size := 8 << 20 // 8MiB
rd := RandomReader(23, size) rd := RandomReader(23, size)
k := crypto.GenerateRandomKeys() k := crypto.GenerateKey()
b.ResetTimer() b.ResetTimer()
b.SetBytes(int64(size)) b.SetBytes(int64(size))
@ -108,8 +108,8 @@ func BenchmarkEncrypt(b *testing.B) {
size := 8 << 20 // 8MiB size := 8 << 20 // 8MiB
data := make([]byte, size) data := make([]byte, size)
k := crypto.GenerateRandomKeys() k := crypto.GenerateKey()
buf := make([]byte, len(data)+crypto.CiphertextExtension) buf := make([]byte, len(data)+crypto.Extension)
b.ResetTimer() b.ResetTimer()
b.SetBytes(int64(size)) b.SetBytes(int64(size))
@ -123,9 +123,9 @@ func BenchmarkEncrypt(b *testing.B) {
func BenchmarkDecryptReader(b *testing.B) { func BenchmarkDecryptReader(b *testing.B) {
size := 8 << 20 // 8MiB size := 8 << 20 // 8MiB
buf := Random(23, size) buf := Random(23, size)
k := crypto.GenerateRandomKeys() k := crypto.GenerateKey()
ciphertext := make([]byte, len(buf)+crypto.CiphertextExtension) ciphertext := make([]byte, len(buf)+crypto.Extension)
_, err := crypto.Encrypt(k, ciphertext, buf) _, err := crypto.Encrypt(k, ciphertext, buf)
OK(b, err) OK(b, err)
@ -145,7 +145,7 @@ func BenchmarkDecryptReader(b *testing.B) {
} }
func BenchmarkEncryptDecryptReader(b *testing.B) { func BenchmarkEncryptDecryptReader(b *testing.B) {
k := crypto.GenerateRandomKeys() k := crypto.GenerateKey()
size := 8 << 20 // 8MiB size := 8 << 20 // 8MiB
rd := RandomReader(23, size) rd := RandomReader(23, size)
@ -176,7 +176,7 @@ func BenchmarkDecrypt(b *testing.B) {
size := 8 << 20 // 8MiB size := 8 << 20 // 8MiB
data := make([]byte, size) data := make([]byte, size)
k := crypto.GenerateRandomKeys() k := crypto.GenerateKey()
ciphertext := restic.GetChunkBuf("BenchmarkDecrypt") ciphertext := restic.GetChunkBuf("BenchmarkDecrypt")
defer restic.FreeChunkBuf("BenchmarkDecrypt", ciphertext) defer restic.FreeChunkBuf("BenchmarkDecrypt", ciphertext)
@ -196,7 +196,7 @@ func BenchmarkDecrypt(b *testing.B) {
} }
func TestEncryptStreamWriter(t *testing.T) { func TestEncryptStreamWriter(t *testing.T) {
k := crypto.GenerateRandomKeys() k := crypto.GenerateKey()
tests := []int{5, 23, 2<<18 + 23, 1 << 20} tests := []int{5, 23, 2<<18 + 23, 1 << 20}
if *testLargeCrypto { if *testLargeCrypto {
@ -215,7 +215,7 @@ func TestEncryptStreamWriter(t *testing.T) {
OK(t, err) OK(t, err)
OK(t, wr.Close()) OK(t, wr.Close())
l := len(data) + crypto.CiphertextExtension l := len(data) + crypto.Extension
Assert(t, len(ciphertext.Bytes()) == l, Assert(t, len(ciphertext.Bytes()) == l,
"wrong ciphertext length: expected %d, got %d", "wrong ciphertext length: expected %d, got %d",
l, len(ciphertext.Bytes())) l, len(ciphertext.Bytes()))
@ -230,7 +230,7 @@ func TestEncryptStreamWriter(t *testing.T) {
} }
func TestDecryptStreamReader(t *testing.T) { func TestDecryptStreamReader(t *testing.T) {
k := crypto.GenerateRandomKeys() k := crypto.GenerateKey()
tests := []int{5, 23, 2<<18 + 23, 1 << 20} tests := []int{5, 23, 2<<18 + 23, 1 << 20}
if *testLargeCrypto { if *testLargeCrypto {
@ -242,14 +242,14 @@ func TestDecryptStreamReader(t *testing.T) {
_, err := io.ReadFull(RandomReader(42, size), data) _, err := io.ReadFull(RandomReader(42, size), data)
OK(t, err) OK(t, err)
ciphertext := make([]byte, size+crypto.CiphertextExtension) ciphertext := make([]byte, size+crypto.Extension)
// encrypt with default function // encrypt with default function
n, err := crypto.Encrypt(k, ciphertext, data) n, err := crypto.Encrypt(k, ciphertext, data)
OK(t, err) OK(t, err)
Assert(t, n == len(data)+crypto.CiphertextExtension, Assert(t, n == len(data)+crypto.Extension,
"wrong number of bytes returned after encryption: expected %d, got %d", "wrong number of bytes returned after encryption: expected %d, got %d",
len(data)+crypto.CiphertextExtension, n) len(data)+crypto.Extension, n)
rd, err := crypto.DecryptFrom(k, bytes.NewReader(ciphertext)) rd, err := crypto.DecryptFrom(k, bytes.NewReader(ciphertext))
OK(t, err) OK(t, err)
@ -264,7 +264,7 @@ func TestDecryptStreamReader(t *testing.T) {
} }
func TestEncryptWriter(t *testing.T) { func TestEncryptWriter(t *testing.T) {
k := crypto.GenerateRandomKeys() k := crypto.GenerateKey()
tests := []int{5, 23, 2<<18 + 23, 1 << 20} tests := []int{5, 23, 2<<18 + 23, 1 << 20}
if *testLargeCrypto { if *testLargeCrypto {
@ -285,7 +285,7 @@ func TestEncryptWriter(t *testing.T) {
ciphertext := buf.Bytes() ciphertext := buf.Bytes()
l := len(data) + crypto.CiphertextExtension l := len(data) + crypto.Extension
Assert(t, len(ciphertext) == l, Assert(t, len(ciphertext) == l,
"wrong ciphertext length: expected %d, got %d", "wrong ciphertext length: expected %d, got %d",
l, len(ciphertext)) l, len(ciphertext))

12
key.go
View File

@ -44,8 +44,8 @@ type Key struct {
Salt []byte `json:"salt"` Salt []byte `json:"salt"`
Data []byte `json:"data"` Data []byte `json:"data"`
user *crypto.MasterKeys user *crypto.Key
master *crypto.MasterKeys master *crypto.Key
name string name string
} }
@ -81,7 +81,7 @@ func OpenKey(s Server, name string, password string) (*Key, error) {
} }
// restore json // restore json
k.master = &crypto.MasterKeys{} k.master = &crypto.Key{}
err = json.Unmarshal(buf, k.master) err = json.Unmarshal(buf, k.master)
if err != nil { if err != nil {
return nil, err return nil, err
@ -176,7 +176,7 @@ func AddKey(s Server, password string, template *Key) (*Key, error) {
if template == nil { if template == nil {
// generate new random master keys // generate new random master keys
newkey.master = crypto.GenerateRandomKeys() newkey.master = crypto.GenerateKey()
// generate random polynomial for cdc // generate random polynomial for cdc
p, err := chunker.RandomPolynomial() p, err := chunker.RandomPolynomial()
if err != nil { if err != nil {
@ -264,12 +264,12 @@ func (k *Key) DecryptFrom(rd io.Reader) (io.ReadCloser, error) {
// Master() returns the master keys for this repository. Only included for // Master() returns the master keys for this repository. Only included for
// debug purposes. // debug purposes.
func (k *Key) Master() *crypto.MasterKeys { func (k *Key) Master() *crypto.Key {
return k.master return k.master
} }
// User() returns the user keys for this key. Only included for debug purposes. // User() returns the user keys for this key. Only included for debug purposes.
func (k *Key) User() *crypto.MasterKeys { func (k *Key) User() *crypto.Key {
return k.user return k.user
} }

View File

@ -21,7 +21,7 @@ type poolStats struct {
max int max int
} }
const maxCiphertextSize = crypto.CiphertextExtension + chunker.MaxSize const maxCiphertextSize = crypto.Extension + chunker.MaxSize
func (s *poolStats) Get(k string) { func (s *poolStats) Get(k string) {
s.m.Lock() s.m.Lock()

View File

@ -159,11 +159,11 @@ func (s Server) Save(t backend.Type, data []byte, id backend.ID) (Blob, error) {
var ciphertext []byte var ciphertext []byte
// if the data is small enough, use a slice from the pool // if the data is small enough, use a slice from the pool
if len(data) <= maxCiphertextSize-crypto.CiphertextExtension { if len(data) <= maxCiphertextSize-crypto.Extension {
ciphertext = GetChunkBuf("ch.Save()") ciphertext = GetChunkBuf("ch.Save()")
defer FreeChunkBuf("ch.Save()", ciphertext) defer FreeChunkBuf("ch.Save()", ciphertext)
} else { } else {
l := len(data) + crypto.CiphertextExtension l := len(data) + crypto.Extension
debug.Log("Server.Save", "create large slice of %d bytes for ciphertext", l) debug.Log("Server.Save", "create large slice of %d bytes for ciphertext", l)