Merge pull request #1395 from restic/small-crypto-improvements
Small improvements
This commit is contained in:
commit
53a554c89d
4 changed files with 43 additions and 24 deletions
|
@ -67,21 +67,40 @@ var testValues = []struct {
|
||||||
plaintext []byte
|
plaintext []byte
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
ekey: EncryptionKey([...]byte{
|
ekey: decodeArray32("303e8687b1d7db18421bdc6bb8588ccadac4d59ee87b8ff70c44e635790cafef"),
|
||||||
0x30, 0x3e, 0x86, 0x87, 0xb1, 0xd7, 0xdb, 0x18, 0x42, 0x1b, 0xdc, 0x6b, 0xb8, 0x58, 0x8c, 0xca,
|
|
||||||
0xda, 0xc4, 0xd5, 0x9e, 0xe8, 0x7b, 0x8f, 0xf7, 0x0c, 0x44, 0xe6, 0x35, 0x79, 0x0c, 0xaf, 0xef,
|
|
||||||
}),
|
|
||||||
skey: MACKey{
|
skey: MACKey{
|
||||||
K: [...]byte{0xef, 0x4d, 0x88, 0x24, 0xcb, 0x80, 0xb2, 0xbc, 0xc5, 0xfb, 0xff, 0x8a, 0x9b, 0x12, 0xa4, 0x2c},
|
K: decodeArray16("ef4d8824cb80b2bcc5fbff8a9b12a42c"),
|
||||||
R: [...]byte{0xcc, 0x8d, 0x4b, 0x94, 0x8e, 0xe0, 0xeb, 0xfe, 0x1d, 0x41, 0x5d, 0xe9, 0x21, 0xd1, 0x03, 0x53},
|
R: decodeArray16("cc8d4b948ee0ebfe1d415de921d10353"),
|
||||||
},
|
},
|
||||||
ciphertext: decodeHex("69fb41c62d12def4593bd71757138606338f621aeaeb39da0fe4f99233f8037a54ea63338a813bcf3f75d8c3cc75dddf8750"),
|
ciphertext: decodeHex("69fb41c62d12def4593bd71757138606338f621aeaeb39da0fe4f99233f8037a54ea63338a813bcf3f75d8c3cc75dddf8750"),
|
||||||
plaintext: []byte("Dies ist ein Test!"),
|
plaintext: []byte("Dies ist ein Test!"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func decodeArray16(s string) (dst [16]byte) {
|
||||||
|
data := decodeHex(s)
|
||||||
|
if len(data) != 16 {
|
||||||
|
panic("data has wrong length")
|
||||||
|
}
|
||||||
|
copy(dst[:], data)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeArray32(s string) (dst [32]byte) {
|
||||||
|
data := decodeHex(s)
|
||||||
|
if len(data) != 32 {
|
||||||
|
panic("data has wrong length")
|
||||||
|
}
|
||||||
|
copy(dst[:], data)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// decodeHex decodes the string s and panics on error.
|
||||||
func decodeHex(s string) []byte {
|
func decodeHex(s string) []byte {
|
||||||
d, _ := hex.DecodeString(s)
|
d, err := hex.DecodeString(s)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
return d
|
return d
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,22 +12,22 @@ import (
|
||||||
|
|
||||||
const saltLength = 64
|
const saltLength = 64
|
||||||
|
|
||||||
// KDFParams are the default parameters used for the key derivation function KDF().
|
// Params are the default parameters used for the key derivation function KDF().
|
||||||
type KDFParams struct {
|
type Params struct {
|
||||||
N int
|
N int
|
||||||
R int
|
R int
|
||||||
P int
|
P int
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultKDFParams are the default parameters used for Calibrate and KDF().
|
// DefaultKDFParams are the default parameters used for Calibrate and KDF().
|
||||||
var DefaultKDFParams = KDFParams{
|
var DefaultKDFParams = Params{
|
||||||
N: sscrypt.DefaultParams.N,
|
N: sscrypt.DefaultParams.N,
|
||||||
R: sscrypt.DefaultParams.R,
|
R: sscrypt.DefaultParams.R,
|
||||||
P: sscrypt.DefaultParams.P,
|
P: sscrypt.DefaultParams.P,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calibrate determines new KDF parameters for the current hardware.
|
// Calibrate determines new KDF parameters for the current hardware.
|
||||||
func Calibrate(timeout time.Duration, memory int) (KDFParams, error) {
|
func Calibrate(timeout time.Duration, memory int) (Params, error) {
|
||||||
defaultParams := sscrypt.Params{
|
defaultParams := sscrypt.Params{
|
||||||
N: DefaultKDFParams.N,
|
N: DefaultKDFParams.N,
|
||||||
R: DefaultKDFParams.R,
|
R: DefaultKDFParams.R,
|
||||||
|
@ -41,7 +41,7 @@ func Calibrate(timeout time.Duration, memory int) (KDFParams, error) {
|
||||||
return DefaultKDFParams, errors.Wrap(err, "scrypt.Calibrate")
|
return DefaultKDFParams, errors.Wrap(err, "scrypt.Calibrate")
|
||||||
}
|
}
|
||||||
|
|
||||||
return KDFParams{
|
return Params{
|
||||||
N: params.N,
|
N: params.N,
|
||||||
R: params.R,
|
R: params.R,
|
||||||
P: params.P,
|
P: params.P,
|
||||||
|
@ -50,7 +50,7 @@ func Calibrate(timeout time.Duration, memory int) (KDFParams, error) {
|
||||||
|
|
||||||
// KDF derives encryption and message authentication keys from the password
|
// KDF derives encryption and message authentication keys from the password
|
||||||
// using the supplied parameters N, R and P and the Salt.
|
// using the supplied parameters N, R and P and the Salt.
|
||||||
func KDF(p KDFParams, salt []byte, password string) (*Key, error) {
|
func KDF(p Params, salt []byte, password string) (*Key, error) {
|
||||||
if len(salt) != saltLength {
|
if len(salt) != saltLength {
|
||||||
return nil, errors.Errorf("scrypt() called with invalid salt bytes (len %d)", len(salt))
|
return nil, errors.Errorf("scrypt() called with invalid salt bytes (len %d)", len(salt))
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,9 +44,9 @@ type Key struct {
|
||||||
name string
|
name string
|
||||||
}
|
}
|
||||||
|
|
||||||
// KDFParams tracks the parameters used for the KDF. If not set, it will be
|
// Params tracks the parameters used for the KDF. If not set, it will be
|
||||||
// calibrated on the first run of AddKey().
|
// calibrated on the first run of AddKey().
|
||||||
var KDFParams *crypto.KDFParams
|
var Params *crypto.Params
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// KDFTimeout specifies the maximum runtime for the KDF.
|
// KDFTimeout specifies the maximum runtime for the KDF.
|
||||||
|
@ -76,7 +76,7 @@ func OpenKey(ctx context.Context, s *Repository, name string, password string) (
|
||||||
}
|
}
|
||||||
|
|
||||||
// derive user key
|
// derive user key
|
||||||
params := crypto.KDFParams{
|
params := crypto.Params{
|
||||||
N: k.N,
|
N: k.N,
|
||||||
R: k.R,
|
R: k.R,
|
||||||
P: k.P,
|
P: k.P,
|
||||||
|
@ -166,13 +166,13 @@ func LoadKey(ctx context.Context, s *Repository, name string) (k *Key, err error
|
||||||
// AddKey adds a new key to an already existing repository.
|
// AddKey adds a new key to an already existing repository.
|
||||||
func AddKey(ctx context.Context, s *Repository, password string, template *crypto.Key) (*Key, error) {
|
func AddKey(ctx context.Context, s *Repository, password string, template *crypto.Key) (*Key, error) {
|
||||||
// make sure we have valid KDF parameters
|
// make sure we have valid KDF parameters
|
||||||
if KDFParams == nil {
|
if Params == nil {
|
||||||
p, err := crypto.Calibrate(KDFTimeout, KDFMemory)
|
p, err := crypto.Calibrate(KDFTimeout, KDFMemory)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "Calibrate")
|
return nil, errors.Wrap(err, "Calibrate")
|
||||||
}
|
}
|
||||||
|
|
||||||
KDFParams = &p
|
Params = &p
|
||||||
debug.Log("calibrated KDF parameters are %v", p)
|
debug.Log("calibrated KDF parameters are %v", p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,9 +180,9 @@ func AddKey(ctx context.Context, s *Repository, password string, template *crypt
|
||||||
newkey := &Key{
|
newkey := &Key{
|
||||||
Created: time.Now(),
|
Created: time.Now(),
|
||||||
KDF: "scrypt",
|
KDF: "scrypt",
|
||||||
N: KDFParams.N,
|
N: Params.N,
|
||||||
R: KDFParams.R,
|
R: Params.R,
|
||||||
P: KDFParams.P,
|
P: Params.P,
|
||||||
}
|
}
|
||||||
|
|
||||||
hn, err := os.Hostname()
|
hn, err := os.Hostname()
|
||||||
|
@ -202,7 +202,7 @@ func AddKey(ctx context.Context, s *Repository, password string, template *crypt
|
||||||
}
|
}
|
||||||
|
|
||||||
// call KDF to derive user key
|
// call KDF to derive user key
|
||||||
newkey.user, err = crypto.KDF(*KDFParams, newkey.Salt, password)
|
newkey.user, err = crypto.KDF(*Params, newkey.Salt, password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// testKDFParams are the parameters for the KDF to be used during testing.
|
// testKDFParams are the parameters for the KDF to be used during testing.
|
||||||
var testKDFParams = crypto.KDFParams{
|
var testKDFParams = crypto.Params{
|
||||||
N: 128,
|
N: 128,
|
||||||
R: 1,
|
R: 1,
|
||||||
P: 1,
|
P: 1,
|
||||||
|
@ -28,7 +28,7 @@ type logger interface {
|
||||||
// TestUseLowSecurityKDFParameters configures low-security KDF parameters for testing.
|
// TestUseLowSecurityKDFParameters configures low-security KDF parameters for testing.
|
||||||
func TestUseLowSecurityKDFParameters(t logger) {
|
func TestUseLowSecurityKDFParameters(t logger) {
|
||||||
t.Logf("using low-security KDF parameters for test")
|
t.Logf("using low-security KDF parameters for test")
|
||||||
KDFParams = &testKDFParams
|
Params = &testKDFParams
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestBackend returns a fully configured in-memory backend.
|
// TestBackend returns a fully configured in-memory backend.
|
||||||
|
|
Loading…
Add table
Reference in a new issue