diff --git a/src/restic/crypto/crypto.go b/src/restic/crypto/crypto.go index 559569679..17cfa3097 100644 --- a/src/restic/crypto/crypto.go +++ b/src/restic/crypto/crypto.go @@ -9,7 +9,6 @@ import ( "fmt" "golang.org/x/crypto/poly1305" - "golang.org/x/crypto/scrypt" ) const ( @@ -315,34 +314,6 @@ func Decrypt(ks *Key, plaintext []byte, ciphertextWithMac []byte) ([]byte, error return plaintext, nil } -// KDF derives encryption and message authentication keys from the password -// using the supplied parameters N, R and P and the Salt. -func KDF(N, R, P int, salt []byte, password string) (*Key, error) { - if len(salt) == 0 { - return nil, fmt.Errorf("scrypt() called with empty salt") - } - - derKeys := &Key{} - - keybytes := macKeySize + aesKeySize - scryptKeys, err := scrypt.Key([]byte(password), salt, N, R, P, keybytes) - if err != nil { - return nil, fmt.Errorf("error deriving keys from password: %v", err) - } - - if len(scryptKeys) != keybytes { - return nil, fmt.Errorf("invalid numbers of bytes expanded from scrypt(): %d", len(scryptKeys)) - } - - // first 32 byte of scrypt output is the encryption key - copy(derKeys.Encrypt[:], scryptKeys[:aesKeySize]) - - // next 32 byte of scrypt output is the mac key, in the form k||r - macKeyFromSlice(&derKeys.MAC, scryptKeys[aesKeySize:]) - - return derKeys, nil -} - // Valid tests if the key is valid. func (k *Key) Valid() bool { return k.Encrypt.Valid() && k.MAC.Valid() diff --git a/src/restic/crypto/kdf.go b/src/restic/crypto/kdf.go new file mode 100644 index 000000000..3551fff60 --- /dev/null +++ b/src/restic/crypto/kdf.go @@ -0,0 +1,35 @@ +package crypto + +import ( + "fmt" + + "golang.org/x/crypto/scrypt" +) + +// KDF derives encryption and message authentication keys from the password +// using the supplied parameters N, R and P and the Salt. +func KDF(N, R, P int, salt []byte, password string) (*Key, error) { + if len(salt) == 0 { + return nil, fmt.Errorf("scrypt() called with empty salt") + } + + derKeys := &Key{} + + keybytes := macKeySize + aesKeySize + scryptKeys, err := scrypt.Key([]byte(password), salt, N, R, P, keybytes) + if err != nil { + return nil, fmt.Errorf("error deriving keys from password: %v", err) + } + + if len(scryptKeys) != keybytes { + return nil, fmt.Errorf("invalid numbers of bytes expanded from scrypt(): %d", len(scryptKeys)) + } + + // first 32 byte of scrypt output is the encryption key + copy(derKeys.Encrypt[:], scryptKeys[:aesKeySize]) + + // next 32 byte of scrypt output is the mac key, in the form k||r + macKeyFromSlice(&derKeys.MAC, scryptKeys[aesKeySize:]) + + return derKeys, nil +}