-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On Friday, February 28, 2003, at 01:03 AM, Jeroen C. van Gelderen wrote:
> Incidentally, the correct and portable (modulo compiler bugs) approach
> at the language level is to mark the array volatile. This means that
> stores to the array cannot be optimized out and neither can function
> calls to functions in which a volatile variable is manipulated (this
> is transitive).
>
> You will still have to disable caching and swapping at the OS (and
> maybe the hardware) level to make sure no copies linger around. And in
> some cases (again, what is your threat model?), you will want to
> overwrite your data with random bytes because overwriting with zeroes
> makes offline forensics easier.
OK, I am adopting 'volatile'. In the discussion on this topic a few
months back, someone pointed out that a solid compiler MUST implement
volatile correctly otherwise device drivers run the risk of producing
smoke and sparks from your computer. I assume gcc is a solid compiler.
Also, I initially allocate all a single locked page of working scratch
pad memory and pass it into my sensitive code. The sensitive code does
not declare ANYTHING sensitive on the stack.
Here we go. Assume these declarations:
typedef unsigned char t_byte;
typedef unsigned long t_word;
typedef volatile t_byte vt_byte;
We have this code:
void main(void) {
...
int pagesize = getpagesize();
vt_byte *page = malloc(pagesize);
if (page) {
if (mlock((caddr_t)page, pagesize) == 0) {
DO_SENSITIVE_STUFF(page);
munlock((caddr_t)page, pagesize);
}
free((void *)page);
}
}
Now, the routine to do all the sensitive stuff uses page for ALL its
working memory. It calls a routine 'wash_bytes' to wipe out whatever
it uses in the page.
I have decided that wash_bytes will use a simple and fast random number
generator to randomize the memory. I have already written a nice
implementation of the Mersenne Twister, so here is the relevant
"laundromat" code:
#include "mersenne.h"
static t_mersenne twister;
void set_wash_seed(t_word seed) {
mersenne_start(&twister, seed);
}
void wash_bytes(vt_byte a[], int n) {
for (...) {
t_word w = mersenne_next(&twister);
/* put the 4 bytes of w into the next 4 bytes of a[] */
}
}
Periodically my main program will call set_wash_seed with a fresh
simple word of entropy, but because the Mersenne Twister has such a
long period I'll probably let it ride for quite a while.
This should give any forensics cryptanalysts a bitch of time. I assume
the main danger of zero blocks is that it give them handy reference
points within the captured memory image. I doubt they'll be able to
recognize any MT sequences, especially if occasionally reseeded. :-)
This stuff is wacky!!!
- -- Patrick
http://fexl.com
-----BEGIN PGP SIGNATURE-----
Version: PGP 8.0
iQA/AwUBPl+eMlA7g7bodUwLEQLzqQCg4t58FsuuyjnHVBqPKIvnHdV/5OkAnRl1
pc8HVgL3dl8uKnB+CtqwfjSa
=hs2S
-----END PGP SIGNATURE-----