aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/include/tinycrypt/utils.h26
-rw-r--r--lib/source/ecc_dh.c14
2 files changed, 32 insertions, 8 deletions
diff --git a/lib/include/tinycrypt/utils.h b/lib/include/tinycrypt/utils.h
index bab5c32..6b7b0ab 100644
--- a/lib/include/tinycrypt/utils.h
+++ b/lib/include/tinycrypt/utils.h
@@ -41,6 +41,7 @@
#include <stdint.h>
#include <stddef.h>
+#include <string.h>
#ifdef __cplusplus
extern "C" {
@@ -69,6 +70,31 @@ unsigned int _copy(uint8_t *to, unsigned int to_len,
*/
void _set(void *to, uint8_t val, unsigned int len);
+/**
+ * @brief Set the value 'val' into the buffer 'to', 'len' times, in a way
+ * which does not risk getting optimized out by the compiler
+ * In cases where the compiler does not set __GNUC__ and where the
+ * optimization level removes the memset, it may be necessary to
+ * implement a _set_secure function and define the
+ * TINYCRYPT_ARCH_HAS_SET_SECURE, which then can ensure that the
+ * memset does not get optimized out.
+ *
+ * @param to OUT -- destination buffer
+ * @param val IN -- value to be set in 'to'
+ * @param len IN -- number of times the value will be copied
+ */
+#ifdef TINYCRYPT_ARCH_HAS_SET_SECURE
+extern void _set_secure(void *to, uint8_t val, unsigned int len);
+#else /* ! TINYCRYPT_ARCH_HAS_SET_SECURE */
+static inline void _set_secure(void *to, uint8_t val, unsigned int len)
+{
+ (void) memset(to, val, len);
+#ifdef __GNUC__
+ __asm__ __volatile__("" :: "g"(to) : "memory");
+#endif /* __GNUC__ */
+}
+#endif /* TINYCRYPT_ARCH_HAS_SET_SECURE */
+
/*
* @brief AES specific doubling function, which utilizes
* the finite field used by AES.
diff --git a/lib/source/ecc_dh.c b/lib/source/ecc_dh.c
index e5257d2..1b108a4 100644
--- a/lib/source/ecc_dh.c
+++ b/lib/source/ecc_dh.c
@@ -57,6 +57,7 @@
#include <tinycrypt/constants.h>
#include <tinycrypt/ecc.h>
#include <tinycrypt/ecc_dh.h>
+#include <tinycrypt/utils.h>
#include <string.h>
#if default_RNG_defined
@@ -92,7 +93,7 @@ int uECC_make_key_with_d(uint8_t *public_key, uint8_t *private_key,
_public + curve->num_words);
/* erasing temporary buffer used to store secret: */
- memset(_private, 0, NUM_ECC_BYTES);
+ _set_secure(_private, 0, NUM_ECC_BYTES);
return 1;
}
@@ -133,7 +134,7 @@ int uECC_make_key(uint8_t *public_key, uint8_t *private_key, uECC_Curve curve)
_public + curve->num_words);
/* erasing temporary buffer that stored secret: */
- memset(_private, 0, NUM_ECC_BYTES);
+ _set_secure(_private, 0, NUM_ECC_BYTES);
return 1;
}
@@ -189,12 +190,9 @@ int uECC_shared_secret(const uint8_t *public_key, const uint8_t *private_key,
clear_and_out:
/* erasing temporary buffer used to store secret: */
- memset(p2, 0, sizeof(p2));
- __asm__ __volatile__("" :: "g"(p2) : "memory");
- memset(tmp, 0, sizeof(tmp));
- __asm__ __volatile__("" :: "g"(tmp) : "memory");
- memset(_private, 0, sizeof(_private));
- __asm__ __volatile__("" :: "g"(_private) : "memory");
+ _set_secure(p2, 0, sizeof(p2));
+ _set_secure(tmp, 0, sizeof(tmp));
+ _set_secure(_private, 0, sizeof(_private));
return r;
}