Description
Final API is here: #21865 (comment)
Forward secrecy is usually only a thing if it's possible to ensure keys aren't actually in memory anymore. Other security properties, too, often require the secure erasure of keys from memory.
The typical way of doing this is through a function such as explicit_bzero
, memzero_explicit
, or the various other functions that C library writers provide that ensure an optimization-free routine for zeroing buffers.
For the most part, the same is possible in Go application code. However, it is not easily possible to do so with crypto API interfaces that internally manage a key buffer, such as the AEAD interface.
In the Go implementation of WireGuard, @rot256 has been forced to resort to unholy hacks such as:
type safeAEAD struct {
mutex sync.RWMutex
aead cipher.AEAD
}
func (con *safeAEAD) clear() {
con.mutex.Lock()
if con.aead != nil {
val := reflect.ValueOf(con.aead)
elm := val.Elem()
typ := elm.Type()
elm.Set(reflect.Zero(typ))
con.aead = nil
}
con.mutex.Unlock()
}
func (con *safeAEAD) setKey(key *[chacha20poly1305.KeySize]byte) {
con.aead, _ = chacha20poly1305.New(key[:])
}
Having to resort to this kind of reflection is a bit unsettling and something we'd much rather not do.
So, this issue is to request and track the addition of a consistent "Clear()" interface for parts of the Go crypto API that store keys in internal buffers.
Furthermore, even if real clearing is deemed to be an abject failure due to Go's GC, and one must instead mmap/mlock or use a library such as memguard, the AEAD interface still is inadequate, because it appears that SetKey winds up allocating its own buffer internally. So again, big problem.
cc: @agl
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
Status