diff --git a/internal/crypto/crypto_int_test.go b/internal/crypto/crypto_int_test.go index db4b791b2..3ace3f393 100644 --- a/internal/crypto/crypto_int_test.go +++ b/internal/crypto/crypto_int_test.go @@ -67,21 +67,40 @@ var testValues = []struct { plaintext []byte }{ { - ekey: EncryptionKey([...]byte{ - 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, - }), + ekey: decodeArray32("303e8687b1d7db18421bdc6bb8588ccadac4d59ee87b8ff70c44e635790cafef"), skey: MACKey{ - K: [...]byte{0xef, 0x4d, 0x88, 0x24, 0xcb, 0x80, 0xb2, 0xbc, 0xc5, 0xfb, 0xff, 0x8a, 0x9b, 0x12, 0xa4, 0x2c}, - R: [...]byte{0xcc, 0x8d, 0x4b, 0x94, 0x8e, 0xe0, 0xeb, 0xfe, 0x1d, 0x41, 0x5d, 0xe9, 0x21, 0xd1, 0x03, 0x53}, + K: decodeArray16("ef4d8824cb80b2bcc5fbff8a9b12a42c"), + R: decodeArray16("cc8d4b948ee0ebfe1d415de921d10353"), }, ciphertext: decodeHex("69fb41c62d12def4593bd71757138606338f621aeaeb39da0fe4f99233f8037a54ea63338a813bcf3f75d8c3cc75dddf8750"), 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 { - d, _ := hex.DecodeString(s) + d, err := hex.DecodeString(s) + if err != nil { + panic(err) + } return d } diff --git a/internal/crypto/kdf.go b/internal/crypto/kdf.go index a0d98e748..a63f3064a 100644 --- a/internal/crypto/kdf.go +++ b/internal/crypto/kdf.go @@ -12,22 +12,22 @@ import ( const saltLength = 64 -// KDFParams are the default parameters used for the key derivation function KDF(). -type KDFParams struct { +// Params are the default parameters used for the key derivation function KDF(). +type Params struct { N int R int P int } // DefaultKDFParams are the default parameters used for Calibrate and KDF(). -var DefaultKDFParams = KDFParams{ +var DefaultKDFParams = Params{ N: sscrypt.DefaultParams.N, R: sscrypt.DefaultParams.R, P: sscrypt.DefaultParams.P, } // 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{ N: DefaultKDFParams.N, R: DefaultKDFParams.R, @@ -41,7 +41,7 @@ func Calibrate(timeout time.Duration, memory int) (KDFParams, error) { return DefaultKDFParams, errors.Wrap(err, "scrypt.Calibrate") } - return KDFParams{ + return Params{ N: params.N, R: params.R, 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 // 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 { return nil, errors.Errorf("scrypt() called with invalid salt bytes (len %d)", len(salt)) } diff --git a/internal/repository/key.go b/internal/repository/key.go index 29198eced..e378991cb 100644 --- a/internal/repository/key.go +++ b/internal/repository/key.go @@ -44,9 +44,9 @@ type Key struct { 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(). -var KDFParams *crypto.KDFParams +var Params *crypto.Params var ( // 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 - params := crypto.KDFParams{ + params := crypto.Params{ N: k.N, R: k.R, 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. func AddKey(ctx context.Context, s *Repository, password string, template *crypto.Key) (*Key, error) { // make sure we have valid KDF parameters - if KDFParams == nil { + if Params == nil { p, err := crypto.Calibrate(KDFTimeout, KDFMemory) if err != nil { return nil, errors.Wrap(err, "Calibrate") } - KDFParams = &p + Params = &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{ Created: time.Now(), KDF: "scrypt", - N: KDFParams.N, - R: KDFParams.R, - P: KDFParams.P, + N: Params.N, + R: Params.R, + P: Params.P, } 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 - newkey.user, err = crypto.KDF(*KDFParams, newkey.Salt, password) + newkey.user, err = crypto.KDF(*Params, newkey.Salt, password) if err != nil { return nil, err } diff --git a/internal/repository/testing.go b/internal/repository/testing.go index 903971138..7b76762dd 100644 --- a/internal/repository/testing.go +++ b/internal/repository/testing.go @@ -15,7 +15,7 @@ import ( ) // testKDFParams are the parameters for the KDF to be used during testing. -var testKDFParams = crypto.KDFParams{ +var testKDFParams = crypto.Params{ N: 128, R: 1, P: 1, @@ -28,7 +28,7 @@ type logger interface { // TestUseLowSecurityKDFParameters configures low-security KDF parameters for testing. func TestUseLowSecurityKDFParameters(t logger) { t.Logf("using low-security KDF parameters for test") - KDFParams = &testKDFParams + Params = &testKDFParams } // TestBackend returns a fully configured in-memory backend.