Zeroization of sensitive data in Erlang
Mon Oct 28 13:23:42 CET 2019
Thanks very much for your thoughts and insights.
Regarding your following comment about refc binaries:
> What you should worry about are things like shared, reference-counted binaries. They may be shared between sensitive and non-sensitive processes, so do they have to be zeroed or not? What about the memory allocated by NIF-s in sensitive processes? Like the openssl data structures where crypto will copy the keys? I have a feeling that blindly zeroing every freed up memory is inefficient, but doable, while extending the sensitive concept to cover every aspect of the BEAM VM may not be feasible at all.
I read up on this a little bit here:
and it seems that even when the binary is not shared it can reside on
the global binary heap - either because it is larger than 64 bytes, or
because it was referenced from another term, even if it's in the same
process. The latter seems to be easily avoidable if you carefully
write your sensitive data handling code, and the same goes for shared
binaries - if you're really writing code that handles sensitive data
you need to be careful about which other processes you share it with
The size limitation of 64 bytes however is a bit more painful,
although actually, for symmetric crypto keys and passwords 64 bytes is
very reasonable because AES-256 keys for example are only 32 bytes
long. Most passwords are also much shorter than 64 bytes. However of
course for asymmetric crypto the key sizes are much larger than 64
bytes and this becomes a real issue.
I have two ideas on how to address this:
1. Add a "sensitive" flag for the entire Erlang node as well, which at
least to begin with, will only tell the GC to also zero the binary
heap when it frees it. More relevant actions can be piled on top of
that semantic in the future.
2. The second would be to allow larger binaries to reside on the
process heap of sensitive processes, possibly even make this
configurable. This sounds to me a bit more complex than 1.
One final point about NIFs - I think that's outside the scope of what
is possible to address. The use case I really want to address is the
handling of sensitive data in Erlang code and the passing of it to and
from the "crypto" module. Granted, OpenSSL is a C program and hence a
NIF (hope I got that right) but if OpenSSL fails to zero its internal
sensitive buffers, that's a bug that should be handled in the OpenSSL
(BTW: after a bit of searching I found that OpenSSL uses
"openssl_cleanse" whenever it
needs to zero a sensitive buffer -
More information about the erlang-questions