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 // construct mac key from slice (k||r), with masking
func macKeyFromSlice(data []byte) *MACKey { func macKeyFromSlice(mk *MACKey, data []byte) {
mk := &MACKey{}
copy(mk.K[:], data[:16]) copy(mk.K[:], data[:16])
copy(mk.R[:], data[16:32]) copy(mk.R[:], data[16:32])
maskKey(mk) maskKey(mk)
return mk
} }
// key: k||r // 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) return poly1305.Verify(&m, msg, &k)
} }
func generateRandomAESKey() (k *AESKey) { // returns new encryption and mac keys. k.MACKey.R is already masked.
k = &AESKey{} func generateRandomKeys() (k *keys) {
n, err := rand.Read(k[:]) k = &keys{}
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")
} }
return
}
// returns a new mac key. k.R is already masked n, err = rand.Read(k.Sign.K[:])
func generateRandomMACKey() (k *MACKey) {
k = &MACKey{}
n, err := rand.Read(k.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.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
maskKey(k) maskKey(&k.Sign)
return return k
} }
func generateRandomIV() (iv IV) { func generateRandomIV() (iv IV) {
@ -174,7 +167,7 @@ func Encrypt(ks *keys, ciphertext, plaintext []byte) (int, error) {
e.XORKeyStream(ciphertext[ivSize:cap(ciphertext)], plaintext) e.XORKeyStream(ciphertext[ivSize:cap(ciphertext)], plaintext)
ciphertext = ciphertext[:ivSize+len(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...) ciphertext = append(ciphertext, mac...)
return len(ciphertext), nil return len(ciphertext), nil
@ -198,7 +191,7 @@ func Decrypt(ks *keys, plaintext, ciphertext []byte) ([]byte, error) {
ciphertext, mac := ciphertext[:l], ciphertext[l:] ciphertext, mac := ciphertext[:l], ciphertext[l:]
// verify mac // 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 return nil, ErrUnauthenticated
} }
@ -225,6 +218,8 @@ func kdf(k *Key, password string) (*keys, error) {
return nil, fmt.Errorf("scrypt() called with empty salt") return nil, fmt.Errorf("scrypt() called with empty salt")
} }
derKeys := &keys{}
keybytes := MACKeySize + AESKeySize keybytes := MACKeySize + AESKeySize
scryptKeys, err := scrypt.Key([]byte(password), k.Salt, k.N, k.R, k.P, keybytes) scryptKeys, err := scrypt.Key([]byte(password), k.Salt, k.N, k.R, k.P, keybytes)
if err != nil { 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 // first 32 byte of scrypt output is the encryption key
ek := &AESKey{} copy(derKeys.Encrypt[:], scryptKeys[:AESKeySize])
copy(ek[:], 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
mk := macKeyFromSlice(scryptKeys[AESKeySize:]) macKeyFromSlice(&derKeys.Sign, scryptKeys[AESKeySize:])
return &keys{Encrypt: ek, Sign: mk}, nil
return derKeys, nil
} }
type encryptWriter struct { type encryptWriter struct {
@ -257,7 +252,7 @@ type encryptWriter struct {
func (e *encryptWriter) Close() error { func (e *encryptWriter) Close() error {
// write mac // 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) _, err := e.origWr.Write(mac)
if err != nil { if err != nil {
return err return err

View file

@ -103,8 +103,8 @@ func TestCrypto(t *testing.T) {
for _, tv := range test_values { for _, tv := range test_values {
// test encryption // test encryption
r.master = &keys{ r.master = &keys{
Encrypt: &tv.ekey, Encrypt: tv.ekey,
Sign: &tv.skey, Sign: tv.skey,
} }
msg := make([]byte, maxCiphertextSize) 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 // encrypted and signed as a JSON data structure in the Data field of the Key
// structure. // structure.
type keys struct { type keys struct {
Sign *MACKey Sign MACKey
Encrypt *AESKey Encrypt AESKey
} }
// CreateKey initializes a master key in the given backend and encrypts it with // 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 { if template == nil {
// generate new random master keys // generate new random master keys
newkey.master = newkey.newKeys() newkey.master = generateRandomKeys()
} else { } else {
// copy master keys from old key // copy master keys from old key
newkey.master = template.master newkey.master = template.master
@ -236,13 +236,6 @@ func AddKey(s Server, password string, template *Key) (*Key, error) {
return newkey, nil return newkey, nil
} }
func (k *Key) newKeys() *keys {
return &keys{
Encrypt: generateRandomAESKey(),
Sign: generateRandomMACKey(),
}
}
func (k *Key) newIV(buf []byte) error { func (k *Key) newIV(buf []byte) error {
_, err := io.ReadFull(rand.Reader, buf[:ivSize]) _, err := io.ReadFull(rand.Reader, buf[:ivSize])
buf = buf[:ivSize] buf = buf[:ivSize]