diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/utils/ct_utils.h | 38 | ||||
-rw-r--r-- | src/tests/test_utils.cpp | 35 | ||||
-rw-r--r-- | src/tests/tests.cpp | 5 | ||||
-rw-r--r-- | src/tests/tests.h | 1 |
4 files changed, 51 insertions, 28 deletions
diff --git a/src/lib/utils/ct_utils.h b/src/lib/utils/ct_utils.h index 709b6d9e5..1a88cee20 100644 --- a/src/lib/utils/ct_utils.h +++ b/src/lib/utils/ct_utils.h @@ -95,6 +95,12 @@ inline T expand_mask(T x) } template<typename T> +inline T expand_top_bit(T a) + { + return expand_mask<T>(a >> (sizeof(T)*8-1)); + } + +template<typename T> inline T select(T mask, T from0, T from1) { return (from0 & mask) | (from1 & ~mask); @@ -119,19 +125,15 @@ inline T is_equal(T x, T y) } template<typename T> -inline T is_less(T x, T y) +inline T is_less(T a, T b) { - /* - This expands to a constant time sequence with GCC 5.2.0 on x86-64 - but something more complicated may be needed for portable const time. - */ - return expand_mask<T>(x < y); + return expand_top_bit(a ^ ((a^b) | ((a-b)^a))); } template<typename T> -inline T is_lte(T x, T y) +inline T is_lte(T a, T b) { - return expand_mask<T>(x <= y); + return CT::is_less(a, b) | CT::is_equal(a, b); } template<typename T> @@ -163,26 +165,6 @@ inline void cond_zero_mem(T cond, } } -template<typename T> -inline T expand_top_bit(T a) - { - return expand_mask<T>(a >> (sizeof(T)*8-1)); - } - -template<typename T> -inline T max(T a, T b) - { - const T a_larger = b - a; // negative if a is larger - return select(expand_top_bit(a), a, b); - } - -template<typename T> -inline T min(T a, T b) - { - const T a_larger = b - a; // negative if a is larger - return select(expand_top_bit(b), b, a); - } - inline secure_vector<uint8_t> strip_leading_zeros(const uint8_t in[], size_t length) { size_t leading_zeros = 0; diff --git a/src/tests/test_utils.cpp b/src/tests/test_utils.cpp index 0ca79b6e9..d4035de65 100644 --- a/src/tests/test_utils.cpp +++ b/src/tests/test_utils.cpp @@ -13,6 +13,7 @@ #include <botan/calendar.h> #include <botan/internal/rounding.h> #include <botan/internal/poly_dbl.h> +#include <botan/internal/ct_utils.h> #include <botan/charset.h> #include <botan/parsing.h> @@ -64,10 +65,44 @@ class Utility_Function_Tests : public Text_Based_Test std::vector<Test::Result> results; results.push_back(test_loadstore()); + results.push_back(test_ct_utils()); return results; } + Test::Result test_ct_utils() + { + Test::Result result("CT utils"); + + result.test_eq_sz("CT::is_zero8", Botan::CT::is_zero<uint8_t>(0), 0xFF); + result.test_eq_sz("CT::is_zero8", Botan::CT::is_zero<uint8_t>(1), 0x00); + result.test_eq_sz("CT::is_zero8", Botan::CT::is_zero<uint8_t>(0xFF), 0x00); + + result.test_eq_sz("CT::is_zero16", Botan::CT::is_zero<uint16_t>(0), 0xFFFF); + result.test_eq_sz("CT::is_zero16", Botan::CT::is_zero<uint16_t>(1), 0x0000); + result.test_eq_sz("CT::is_zero16", Botan::CT::is_zero<uint16_t>(0xFF), 0x0000); + + result.test_eq_sz("CT::is_zero32", Botan::CT::is_zero<uint32_t>(0), 0xFFFFFFFF); + result.test_eq_sz("CT::is_zero32", Botan::CT::is_zero<uint32_t>(1), 0x00000000); + result.test_eq_sz("CT::is_zero32", Botan::CT::is_zero<uint32_t>(0xFF), 0x00000000); + + result.test_eq_sz("CT::is_less8", Botan::CT::is_less<uint8_t>(0, 1), 0xFF); + result.test_eq_sz("CT::is_less8", Botan::CT::is_less<uint8_t>(1, 0), 0x00); + result.test_eq_sz("CT::is_less8", Botan::CT::is_less<uint8_t>(0xFF, 5), 0x00); + + result.test_eq_sz("CT::is_less16", Botan::CT::is_less<uint16_t>(0, 1), 0xFFFF); + result.test_eq_sz("CT::is_less16", Botan::CT::is_less<uint16_t>(1, 0), 0x0000); + result.test_eq_sz("CT::is_less16", Botan::CT::is_less<uint16_t>(0xFFFF, 5), 0x0000); + + result.test_eq_sz("CT::is_less32", Botan::CT::is_less<uint32_t>(0, 1), 0xFFFFFFFF); + result.test_eq_sz("CT::is_less32", Botan::CT::is_less<uint32_t>(1, 0), 0x00000000); + result.test_eq_sz("CT::is_less32", Botan::CT::is_less<uint32_t>(0xFFFF5, 5), 0x00000000); + result.test_eq_sz("CT::is_less32", Botan::CT::is_less<uint32_t>(0xFFFFFFFF, 5), 0x00000000); + result.test_eq_sz("CT::is_less32", Botan::CT::is_less<uint32_t>(5, 0xFFFFFFFF), 0xFFFFFFFF); + + return result; + } + Test::Result test_loadstore() { Test::Result result("Util load/store"); diff --git a/src/tests/tests.cpp b/src/tests/tests.cpp index 930d7c623..af2cd5909 100644 --- a/src/tests/tests.cpp +++ b/src/tests/tests.cpp @@ -233,6 +233,11 @@ bool Test::Result::test_eq(const std::string& what, size_t produced, size_t expe return test_is_eq(what, produced, expected); } +bool Test::Result::test_eq_sz(const std::string& what, size_t produced, size_t expected) + { + return test_is_eq(what, produced, expected); + } + bool Test::Result::test_eq(const std::string& what, OctetString produced, OctetString expected) { std::ostringstream out; diff --git a/src/tests/tests.h b/src/tests/tests.h index 0673705d9..16b968bd4 100644 --- a/src/tests/tests.h +++ b/src/tests/tests.h @@ -203,6 +203,7 @@ class Test bool test_eq(const std::string& what, bool produced, bool expected); bool test_eq(const std::string& what, size_t produced, size_t expected); + bool test_eq_sz(const std::string& what, size_t produced, size_t expected); bool test_eq(const std::string& what, OctetString produced, OctetString expected); |