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

randombit / botan / 19012754211

02 Nov 2025 01:10PM UTC coverage: 90.677% (+0.006%) from 90.671%
19012754211

push

github

web-flow
Merge pull request #5137 from randombit/jack/clang-tidy-includes

Remove various unused includes flagged by clang-tidy misc-include-cleaner

100457 of 110786 relevant lines covered (90.68%)

12189873.8 hits per line

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

98.99
/src/lib/modes/mode_pad/mode_pad.cpp
1
/*
2
* CBC Padding Methods
3
* (C) 1999-2007,2013,2018,2020 Jack Lloyd
4
* (C) 2016 René Korthaus, Rohde & Schwarz Cybersecurity
5
* (C) 2025 René Meusel, Rohde & Schwarz Cybersecurity
6
*
7
* Botan is released under the Simplified BSD License (see license.txt)
8
*/
9

10
#include <botan/internal/mode_pad.h>
11

12
#include <botan/internal/ct_utils.h>
13

14
namespace Botan {
15

16
/**
17
* Get a block cipher padding method by name
18
*/
19
std::unique_ptr<BlockCipherModePaddingMethod> BlockCipherModePaddingMethod::create(std::string_view algo_spec) {
2,704✔
20
   if(algo_spec == "NoPadding") {
2,704✔
21
      return std::make_unique<Null_Padding>();
107✔
22
   }
23

24
   if(algo_spec == "PKCS7") {
2,597✔
25
      return std::make_unique<PKCS7_Padding>();
2,373✔
26
   }
27

28
   if(algo_spec == "OneAndZeros") {
224✔
29
      return std::make_unique<OneAndZeros_Padding>();
188✔
30
   }
31

32
   if(algo_spec == "X9.23") {
36✔
33
      return std::make_unique<ANSI_X923_Padding>();
16✔
34
   }
35

36
   if(algo_spec == "ESP") {
20✔
37
      return std::make_unique<ESP_Padding>();
20✔
38
   }
39

40
   return nullptr;
×
41
}
42

43
void BlockCipherModePaddingMethod::add_padding(std::span<uint8_t> buffer, size_t last_byte_pos, size_t BS) const {
1,768✔
44
   BOTAN_ASSERT_NOMSG(valid_blocksize(BS));
1,768✔
45
   BOTAN_ASSERT_NOMSG(last_byte_pos < BS);
1,768✔
46
   BOTAN_ASSERT_NOMSG(buffer.size() % BS == 0);
1,768✔
47
   BOTAN_ASSERT_NOMSG(buffer.size() >= BS);
1,768✔
48

49
   auto poison = CT::scoped_poison(last_byte_pos, buffer);
1,768✔
50
   apply_padding(buffer.last(BS), last_byte_pos);
1,768✔
51
}
1,768✔
52

53
size_t BlockCipherModePaddingMethod::unpad(std::span<const uint8_t> last_block) const {
3,603✔
54
   if(!valid_blocksize(last_block.size())) {
3,603✔
55
      return last_block.size();
56
   }
57

58
   auto poison = CT::scoped_poison(last_block);
3,603✔
59
   return CT::driveby_unpoison(remove_padding(last_block));
3,603✔
60
}
3,603✔
61

62
/*
63
* Pad with PKCS #7 Method
64
*/
65
void PKCS7_Padding::apply_padding(std::span<uint8_t> last_block, size_t padding_start_pos) const {
1,622✔
66
   /*
67
   Padding format is
68
   01
69
   0202
70
   030303
71
   ...
72
   */
73
   const uint8_t BS = static_cast<uint8_t>(last_block.size());
1,622✔
74
   const uint8_t start_pos = static_cast<uint8_t>(padding_start_pos);
1,622✔
75
   const uint8_t padding_len = BS - start_pos;
1,622✔
76
   for(uint8_t i = 0; i < BS; ++i) {
26,470✔
77
      auto needs_padding = CT::Mask<uint8_t>::is_gte(i, start_pos);
24,848✔
78
      last_block[i] = needs_padding.select(padding_len, last_block[i]);
24,848✔
79
   }
80
}
1,622✔
81

82
/*
83
* Unpad with PKCS #7 Method
84
*/
85
size_t PKCS7_Padding::remove_padding(std::span<const uint8_t> input) const {
1,841✔
86
   const size_t BS = input.size();
1,841✔
87
   const uint8_t last_byte = input.back();
1,841✔
88

89
   /*
90
   The input should == the block size so if the last byte exceeds
91
   that then the padding is certainly invalid
92
   */
93
   auto bad_input = CT::Mask<size_t>::is_gt(last_byte, BS);
1,841✔
94

95
   const size_t pad_pos = BS - last_byte;
1,841✔
96

97
   for(size_t i = 0; i != BS - 1; ++i) {
56,883✔
98
      // Does this byte equal the expected pad byte?
99
      const auto pad_eq = CT::Mask<size_t>::is_equal(input[i], last_byte);
55,042✔
100

101
      // Ignore values that are not part of the padding
102
      const auto in_range = CT::Mask<size_t>::is_gte(i, pad_pos);
55,042✔
103
      bad_input |= in_range & (~pad_eq);
55,042✔
104
   }
105

106
   return bad_input.select(BS, pad_pos);
1,841✔
107
}
108

109
/*
110
* Pad with ANSI X9.23 Method
111
*/
112
void ANSI_X923_Padding::apply_padding(std::span<uint8_t> last_block, size_t padding_start_pos) const {
8✔
113
   /*
114
   Padding format is
115
   01
116
   0002
117
   000003
118
   ...
119
   */
120
   const uint8_t BS = static_cast<uint8_t>(last_block.size());
8✔
121
   const uint8_t start_pos = static_cast<uint8_t>(padding_start_pos);
8✔
122
   const uint8_t padding_len = BS - start_pos;
8✔
123
   for(uint8_t i = 0; i != BS - 1; ++i) {
144✔
124
      auto needs_padding = CT::Mask<uint8_t>::is_gte(i, start_pos);
136✔
125
      last_block[i] = needs_padding.select(0, last_block[i]);
136✔
126
   }
127

128
   last_block.back() = padding_len;
8✔
129
}
8✔
130

131
/*
132
* Unpad with ANSI X9.23 Method
133
*/
134
size_t ANSI_X923_Padding::remove_padding(std::span<const uint8_t> input) const {
269✔
135
   const size_t BS = input.size();
269✔
136
   const size_t last_byte = input.back();
269✔
137

138
   auto bad_input = CT::Mask<size_t>::is_gt(last_byte, BS);
269✔
139

140
   const size_t pad_pos = BS - last_byte;
269✔
141

142
   for(size_t i = 0; i != BS - 1; ++i) {
32,841✔
143
      // Ignore values that are not part of the padding
144
      const auto in_range = CT::Mask<size_t>::is_gte(i, pad_pos);
32,572✔
145
      const auto pad_is_nonzero = CT::Mask<size_t>::expand(input[i]);
32,572✔
146
      bad_input |= pad_is_nonzero & in_range;
32,572✔
147
   }
148

149
   return bad_input.select(BS, pad_pos);
269✔
150
}
151

152
/*
153
* Pad with One and Zeros Method
154
*/
155
void OneAndZeros_Padding::apply_padding(std::span<uint8_t> last_block, size_t padding_start_pos) const {
126✔
156
   /*
157
   Padding format is
158
   80
159
   8000
160
   800000
161
   ...
162
   */
163
   for(size_t i = 0; i != last_block.size(); ++i) {
1,214✔
164
      auto needs_80 = CT::Mask<uint8_t>(CT::Mask<size_t>::is_equal(i, padding_start_pos));
1,088✔
165
      auto needs_00 = CT::Mask<uint8_t>(CT::Mask<size_t>::is_gt(i, padding_start_pos));
1,088✔
166
      last_block[i] = needs_00.select(0x00, needs_80.select(0x80, last_block[i]));
1,088✔
167
   }
168
}
126✔
169

170
/*
171
* Unpad with One and Zeros Method
172
*/
173
size_t OneAndZeros_Padding::remove_padding(std::span<const uint8_t> input) const {
1,129✔
174
   const size_t BS = input.size();
1,129✔
175
   auto bad_input = CT::Mask<uint8_t>::cleared();
1,129✔
176
   auto seen_0x80 = CT::Mask<uint8_t>::cleared();
1,129✔
177

178
   size_t pad_pos = BS - 1;
1,129✔
179

180
   for(size_t i = BS; i != 0; --i) {
502,010✔
181
      const auto is_0x80 = CT::Mask<uint8_t>::is_equal(input[i - 1], 0x80);
500,881✔
182
      const auto is_zero = CT::Mask<uint8_t>::is_zero(input[i - 1]);
500,881✔
183

184
      seen_0x80 |= is_0x80;
500,881✔
185
      pad_pos -= seen_0x80.if_not_set_return(1);
500,881✔
186
      bad_input |= ~seen_0x80 & ~is_zero;
500,881✔
187
   }
188
   bad_input |= ~seen_0x80;
1,129✔
189

190
   return CT::Mask<size_t>::expand(bad_input).select(BS, pad_pos);
1,129✔
191
}
192

193
/*
194
* Pad with ESP Padding Method
195
*/
196
void ESP_Padding::apply_padding(std::span<uint8_t> last_block, size_t padding_start_pos) const {
12✔
197
   /*
198
   Padding format is
199
   01
200
   0102
201
   010203
202
   ...
203
   */
204
   const uint8_t BS = static_cast<uint8_t>(last_block.size());
12✔
205
   const uint8_t start_pos = static_cast<uint8_t>(padding_start_pos);
12✔
206

207
   uint8_t pad_ctr = 0x01;
12✔
208
   for(uint8_t i = 0; i != BS; ++i) {
196✔
209
      auto needs_padding = CT::Mask<uint8_t>::is_gte(i, start_pos);
184✔
210
      last_block[i] = needs_padding.select(pad_ctr, last_block[i]);
184✔
211
      pad_ctr = needs_padding.select(pad_ctr + 1, pad_ctr);
212
   }
213
}
12✔
214

215
/*
216
* Unpad with ESP Padding Method
217
*/
218
size_t ESP_Padding::remove_padding(std::span<const uint8_t> input) const {
273✔
219
   const size_t BS = input.size();
273✔
220
   const uint8_t last_byte = input.back();
273✔
221

222
   auto bad_input = CT::Mask<size_t>::is_zero(last_byte) | CT::Mask<size_t>::is_gt(last_byte, BS);
273✔
223

224
   const size_t pad_pos = BS - last_byte;
273✔
225
   for(size_t i = BS - 1; i != 0; --i) {
32,893✔
226
      const auto in_range = CT::Mask<size_t>::is_gt(i, pad_pos);
32,620✔
227
      const auto incrementing = CT::Mask<size_t>::is_equal(input[i - 1], input[i] - 1);
32,620✔
228

229
      bad_input |= CT::Mask<size_t>(in_range) & ~incrementing;
32,620✔
230
   }
231

232
   return bad_input.select(BS, pad_pos);
273✔
233
}
234

235
}  // namespace Botan
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

© 2026 Coveralls, Inc