From fa64817e61a7670ab787818bc8f3ca8ed4c8d51d Mon Sep 17 00:00:00 2001 From: Koen Zandberg Date: Sun, 21 Oct 2018 20:31:54 +0200 Subject: [PATCH 1/2] crypto/helper: Add secure wipe function Adds a cryptographically secure wipe function to wipe structs with sensitive data. Works by first casting the pointer to a `volatile` pointer to ensure that the compiler doesn't optimize the "memset" away. --- sys/crypto/helper.c | 9 +++++++++ sys/include/crypto/helper.h | 15 +++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/sys/crypto/helper.c b/sys/crypto/helper.c index 9ddbfc47f8..707671b22c 100644 --- a/sys/crypto/helper.c +++ b/sys/crypto/helper.c @@ -33,3 +33,12 @@ int crypto_equals(uint8_t *a, uint8_t *b, size_t len) return diff; } + +/* Compiler should not be allowed to optimize this */ +void crypto_secure_wipe(void *buf, size_t len) +{ + volatile uint8_t *vbuf = (uint8_t*)buf; + for (size_t i = 0; i < len; i++) { + vbuf[i] = 0; + } +} diff --git a/sys/include/crypto/helper.h b/sys/include/crypto/helper.h index 7744dc981d..18ccffe40c 100644 --- a/sys/include/crypto/helper.h +++ b/sys/include/crypto/helper.h @@ -49,6 +49,21 @@ void crypto_block_inc_ctr(uint8_t block[16], int L); */ int crypto_equals(uint8_t *a, uint8_t *b, size_t len); +/** + * @brief Secure wipe function. + * + * This wipe function zeros the supplied buffer in a way that the compiler is + * not allowed to optimize. This can be used to erase secrets from memory. + * + * Note that this function on its own could be insufficient against (data + * remanence) attacks. It is outside the scope of this function to thoroughly + * shred the memory area. + * + * @param[in] buf buffer to wipe + * @param[in] len size of the buffer in bytes + */ +void crypto_secure_wipe(void *buf, size_t len); + #ifdef __cplusplus } #endif From 730286903a57baf2ad1fe592b94efce3e685982e Mon Sep 17 00:00:00 2001 From: Koen Zandberg Date: Tue, 23 Oct 2018 14:06:15 +0200 Subject: [PATCH 2/2] crypto/helper: Add test for crypto_secure_wipe The test added for crypto_secure_wipe wipes a buffer with a secret in it. Only the last byte is kept as it was. The last byte is used to check that the function doesn't write outside the supplied buffer. --- .../tests-crypto/tests-crypto-helper.c | 38 +++++++++++++++++++ tests/unittests/tests-crypto/tests-crypto.c | 1 + tests/unittests/tests-crypto/tests-crypto.h | 6 +++ 3 files changed, 45 insertions(+) create mode 100644 tests/unittests/tests-crypto/tests-crypto-helper.c diff --git a/tests/unittests/tests-crypto/tests-crypto-helper.c b/tests/unittests/tests-crypto/tests-crypto-helper.c new file mode 100644 index 0000000000..c9cf8d781a --- /dev/null +++ b/tests/unittests/tests-crypto/tests-crypto-helper.c @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2018 Koen Zandberg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#include + +#include "embUnit/embUnit.h" +#include "crypto/helper.h" + +#define VALUE 0xAA + +/* Secret to wipe */ +static uint8_t secret[20]; + +void test_crypto_wipe(void) +{ + memset(secret, VALUE, sizeof(secret)); + /* Wipe everything except the last byte */ + crypto_secure_wipe(secret, sizeof(secret) - 1); + for (size_t i = 0; i < (sizeof(secret) - 1); i++) { + TEST_ASSERT_EQUAL_INT(0, secret[i]); + } + /* Check last byte */ + TEST_ASSERT_EQUAL_INT(VALUE, secret[19]); +} + +Test *tests_crypto_helper_tests(void) +{ + EMB_UNIT_TESTFIXTURES(fixtures) { + new_TestFixture(test_crypto_wipe), + }; + EMB_UNIT_TESTCALLER(crypto_helper_tests, NULL, NULL, fixtures); + return (Test *) &crypto_helper_tests; +} diff --git a/tests/unittests/tests-crypto/tests-crypto.c b/tests/unittests/tests-crypto/tests-crypto.c index d1c1ce2aaf..38910467b2 100644 --- a/tests/unittests/tests-crypto/tests-crypto.c +++ b/tests/unittests/tests-crypto/tests-crypto.c @@ -11,6 +11,7 @@ void tests_crypto(void) { + TESTS_RUN(tests_crypto_helper_tests()); TESTS_RUN(tests_crypto_chacha_tests()); TESTS_RUN(tests_crypto_aes_tests()); TESTS_RUN(tests_crypto_cipher_tests()); diff --git a/tests/unittests/tests-crypto/tests-crypto.h b/tests/unittests/tests-crypto/tests-crypto.h index db49773288..aa25a82a89 100644 --- a/tests/unittests/tests-crypto/tests-crypto.h +++ b/tests/unittests/tests-crypto/tests-crypto.h @@ -33,6 +33,12 @@ extern "C" { */ void tests_crypto(void); +/** + * @brief Generates tests for helper functions + * + * @return embUnit tests + */ +Test *tests_crypto_helper_tests(void); /** * @brief Generates tests for crypto/chacha.h *