From 0efd220d1e10ac8e3d0048ff4d068cc8174e7185 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Sun, 18 Feb 2018 12:37:37 +0100 Subject: [PATCH] configfile: overwrite and let keys run out of scope As soon as we don't need them anymore, overwrite keys with zeros and make sure they run out of scope so we don't create a risk of inadvertedly using all-zero keys for encryption. https://github.com/rfjakob/gocryptfs/issues/211 --- internal/configfile/config_file.go | 36 +++++++++++++++++------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/internal/configfile/config_file.go b/internal/configfile/config_file.go index 67d67f0..01e3b80 100644 --- a/internal/configfile/config_file.go +++ b/internal/configfile/config_file.go @@ -87,20 +87,23 @@ func CreateConfFile(filename string, password string, plaintextNames bool, logN if aessiv { cf.FeatureFlags = append(cf.FeatureFlags, knownFlags[FlagAESSIV]) } - - // Generate new random master key - var key []byte - if devrandom { - key = randBytesDevRandom(cryptocore.KeyLen) - } else { - key = cryptocore.RandBytes(cryptocore.KeyLen) + { + // Generate new random master key + var key []byte + if devrandom { + key = randBytesDevRandom(cryptocore.KeyLen) + } else { + key = cryptocore.RandBytes(cryptocore.KeyLen) + } + // Encrypt it using the password + // This sets ScryptObject and EncryptedKey + // Note: this looks at the FeatureFlags, so call it AFTER setting them. + cf.EncryptKey(key, password, logN) + for i := range key { + key[i] = 0 + } + // key runs out of scope here } - - // Encrypt it using the password - // This sets ScryptObject and EncryptedKey - // Note: this looks at the FeatureFlags, so call it AFTER setting them. - cf.EncryptKey(key, password, logN) - // Write file to disk return cf.WriteFile() } @@ -197,14 +200,17 @@ func LoadConfFile(filename string, password string) ([]byte, *ConfFile, error) { // Uses scrypt with cost parameter logN and stores the scrypt parameters in // cf.ScryptObject. func (cf *ConfFile) EncryptKey(key []byte, password string, logN int) { - // Generate derived key from password + // Generate scrypt-derived key from password cf.ScryptObject = NewScryptKDF(logN) scryptHash := cf.ScryptObject.DeriveKey(password) - // Lock master key using password-based key useHKDF := cf.IsFeatureFlagSet(FlagHKDF) ce := getKeyEncrypter(scryptHash, useHKDF) cf.EncryptedKey = ce.EncryptBlock(key, 0, nil) + // Purge scrypt-derived key + for i := range scryptHash { + scryptHash[i] = 0 + } } // WriteFile - write out config in JSON format to file "filename.tmp"