From 3ae1abe53e6f43219904cd2860d51c7e34dc3821 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Tue, 31 Mar 2015 10:13:33 +1000 Subject: [PATCH] Secure memory block compares --- libraries/Crypto/Crypto.cpp | 24 ++++++++++++++++++++++++ libraries/Crypto/Crypto.h | 2 ++ 2 files changed, 26 insertions(+) diff --git a/libraries/Crypto/Crypto.cpp b/libraries/Crypto/Crypto.cpp index 28295258..8088db8a 100644 --- a/libraries/Crypto/Crypto.cpp +++ b/libraries/Crypto/Crypto.cpp @@ -53,3 +53,27 @@ void clean(void *dest, size_t size) * Unlike memset(), this function attempts to prevent the compiler * from optimizing away the variable clear. */ + +/** + * \brief Compares two memory blocks for equality. + * + * \param data1 Points to the first memory block. + * \param data2 Points to the second memory block. + * \param len The size of the memory blocks in bytes. + * + * Unlike memcmp(), this function attempts to compare the two memory blocks + * in a way that will not reveal the contents in the instruction timing. + * In particular, this function will not stop early if a byte is different. + * It will instead continue onto the end of the array. + */ +bool secure_compare(const void *data1, const void *data2, size_t len) +{ + uint8_t result = 0; + const uint8_t *d1 = (const uint8_t *)data1; + const uint8_t *d2 = (const uint8_t *)data2; + while (len > 0) { + result |= (*d1++ ^ *d2++); + --len; + } + return (bool)((((uint16_t)0x0100) - result) >> 8); +} diff --git a/libraries/Crypto/Crypto.h b/libraries/Crypto/Crypto.h index b4ba2446..98d8d9fc 100644 --- a/libraries/Crypto/Crypto.h +++ b/libraries/Crypto/Crypto.h @@ -34,4 +34,6 @@ inline void clean(T &var) clean(&var, sizeof(T)); } +bool secure_compare(const void *data1, const void *data2, size_t len); + #endif