Botan 3.6.1
Crypto and TLS for C&
Botan::CT Namespace Reference

Classes

class  Choice
 
class  Mask
 
class  Option
 

Concepts

concept  poisonable
 
concept  unpoisonable
 
concept  ct_conditional_assignable
 

Functions

template<typename T >
constexpr CT::Mask< Tall_zeros (const T elem[], size_t len)
 
template<typename T >
constexpr Mask< Tconditional_assign_mem (Choice cnd, T *sink, const T *src, size_t elems)
 
template<typename T >
constexpr Mask< Tconditional_assign_mem (T cnd, T *sink, const T *src, size_t elems)
 
template<typename T >
constexpr Mask< Tconditional_copy_mem (Mask< T > mask, T *to, const T *from0, const T *from1, size_t elems)
 
template<typename T >
constexpr Mask< Tconditional_copy_mem (T cnd, T *to, const T *from0, const T *from1, size_t elems)
 
template<typename T >
constexpr void conditional_swap (bool cnd, T &x, T &y)
 
template<typename T >
constexpr void conditional_swap_ptr (bool cnd, T &x, T &y)
 
BOTAN_TEST_API CT::Option< size_t > copy_output (CT::Choice accept, std::span< uint8_t > output, std::span< const uint8_t > input, size_t offset)
 
size_t count_leading_zero_bytes (std::span< const uint8_t > input)
 
template<typename T >
constexpr CT::Mask< Tis_equal (const T x[], const T y[], size_t len)
 
template<typename T >
constexpr CT::Mask< Tis_not_equal (const T x[], const T y[], size_t len)
 
secure_vector< uint8_t > strip_leading_zeros (std::span< const uint8_t > input)
 
template<typename T >
constexpr T value_barrier (T x)
 
Constant Time Check Annotation Helpers
template<typename T >
constexpr void poison (const T *p, size_t n)
 
template<typename T >
constexpr void unpoison (const T *p, size_t n)
 
bool poison_has_effect ()
 
Constant Time Check Annotation Convenience overloads
template<std::integral T>
constexpr void poison (T &p)
 
template<std::integral T>
constexpr void unpoison (T &p)
 
template<ranges::spanable_range R>
requires std::is_trivially_copyable_v<std::ranges::range_value_t<R>>
constexpr void poison (R &&r)
 
template<ranges::spanable_range R>
requires std::is_trivially_copyable_v<std::ranges::range_value_t<R>>
constexpr void unpoison (R &&r)
 
template<typename T >
requires requires(const T& x) { x._const_time_poison(); }
constexpr void poison (const T &x)
 
template<typename T >
requires requires(const T& x) { x._const_time_unpoison(); }
constexpr void unpoison (const T &x)
 
template<typename T >
requires requires(const T& v) { ::Botan::CT::poison(v); }
constexpr void poison (const std::optional< T > &x)
 
template<typename T >
requires requires(const T& v) { ::Botan::CT::unpoison(v); }
constexpr void unpoison (const std::optional< T > &x)
 
Higher-level Constant Time Check Annotation Helpers
template<std::ranges::range R>
requires poisonable<std::ranges::range_value_t<R>>
constexpr void poison_range (R &&r)
 
template<std::ranges::range R>
requires unpoisonable<std::ranges::range_value_t<R>>
constexpr void unpoison_range (R &&r)
 
template<poisonable... Ts>
requires (sizeof...(Ts) > 0)
constexpr void poison_all (Ts &&... ts)
 
template<unpoisonable... Ts>
requires (sizeof...(Ts) > 0)
constexpr void unpoison_all (Ts &&... ts)
 
template<typename... Ts>
requires (sizeof...(Ts) > 0) && (poisonable<Ts> && ...) && (unpoisonable<Ts> && ...)
constexpr auto scoped_poison (const Ts &... xs)
 
template<poisonable T>
requires (std::is_rvalue_reference_v<decltype(v)>)
decltype(auto) driveby_poison (T &&v)
 
template<unpoisonable T>
requires (std::is_rvalue_reference_v<decltype(v)>)
decltype(auto) driveby_unpoison (T &&v)
 

Function Documentation

◆ all_zeros()

template<typename T >
CT::Mask< T > Botan::CT::all_zeros ( const T elem[],
size_t len )
inlineconstexpr

Definition at line 746 of file ct_utils.h.

