Change mbedtls_zeroize() to prevent optimizations

Change mbedtls_zeroize() implementation to use memset() instead of a
custom implementation for performance reasons. Furthermore, we would
also like to prevent as much as we can compiler optimisations that
remove zeroization code.

The implementation of mbedtls_zeroize() now uses a volatile function
pointer to memset() as suggested by Colin Percival at:

http://www.daemonology.net/blog/2014-09-04-how-to-zero-a-buffer.html
This commit is contained in:
Andres Amaya Garcia 2017-10-26 22:43:41 +01:00 committed by Andres Amaya Garcia
parent 2967381ccd
commit ecd1891c51

View File

@ -28,14 +28,33 @@
#include "mbedtls/utils.h" #include "mbedtls/utils.h"
#include <stddef.h> #include <stddef.h>
#include <string.h>
#if !defined(MBEDTLS_UTILS_ZEROIZE_ALT) #if !defined(MBEDTLS_UTILS_ZEROIZE_ALT)
/* This implementation should never be optimized out by the compiler */ /*
* This implementation should never be optimized out by the compiler
*
* This implementation for mbedtls_zeroize() uses a volatile function pointer.
* We always know that it points to memset(), but because it is volatile the
* compiler expects it to change at any time and will not optimize out the
* call that could potentially perform other operations on the input buffer
* instead of just setting it to 0. Nevertheless, optimizations of the
* following form are still possible:
*
* if( memset_func != memset )
* memset_func( buf, 0, len );
*
* Note that it is extremely difficult to guarantee that mbedtls_zeroize()
* will not be optimized out by aggressive compilers in a portable way. For
* this reason, mbed TLS also provides the configuration option
* MBEDTLS_UTILS_ZEROIZE_ALT, which allows users to configure
* mbedtls_zeroize() to use a suitable implementation for their platform and
* needs.
*/
static void * (* const volatile memset_func)( void *, int, size_t ) = memset;
void mbedtls_zeroize( void *buf, size_t len ) void mbedtls_zeroize( void *buf, size_t len )
{ {
volatile unsigned char *p = (unsigned char *)buf; memset_func( buf, 0, len );
while( len-- )
*p++ = 0;
} }
#endif /* MBEDTLS_UTILS_ZEROIZE_ALT */ #endif /* MBEDTLS_UTILS_ZEROIZE_ALT */