Botan 3.13.0
Crypto and TLS for C&
mode_pad.h
Go to the documentation of this file.
1/*
2* CBC Padding Methods
3* (C) 1999-2008,2013 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#ifndef BOTAN_MODE_PADDING_H_
11#define BOTAN_MODE_PADDING_H_
12
13#include <botan/assert.h>
14#include <botan/secmem.h>
15#include <memory>
16#include <span>
17#include <string>
18
19namespace Botan {
20
21/**
22* Block Cipher Mode Padding Method
23* This class is pretty limited, it cannot deal well with
24* randomized padding methods, or any padding method that
25* wants to add more than one block. For instance, it should
26* be possible to define cipher text stealing mode as simply
27* a padding mode for CBC, which happens to consume the last
28* two block (and requires use of the block cipher).
29*/
30class BOTAN_TEST_API BlockCipherModePaddingMethod /* NOLINT(*-special-member-functions) */ {
31 public:
32 /**
33 * Get a block cipher padding mode by name (eg "NoPadding" or "PKCS7")
34 * @param algo_spec block cipher padding mode name
35 */
36 static std::unique_ptr<BlockCipherModePaddingMethod> create(std::string_view algo_spec);
37
38 /**
39 * Add padding bytes to buffer.
40 * @param buffer data to pad, span must be large enough to hold the padding
41 * behind the final (partial) block
42 * @param final_block_bytes size of the final block in bytes
43 * @param block_size size of each block in bytes
44 */
45 virtual void add_padding(std::span<uint8_t> buffer, size_t final_block_bytes, size_t block_size) const;
46
47 /**
48 * Remove padding bytes from block
49 * @param last_block the last block containing the padding
50 * @return number of data bytes, or if the padding is invalid returns the
51 * byte length of @p last_block (i.e. the block size)
52 */
53 size_t unpad(std::span<const uint8_t> last_block) const;
54
55 /**
56 * @param block_size of the cipher
57 * @return valid block size for this padding mode
58 */
59 virtual bool valid_blocksize(size_t block_size) const = 0;
60
61 /**
62 * @param input_length number of bytes to be padded
63 * @param block_size size of each block in bytes
64 * @return the total number of output bytes (including the padding)
65 */
66 virtual size_t output_length(size_t input_length, size_t block_size) const;
67
68 /**
69 * @return name of the mode
70 */
71 virtual std::string name() const = 0;
72
73 /**
74 * virtual destructor
75 */
76 virtual ~BlockCipherModePaddingMethod() = default;
77
78 protected:
79 /**
80 * Applies the concrete padding to the @p last_block assuming the padding
81 * bytes should start at @p padding_start_pos within the last block.
82 *
83 * Concrete implementations of this function must ensure not to leak
84 * @p padding_start_pos via side channels. Both the bytes of @p last_block
85 * and @p padding_start_pos are passed in with CT::poison applied.
86 */
87 virtual void apply_padding(std::span<uint8_t> last_block, size_t padding_start_pos) const = 0;
88
89 /**
90 * Removes the padding from @p last_block and returns the number of data
91 * bytes. If the padding is invalid, this returns the byte length of
92 * @p last_block.
93 *
94 * Concrete implementations of this function must ensure not to leak
95 * the size or validity of the padding via side channels. The bytes of
96 * @p last_block are passed in with CT::poison applied to them.
97 */
98 virtual size_t remove_padding(std::span<const uint8_t> last_block) const = 0;
99};
100
101/**
102* PKCS#7 Padding
103*/
105 public:
106 void apply_padding(std::span<uint8_t> last_block, size_t final_block_bytes) const override;
107
108 size_t remove_padding(std::span<const uint8_t> last_block) const override;
109
110 bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); }
111
112 std::string name() const override { return "PKCS7"; }
113};
114
115/**
116* ANSI X9.23 Padding
117*/
119 public:
120 void apply_padding(std::span<uint8_t> last_block, size_t final_block_bytes) const override;
121
122 size_t remove_padding(std::span<const uint8_t> last_block) const override;
123
124 bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); }
125
126 std::string name() const override { return "X9.23"; }
127};
128
129/**
130* One And Zeros Padding (ISO/IEC 9797-1, padding method 2)
131*/
133 public:
134 void apply_padding(std::span<uint8_t> last_block, size_t final_block_bytes) const override;
135
136 size_t remove_padding(std::span<const uint8_t> last_block) const override;
137
138 bool valid_blocksize(size_t bs) const override { return (bs > 2); }
139
140 std::string name() const override { return "OneAndZeros"; }
141};
142
143/**
144* ESP Padding (RFC 4303)
145*/
147 public:
148 void apply_padding(std::span<uint8_t> last_block, size_t final_block_bytes) const override;
149
150 size_t remove_padding(std::span<const uint8_t> last_block) const override;
151
152 bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); }
153
154 std::string name() const override { return "ESP"; }
155};
156
157/**
158* Null Padding
159*/
161 public:
162 void add_padding(std::span<uint8_t> /*buffer*/,
163 size_t /*final_block_bytes*/,
164 size_t /*block_size*/) const override {
165 // no padding
166 }
167
168 size_t remove_padding(std::span<const uint8_t> last_block) const override { return last_block.size(); }
169
170 bool valid_blocksize(size_t /*block_size*/) const override { return true; }
171
172 size_t output_length(size_t input_length, size_t /*block_size*/) const override { return input_length; }
173
174 std::string name() const override { return "NoPadding"; }
175
176 private:
177 void apply_padding(std::span<uint8_t> /*last_block*/, size_t /*padding_start_pos*/) const override {
178 // This class overrides add_padding() as a NOOP, so this customization
179 // point can never be called by anyone.
181 }
182};
183
184} // namespace Botan
185
186#endif
#define BOTAN_FUZZER_API
Definition api.h:65
#define BOTAN_TEST_API
Definition api.h:41
#define BOTAN_ASSERT_UNREACHABLE()
Definition assert.h:166
size_t remove_padding(std::span< const uint8_t > last_block) const override
Definition mode_pad.cpp:141
void apply_padding(std::span< uint8_t > last_block, size_t final_block_bytes) const override
Definition mode_pad.cpp:119
std::string name() const override
Definition mode_pad.h:126
bool valid_blocksize(size_t bs) const override
Definition mode_pad.h:124
virtual std::string name() const =0
static std::unique_ptr< BlockCipherModePaddingMethod > create(std::string_view algo_spec)
Definition mode_pad.cpp:26
virtual size_t remove_padding(std::span< const uint8_t > last_block) const =0
virtual bool valid_blocksize(size_t block_size) const =0
virtual size_t output_length(size_t input_length, size_t block_size) const
Definition mode_pad.cpp:17
size_t unpad(std::span< const uint8_t > last_block) const
Definition mode_pad.cpp:60
virtual ~BlockCipherModePaddingMethod()=default
virtual void apply_padding(std::span< uint8_t > last_block, size_t padding_start_pos) const =0
virtual void add_padding(std::span< uint8_t > buffer, size_t final_block_bytes, size_t block_size) const
Definition mode_pad.cpp:50
std::string name() const override
Definition mode_pad.h:154
bool valid_blocksize(size_t bs) const override
Definition mode_pad.h:152
size_t remove_padding(std::span< const uint8_t > last_block) const override
Definition mode_pad.cpp:225
void apply_padding(std::span< uint8_t > last_block, size_t final_block_bytes) const override
Definition mode_pad.cpp:203
std::string name() const override
Definition mode_pad.h:174
bool valid_blocksize(size_t) const override
Definition mode_pad.h:170
size_t output_length(size_t input_length, size_t) const override
Definition mode_pad.h:172
void add_padding(std::span< uint8_t >, size_t, size_t) const override
Definition mode_pad.h:162
size_t remove_padding(std::span< const uint8_t > last_block) const override
Definition mode_pad.h:168
std::string name() const override
Definition mode_pad.h:140
bool valid_blocksize(size_t bs) const override
Definition mode_pad.h:138
size_t remove_padding(std::span< const uint8_t > last_block) const override
Definition mode_pad.cpp:180
void apply_padding(std::span< uint8_t > last_block, size_t final_block_bytes) const override
Definition mode_pad.cpp:162
size_t remove_padding(std::span< const uint8_t > last_block) const override
Definition mode_pad.cpp:92
void apply_padding(std::span< uint8_t > last_block, size_t final_block_bytes) const override
Definition mode_pad.cpp:72
bool valid_blocksize(size_t bs) const override
Definition mode_pad.h:110
std::string name() const override
Definition mode_pad.h:112