746 {
747 T sum = 0;
748 for(size_t i = 0; i != len; ++i) {
749 sum |= elem[i];
750 }
751 return CT::Mask<T>::is_zero(sum);
752}
FE_25519 T
Definition ge.cpp:34

References Botan::CT::Mask< T >::is_zero(), and T.

Referenced by Botan::EC_Point::add(), Botan::EC_Point::add_affine(), Botan::Scalar448::bytes_are_reduced(), and Botan::Gf448Elem::is_zero().

◆ conditional_assign_mem() [1/2]

template<typename T >
Mask< T > Botan::CT::conditional_assign_mem ( Choice cnd,
T * sink,
const T * src,
size_t elems )
inlineconstexpr

Definition at line 718 of file ct_utils.h.

718 {
719 const auto mask = CT::Mask<T>::from_choice(cnd);
720 mask.select_n(sink, src, sink, elems);
721 return mask;
722}

References Botan::CT::Mask< T >::from_choice().

◆ conditional_assign_mem() [2/2]

template<typename T >
Mask< T > Botan::CT::conditional_assign_mem ( T cnd,
T * sink,
const T * src,
size_t elems )
inlineconstexpr

Definition at line 711 of file ct_utils.h.

711 {
712 const auto mask = CT::Mask<T>::expand(cnd);
713 mask.select_n(sink, src, sink, elems);
714 return mask;
715}

References Botan::CT::Mask< T >::expand().

Referenced by Botan::bigint_monty_maybe_sub(), Botan::bigint_monty_maybe_sub(), and Botan::Gf448Elem::ct_cond_assign().

◆ conditional_copy_mem() [1/2]

template<typename T >
Mask< T > Botan::CT::conditional_copy_mem ( Mask< T > mask,
T * to,
const T * from0,
const T * from1,
size_t elems )
inlineconstexpr

Definition at line 699 of file ct_utils.h.

699 {
700 mask.select_n(to, from0, from1, elems);
701 return mask;
702}
constexpr void select_n(T output[], const T x[], const T y[], size_t len) const
Definition ct_utils.h:557

References Botan::CT::Mask< T >::select_n().

Referenced by Botan::bigint_sub_abs(), conditional_copy_mem(), Botan::Kyber_KEM_Decryptor::decapsulate(), Botan::ML_KEM_Decryptor::decapsulate(), and Botan::BigInt::mod_add().

◆ conditional_copy_mem() [2/2]

template<typename T >
Mask< T > Botan::CT::conditional_copy_mem ( T cnd,
T * to,
const T * from0,
const T * from1,
size_t elems )
inlineconstexpr

Definition at line 705 of file ct_utils.h.

705 {
706 const auto mask = CT::Mask<T>::expand(cnd);
707 return CT::conditional_copy_mem(mask, to, from0, from1, elems);
708}

References conditional_copy_mem(), and Botan::CT::Mask< T >::expand().

◆ conditional_swap()

template<typename T >
void Botan::CT::conditional_swap ( bool cnd,
T & x,
T & y )
inlineconstexpr

Definition at line 725 of file ct_utils.h.

725 {
726 const auto swap = CT::Mask<T>::expand(cnd);
727
728 T t0 = swap.select(y, x);
729 T t1 = swap.select(x, y);
730 x = t0;
731 y = t1;
732}

References Botan::CT::Mask< T >::expand(), and T.

Referenced by Botan::bigint_sub_abs(), conditional_swap_ptr(), and Botan::Gf448Elem::ct_cond_swap().

◆ conditional_swap_ptr()

template<typename T >
void Botan::CT::conditional_swap_ptr ( bool cnd,
T & x,
T & y )
inlineconstexpr

Definition at line 735 of file ct_utils.h.

735 {
736 uintptr_t xp = reinterpret_cast<uintptr_t>(x);
737 uintptr_t yp = reinterpret_cast<uintptr_t>(y);
738
739 conditional_swap<uintptr_t>(cnd, xp, yp);
740
741 x = reinterpret_cast<T>(xp);
742 y = reinterpret_cast<T>(yp);
743}

References conditional_swap(), and T.

Referenced by Botan::bigint_sub_abs().

◆ copy_output()

CT::Option< size_t > Botan::CT::copy_output ( CT::Choice accept,
std::span< uint8_t > output,
std::span< const uint8_t > input,
size_t offset )

