Skip to content

Commit 6c69471

Browse files
committed
cryptocore: zero derived keys
Zero the HKDF-derived keys when we don't need them anymore, and let the variable run of of scope. #211
1 parent 344d7e0 commit 6c69471

File tree

1 file changed

+33
-13
lines changed

1 file changed

+33
-13
lines changed

internal/cryptocore/cryptocore.go

+33-13
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,18 @@ func New(key []byte, aeadType AEADTypeEnum, IVBitLen int, useHKDF bool, forceDec
6565

6666
// Initialize EME for filename encryption.
6767
var emeCipher *eme.EMECipher
68+
var err error
6869
{
69-
emeKey := key
70+
var emeBlockCipher cipher.Block
7071
if useHKDF {
71-
emeKey = hkdfDerive(key, hkdfInfoEMENames, KeyLen)
72+
emeKey := hkdfDerive(key, hkdfInfoEMENames, KeyLen)
73+
emeBlockCipher, err = aes.NewCipher(emeKey)
74+
for i := range emeKey {
75+
emeKey[i] = 0
76+
}
77+
} else {
78+
emeBlockCipher, err = aes.NewCipher(key)
7279
}
73-
emeBlockCipher, err := aes.NewCipher(emeKey)
7480
if err != nil {
7581
log.Panic(err)
7682
}
@@ -80,9 +86,11 @@ func New(key []byte, aeadType AEADTypeEnum, IVBitLen int, useHKDF bool, forceDec
8086
// Initialize an AEAD cipher for file content encryption.
8187
var aeadCipher cipher.AEAD
8288
if aeadType == BackendOpenSSL || aeadType == BackendGoGCM {
83-
gcmKey := key
89+
var gcmKey []byte
8490
if useHKDF {
8591
gcmKey = hkdfDerive(key, hkdfInfoGCMContent, KeyLen)
92+
} else {
93+
gcmKey = append([]byte{}, key...)
8694
}
8795
switch aeadType {
8896
case BackendOpenSSL:
@@ -100,22 +108,29 @@ func New(key []byte, aeadType AEADTypeEnum, IVBitLen int, useHKDF bool, forceDec
100108
log.Panic(err)
101109
}
102110
}
111+
for i := range gcmKey {
112+
gcmKey[i] = 0
113+
}
103114
} else if aeadType == BackendAESSIV {
104115
if IVLen != 16 {
105116
// SIV supports any nonce size, but we only use 16.
106117
log.Panic("AES-SIV must use 16-byte nonces")
107118
}
119+
// AES-SIV uses 1/2 of the key for authentication, 1/2 for
120+
// encryption, so we need a 64-bytes key for AES-256. Derive it from
121+
// the 32-byte master key using HKDF, or, for older filesystems, with
122+
// SHA256.
108123
var key64 []byte
109124
if useHKDF {
110125
key64 = hkdfDerive(key, hkdfInfoSIVContent, siv_aead.KeyLen)
111126
} else {
112-
// AES-SIV uses 1/2 of the key for authentication, 1/2 for
113-
// encryption, so we need a 64-bytes key for AES-256. Derive it from
114-
// the master key by hashing it with SHA-512.
115127
s := sha512.Sum512(key)
116128
key64 = s[:]
117129
}
118130
aeadCipher = siv_aead.New(key64)
131+
for i := range key64 {
132+
key64[i] = 0
133+
}
119134
} else {
120135
log.Panic("unknown backend cipher")
121136
}
@@ -129,20 +144,25 @@ func New(key []byte, aeadType AEADTypeEnum, IVBitLen int, useHKDF bool, forceDec
129144
}
130145
}
131146

147+
type wiper interface {
148+
Wipe()
149+
}
150+
132151
// Wipe tries to wipe secret keys from memory by overwriting them with zeros
133152
// and/or setting references to nil.
134153
//
135154
// This is not bulletproof due to possible GC copies, but
136155
// still raises to bar for extracting the key.
137156
func (c *CryptoCore) Wipe() {
138-
if c.AEADBackend == BackendOpenSSL {
139-
tlog.Debug.Print("CryptoCore.Wipe: Wiping stupidgcm key")
157+
be := c.AEADBackend
158+
if be == BackendOpenSSL || be == BackendAESSIV {
159+
tlog.Debug.Printf("CryptoCore.Wipe: Wiping AEADBackend %d key", be)
140160
// We don't use "x, ok :=" because we *want* to crash loudly if the
141-
// type assertion fails (it should never fail).
142-
sgcm := c.AEADCipher.(*stupidgcm.StupidGCM)
143-
sgcm.Wipe()
161+
// type assertion fails.
162+
w := c.AEADCipher.(wiper)
163+
w.Wipe()
144164
} else {
145-
tlog.Debug.Print("CryptoCore.Wipe: niling stdlib refs")
165+
tlog.Debug.Print("CryptoCore.Wipe: Only nil'ing stdlib refs")
146166
}
147167
// We have no access to the keys (or key-equivalents) stored inside the
148168
// Go stdlib. Best we can is to nil the references and force a GC.

0 commit comments

Comments
 (0)