• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 5079590438

25 May 2023 12:28PM UTC coverage: 92.228% (+0.5%) from 91.723%
5079590438

Pull #3502

github

Pull Request #3502: Apply clang-format to the codebase

75589 of 81959 relevant lines covered (92.23%)

12139530.51 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.0
/src/lib/utils/ct_utils.cpp
1
/*
2
* (C) 2018,2021 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::CT {
10

11
secure_vector<uint8_t> copy_output(CT::Mask<uint8_t> bad_input_u8,
4,961✔
12
                                   const uint8_t input[],
13
                                   size_t input_length,
14
                                   size_t offset) {
15
   /*
16
   * We do not poison the input here because if we did we would have
17
   * to unpoison it at exit. We assume instead that callers have
18
   * already poisoned the input and will unpoison it at their own
19
   * time.
20
   */
21
   CT::poison(&offset, sizeof(size_t));
4,961✔
22

23
   secure_vector<uint8_t> output(input_length);
4,961✔
24

25
   auto bad_input = CT::Mask<size_t>::expand(bad_input_u8);
4,961✔
26

27
   /*
28
   * If the offset is greater than input_length then the arguments are
29
   * invalid. Ideally we would through an exception but that leaks
30
   * information about the offset. Instead treat it as if the input
31
   * was invalid.
32
   */
33
   bad_input |= CT::Mask<size_t>::is_gt(offset, input_length);
4,961✔
34

35
   /*
36
   * If the input is invalid, then set offset == input_length as a result
37
   * at the end we will set output_bytes == 0 causing the final result to
38
   * be an empty vector.
39
   */
40
   offset = bad_input.select(input_length, offset);
4,961✔
41

42
   /*
43
   Move the desired output bytes to the front using a slow (O^n)
44
   but constant time loop that does not leak the value of the offset
45
   */
46
   for(size_t i = 0; i != input_length; ++i) {
1,073,876✔
47
      /*
48
      * If bad_input was set then we modified offset to equal the input_length.
49
      * In that case, this_loop will be greater than input_length, and so is_eq
50
      * mask will always be false. As a result none of the input values will be
51
      * written to output.
52
      *
53
      * This is ignoring the possibility of integer overflow of offset + i. But
54
      * for this to happen the input would have to consume nearly the entire
55
      * address space, and we just allocated an output buffer of equal size.
56
      */
57
      const size_t this_loop = offset + i;
1,068,915✔
58

59
      /*
60
      start index from i rather than 0 since we know j must be >= i + offset
61
      to have any effect, and starting from i does not reveal information
62
      */
63
      for(size_t j = i; j != input_length; ++j) {
256,805,016✔
64
         const uint8_t b = input[j];
255,736,101✔
65
         const auto is_eq = CT::Mask<size_t>::is_equal(j, this_loop);
255,736,101✔
66
         output[i] |= is_eq.if_set_return(b);
255,736,101✔
67
      }
68
   }
69

70
   const size_t output_bytes = input_length - offset;
4,961✔
71

72
   CT::unpoison(output.data(), output.size());
4,961✔
73
   CT::unpoison(output_bytes);
4,961✔
74

75
   /*
76
   This is potentially not const time, depending on how std::vector is
77
   implemented. But since we are always reducing length, it should
78
   just amount to setting the member var holding the length.
79
   */
80
   output.resize(output_bytes);
4,961✔
81
   return output;
4,961✔
82
}
×
83

84
secure_vector<uint8_t> strip_leading_zeros(const uint8_t in[], size_t length) {
2,110✔
85
   size_t leading_zeros = 0;
2,110✔
86

87
   auto only_zeros = Mask<uint8_t>::set();
2,110✔
88

89
   for(size_t i = 0; i != length; ++i) {
250,033✔
90
      only_zeros &= CT::Mask<uint8_t>::is_zero(in[i]);
247,923✔
91
      leading_zeros += only_zeros.if_set_return(1);
247,923✔
92
   }
93

94
   return copy_output(CT::Mask<uint8_t>::cleared(), in, length, leading_zeros);
2,110✔
95
}
96

97
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc