Many crypto libraries include code similar to the following snippet:
/* Implementation that should never be optimized out by the compiler */
static void optimize_proof_zeroize( void *v, size_t n )
{
volatile unsigned char *p = v;
while( n-- ) *p++ = 0;
}
But my naive implementation doesn't survive an optimizing compiler:
/* Naive zeroization implementation */
static void naive_zeroize( unsigned char *c, size_t n)
{
int i;
for( i = 0; i < n; i++ )
c[i] = 0;
}
The code is used to zeroize sensitive data before freeing the memory. Since the buffer is not used again, optimizing compilers assume that they can safely remove the zeriozation from the compiled code.
What prevents the first implemention from being optimized out?