Botan 3.9.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 return ((input_length + block_size) / block_size) * block_size;
68 }
69
70 /**
71 * @return name of the mode
72 */
73 virtual std::string name() const = 0;
74
75 /**
76 * virtual destructor
77 */
78 virtual ~BlockCipherModePaddingMethod() = default;
79
80 protected:
81 /**
82 * Applies the concrete padding to the @p last_block assuming the padding
83 * bytes should start at @p padding_start_pos within the last block.
84 *
85 * Concrete implementations of this function must ensure not to leak
86 * @p padding_start_pos via side channels. Both the bytes of @p last_block
87 * and @p padding_start_pos are passed in with CT::poison applied.
88 */
89 virtual void apply_padding(std::span<uint8_t> last_block, size_t padding_start_pos) const = 0;
90
91 /**
92 * Removes the padding from @p last_block and returns the number of data
93 * bytes. If the padding is invalid, this returns the byte length of
94 * @p last_block.
95 *
96 * Concrete implementations of this function must ensure not to leak
97 * the size or validity of the padding via side channels. The bytes of
98 * @p last_block are passed in with CT::poison applied to them.
99 */
100 virtual size_t remove_padding(std::span<const uint8_t> last_block) const = 0;
101};
102
103/**
104* PKCS#7 Padding
105*/
107 public:
108 void apply_padding(std::span<uint8_t> last_block, size_t final_block_bytes) const override;
109
110 size_t remove_padding(std::span<const uint8_t> last_block) const override;
111
112 bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); }
113
114 std::string name() const override { return "PKCS7"; }
115};
116
117/**
118* ANSI X9.23 Padding
119*/
121 public:
122 void apply_padding(std::span<uint8_t> last_block, size_t final_block_bytes) const override;
123
124 size_t remove_padding(std::span<const uint8_t> last_block) const override;
125
126 bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); }
127
128 std::string name() const override { return "X9.23"; }
129};
130
131/**
132* One And Zeros Padding (ISO/IEC 9797-1, padding method 2)
133*/
135 public:
136 void apply_padding(std::span<uint8_t> last_block, size_t final_block_bytes) const override;
137
138 size_t remove_padding(std::span<const uint8_t> last_block) const override;
139
140 bool valid_blocksize(size_t bs) const override { return (bs > 2); }
141
142 std::string name() const override { return "OneAndZeros"; }
143};
144
145/**
146* ESP Padding (RFC 4303)
147*/
149 public:
150 void apply_padding(std::span<uint8_t> last_block, size_t final_block_bytes) const override;
151
152 size_t remove_padding(std::span<const uint8_t> last_block) const override;
153
154 bool valid_blocksize(size_t bs) const override { return (bs > 2 && bs < 256); }
155
156 std::string name() const override { return "ESP"; }
157};
158
159/**
160* Null Padding
161*/
163 public:
164 void add_padding(std::span<uint8_t> /*buffer*/,
165 size_t /*final_block_bytes*/,
166 size_t /*block_size*/) const override {
167 // no padding
168 }
169
170 size_t remove_padding(std::span<const uint8_t> last_block) const override { return last_block.size(); }
171
172 bool valid_blocksize(size_t /*block_size*/) const override { return true; }
173
174 size_t output_length(size_t input_length, size_t /*block_size*/) const override { return input_length; }
175
176 std::string name() const override { return "NoPadding"; }
177
178 private:
179 void apply_padding(std::span<uint8_t> /*last_block*/, size_t /*padding_start_pos*/) const override {
180 // This class overrides add_padding() as a NOOP, so this customization
181 // point can never be called by anyone.
183 }
184};
185
186} // namespace Botan
187
188#endif
#define BOTAN_FUZZER_API
Definition api.h:65
#define BOTAN_TEST_API
Definition api.h:41
#define BOTAN_ASSERT_UNREACHABLE()
Definition assert.h:163
size_t remove_padding(std::span< const uint8_t > last_block) const override
Definition mode_pad.cpp:135
void apply_padding(std::span< uint8_t > last_block, size_t final_block_bytes) const override
Definition mode_pad.cpp:113
std::string name() const override
Definition mode_pad.h:128
bool valid_blocksize(size_t bs) const override
Definition mode_pad.h:126
virtual std::string name() const =0
static std::unique_ptr< BlockCipherModePaddingMethod > create(std::string_view algo_spec)
Definition mode_pad.cpp:20
virtual size_t remove_padding(std::span< const uint8_t > last_block) const =0
virtual bool valid_blocksize(size_t block_size) const =0
size_t unpad(std::span< const uint8_t > last_block) const
Definition mode_pad.cpp:54
virtual size_t output_length(size_t input_length, size_t block_size) const
Definition mode_pad.h:66
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:44
std::string name() const override
Definition mode_pad.h:156
bool valid_blocksize(size_t bs) const override
Definition mode_pad.h:154
size_t remove_padding(std::span< const uint8_t > last_block) const override
Definition mode_pad.cpp:219
void apply_padding(std::span< uint8_t > last_block, size_t final_block_bytes) const override
Definition mode_pad.cpp:197
std::string name() const override
Definition mode_pad.h:176
bool valid_blocksize(size_t) const override
Definition mode_pad.h:172
size_t output_length(size_t input_length, size_t) const override
Definition mode_pad.h:174
void add_padding(std::span< uint8_t >, size_t, size_t) const override
Definition mode_pad.h:164
size_t remove_padding(std::span< const uint8_t > last_block) const override
Definition mode_pad.h:170
std::string name() const override
Definition mode_pad.h:142
bool valid_blocksize(size_t bs) const override
Definition mode_pad.h:140
size_t remove_padding(std::span< const uint8_t > last_block) const override
Definition mode_pad.cpp:174
void apply_padding(std::span< uint8_t > last_block, size_t final_block_bytes) const override
Definition mode_pad.cpp:156
size_t remove_padding(std::span< const uint8_t > last_block) const override
Definition mode_pad.cpp:86
void apply_padding(std::span< uint8_t > last_block, size_t final_block_bytes) const override
Definition mode_pad.cpp:66
bool valid_blocksize(size_t bs) const override
Definition mode_pad.h:112
std::string name() const override
Definition mode_pad.h:114