Botan 3.8.1
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 * @return list of available providers for this algorithm, empty if not available
42 * @param algo_spec algorithm name
43 */
44 static std::vector<std::string> providers(std::string_view algo_spec);
45
46 /**
47 * Multiplier on a block cipher's native parallelism
48 *
49 * Usually notable performance gains come from further loop blocking,
50 * at least for 2 or 4x
51 */
52 static constexpr size_t ParallelismMult = 4;
53
54 /**
55 * @return block size of this algorithm
56 */
57 virtual size_t block_size() const = 0;
58
59 /**
60 * @return native parallelism of this cipher in blocks
61 */
62 virtual size_t parallelism() const { return 1; }
63
64 /**
65 * @return prefererred parallelism of this cipher in bytes
66 */
68
69 /**
70 * @return provider information about this implementation. Default is "base",
71 * might also return "sse2", "avx2", "openssl", or some other arbitrary string.
72 */
73 virtual std::string provider() const { return "base"; }
74
75 /**
76 * Encrypt a block.
77 * @param in The plaintext block to be encrypted as a byte array.
78 * Must be of length block_size().
79 * @param out The byte array designated to hold the encrypted block.
80 * Must be of length block_size().
81 */
82 void encrypt(const uint8_t in[], uint8_t out[]) const { encrypt_n(in, out, 1); }
83
84 /**
85 * Decrypt a block.
86 * @param in The ciphertext block to be decypted as a byte array.
87 * Must be of length block_size().
88 * @param out The byte array designated to hold the decrypted block.
89 * Must be of length block_size().
90 */
91 void decrypt(const uint8_t in[], uint8_t out[]) const { decrypt_n(in, out, 1); }
92
93 /**
94 * Encrypt a block.
95 * @param block the plaintext block to be encrypted
96 * Must be of length block_size(). Will hold the result when the function
97 * has finished.
98 */
99 void encrypt(uint8_t block[]) const { encrypt_n(block, block, 1); }
100
101 /**
102 * Decrypt a block.
103 * @param block the ciphertext block to be decrypted
104 * Must be of length block_size(). Will hold the result when the function
105 * has finished.
106 */
107 void decrypt(uint8_t block[]) const { decrypt_n(block, block, 1); }
108
109 /**
110 * Encrypt one or more blocks
111 * @param block the input/output buffer (multiple of block_size())
112 */
113 void encrypt(std::span<uint8_t> block) const {
114 return encrypt_n(block.data(), block.data(), block.size() / block_size());
115 }
116
117 /**
118 * Decrypt one or more blocks
119 * @param block the input/output buffer (multiple of block_size())
120 */
121 void decrypt(std::span<uint8_t> block) const {
122 return decrypt_n(block.data(), block.data(), block.size() / block_size());
123 }
124
125 /**
126 * Encrypt one or more blocks
127 * @param in the input buffer (multiple of block_size())
128 * @param out the output buffer (same size as in)
129 */
130 void encrypt(std::span<const uint8_t> in, std::span<uint8_t> out) const {
131 return encrypt_n(in.data(), out.data(), in.size() / block_size());
132 }
133
134 /**
135 * Decrypt one or more blocks
136 * @param in the input buffer (multiple of block_size())
137 * @param out the output buffer (same size as in)
138 */
139 void decrypt(std::span<const uint8_t> in, std::span<uint8_t> out) const {
140 return decrypt_n(in.data(), out.data(), in.size() / block_size());
141 }
142
143 /**
144 * Encrypt one or more blocks
145 * @param in the input buffer (multiple of block_size())
146 * @param out the output buffer (same size as in)
147 * @param blocks the number of blocks to process
148 */
149 virtual void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const = 0;
150
151 /**
152 * Decrypt one or more blocks
153 * @param in the input buffer (multiple of block_size())
154 * @param out the output buffer (same size as in)
155 * @param blocks the number of blocks to process
156 */
157 virtual void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const = 0;
158
159 BOTAN_DEPRECATED("Deprecated no replacement")
160 void encrypt_n_xex(uint8_t data[], const uint8_t mask[], size_t blocks) const {
161 const size_t BS = block_size();
162 for(size_t i = 0; i != blocks * BS; ++i) {
163 data[i] ^= mask[i];
164 }
165 encrypt_n(data, data, blocks);
166 for(size_t i = 0; i != blocks * BS; ++i) {
167 data[i] ^= mask[i];
168 }
169 }
170
171 BOTAN_DEPRECATED("Deprecated no replacement")
172 void decrypt_n_xex(uint8_t data[], const uint8_t mask[], size_t blocks) const {
173 const size_t BS = block_size();
174 for(size_t i = 0; i != blocks * BS; ++i) {
175 data[i] ^= mask[i];
176 }
177 decrypt_n(data, data, blocks);
178 for(size_t i = 0; i != blocks * BS; ++i) {
179 data[i] ^= mask[i];
180 }
181 }
182
183 /**
184 * @return new object representing the same algorithm as *this
185 */
186 virtual std::unique_ptr<BlockCipher> new_object() const = 0;
187
188 BlockCipher* clone() const { return this->new_object().release(); }
189
190 ~BlockCipher() override = default;
191};
192
193/**
194* Tweakable block ciphers allow setting a tweak which is a non-keyed
195* value which affects the encryption/decryption operation.
196*/
198 public:
199 /**
200 * Set the tweak value. This must be called after setting a key. The value
201 * persists until either set_tweak, set_key, or clear is called.
202 * Different algorithms support different tweak length(s). If called with
203 * an unsupported length, Invalid_Argument will be thrown.
204 */
205 virtual void set_tweak(const uint8_t tweak[], size_t len) = 0;
206};
207
208/**
209* Represents a block cipher with a single fixed block size
210*/
211template <size_t BS, size_t KMIN, size_t KMAX = 0, size_t KMOD = 1, typename BaseClass = BlockCipher>
212class Block_Cipher_Fixed_Params : public BaseClass {
213 public:
214 enum { BLOCK_SIZE = BS };
215
216 size_t block_size() const final { return BS; }
217
218 Key_Length_Specification key_spec() const final { return Key_Length_Specification(KMIN, KMAX, KMOD); }
219};
220
221} // namespace Botan
222
223#endif
#define BOTAN_PUBLIC_API(maj, min)
Definition api.h:19
#define BOTAN_DEPRECATED(msg)
Definition api.h:59
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="")
~BlockCipher() override=default
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