14#ifndef BOTAN_CT_UTILS_H_
15#define BOTAN_CT_UTILS_H_
17#include <botan/secmem.h>
18#include <botan/internal/bit_ops.h>
22#if defined(BOTAN_HAS_VALGRIND)
23 #include <valgrind/memcheck.h>
47#if defined(BOTAN_HAS_VALGRIND)
48 if(!std::is_constant_evaluated()) {
49 VALGRIND_MAKE_MEM_UNDEFINED(p, n *
sizeof(
T));
57constexpr inline void unpoison(
const T* p,
size_t n) {
58#if defined(BOTAN_HAS_VALGRIND)
59 if(!std::is_constant_evaluated()) {
60 VALGRIND_MAKE_MEM_DEFINED(p, n *
sizeof(
T));
69#if defined(BOTAN_HAS_VALGRIND)
70 if(!std::is_constant_evaluated()) {
71 VALGRIND_MAKE_MEM_DEFINED(&p,
sizeof(
T));
88 static_assert(std::is_unsigned<T>::value && !std::is_same<bool, T>::value,
89 "Only unsigned integer types are supported by CT::Mask");
99 static_assert(
sizeof(U) >
sizeof(
T),
"sizes ok");
120 template <
typename U>
122 static_assert(
sizeof(U) <
sizeof(
T),
"sizes ok");
159 const T v_lt_l = v ^ ((v ^ l) | ((v - l) ^ v));
160 const T v_gt_u = u ^ ((u ^ v) | ((u - v) ^ u));
161 const T either = v_lt_l | v_gt_u;
168 for(
auto a : accepted) {
169 const T diff = a ^ v;
170 const T eq_zero = ~diff & (diff - 1);
251 constexpr void select_n(
T output[],
const T x[],
const T y[],
size_t len)
const {
252 for(
size_t i = 0; i != len; ++i) {
253 output[i] = this->
select(x[i], y[i]);
261 for(
size_t i = 0; i != elems; ++i) {
283 constexpr T value()
const {
return m_mask; }
286 constexpr Mask(
T m) : m_mask(m) {}
293 mask.
select_n(to, from0, from1, elems);
306 mask.select_n(sink, src, sink, elems);
314 T t0 = swap.select(y, x);
315 T t1 = swap.select(x, y);
322 uintptr_t xp =
reinterpret_cast<uintptr_t
>(x);
323 uintptr_t yp =
reinterpret_cast<uintptr_t
>(y);
325 conditional_swap<uintptr_t>(cnd, xp, yp);
327 x =
reinterpret_cast<T>(xp);
328 y =
reinterpret_cast<T>(yp);
334 for(
size_t i = 0; i != len; ++i) {
346 if(std::is_constant_evaluated()) {
349 for(
size_t i = 0; i != len; ++i) {
350 difference = difference | (x[i] ^ y[i]);
355 volatile T difference = 0;
357 for(
size_t i = 0; i != len; ++i) {
358 difference = difference | (x[i] ^ y[i]);
388 const uint8_t input[],
Mask< T > select_mask(Mask< T > x, Mask< T > y) const
constexpr T value() const
constexpr void if_set_zero_out(T buf[], size_t elems)
static constexpr Mask< T > is_lte(T x, T y)
static constexpr Mask< T > is_gte(T x, T y)
constexpr T if_not_set_return(T x) const
constexpr Mask(Mask< U > o)
static constexpr Mask< T > set()
friend Mask< T > operator|(Mask< T > x, Mask< T > y)
Mask< T > & operator^=(Mask< T > o)
constexpr T unpoisoned_value() const
constexpr void select_n(T output[], const T x[], const T y[], size_t len) const
friend Mask< T > operator^(Mask< T > x, Mask< T > y)
constexpr T if_set_return(T x) const
Mask< T > & operator=(const Mask< T > &other)=default
Mask(const Mask< T > &other)=default
static constexpr Mask< T > expand(Mask< U > m)
Mask< T > & operator&=(Mask< T > o)
constexpr T select_and_unpoison(T x, T y) const
static constexpr Mask< T > expand(T v)
constexpr T select(T x, T y) const
static constexpr Mask< T > is_within_range(T v, T l, T u)
static constexpr Mask< T > is_equal(T x, T y)
Mask< T > & operator|=(Mask< T > o)
constexpr Mask< T > operator~() const
static constexpr Mask< T > is_gt(T x, T y)
constexpr bool as_bool() const
static constexpr Mask< T > is_lt(T x, T y)
friend Mask< T > operator&(Mask< T > x, Mask< T > y)
static constexpr Mask< T > is_any_of(T v, std::initializer_list< T > accepted)
static constexpr Mask< T > is_zero(T x)
static constexpr Mask< T > cleared()
int(* final)(unsigned char *, CTX *)
constexpr void conditional_swap_ptr(bool cnd, T &x, T &y)
void poison(const T *p, size_t n)
constexpr void conditional_swap(bool cnd, T &x, T &y)
constexpr Mask< T > conditional_assign_mem(T cnd, T *sink, const T *src, size_t elems)
secure_vector< uint8_t > copy_output(CT::Mask< uint8_t > bad_input_u8, const uint8_t input[], size_t input_length, size_t offset)
secure_vector< uint8_t > strip_leading_zeros(const uint8_t in[], size_t length)
constexpr Mask< T > conditional_copy_mem(Mask< T > mask, T *to, const T *from0, const T *from1, size_t elems)
constexpr CT::Mask< T > is_not_equal(const T x[], const T y[], size_t len)
constexpr CT::Mask< T > is_equal(const T x[], const T y[], size_t len)
constexpr void unpoison(const T *p, size_t n)
constexpr CT::Mask< T > all_zeros(const T elem[], size_t len)
constexpr T choose(T mask, T a, T b)
std::vector< T, secure_allocator< T > > secure_vector
constexpr T expand_top_bit(T a)