Skip to content

Commit 344d7e0

Browse files
committed
siv_aead: create private key copy and implement wiping
Having a private copy relieves the caller from worrying about whether he can zero his copy. The copy can be cleared by calling Wipe().
1 parent adf7d75 commit 344d7e0

File tree

1 file changed

+21
-1
lines changed

1 file changed

+21
-1
lines changed

internal/siv_aead/siv_aead.go

+21-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ func New(key []byte) cipher.AEAD {
3232
}
3333

3434
// Same as "New" without the 64-byte restriction.
35-
func new2(key []byte) cipher.AEAD {
35+
func new2(keyIn []byte) cipher.AEAD {
36+
// Create a private copy so the caller can zero the one he owns
37+
key := append([]byte{}, keyIn...)
3638
return &sivAead{
3739
key: key,
3840
}
@@ -53,6 +55,9 @@ func (s *sivAead) Seal(dst, nonce, plaintext, authData []byte) []byte {
5355
// SIV supports any nonce size, but in gocryptfs we exclusively use 16.
5456
log.Panic("nonce must be 16 bytes long")
5557
}
58+
if len(s.key) == 0 {
59+
log.Panic("Key has been wiped?")
60+
}
5661
// https://github.com/jacobsa/crypto/blob/master/siv/encrypt.go#L48:
5762
// As per RFC 5297 section 3, you may use this function for nonce-based
5863
// authenticated encryption by passing a nonce as the last associated
@@ -71,7 +76,22 @@ func (s *sivAead) Open(dst, nonce, ciphertext, authData []byte) ([]byte, error)
7176
// SIV supports any nonce size, but in gocryptfs we exclusively use 16.
7277
log.Panic("nonce must be 16 bytes long")
7378
}
79+
if len(s.key) == 0 {
80+
log.Panic("Key has been wiped?")
81+
}
7482
associated := [][]byte{authData, nonce}
7583
dec, err := siv.Decrypt(s.key, ciphertext, associated)
7684
return append(dst, dec...), err
7785
}
86+
87+
// Wipe tries to wipe the AES key from memory by overwriting it with zeros
88+
// and setting the reference to nil.
89+
//
90+
// This is not bulletproof due to possible GC copies, but
91+
// still raises to bar for extracting the key.
92+
func (s *sivAead) Wipe() {
93+
for i := range s.key {
94+
s.key[i] = 0
95+
}
96+
s.key = nil
97+
}

0 commit comments

Comments
 (0)