Zeroization of sensitive data in Erlang

Dániel Szoboszlay dszoboszlay@REDACTED
Mon Oct 28 23:46:46 CET 2019

Hi Amit,

Maybe instead of 1. and 2. it would work just to make the GC in sensitive
processes to zero refcounted binaries when it removes the last reference to
them. This means all binary data exclusive to a sensitive process would be
zeroed, and a binary shared between a sensitive and nonsensitive process
may or may not get zeroed, depending on which process stops using it last.
But that's fine most of the cases: data shared with a nonsensitive process
shouldn't be sensitive.

There's one caveat with sub binaries: you may have a large binary in a
sensitive process that contains some sensitive data and some nonsensitive
data too (e.g. you read in a file that contains a private key and a
certificate), in which case you have to be careful not to share the
nonsensitive part as a sub binary with an other process. Otherwise the GC
may fail to zero out the sensitive part too when run from the nonsensitive
process. This could be avoided by using binary:copy/1 before sharing the
nonsensitive part.


On Mon, 28 Oct 2019 at 13:23, Amit K <klg.amit@REDACTED> wrote:

> Hi Daniel,
> 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
> anyway :)
> 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
> context :)
> (BTW: after a bit of searching I found that OpenSSL uses
> "openssl_cleanse" whenever it
> needs to zero a sensitive buffer -
> )
> Thanks,
> Amit
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the erlang-questions mailing list