aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/utils/ct_utils.h38
-rw-r--r--src/tests/test_utils.cpp35
-rw-r--r--src/tests/tests.cpp5
-rw-r--r--src/tests/tests.h1
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);