Botan 3.13.0
Crypto and TLS for C&
block_cipher.h
Go to the documentation of this file.
1/*
2* Block Cipher Base Class
3* (C) 1999-2009 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#ifndef BOTAN_BLOCK_CIPHER_H_
9#define BOTAN_BLOCK_CIPHER_H_
10
11#include <botan/sym_algo.h>
12#include <memory>
13#include <string>
14#include <string_view>
15#include <vector>
16
17namespace Botan {
18
19/**
20* This class represents a block cipher object.
21*/
23 public:
24 /**
25 * Create an instance based on a name
26 * If provider is empty then best available is chosen.
27 * @param algo_spec algorithm name
28 * @param provider provider implementation to choose
29 * @return a null pointer if the algo/provider combination cannot be found
30 */
31 static std::unique_ptr<BlockCipher> create(std::string_view algo_spec, std::string_view provider = "");
32
33 /**
34 * Create an instance based on a name, or throw if the
35 * algo/provider combination cannot be found. If provider is
36 * empty then best available is chosen.
37 */
38 static std::unique_ptr<BlockCipher> create_or_throw(std::string_view algo_spec, std::string_view provider = "");
39
40 /**
41 * List the providers available for a given block cipher
42 * @return list of available providers for this algorithm, empty if not available
43 * @param algo_spec algorithm name
44 */
45 static std::vector<std::string> providers(std::string_view algo_spec);
46
47 /**
48 * Multiplier on a block cipher's native parallelism
49 *
50 * Usually notable performance gains come from further loop blocking,
51 * at least for 2 or 4x
52 */
53 static constexpr size_t ParallelismMult = 4;
54
55 /**
56 * Return the block size of this cipher
57 * @return block size of this algorithm
58 */
59 virtual size_t block_size() const = 0;
60
61 /**
62 * Return how many blocks this cipher processes in parallel
63 * @return native parallelism of this cipher in blocks
64 */
65 virtual size_t parallelism() const { return 1; }
66
67 /**
68 * Return the preferred input size for bulk processing
69 * @return preferred parallelism of this cipher in bytes
70 */
72
73 /**
74 * Return the name of the provider implementing this object
75 * @return provider information about this implementation. Default is "base",
76 * might also return "sse2", "avx2", "openssl", or some other arbitrary string.
77 */
78 virtual std::string provider() const { return "base"; }
79
80 /**
81 * Encrypt a block.
82 * @param in The plaintext block to be encrypted as a byte array.
83 * Must be of length block_size().
84 * @param out The byte array designated to hold the encrypted block.
85 * Must be of length block_size().
86 */
87 void encrypt(const uint8_t in[], uint8_t out[]) const { encrypt_n(in, out, 1); }
88
89 /**
90 * Decrypt a block.
91 * @param in The ciphertext block to be decrypted as a byte array.
92 * Must be of length block_size().
93 * @param out The byte array designated to hold the decrypted block.
94 * Must be of length block_size().
95 */
96 void decrypt(const uint8_t in[], uint8_t out[]) const { decrypt_n(in, out, 1); }
97
98 /**
99 * Encrypt a block.
100 * @param block the plaintext block to be encrypted
101 * Must be of length block_size(). Will hold the result when the function
102 * has finished.
103 */
104 void encrypt(uint8_t block[]) const { encrypt_n(block, block, 1); }
105
106 /**
107 * Decrypt a block.
108 * @param block the ciphertext block to be decrypted
109 * Must be of length block_size(). Will hold the result when the function
110 * has finished.
111 */
112 void decrypt(uint8_t block[]) const { decrypt_n(block, block, 1); }
113
114 /**
115 * Encrypt one or more blocks
116 * @param block the input/output buffer (multiple of block_size())
117 */
118 void encrypt(std::span<uint8_t> block) const {
119 return encrypt_n(block.data(), block.data(), block.size() / block_size());
120 }
121
122 /**
123 * Decrypt one or more blocks
124 * @param block the input/output buffer (multiple of block_size())
125 */
126 void decrypt(std::span<uint8_t> block) const {
127 return decrypt_n(block.data(), block.data(), block.size() / block_size());
128 }
129
130 /**
131 * Encrypt one or more blocks
132 * @param in the input buffer (multiple of block_size())
133 * @param out the output buffer (same size as in)
134 */
135 void encrypt(std::span<const uint8_t> in, std::span<uint8_t> out) const {
136 return encrypt_n(in.data(), out.data(), in.size() / block_size());
137 }
138
139 /**
140 * Decrypt one or more blocks
141 * @param in the input buffer (multiple of block_size())
142 * @param out the output buffer (same size as in)
143 */
144 void decrypt(std::span<const uint8_t> in, std::span<uint8_t> out) const {
145 return decrypt_n(in.data(), out.data(), in.size() / block_size());
146 }
147
148 /**
149 * Encrypt one or more blocks
150 * @param in the input buffer (multiple of block_size())
151 * @param out the output buffer (same size as in)
152 * @param blocks the number of blocks to process
153 */
154 virtual void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const = 0;
155
156 /**
157 * Decrypt one or more blocks
158 * @param in the input buffer (multiple of block_size())
159 * @param out the output buffer (same size as in)
160 * @param blocks the number of blocks to process
161 */
162 virtual void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const = 0;
163
164 /**
165 * Encrypt blocks in XEX mode: XOR with the mask, encrypt, then XOR again
166 * @param data the input/output buffer of blocks*block_size() bytes
167 * @param mask the mask to XOR with, same size as data
168 * @param blocks the number of blocks to process
169 */
170 BOTAN_DEPRECATED("Deprecated no replacement")
171 void encrypt_n_xex(uint8_t data[], const uint8_t mask[], size_t blocks) const {
172 const size_t BS = block_size();
173 for(size_t i = 0; i != blocks * BS; ++i) {
174 data[i] ^= mask[i];
175 }
176 encrypt_n(data, data, blocks);
177 for(size_t i = 0; i != blocks * BS; ++i) {
178 data[i] ^= mask[i];
179 }
180 }
181
182 /**
183 * Decrypt blocks in XEX mode: XOR with the mask, decrypt, then XOR again
184 * @param data the input/output buffer of blocks*block_size() bytes
185 * @param mask the mask to XOR with, same size as data
186 * @param blocks the number of blocks to process
187 */
188 BOTAN_DEPRECATED("Deprecated no replacement")
189 void decrypt_n_xex(uint8_t data[], const uint8_t mask[], size_t blocks) const {
190 const size_t BS = block_size();
191 for(size_t i = 0; i != blocks * BS; ++i) {
192 data[i] ^= mask[i];
193 }
194 decrypt_n(data, data, blocks);
195 for(size_t i = 0; i != blocks * BS; ++i) {
196 data[i] ^= mask[i];
197 }
198 }
199
200 /**
201 * Create a new uninitialized object of the same type
202 * @return new object representing the same algorithm as *this
203 */
204 virtual std::unique_ptr<BlockCipher> new_object() const = 0;
205
206 /**
207 * Create a new uninitialized object of the same type
208 * @return new object representing the same algorithm as *this
209 */
210 BlockCipher* clone() const { return this->new_object().release(); }
211};
212
213/**
214* Tweakable block ciphers allow setting a tweak which is a non-keyed
215* value which affects the encryption/decryption operation.
216*/
218 public:
219 /**
220 * Set the tweak value. This must be called after setting a key. The value
221 * persists until either set_tweak, set_key, or clear is called.
222 * Different algorithms support different tweak length(s). If called with
223 * an unsupported length, Invalid_Argument will be thrown.
224 */
225 virtual void set_tweak(const uint8_t tweak[], size_t len) = 0;
226};
227
228/**
229* Represents a block cipher with a single fixed block size
230*/
231template <size_t BS, size_t KMIN, size_t KMAX = 0, size_t KMOD = 1, typename BaseClass = BlockCipher>
232class Block_Cipher_Fixed_Params : public BaseClass {
233 public:
234 enum { BLOCK_SIZE = BS }; /* NOLINT(*-enum-size,*-use-enum-class) */
235
236 /**
237 * Return the block size of this cipher
238 * @return the fixed block size BS
239 */
240 size_t block_size() const final { return BS; }
241
242 /**
243 * Return the key lengths supported by this cipher
244 * @return the fixed key length specification
245 */
246 Key_Length_Specification key_spec() const final { return Key_Length_Specification(KMIN, KMAX, KMOD); }
247};
248
249} // namespace Botan
250
251#endif
#define BOTAN_PUBLIC_API(maj, min)
Definition api.h:21
#define BOTAN_DEPRECATED(msg)
Definition api.h:73
void encrypt(const uint8_t in[], uint8_t out[]) const
void decrypt(const uint8_t in[], uint8_t out[]) const
void decrypt(std::span< uint8_t > block) const
void decrypt(std::span< const uint8_t > in, std::span< uint8_t > out) const
static std::unique_ptr< BlockCipher > create_or_throw(std::string_view algo_spec, std::string_view provider="")
void encrypt(std::span< const uint8_t > in, std::span< uint8_t > out) const
void encrypt(std::span< uint8_t > block) const
virtual void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const =0
static std::vector< std::string > providers(std::string_view algo_spec)
static constexpr size_t ParallelismMult
virtual void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const =0
void decrypt_n_xex(uint8_t data[], const uint8_t mask[], size_t blocks) const
static std::unique_ptr< BlockCipher > create(std::string_view algo_spec, std::string_view provider="")
BlockCipher * clone() const
void encrypt_n_xex(uint8_t data[], const uint8_t mask[], size_t blocks) const
virtual std::unique_ptr< BlockCipher > new_object() const =0
virtual size_t block_size() const =0
virtual size_t parallelism() const
void decrypt(uint8_t block[]) const
virtual std::string provider() const
size_t parallel_bytes() const
void encrypt(uint8_t block[]) const
size_t block_size() const final
Key_Length_Specification key_spec() const final
virtual void set_tweak(const uint8_t tweak[], size_t len)=0