aboutsummaryrefslogtreecommitdiff
path: root/internal/siv_aead
diff options
context:
space:
mode:
authorJakob Unterwurzacher2018-02-18 16:01:46 +0100
committerJakob Unterwurzacher2018-02-18 16:01:46 +0100
commit344d7e0a6f06cf7829dc5af1732dfbd116597dc1 (patch)
tree24fc069cd886fa59860bdf954efabe063ce272ca /internal/siv_aead
parentadf7d75d31889e2dbd52c15efdecf3a8304c0bc1 (diff)
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().
Diffstat (limited to 'internal/siv_aead')
-rw-r--r--internal/siv_aead/siv_aead.go22
1 files changed, 21 insertions, 1 deletions
diff --git a/internal/siv_aead/siv_aead.go b/internal/siv_aead/siv_aead.go
index 3cb42ab..eabb5e2 100644
--- a/internal/siv_aead/siv_aead.go
+++ b/internal/siv_aead/siv_aead.go
@@ -32,7 +32,9 @@ func New(key []byte) cipher.AEAD {
}
// Same as "New" without the 64-byte restriction.
-func new2(key []byte) cipher.AEAD {
+func new2(keyIn []byte) cipher.AEAD {
+ // Create a private copy so the caller can zero the one he owns
+ key := append([]byte{}, keyIn...)
return &sivAead{
key: key,
}
@@ -53,6 +55,9 @@ func (s *sivAead) Seal(dst, nonce, plaintext, authData []byte) []byte {
// SIV supports any nonce size, but in gocryptfs we exclusively use 16.
log.Panic("nonce must be 16 bytes long")
}
+ if len(s.key) == 0 {
+ log.Panic("Key has been wiped?")
+ }
// https://github.com/jacobsa/crypto/blob/master/siv/encrypt.go#L48:
// As per RFC 5297 section 3, you may use this function for nonce-based
// 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)
// SIV supports any nonce size, but in gocryptfs we exclusively use 16.
log.Panic("nonce must be 16 bytes long")
}
+ if len(s.key) == 0 {
+ log.Panic("Key has been wiped?")
+ }
associated := [][]byte{authData, nonce}
dec, err := siv.Decrypt(s.key, ciphertext, associated)
return append(dst, dec...), err
}
+
+// Wipe tries to wipe the AES key from memory by overwriting it with zeros
+// and setting the reference to nil.
+//
+// This is not bulletproof due to possible GC copies, but
+// still raises to bar for extracting the key.
+func (s *sivAead) Wipe() {
+ for i := range s.key {
+ s.key[i] = 0
+ }
+ s.key = nil
+}