2
2
mirror of https://github.com/octoleo/restic.git synced 2024-11-29 16:23:59 +00:00

Collect all master crypto keys in a single structure

This commit is contained in:
Alexander Neumann 2015-03-22 19:18:34 +01:00
parent 78727c17a3
commit 664a12c950
3 changed files with 23 additions and 35 deletions

View File

@ -85,13 +85,10 @@ func maskKey(k *MACKey) {
}
// construct mac key from slice (k||r), with masking
func macKeyFromSlice(data []byte) *MACKey {
mk := &MACKey{}
func macKeyFromSlice(mk *MACKey, data []byte) {
copy(mk.K[:], data[:16])
copy(mk.R[:], data[16:32])
maskKey(mk)
return mk
}
// key: k||r
@ -119,31 +116,27 @@ func poly1305_verify(msg []byte, nonce []byte, key *MACKey, mac []byte) bool {
return poly1305.Verify(&m, msg, &k)
}
func generateRandomAESKey() (k *AESKey) {
k = &AESKey{}
n, err := rand.Read(k[:])
// returns new encryption and mac keys. k.MACKey.R is already masked.
func generateRandomKeys() (k *keys) {
k = &keys{}
n, err := rand.Read(k.Encrypt[:])
if n != AESKeySize || err != nil {
panic("unable to read enough random bytes for encryption key")
}
return
}
// returns a new mac key. k.R is already masked
func generateRandomMACKey() (k *MACKey) {
k = &MACKey{}
n, err := rand.Read(k.K[:])
n, err = rand.Read(k.Sign.K[:])
if n != MACKeySizeK || err != nil {
panic("unable to read enough random bytes for mac encryption key")
}
n, err = rand.Read(k.R[:])
n, err = rand.Read(k.Sign.R[:])
if n != MACKeySizeR || err != nil {
panic("unable to read enough random bytes for mac signing key")
}
// mask r
maskKey(k)
maskKey(&k.Sign)
return
return k
}
func generateRandomIV() (iv IV) {
@ -174,7 +167,7 @@ func Encrypt(ks *keys, ciphertext, plaintext []byte) (int, error) {
e.XORKeyStream(ciphertext[ivSize:cap(ciphertext)], plaintext)
ciphertext = ciphertext[:ivSize+len(plaintext)]
mac := poly1305_sign(ciphertext[ivSize:], ciphertext[:ivSize], ks.Sign)
mac := poly1305_sign(ciphertext[ivSize:], ciphertext[:ivSize], &ks.Sign)
ciphertext = append(ciphertext, mac...)
return len(ciphertext), nil
@ -198,7 +191,7 @@ func Decrypt(ks *keys, plaintext, ciphertext []byte) ([]byte, error) {
ciphertext, mac := ciphertext[:l], ciphertext[l:]
// verify mac
if !poly1305_verify(ciphertext[ivSize:], ciphertext[:ivSize], ks.Sign, mac) {
if !poly1305_verify(ciphertext[ivSize:], ciphertext[:ivSize], &ks.Sign, mac) {
return nil, ErrUnauthenticated
}
@ -225,6 +218,8 @@ func kdf(k *Key, password string) (*keys, error) {
return nil, fmt.Errorf("scrypt() called with empty salt")
}
derKeys := &keys{}
keybytes := MACKeySize + AESKeySize
scryptKeys, err := scrypt.Key([]byte(password), k.Salt, k.N, k.R, k.P, keybytes)
if err != nil {
@ -236,12 +231,12 @@ func kdf(k *Key, password string) (*keys, error) {
}
// first 32 byte of scrypt output is the encryption key
ek := &AESKey{}
copy(ek[:], scryptKeys[:AESKeySize])
copy(derKeys.Encrypt[:], scryptKeys[:AESKeySize])
// next 32 byte of scrypt output is the mac key, in the form k||r
mk := macKeyFromSlice(scryptKeys[AESKeySize:])
return &keys{Encrypt: ek, Sign: mk}, nil
macKeyFromSlice(&derKeys.Sign, scryptKeys[AESKeySize:])
return derKeys, nil
}
type encryptWriter struct {
@ -257,7 +252,7 @@ type encryptWriter struct {
func (e *encryptWriter) Close() error {
// write mac
mac := poly1305_sign(e.data.Bytes()[ivSize:], e.data.Bytes()[:ivSize], e.key.Sign)
mac := poly1305_sign(e.data.Bytes()[ivSize:], e.data.Bytes()[:ivSize], &e.key.Sign)
_, err := e.origWr.Write(mac)
if err != nil {
return err

View File

@ -103,8 +103,8 @@ func TestCrypto(t *testing.T) {
for _, tv := range test_values {
// test encryption
r.master = &keys{
Encrypt: &tv.ekey,
Sign: &tv.skey,
Encrypt: tv.ekey,
Sign: tv.skey,
}
msg := make([]byte, maxCiphertextSize)

13
key.go
View File

@ -64,8 +64,8 @@ type Key struct {
// encrypted and signed as a JSON data structure in the Data field of the Key
// structure.
type keys struct {
Sign *MACKey
Encrypt *AESKey
Sign MACKey
Encrypt AESKey
}
// CreateKey initializes a master key in the given backend and encrypts it with
@ -186,7 +186,7 @@ func AddKey(s Server, password string, template *Key) (*Key, error) {
if template == nil {
// generate new random master keys
newkey.master = newkey.newKeys()
newkey.master = generateRandomKeys()
} else {
// copy master keys from old key
newkey.master = template.master
@ -236,13 +236,6 @@ func AddKey(s Server, password string, template *Key) (*Key, error) {
return newkey, nil
}
func (k *Key) newKeys() *keys {
return &keys{
Encrypt: generateRandomAESKey(),
Sign: generateRandomMACKey(),
}
}
func (k *Key) newIV(buf []byte) error {
_, err := io.ReadFull(rand.Reader, buf[:ivSize])
buf = buf[:ivSize]