Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Safely zeroing buffers after working with crypto/*

Is there a way to zero buffers containing e. g. private keys after using them and make sure that compilers don't delete the zeroing code as unused? Something tells me that a simple:

copy(privateKey, make([]byte, keySize))

Is not guaranteed to stay there.

like image 822
Ainar-G Avatar asked Nov 14 '19 06:11

Ainar-G


2 Answers

How about checking (some of) the content of the buffer after zeroing it and passing it to another function? For example:

copy(privateKey, make([]byte, keySize))

if privateKey[0] != 0 {
    // If you pass the buffer to another function,
    // this check and above copy() can't be optimized away:
    fmt.Println("Zeroing failed", privateKey[0])
}

To be absolutely safe, you could XOR the passed buffer content with random bytes, but if / since the zeroing is not optimized away, the if body is never reached.

You might think a very intelligent compiler might deduce the above copy() zeros privateKey[0] and thus determine the condition is always false and still optimize it away (although this is very unlikely). The solution to this is not to use make([]byte, keySize) but e.g. a slice coming from a global variable or a function argument (whose value can only be determined at runtime) so the compiler can't be smart enough to deduce the condition is going to be always false at compile time.

like image 32
icza Avatar answered Nov 04 '22 07:11

icza


Sounds like you want to prevent sensitive data remaining in memory. But have you considered the data might have been replicated, or swapped to disk?

For these reasons I use the https://github.com/awnumar/memguard package. It provides features to destroy the data when no longer required, while keeping it safe in the mean time.

You can read about its background here; https://spacetime.dev/memory-security-go

like image 101
Ferdy Avatar answered Nov 04 '22 08:11

Ferdy