Merge pull request #7173 from daverodgman/zeroize-platform
Use platform-provided secure zeroization
This commit is contained in:
commit
4693fd9e9e
4 changed files with 107 additions and 5 deletions
3
ChangeLog.d/platform-zeroization.txt
Normal file
3
ChangeLog.d/platform-zeroization.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
Security
|
||||
* Use platform-provided secure zeroization function where possible, such as
|
||||
explicit_bzero().
|
|
@ -26,6 +26,11 @@
|
|||
#define _POSIX_C_SOURCE 200112L
|
||||
#endif
|
||||
|
||||
#if !defined(_GNU_SOURCE)
|
||||
/* Clang requires this to get support for explicit_bzero */
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "mbedtls/platform_util.h"
|
||||
|
@ -33,11 +38,31 @@
|
|||
#include "mbedtls/threading.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifndef __STDC_WANT_LIB_EXT1__
|
||||
#define __STDC_WANT_LIB_EXT1__ 1 /* Ask for the C11 gmtime_s() and memset_s() if available */
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
// Detect platforms known to support explicit_bzero()
|
||||
#if defined(__GLIBC__) && (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 25)
|
||||
#define MBEDTLS_PLATFORM_HAS_EXPLICIT_BZERO 1
|
||||
#elif defined(__FreeBSD__) && (__FreeBSD_version >= 1100037)
|
||||
#define MBEDTLS_PLATFORM_HAS_EXPLICIT_BZERO 1
|
||||
#endif
|
||||
|
||||
#if !defined(MBEDTLS_PLATFORM_ZEROIZE_ALT)
|
||||
/*
|
||||
* This implementation should never be optimized out by the compiler
|
||||
* Where possible, we try to detect the presence of a platform-provided
|
||||
* secure memset, such as explicit_bzero(), that is safe against being optimized
|
||||
* out, and use that.
|
||||
*
|
||||
* For other platforms, we provide an implementation that aims not to be
|
||||
* optimized out by the compiler.
|
||||
*
|
||||
* This implementation for mbedtls_platform_zeroize() was inspired from Colin
|
||||
* Percival's blog article at:
|
||||
|
@ -52,30 +77,40 @@
|
|||
* (refer to http://www.daemonology.net/blog/2014-09-05-erratum.html for
|
||||
* details), optimizations of the following form are still possible:
|
||||
*
|
||||
* if( memset_func != memset )
|
||||
* memset_func( buf, 0, len );
|
||||
* if (memset_func != memset)
|
||||
* memset_func(buf, 0, len);
|
||||
*
|
||||
* Note that it is extremely difficult to guarantee that
|
||||
* mbedtls_platform_zeroize() will not be optimized out by aggressive compilers
|
||||
* the memset() call will not be optimized out by aggressive compilers
|
||||
* in a portable way. For this reason, Mbed TLS also provides the configuration
|
||||
* option MBEDTLS_PLATFORM_ZEROIZE_ALT, which allows users to configure
|
||||
* mbedtls_platform_zeroize() to use a suitable implementation for their
|
||||
* platform and needs.
|
||||
*/
|
||||
#if !defined(MBEDTLS_PLATFORM_HAS_EXPLICIT_BZERO) && !defined(__STDC_LIB_EXT1__) \
|
||||
&& !defined(_WIN32)
|
||||
static void *(*const volatile memset_func)(void *, int, size_t) = memset;
|
||||
#endif
|
||||
|
||||
void mbedtls_platform_zeroize(void *buf, size_t len)
|
||||
{
|
||||
MBEDTLS_INTERNAL_VALIDATE(len == 0 || buf != NULL);
|
||||
|
||||
if (len > 0) {
|
||||
#if defined(MBEDTLS_PLATFORM_HAS_EXPLICIT_BZERO)
|
||||
explicit_bzero(buf, len);
|
||||
#elif defined(__STDC_LIB_EXT1__)
|
||||
memset_s(buf, len, 0, len);
|
||||
#elif defined(_WIN32)
|
||||
SecureZeroMemory(buf, len);
|
||||
#else
|
||||
memset_func(buf, 0, len);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_PLATFORM_ZEROIZE_ALT */
|
||||
|
||||
#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT)
|
||||
#define __STDC_WANT_LIB_EXT1__ 1 /* Ask for the C11 gmtime_s() if it's available */
|
||||
#include <time.h>
|
||||
#if !defined(_WIN32) && (defined(unix) || \
|
||||
defined(__unix) || defined(__unix__) || (defined(__APPLE__) && \
|
||||
|
|
23
tests/suites/test_suite_platform_util.data
Normal file
23
tests/suites/test_suite_platform_util.data
Normal file
|
@ -0,0 +1,23 @@
|
|||
Zeroize len 0, null
|
||||
mbedtls_platform_zeroize:0:1
|
||||
|
||||
Zeroize len 0, non-null
|
||||
mbedtls_platform_zeroize:0:0
|
||||
|
||||
Zeroize len 1
|
||||
mbedtls_platform_zeroize:1:0
|
||||
|
||||
Zeroize len 4
|
||||
mbedtls_platform_zeroize:1:0
|
||||
|
||||
Zeroize len 5
|
||||
mbedtls_platform_zeroize:1:0
|
||||
|
||||
Zeroize len 32
|
||||
mbedtls_platform_zeroize:32:0
|
||||
|
||||
Zeroize len 127
|
||||
mbedtls_platform_zeroize:127:0
|
||||
|
||||
Zeroize len 128
|
||||
mbedtls_platform_zeroize:128:0
|
41
tests/suites/test_suite_platform_util.function
Normal file
41
tests/suites/test_suite_platform_util.function
Normal file
|
@ -0,0 +1,41 @@
|
|||
/* BEGIN_HEADER */
|
||||
#include "mbedtls/platform_util.h"
|
||||
/* END_HEADER */
|
||||
|
||||
/* BEGIN_CASE */
|
||||
void mbedtls_platform_zeroize(int len, int null)
|
||||
{
|
||||
char buf[130];
|
||||
char *p = NULL;
|
||||
|
||||
TEST_ASSERT(len <= 128);
|
||||
|
||||
/* Write sentinel values */
|
||||
buf[0] = 2;
|
||||
buf[len + 1] = 2;
|
||||
|
||||
/* Write non-zero content */
|
||||
if (!null) {
|
||||
p = &buf[1];
|
||||
for (int i = 0; i < len; i++) {
|
||||
p[i] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check content is non-zero */
|
||||
TEST_EQUAL(buf[0], 2);
|
||||
for (int i = 0; i < len; i++) {
|
||||
TEST_ASSERT(p[i] == 1);
|
||||
}
|
||||
TEST_EQUAL(buf[len + 1], 2);
|
||||
|
||||
mbedtls_platform_zeroize(p, len);
|
||||
|
||||
/* Check content is zero and sentinels un-changed */
|
||||
TEST_EQUAL(buf[0], 2);
|
||||
for (int i = 0; i < len; i++) {
|
||||
TEST_ASSERT(p[i] == 0);
|
||||
}
|
||||
TEST_EQUAL(buf[len + 1], 2);
|
||||
}
|
||||
/* END_CASE */
|
Loading…
Reference in a new issue