Botan 2.13.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

ct_utils.cpp
Go to the documentation of this file.
1 /*
2 * (C) 2018 Jack Lloyd
3 *
4 * Botan is released under the Simplified BSD License (see license.txt)
5 */
6
7 #include <botan/internal/ct_utils.h>
8
9 namespace Botan {
10
11 namespace CT {
12
13 secure_vector<uint8_t> copy_output(CT::Mask<uint8_t> bad_input,
14 const uint8_t input[],
15 size_t input_length,
16 size_t offset)
17 {
18 if(input_length == 0)
19 return secure_vector<uint8_t>();
20
21 /*
22 * Ensure at runtime that offset <= input_length. This is an invalid input,
23 * but we can't throw without using the poisoned value. Instead, if it happens,
24 * set offset to be equal to the input length (so output_bytes becomes 0 and
25 * the returned vector is empty)
26 */
27 const auto valid_offset = CT::Mask<size_t>::is_lte(offset, input_length);
28 offset = valid_offset.select(offset, input_length);
29
30 const size_t output_bytes = input_length - offset;
31
32 secure_vector<uint8_t> output(input_length);
33
34 /*
35 Move the desired output bytes to the front using a slow (O^n)
36 but constant time loop that does not leak the value of the offset
37 */
38 for(size_t i = 0; i != input_length; ++i)
39 {
40 /*
41 start index from i rather than 0 since we know j must be >= i + offset
42 to have any effect, and starting from i does not reveal information
43 */
44 for(size_t j = i; j != input_length; ++j)
45 {
46 const uint8_t b = input[j];
47 const auto is_eq = CT::Mask<size_t>::is_equal(j, offset + i);
48 output[i] |= is_eq.if_set_return(b);
49 }
50 }
51
52 bad_input.if_set_zero_out(output.data(), output.size());
53
54 /*
55 This is potentially not const time, depending on how std::vector is
56 implemented. But since we are always reducing length, it should
57 just amount to setting the member var holding the length.
58 */
59 CT::unpoison(output.data(), output.size());
60 CT::unpoison(output_bytes);
61 output.resize(output_bytes);
62 return output;
63 }
64
65 secure_vector<uint8_t> strip_leading_zeros(const uint8_t in[], size_t length)
66 {
67 size_t leading_zeros = 0;
68
69 auto only_zeros = Mask<uint8_t>::set();
70
71 for(size_t i = 0; i != length; ++i)
72 {
73 only_zeros &= CT::Mask<uint8_t>::is_zero(in[i]);
74 leading_zeros += only_zeros.if_set_return(1);
75 }
76
77 return copy_output(CT::Mask<uint8_t>::cleared(), in, length, leading_zeros);
78 }
79
80 }
81
82 }
Botan::CT::Mask
Definition: ct_utils.h:87
Botan::CT::strip_leading_zeros
secure_vector< uint8_t > strip_leading_zeros(const uint8_t in[], size_t length)
Definition: ct_utils.cpp:65
Botan::CT::Mask::is_lte
static Mask< T > is_lte(T x, T y)
Definition: ct_utils.h:173
Botan::secure_vector
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:65
Botan::CT::copy_output
secure_vector< uint8_t > copy_output(CT::Mask< uint8_t > bad_input, const uint8_t input[], size_t input_length, size_t offset)
Definition: ct_utils.cpp:13
Botan
Definition: alg_id.cpp:13
Botan::CT::unpoison
void unpoison(const T *p, size_t n)
Definition: ct_utils.h:59
Botan::CT::Mask::set
static Mask< T > set()
Definition: ct_utils.h:107
Botan::CT::Mask::if_set_zero_out
void if_set_zero_out(T buf[], size_t elems)
Definition: ct_utils.h:298
Botan::CT::Mask::is_zero
static Mask< T > is_zero(T x)
Definition: ct_utils.h:141
Botan::CT::Mask::is_equal
static Mask< T > is_equal(T x, T y)
Definition: ct_utils.h:149