When I allocate the key on the heap, the memset is carried (heavily optimized and inlined). When I allocate key on the stack, it disappears. Using gcc -03: #include void doSecure(void) { /*char key[32];*/ char *key = (char*) malloc(sizeof(char)*32); memset(key,sizeof(char),32); } int main(void) { doSecure(); return 0; } -- key on stack main: .LFB13: .cfi_startproc xorl %eax, %eax ret .cfi_endproc -- key on heap main:…
How to zero a buffer
51–60 of 216 posts
Re: How to zero a buffer
#52Earlier quoted context omitted.
If you're not worried about writing in a language which is widely supported, just use memset_s and tell people to find a C11 compiler.
Or have your build system add memset_s.c to their compile on systems that don't have it.
Re: How to zero a buffer
#53Re: How to zero a buffer
#54When I allocate the key on the heap, the memset is carried (heavily optimized and inlined). When I allocate key on the stack, it disappears. Using gcc -03: #include void doSecure(void) { /*char key[32];*/ char *key = (char*) malloc(sizeof(char)*32); memset(key,sizeof(char),32); } int main(void) { doSecure(); return 0; } -- key on stack main: .LFB13: .cfi_startproc xorl %eax, %eax ret .cfi_endproc -- key on heap main:…
Re: How to zero a buffer
#55While this completely subverts our intention, it is perfectly legal: The observable behaviour of the program is unchanged by the optimization. This begs the question of what is "observable behaviour" - execution time, which is definitely "observable" and the basis of timing-based attacks, can certainly change depending on what the optimiser decides to do. I think this and similar cases of "fighting the optimiser" sho…
The term "observable behaviour" is defined in the standard: Essentially, I/O to files and interactive devices, plus accesses to volatile objects.
Re: How to zero a buffer
#56Re: How to zero a buffer
#57When this still doesn't work: JIT compiled C. The compiler can check for memset and elide it. (Or hell, one can envision the hypothetical Antagonizer9000 compiler including a version of memset which peeks up the stack to see what it's clearing and stops short.)
This might cause side effects if /dev/null does not exist or is not the null device.
Re: How to zero a buffer
#58Why would the compiler be allowed optimize away a call to a perfectly valid function? This seems like it's allowing to compiler to make judgement calls on whether or not your code is worthy of being executed.
Because the C standard permits such optimizations. It is really just a case of inlining followed by dead store optimization, two fairly common optimization passes which are normally desired. The subtlety is that while the compiler considers it a dead store, you don't, because you're going behind the compilers back to examine memory afterwards.
Re: How to zero a buffer
#59Earlier quoted context omitted.
Coredumps?
OS/language runtine should provide cryptographic key management routines that are correct in the OS/device context?
Re: How to zero a buffer
#60When this still doesn't work: JIT compiled C. The compiler can check for memset and elide it. (Or hell, one can envision the hypothetical Antagonizer9000 compiler including a version of memset which peeks up the stack to see what it's clearing and stops short.)
Would it be possible to read a value from the array and do something with it (e.g. send it to /dev/null)? Even a JIT shouldn't be able to optimize the value out if you're actually using the value, and as long as you're not zeroing secure memory all the time, the performance hit shouldn't be that large. This might cause side effects if /dev/null does not exist or is not the null device.