Constant time conditional copy out with offset

If accept is set and offset <= input_length, sets output[0..] to input[offset:input_length] and returns input_length - offset. The remaining bytes of output are zeroized.

Otherwise, output is zeroized, and returns an empty Ct::Option

The input and output spans may not overlap, and output must be at least as large as input.

This function attempts to avoid leaking the following to side channels

  • if accept was set or not
  • the value of offset
  • the value of input

This function leaks the length of the input

Zeroize the entire output buffer to get started

Definition at line 13 of file ct_utils.cpp.

16 {
17 // This leaks information about the input length, but this happens
18 // unavoidably since we are unable to ready any bytes besides those
19 // in input[0..n]
20 BOTAN_ARG_CHECK(output.size() >= input.size(), "Invalid span lengths");
21
22 /*
23 * We do not poison the input here because if we did we would have
24 * to unpoison it at exit. We assume instead that callers have
25 * already poisoned the input and will unpoison it at their own
26 * time.
27 */
28 CT::poison(offset);
29
30 /**
31 * Zeroize the entire output buffer to get started
32 */
33 clear_mem(output);
34
35 /*
36 * If the offset is greater than input length, then the arguments are
37 * invalid. Ideally we would throw an exception, but that leaks
38 * information about the offset. Instead treat it as if the input
39 * was invalid.
40 */
41 accept = accept && CT::Mask<size_t>::is_lte(offset, input.size()).as_choice();
42
43 /*
44 * If the input is invalid, then set offset == input_length
45 */
46 offset = CT::Mask<size_t>::from_choice(accept).select(offset, input.size());
47
48 /*
49 * Move the desired output bytes to the front using a slow (O^n)
50 * but constant time loop that does not leak the value of the offset
51 */
52 for(size_t i = 0; i != input.size(); ++i) {
53 /*
54 * If bad_input was set then we modified offset to equal the input_length.
55 * In that case, this_loop will be greater than input_length, and so is_eq
56 * mask will always be false. As a result none of the input values will be
57 * written to output.
58 *
59 * This is ignoring the possibility of integer overflow of offset + i. But
60 * for this to happen the input would have to consume nearly the entire
61 * address space.
62 */
63 const size_t this_loop = offset + i;
64
65 /*
66 start index from i rather than 0 since we know j must be >= i + offset
67 to have any effect, and starting from i does not reveal information
68 */
69 for(size_t j = i; j != input.size(); ++j) {
70 const uint8_t b = input[j];
71 const auto is_eq = CT::Mask<size_t>::is_equal(j, this_loop);
72 output[i] |= is_eq.if_set_return(b);
73 }
74 }
75
76 // This will always be zero if the input was invalid
77 const size_t output_bytes = input.size() - offset;
78
79 CT::unpoison_all(output, output_bytes);
80
81 return CT::Option<size_t>(output_bytes, accept);
82}
#define BOTAN_ARG_CHECK(expr, msg)
Definition assert.h:29
constexpr T select(T x, T y) const
Definition ct_utils.h:540
constexpr CT::Choice as_choice() const
Definition ct_utils.h:597
const SIMD_8x32 & b
constexpr void clear_mem(T *ptr, size_t n)
Definition mem_ops.h:120

References Botan::b, BOTAN_ARG_CHECK, Botan::clear_mem(), Botan::CT::Mask< T >::from_choice(), Botan::CT::Mask< T >::is_equal(), Botan::CT::Mask< T >::is_lte(), poison(), and unpoison_all().

Referenced by strip_leading_zeros().

◆ count_leading_zero_bytes()

size_t Botan::CT::count_leading_zero_bytes ( std::span< const uint8_t > input)

Referenced by strip_leading_zeros().

◆ driveby_poison()

template<poisonable T>
requires (std::is_rvalue_reference_v<decltype(v)>)
decltype(auto) Botan::CT::driveby_poison ( T && v)
nodiscard

Poisons an r-value v and forwards it as the return value.

Definition at line 226 of file ct_utils.h.

228{
229 poison(v);
230 return std::forward<T>(v);
231}
constexpr void poison(const T *p, size_t n)
Definition ct_utils.h:53

References poison().

◆ driveby_unpoison()

template<unpoisonable T>
requires (std::is_rvalue_reference_v<decltype(v)>)
decltype(auto) Botan::CT::driveby_unpoison ( T && v)
nodiscard

