Está en la página 1de 3

Erasing Data from Memory Securely :

Avoid using realloc() : (and API functions that rely on realloc())


copies memory content pointed by a pointer to another larger/smaller memory space, then
updates pointer
=> old memory space still has a copy of sensitive data

memset() ignored by compilers, because of code optimization


Example : at the end of function, when calling memset on a local variable or an
argument
=> compiler knows that the variable will never be used again after memset()
=> memset() ignored

Solution : USE volatile qualifier for all variables that hold sensitive data

Every access (both read and write) made through an lvalue expression of volatile-qualified type is
considered an observable side effect for the purpose of optimization and is evaluated strictly
according to the rules of the abstract machine (that is, all writes are completed at some time
before the next sequence point). This means that within a single thread of execution, a volatile
access cannot be optimized out or reordered relative to another visible side effect that is
separated by a sequence point from the volatile access.

Some compilers have agressive dead-code elimination


Solution : Implement memset(), memcpy(), memmove()

1st level : return value as volatile ,still calls compiler's memset (which is known by compiler)

/*
* Pointer to memset is volatile so that compiler must de-reference
* the pointer and can't assume that it points to any function in
* particular (such as memset, which it then might further "optimize")
*/
typedef void *(*memset_t)(void *, int, size_t);
static volatile memset_t memset_func = memset;
void OPENSSL_cleanse(void *ptr, size_t len)
{
memset_func(ptr, 0, len);
}

2nd level : own function, is unknown to compiler, might be slower but we're certain there will be no
optimization

volatile void *spc_memset(volatile void *dst, int c, size_t len) {


volatile char *buf;
for (buf = (volatile char *)dst; len; buf[--len] = c);
return dst;
}
volatile void *spc_memcpy(volatile void *dst, volatile void *src, size_t len) {
volatile char *cdst, *csrc;
cdst = (volatile char *)dst;
csrc = (volatile char *)src;
while (len--) cdst[len] = csrc[len];
return dst;
}
volatile void *spc_memmove(volatile void *dst, volatile void *src, size_t len) {
size_t i;
volatile char *cdst, *csrc;
cdst = (volatile char *)dst;
csrc = (volatile char *)src;
if (csrc > cdst && csrc < cdst + len)
for (i = 0; i < len; i++) cdst[i] = csrc[i];
else
while (len--) cdst[len] = csrc[len];
return dst;
}

static volatile void * my_memset(void * ptr, int value, size_t num) {


volatile unsigned char * buf;
buf = (volatile unsigned char *)ptr;

do {
buf[--num] = (unsigned char)value;
} while (num);

return ptr;
}

static volatile void * my_memclr(void * ptr, size_t num) {


return (my_memset(ptr, 0, num));
}

N.B : const use <=> volatile use


Preventing Memory from Being Paged to Disk :

Modern system => virtual memory => programs do not run on actual physical memory (RAM)
=> each program actually uses a chunk of RAM (a limited space of addresses)
=> virtual memory manager makes it so that program sees this chunk as if it was
the whole RAM (program sees as if start = 0x00000000 when it is 0x45ba2fee i.e)

System running low on physical memory (RAM) => vm manager frees RAM => swaps data on
RAM to DISK

Sensitive data might be stored on disk => very bad

Solution :
1-Lock virtual memory space to actual physical memory (RAM) space => Tell system not to erase
that memory space from RAM
2-Avoid swapping that region of memory from RAM to disk => Tell system not to copy that
memory region content to disk from RAM and use the data from disk

On Windows systems, the VirtualLock( ) API function allows an application to


lock virtual memory into physical memory. The function guarantees that successfully
locked memory will never be swapped to disk.

On Unix systems, the POSIX 1003.1b standard for real-time extensions introduces
an optional system call, mlock( ), which is intended to guarantee that locked memory
is always resident in physical memory. However, contrary to popular belief, it
does not guarantee that locked memory will never be swapped to disk.
=> locked memory is always on RAM, but the system can copy it to disk
=> it just means that the program will continue using the addresses from RAM rather from disk