8 ms·
RAM encryption for sensitive data is overlooked in so many applications, even "highly secure" applications like veracrypt [0] only recently started adding it.
by Koffiepoeder 7y ago
RAM encryption for sensitive data is overlooked in so many applications, even "highly secure" applications like veracrypt [0] only recently started adding it.
In my opinion server-applications of all sorts should encrypt their private keys by default; this makes cold-boot attacks and other memory-escape attacks so much harder, since now two totally unrelated memory chunks have to be combined in order to retrieve the private key (in fact one could argue that, the higher the quantity of memory chunks is, the harder it is to correctly decrypt the original private key; although to me this has the security through obscurity smell).
In practice however, this is rarely done. OpenSSL for example has a whole lot of memory-management functions [1], but none of them seem to include RAM encryption (AFAIK it is not present in the source code elsewhere either, but it's a large one, so I am not familiar with all code. Related: in fact some people even argue it's way too large for it's own good [2]).
Even better still, would be to use the CPU Cache for private keys, since this memory is even more difficult to access through any sort of cold boot. An interesting paper with much more information about this subject can be found here [3], to whom it may concern.
[0] https://github.com/veracrypt/VeraCrypt/commit/321715202aed04dd9892d1c0686d080763ab212d https://github.com/veracrypt/VeraCrypt/commit/321715202aed04...
[1] https://www.openssl.org/docs/man1.1.0/man3/OPENSSL_zalloc.html https://www.openssl.org/docs/man1.1.0/man3/OPENSSL_zalloc.ht...
[2] https://queue.acm.org/detail.cfm?id=2602816 https://queue.acm.org/detail.cfm?id=2602816
[3] https://www.ieee-security.org/TC/SP2015/papers-archived/6949a003.pdf https://www.ieee-security.org/TC/SP2015/papers-archived/6949...
- spacephysics 7y agoIf I were writing a cryptographic algorithm in C++, how would I ensure the CPU cache was used for private keys? Would it have to be written in a lower level language, or does there exist a library for C/C++?
- Zarathustra_ 7y agoPrevious thread with lots of relevant information: https://news.ycombinator.com/item?id=8542405 https://news.ycombinator.com/item?id=8542405 Short answer is yes usually, and if not, you can always do inline asm. Of course, you're really, really, really not supposed to write your own crypto.
- vinay_ys 7y agoIf everyone follows this advice, who will write the crypto code? If anything we need lot more people who are formally trained to write proper crypto code and find bugs in such code etc.
- Zarathustra_ 7y agoLet me qualify that. You're right, we do need a lot more people. But the answer is, don't write your own, write as part of a team. Ideally, a public and peer-reviewed project. The short answer is many people will work on it together, but don't write your own.
- reza_n 7y agoYup, we added this feature to Varnish Cache a few years ago, random key encryption. It generates a random key at startup and encrypts all memory with it. Since this kind of memory is only resident for the lifetime of the process, it works. We stored the random key in the Linux kernel using the crypto API [0] just because its not safe storing any kind of keys in a memory space used for caching (Cloudbleed [1]). We then use the key to generate a per object HMAC, so each piece of data ends up with its own key, which further prevents something like Cloudbleed. Since we used kernel crypto, overhead was about 50%. If you stay completely in user space, its probably much lower. [0] https://www.kernel.org/doc/html/v4.17/crypto/userspace-if.html https://www.kernel.org/doc/html/v4.17/crypto/userspace-if.ht... [1] https://en.wikipedia.org/wiki/Cloudbleed https://en.wikipedia.org/wiki/Cloudbleed
- Koffiepoeder 7y agoCould you point me to the relevant source code? Am highly interested to take a look at it during the weekend.
- deleted 7y ago[deleted]
- reza_n 7y agoClosed source, write up would be here: https://info.varnish-software.com/blog/introducing-varnish-total-encryption https://info.varnish-software.com/blog/introducing-varnish-t...
- ris 7y ago> Closed source Ah, so we'll just have to trust you that it's doing anything at all, then.
- dang 7y ago"Please respond to the strongest plausible interpretation of what someone says, not a weaker one that's easier to criticize. Assume good faith." https://news.ycombinator.com/newsguidelines.html https://news.ycombinator.com/newsguidelines.html
- latchkey 7y agoAMD has some interesting work in this area. https://github.com/qemu/qemu/blob/master/docs/amd-memory-encryption.txt https://github.com/qemu/qemu/blob/master/docs/amd-memory-enc...
- java-man 7y agoRAM encryption is a feature in my password manager (java): https://github.com/andy-goryachev/PasswordSafe/blob/master/src/goryachev/crypto/OpaqueMemObject.java https://github.com/andy-goryachev/PasswordSafe/blob/master/s... Curiously, RAM encryption, and its relative - clearing secrets from memory when not in use - cannot be added to the Bouncycastle library because they use java BigInteger (unless reflection is used of course).
- sjwright 7y agoHow do you guarantee actual clearing of physical memory in a garbage collected VM?
- java-man 7y agoby explicitly clearing it when an operation is finished. example: https://github.com/andy-goryachev/PasswordSafe/blob/master/src/goryachev/crypto/MemCrypt.java https://github.com/andy-goryachev/PasswordSafe/blob/master/s... byte[] key = generateKey(); try { // sensitive operation } finally { Crypto.zero(key); } once the operation finishes, the memory is cleared (and possibly subject to gc) the problem is that some java classes, for instance BigInteger, are not designed for cryptographic operations - it's underlying arrays are not easily accessible (save for reflection).
- pstrateman 7y agoThat operation is almost certainly optimized out.
- simias 7y agoI've tried implementing a couple of (toy) password managers over the years and dealing with private keys is genuinely complicated. Even something as trivial as making sure that the memory gets zeroed correctly when you discard the key is trickier than it seems. Compilers these days are very good at detecting "dummy" memsets to memory that's never read afterwards and optimize them away. You have to use some dirty tricks to get the compiler to do what you want (copious amounts of volatile helps). There's also the problem of making sure that your internal API is sound and doesn't copy the key around. In languages like C it's relatively easy to achieve (because copying a buffer in C normally requires some explicit code) but in higher level languages you might easily mistakenly pass the key object by copy instead of reference, leaving some duplicate of the sensitive information in some other location in RAM. I think there really should be some kind of industry-standard multiplatform library meant to deal with secret keys that would implement all that behind the scenes and offer a simple API. It's simply too easy to make a dumb mistake when implementing these things, and you won't notice anything is wrong until somebody attempts to actually recover the key somehow.
- cesarb 7y ago> Compilers these days are very good at detecting "dummy" memsets to memory that's never read afterwards and optimize them away. You have to use some dirty tricks to get the compiler to do what you want (copious amounts of volatile helps). Or you can use explicit_bzero(), which is designed for that use case.
- loeg 7y agoSure, although this is a non-standard and potentially non-portable extension. memset_s in Annex K is standard, but all of Annex K is optional, and like the rest of Annex K, it has an awful interface.
- rurban 7y agoexplicit_bzero or SecureZeroMemory are all insecure against those new sidechannel attacks we are talking about here. Only memset_s is. You really need a mfence (full memory barrier), not just a compiler barrier, maybe even a clflush.
- rocqua 7y ago> in fact one could argue that, the higher the quantity of memory chunks is, the harder it is to correctly decrypt the original private key; although to me this has the security through obscurity smell I am not sure this is a bad place for security through obscurity. ASLR is similar. The thing is, here we are not using this is a primary mechanism. (that would be preventing RCE) Instead, this would be a secondary 'defense in depth' measure meant to make it harder to deploy an exploit after you have been compromised. For such a second layer of defense in depth, obscurity is a decent option. Things go wrong if you start relying on your obscurity to do anything but slow down an attacker.
- viraptor 7y agoI feel like the should be a different name for that class of mitigations. Probabilistic security maybe? Security through obscurity for me is "we won't publish our algorithm". But that's not the same as ASLR or memory encryption which targets specific type of attack by adding probably-too-high randomness to the attack path.
- EGreg 7y agoYes, ALL private keys should be encrypted and stored elsewhere. The onion/knot should be unwound from some remote place, so you have to get access to a FEW places in order to get any private keys. Now, in MY opinion, the whole idea of servers storing OR MANIPULATING unencrypted user-submitted information is what’s wrong with our current Internet culture. This needs to stop. It has massive social and economic effects and creates honeypots for hackers. The sooner we make end-to-end encryption a basic expectation, the sooner we change our society to have a far more private and safe environment for everyone, and correct massive power imbalances: an organization or user should have power and data and connections and ability to SPAM others because people VOLUNTARILY gave them those things, not because they happened to build proprietary software and run it on infrastructure that is needed to operate the application!!!
- Too 7y agoIdeally private keys should never touch the main CPU at all. You should use something like a secure enclave or a a key-dongle like Yubikey.
- rurban 7y agoNo. The CPU cache can easily be read out with sidechannel attacks via hyperthreading. It's the similar problem as unencrypted keys at the absolute location, which doesn't get cleared with explicit_bzero, which e.g. libsodium refused to fix. Hopefully crypto maintainers will get to their senses eventually. https://github.com/jedisct1/libsodium/issues/802 https://github.com/jedisct1/libsodium/issues/802
- jedisct1 7y agolibsodium has the sodium_mshield()/sodium_munshield(). For libhydrogen, storing a large prekey can be a problem, so it may only be implemented on some platforms.