When dealing with cryptographic data, is there a chance that attacker recovers portion of data I used in my program? Should I try to delete every bit of keys and encrypted data that I used, overwrite it with zeroes?

And one extra, how is situation different in languages with garbage collection like Python or Java?

What are you trying to prevent exactly? Presumably an "attacker" who had access to the machine's memory would thereby be entitled to the data the machine had processed. And if your model is that an attacker may have control over the machine while it's processing the data, erasing it later won't help. Are you trying to protect against sensitive data in swap or core dumps?
–
David SchwartzAug 28 '13 at 7:04

3 Answers
3

The book Cryptography Engineering devotes part of a chapter to this topic. Overwriting sensitive data with zeroes is a good start, but there are lots of other considerations.

If you rely on a language's default object destruction behavior to zero the memory, it's possible for an unexpected error to prematurely halt the program's execution without it cleaning up after itself. In Java, exception handling can discard object references without cleaning up the objects themselves. [Not sure if this is still the case]

Sometimes compilers will optimize away the code used to overwrite the memory because it's acting on a piece of memory with no other uses in the program.

OS memory management can foil your attempts to delete data by paging it to the system's hard disk. There are ways of preventing this but they are language- and platform-specific.

If the OS does a context switch the values in the registers are stored elsewhere in memory until execution resumes. This can cause sensitive data to end up in strange places. Modern processors also have multiple caches where sensitive data can be held.

In languages where memory management is automatic it's even more difficult to know where exactly in the system your allocated memory is (and for how long). In Java, objects all live on the heap and are reference-counted as a part of garbage collection. When there are no more references to the object, it can be deleted by the next pass of the garbage collector. However, short of calling System.gc() there's no way of knowing when garbage collection will occur. And even if you force garbage collection it still might not execute immediately. This SO question talks a little bit about System.gc behavior.

Cold boot attacks happen when keys are always written to the same physical region of a computer's memory. Over time, the electromagnetic forces can cause the memory to retain a state after the power is shut off.

This probably isn't all in scope for your application, but it should give you a good idea of the capabilities of an attacker with physical system access. The most important thing you can do is know your language and platform very, very well. For further reading, this Wikipedia article should give you a good start.

Number 2 is particularly important. For instance you can look at how OpenSSL does it, by doing strange operations on the data to overwrite to trick the compiler into randomizing it even though it will never be used later on (for higher level languages this may well be impossible to achieve). There is indeed no generic solution.
–
ThomasAug 27 '13 at 3:36

Excellent answer, although technically, it answers the question "how do I erase sensitive data I used in my programmed" and not the question "should I erase sensitive data I used in my program".
–
Henrick HellströmAug 27 '13 at 13:59

Haha I guess it does. I thought I'd kill two birds with one stone.
–
pg1989Aug 27 '13 at 17:15

This question is actually not entirely easy to answer. Usually, adding complexity to a cryptographic scheme or implementation, should be avoided, unless the added complexity is necessary in order to meet a specific requirement. The problem with software that is zeroing internal memory, is just that it is hard to come up with a credible scenario, where this is both effective and necessary, in order to counter a specific threat.

Suppose you have a client certificate in a password protected .pfx file on disk. You trust that the passphrase you use for the .pfx file is strong enough, for the encryption not to be broken, at least before the certificate expires. You use the certificate in a program you know implements state-of-the-art methods for zeroing internal memory. Later, either you discover that you have had malware on the same computer, or the computer is physically stolen. Would you, in either case, trust the methods that are zeroing internal memory, or would you revoke your certificate? Arguably, the sane thing to do, would be to revoke the certificate, regardless of whether the software is zeroing internal memory or not.

Yes, it's a good idea. But unfortunatelly it's far from trivial to securely wipe data from memory. Modern compilers, operating system and CPUs make it really, really hard.

For instance you never know where your computer has stored sensitive data. CPUs have L1, L2 and shared L3 caches. NUMA (even ccNUMA) can do fancy stuff with your data until you enforce a memory barrier. The operating system may decide to swap the memory pages to disk, too. mlock() could help but it requires extra capabilities and is hard to use, because it operates on pages.

Your __memset_vp code is wrong. A compiler can always compare the __memset_vp function pointer and if it is equal to memset omit the code.
–
Steven Stewart-GallusDec 21 '14 at 20:07

Your memset code that uses the inline asm to explain to GCC that the data may be read later is better but does not take into account multithreading. For example, your zeroing writes could be stuck in a core's store buffer for a bit before the memory is actually zeroed. You should also flush OS and hardware caches.
–
Steven Stewart-GallusDec 21 '14 at 20:09