Unpoisons an r-value v and forwards it as the return value.

Definition at line 237 of file ct_utils.h.

239{
240 unpoison(v);
241 return std::forward<T>(v);
242}
constexpr void unpoison(const T *p, size_t n)
Definition ct_utils.h:64

References unpoison().

Referenced by Botan::Dilithium_Algos::infinity_norm_within_bound(), and Botan::HSS_LMS_PrivateKey::private_key_bits().

◆ is_equal()

template<typename T >
CT::Mask< T > Botan::CT::is_equal ( const T x[],
const T y[],
size_t len )
inlineconstexpr

Compare two arrays of equal size and return a Mask indicating if they are equal or not. The mask is set if they are identical.

Definition at line 759 of file ct_utils.h.

759 {
760 if(std::is_constant_evaluated()) {
761 T difference = 0;
762
763 for(size_t i = 0; i != len; ++i) {
764 difference = difference | (x[i] ^ y[i]);
765 }
766
767 return CT::Mask<T>::is_zero(difference);
768 } else {
769 volatile T difference = 0;
770
771 for(size_t i = 0; i != len; ++i) {
772 difference = difference | (x[i] ^ y[i]);
773 }
774
775 return CT::Mask<T>::is_zero(difference);
776 }
777}

References Botan::CT::Mask< T >::is_zero(), and T.

Referenced by Botan::argon2_check_pwhash(), botan_constant_time_compare(), Botan::Gf448Elem::bytes_are_canonical_representation(), Botan::check_bcrypt(), Botan::Ed25519_PublicKey::check_key(), Botan::X448_PrivateKey::check_key(), Botan::check_passhash9(), Botan::constant_time_compare(), Botan::FrodoMatrix::constant_time_compare(), Botan::Sodium::crypto_secretbox_open_detached(), Botan::Sodium::crypto_verify_16(), Botan::Sodium::crypto_verify_32(), Botan::Sodium::crypto_verify_64(), Botan::ct_compare_u8(), Botan::Kyber_KEM_Decryptor::decapsulate(), Botan::ML_KEM_Decryptor::decapsulate(), Botan::TLS::Session::decrypt(), Botan::CryptoBox::decrypt_bin(), Botan::ed25519_verify(), is_not_equal(), Botan::Gf448Elem::operator==(), Botan::RTSS_Share::reconstruct(), Botan::Sodium::sodium_memcmp(), Botan::TLS::Finished_12::verify(), and Botan::MessageAuthenticationCode::verify_mac_result().

◆ is_not_equal()

template<typename T >
CT::Mask< T > Botan::CT::is_not_equal ( const T x[],
const T y[],
size_t len )
inlineconstexpr

Compare two arrays of equal size and return a Mask indicating if they are equal or not. The mask is set if they differ.

Definition at line 784 of file ct_utils.h.

784 {
785 return ~CT::is_equal(x, y, len);
786}

References is_equal().

Referenced by Botan::Sodium::crypto_secretbox_xsalsa20poly1305_open(), and Botan::oaep_find_delim().

◆ poison() [1/5]

template<typename T >
requires requires(const T& v) { ::Botan::CT::poison(v); }
void Botan::CT::poison ( const std::optional< T > & x)
constexpr

Poison an optional object if it has a value.

Definition at line 146 of file ct_utils.h.

146 {
147 if(x.has_value()) {
148 poison(x.value());
149 }
150}

References poison().

◆ poison() [2/5]

template<typename T >
requires requires(const T& x) { x._const_time_poison(); }
void Botan::CT::poison ( const T & x)
constexpr

Poison a class type that provides a public _const_time_poison() method For instance: BigInt, CT::Mask<>, FrodoMatrix, ...

Definition at line 131 of file ct_utils.h.

131 {
132 x._const_time_poison();
133}

◆ poison() [3/5]

template<typename T >
void Botan::CT::poison ( const T * p,
size_t n )
inlineconstexpr

Use valgrind to mark the contents of memory as being undefined. Valgrind will accept operations which manipulate undefined values, but will warn if an undefined value is used to decided a conditional jump or a load/store address. So if we poison all of our inputs we can confirm that the operations in question are truly const time when compiled by whatever compiler is in use.

Even better, the VALGRIND_MAKE_MEM_* macros work even when the program is not run under valgrind (though with a few cycles of overhead, which is unfortunate in final binaries as these annotations tend to be used in fairly important loops).

