[cryptography] Best practices for paranoid secret buffers
Kevin W. Wall
kevin.w.wall at gmail.com
Wed May 7 22:32:02 EDT 2014
On Wed, May 7, 2014 at 8:15 AM, Jeffrey Walton <noloader at gmail.com> wrote:
> On Tue, May 6, 2014 at 11:56 PM, Tony Arcieri <bascule at gmail.com> wrote:
>> Can anyone point me at some best practices for implementing buffer types for
>> storing secrets?
>> There are the general coding rules at cryptocoding.net for example, that say
>> you should use unsigned bytes and zero memory when you're done, but I'm more
>> curious about specific strategies, like:
>> - malloc/free + separate process for crypto
> I think this is a good idea. I seem to recall the new FIPS 140 will
> have some language for it. I also seem to recall something about
> Microsoft's CryptNG, but I don't recall the details.
>> - malloc/free + mlock/munlock + "secure zeroing"
> On Microsoft platforms, you have `SecureZeroMemory`
> It is guaranteed *not* to be removed by the optimizer. On Linux, you
> have `bzero`, but I'm not sure about any guarantees. On OpenSSL, you
> have OpenSSL_cleanse. OpenSSL_cleanse is most acrobatic of the three.
>> - mmap/munmap (+ mlock/munlock)
> Keeping secrets out of the page file or swap file can be tricky. VMs
> can be trickier.
>> Should finalizers be explicit or implicit? (or should an implicit finalizer
>> try to make sure buffers are finalized if you don't do it yourself?)
> Not all languages have finalizers.
> Java has finalizers but tells you to put secrets in a char or byte
> so you can overwrite them manually: See, for example,
> (I think that link may be dead now).
Right; in Java you can't count on when the finalizers will be called (they
aren't like DTORs in C++), so you best do so immediately, probably in a
'finally' block to make sure it is done.
Also, In Java, I suspect that you have to beware of JIT optimizers like HotSpot.
In Java, disabling HotSpot or any other JIT on the server side is just not going
to happen and AFAIK (would love to be shown I'm ignorant here), you
JIT optimizers for just a few classes. [If you can, someone *please*
tell me how.]
>> Are paranoid buffers worth the effort? Are the threats they'd potentially
>> mitigate realistic? Are there too many other things that can go wrong (e.g.
>> rewindable VMs) for this to matter?
> I think they are worth the effort. Target's data breach was the result
> of (among others): memory scraping malware. At minimum, they cost next
> to nothing.
> You also have wrapping. That is, a buffer get a quick dose of XOR to
> mask the secrets while in memory but not in use.
> .Net's SecureString uses wrapping
> and NIST has a key wrap for symmetric encryption keys
Yes, in Java, the Cipher class supports the key wrapping, at least for AES.
I'm never tried of for something else like DESede.
> Maybe the later would have helped with Heartbleed, too... who knows.
Perhaps; it's doubtful that it would have hurt unless it was done in some
way that would introduce some sort of blatant timing side-channel
attack, which seems very unlikely if you always do it in the same place and
in the same manner regardless.
However, I don't think it's a panacea. Didn't someone have an
attack where they were able to reconstruct AES encryption keys
by recovering some fraction of the S-box values? I thought that
was either Felten, et al, Cold Boot attack or something that
was discussed in the literature around that time. Maybe I'm
just blabbering here since I can barely remember what I had
for lunch two days ago much less recall details of papers that
I've read from 5 or 6 years ago. Anyhow, I'm sure someone
on this list knows the details and I probably have it all wrong
NSA: All your crypto bit are belong to us.
More information about the cryptography