This approach was first used in ctgrind (https://github.com/agl/ctgrind) but calling the valgrind mecheck API directly works just as well and doesn't require a custom patched valgrind.

Definition at line 53 of file ct_utils.h.

53 {
54#if defined(BOTAN_HAS_VALGRIND)
55 if(!std::is_constant_evaluated()) {
56 VALGRIND_MAKE_MEM_UNDEFINED(p, n * sizeof(T));
57 }
58#endif
59
60 BOTAN_UNUSED(p, n);
61}
#define BOTAN_UNUSED
Definition assert.h:118

References BOTAN_UNUSED, and T.

Referenced by Botan::CRYSTALS::Polynomial< Trait, D >::_const_time_poison(), Botan::CT::Mask< T >::_const_time_poison(), Botan::Dilithium_PrivateKeyInternal::_const_time_poison(), Botan::FrodoMatrix::_const_time_poison(), Botan::ANSI_X923_Padding::add_padding(), Botan::ESP_Padding::add_padding(), Botan::OneAndZeros_Padding::add_padding(), Botan::PKCS7_Padding::add_padding(), Botan::BOTAN_FUNC_ISA(), copy_output(), Botan::curve25519_donna(), driveby_poison(), Botan::Kyber_KEM_Encryptor::encapsulate(), Botan::Dilithium_Algos::expand_keypair(), Botan::Kyber_Algos::expand_keypair(), poison(), poison(), poison(), poison_all(), poison_range(), Botan::ANSI_X923_Padding::unpad(), Botan::ESP_Padding::unpad(), Botan::OneAndZeros_Padding::unpad(), and Botan::PKCS7_Padding::unpad().

◆ poison() [4/5]

template<ranges::spanable_range R>
requires std::is_trivially_copyable_v<std::ranges::range_value_t<R>>
void Botan::CT::poison ( R && r)
constexpr

Poison a contiguous buffer of trivial objects (e.g. integers and such)

Definition at line 113 of file ct_utils.h.

113 {
114 std::span s{r};
115 poison(s.data(), s.size());
116}

References poison().

◆ poison() [5/5]

template<std::integral T>
void Botan::CT::poison ( T & p)
constexpr

Poison a single integral object

Definition at line 99 of file ct_utils.h.

99 {
100 poison(&p, 1);
101}

References poison().

◆ poison_all()

template<poisonable... Ts>
requires (sizeof...(Ts) > 0)
void Botan::CT::poison_all ( Ts &&... ts)
constexpr

Poisons an arbitrary number of values in a single call. Mostly syntactic sugar to save clutter (i.e. lines-of-code).

Definition at line 195 of file ct_utils.h.

195 {
196 (poison(ts), ...);
197}

References poison().

Referenced by Botan::Dilithium_PrivateKeyInternal::_const_time_poison(), Botan::Kyber_PrivateKeyInternal::_const_time_poison(), Botan::FrodoKEM_PrivateKey::FrodoKEM_PrivateKey(), Botan::gcd(), and scoped_poison().

◆ poison_has_effect()

bool Botan::CT::poison_has_effect ( )
inline

Checks whether CT::poison() and CT::unpoison() actually have an effect.

If the build is not instrumented and/or not run using an analysis tool like valgrind, the functions are no-ops and the return value is false.

Returns
true if CT::poison() and CT::unpoison() are effective

Definition at line 82 of file ct_utils.h.

82 {
83#if defined(BOTAN_HAS_VALGRIND)
84 return RUNNING_ON_VALGRIND;
85#else
86 return false;
87#endif
88}

◆ poison_range()

template<std::ranges::range R>
requires poisonable<std::ranges::range_value_t<R>>
void Botan::CT::poison_range ( R && r)
constexpr

Poison a range of objects by calling poison on each element.

Definition at line 175 of file ct_utils.h.

175 {
176 for(const auto& v : r) {
177 poison(v);
178 }
179}

References poison().

Referenced by Botan::CRYSTALS::PolynomialMatrix< Trait >::_const_time_poison(), and Botan::CRYSTALS::PolynomialVector< Trait, D >::_const_time_poison().

◆ scoped_poison()

template<typename... Ts>
requires (sizeof...(Ts) > 0) && (poisonable<Ts> && ...) && (unpoisonable<Ts> && ...)
auto Botan::CT::scoped_poison ( const Ts &... xs)
nodiscardconstexpr

Poisons an arbitrary number of poisonable values, and unpoisons them when the returned object runs out-of-scope

Use this when you want to poison a value that remains valid longer than the scope you are currently in. For instance, a private key structure that is a member of a Signature_Operation object, that may be used for multiple signatures.

Definition at line 216 of file ct_utils.h.

216 {
217 auto scope = scoped_cleanup([&] { unpoison_all(xs...); });
218 poison_all(xs...);
219 return scope;
220}
Helper class to create a RAII-style cleanup callback.
Definition stl_util.h:354
constexpr void unpoison_all(Ts &&... ts)
Definition ct_utils.h:201

References poison_all(), and unpoison_all().

Referenced by Botan::X448_PrivateKey::check_key(), Botan::Kyber_KEM_Decryptor::decapsulate(), Botan::ML_KEM_Decryptor::decapsulate(), Botan::Kyber_Expanded_Keypair_Codec::decode_keypair(), Botan::Ed448_PrivateKey::Ed448_PrivateKey(), Botan::ML_KEM_Encryptor::encapsulate(), Botan::Kyber_Expanded_Keypair_Codec::encode_keypair(), Botan::HSS_LMS_PrivateKey::HSS_LMS_PrivateKey(), Botan::HSS_LMS_PrivateKey::HSS_LMS_PrivateKey(), Botan::HSS_LMS_PrivateKey::private_key_bits(), and Botan::X448_PrivateKey::X448_PrivateKey().

◆ strip_leading_zeros()

secure_vector< uint8_t > Botan::CT::strip_leading_zeros ( std::span< const uint8_t > input)

Definition at line 94 of file ct_utils.cpp.

94 {
95 const size_t leading_zeros = CT::count_leading_zero_bytes(input);
96
97 secure_vector<uint8_t> output(input.size());
98
99 const auto written = CT::copy_output(CT::Choice::yes(), output, input, leading_zeros);
100
101 /*
102 This is potentially not const time, depending on how std::vector is
103 implemented. But since we are always reducing length, it should
104 just amount to setting the member var holding the length.
105 */
106 output.resize(written.value_or(0));
107
108 return output;
109}
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:61

References copy_output(), count_leading_zero_bytes(), and Botan::CT::Choice::yes().

Referenced by Botan::TLS::Client_Key_Exchange::Client_Key_Exchange(), and Botan::TLS::Client_Key_Exchange::Client_Key_Exchange().

◆ unpoison() [1/5]

template<typename T >
requires requires(const T& v) { ::Botan::CT::unpoison(v); }
void Botan::CT::unpoison ( const std::optional< T > & x)
constexpr

Definition at line 154 of file ct_utils.h.

154 {
155 if(x.has_value()) {
156 unpoison(x.value());
157 }
158}

References unpoison().

◆ unpoison() [2/5]

template<typename T >
requires requires(const T& x) { x._const_time_unpoison(); }
void Botan::CT::unpoison ( const T & x)
constexpr

Definition at line 137 of file ct_utils.h.

137 {
138 x._const_time_unpoison();
139}

◆ unpoison() [3/5]

template<typename T >
void Botan::CT::unpoison ( const T * p,
size_t n )
inlineconstexpr

Definition at line 64 of file ct_utils.h.

64 {
65#if defined(BOTAN_HAS_VALGRIND)
66 if(!std::is_constant_evaluated()) {
67 VALGRIND_MAKE_MEM_DEFINED(p, n * sizeof(T));
68 }
69#endif
70
71 BOTAN_UNUSED(p, n);
72}

References BOTAN_UNUSED, and T.

Referenced by Botan::CRYSTALS::Polynomial< Trait, D >::_const_time_unpoison(), Botan::CT::Mask< T >::_const_time_unpoison(), Botan::Dilithium_PrivateKeyInternal::_const_time_unpoison(), Botan::FrodoMatrix::_const_time_unpoison(), Botan::ANSI_X923_Padding::add_padding(), Botan::ESP_Padding::add_padding(), Botan::OneAndZeros_Padding::add_padding(), Botan::PKCS7_Padding::add_padding(), Botan::bigint_cmp(), Botan::BOTAN_FUNC_ISA(), Botan::curve25519_donna(), Botan::Kyber_KEM_Decryptor::decapsulate(), Botan::ML_KEM_Decryptor::decapsulate(), driveby_unpoison(), Botan::Ed448_PrivateKey::Ed448_PrivateKey(), Botan::Kyber_Expanded_Keypair_Codec::encode_keypair(), Botan::Dilithium_Algos::expand_keypair(), Botan::Kyber_Algos::expand_keypair(), Botan::HSS_LMS_PrivateKey::HSS_LMS_PrivateKey(), Botan::HSS_LMS_PrivateKey::HSS_LMS_PrivateKey(), Botan::redc_p192(), Botan::redc_p224(), Botan::redc_p256(), Botan::redc_p384(), Botan::CT::Mask< T >::select_and_unpoison(), Botan::LMOTS_Private_Key::sign(), Botan::LMS_PrivateKey::sign_and_get_pk(), Botan::BigInt::top_bits_free(), Botan::ANSI_X923_Padding::unpad(), Botan::ESP_Padding::unpad(), Botan::OneAndZeros_Padding::unpad(), Botan::PKCS7_Padding::unpad(), unpoison(), unpoison(), unpoison(), unpoison_all(), unpoison_range(), Botan::CT::Mask< T >::unpoisoned_value(), and Botan::X448_PrivateKey::X448_PrivateKey().

◆ unpoison() [4/5]

template<ranges::spanable_range R>
requires std::is_trivially_copyable_v<std::ranges::range_value_t<R>>
void Botan::CT::unpoison ( R && r)
constexpr

Definition at line 120 of file ct_utils.h.

120 {
121 std::span s{r};
122 unpoison(s.data(), s.size());
123}

References unpoison().

◆ unpoison() [5/5]

template<std::integral T>
void Botan::CT::unpoison ( T & p)
constexpr

Definition at line 104 of file ct_utils.h.

104 {
105 unpoison(&p, 1);
106}

References unpoison().

◆ unpoison_all()

◆ unpoison_range()

template<std::ranges::range R>
requires unpoisonable<std::ranges::range_value_t<R>>
void Botan::CT::unpoison_range ( R && r)
constexpr

Definition at line 183 of file ct_utils.h.

183 {
184 for(const auto& v : r) {
185 unpoison(v);
186 }
187}

References unpoison().

Referenced by Botan::CRYSTALS::PolynomialMatrix< Trait >::_const_time_unpoison(), and Botan::CRYSTALS::PolynomialVector< Trait, D >::_const_time_unpoison().

◆ value_barrier()

template<typename T >
T Botan::CT::value_barrier ( T x)
inlineconstexpr

This function returns its argument, but (if called in a non-constexpr context) attempts to prevent the compiler from reasoning about the value or the possible range of values. Such optimizations have a way of breaking constant time code.

Definition at line 252 of file ct_utils.h.

252 {
253 if(!std::is_constant_evaluated()) {
254 /*
255 * For compilers without inline asm, is there something else we can do?
256 *
257 * For instance we could potentially launder the value through a
258 * `volatile T` or `volatile T*`. This would require some experimentation.
259 *
260 * GCC has an attribute noipa which disables interprocedural analysis, which
261 * might be useful here. However Clang does not currently support this attribute.
262 *
263 * We may want a "stronger" statement such as
264 * asm volatile("" : "+r,m"(x) : : "memory);
265 * (see https://theunixzoo.co.uk/blog/2021-10-14-preventing-optimisations.html)
266 * however the current approach seems sufficient with current compilers,
267 * and is minimally damaging with regards to degrading code generation.
268 */
269#if defined(BOTAN_USE_GCC_INLINE_ASM) && !defined(BOTAN_HAS_SANITIZER_MEMORY)
270 asm("" : "+r"(x) : /* no input */);
271#endif
272 return x;
273 } else {
274 return x;
275 }
276}

Referenced by Botan::CT::Mask< T >::expand(), Botan::CT::Mask< T >::expand_top_bit(), Botan::CT::Choice::from_int(), Botan::CT::Mask< T >::is_any_of(), Botan::CT::Mask< T >::is_equal(), Botan::CT::Mask< T >::is_within_range(), Botan::CT::Mask< T >::is_zero(), Botan::FrodoMatrix::sample(), Botan::BigInt::top_bits_free(), Botan::CT::Choice::value(), and Botan::CT::Mask< T >::value().