Botan 3.0.0
Crypto and TLS for C&
cipher_mode.h
Go to the documentation of this file.
1/*
2* Cipher Modes
3* (C) 2013,2016 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#ifndef BOTAN_CIPHER_MODE_H_
9#define BOTAN_CIPHER_MODE_H_
10
11#include <botan/concepts.h>
12#include <botan/secmem.h>
13#include <botan/sym_algo.h>
14#include <botan/exceptn.h>
15#include <string_view>
16#include <string>
17#include <span>
18#include <vector>
19
20namespace Botan {
21
22/**
23* The two possible directions for cipher filters, determining whether they
24* actually perform encryption or decryption.
25*/
26enum class Cipher_Dir : int {
29
30 ENCRYPTION BOTAN_DEPRECATED("Use Cipher_Dir::Encryption") = Encryption,
31 DECRYPTION BOTAN_DEPRECATED("Use Cipher_Dir::Decryption") = Decryption,
32};
33
34/**
35* Interface for cipher modes
36*/
38 {
39 public:
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 * Create an AEAD mode
48 * @param algo the algorithm to create
49 * @param direction specify if this should be an encryption or decryption AEAD
50 * @param provider optional specification for provider to use
51 * @return an AEAD mode or a null pointer if not available
52 */
53 static std::unique_ptr<Cipher_Mode> create(std::string_view algo,
54 Cipher_Dir direction,
55 std::string_view provider = "");
56
57 /**
58 * Create an AEAD mode, or throw
59 * @param algo the algorithm to create
60 * @param direction specify if this should be an encryption or decryption AEAD
61 * @param provider optional specification for provider to use
62 * @return an AEAD mode, or throw an exception
63 */
64 static std::unique_ptr<Cipher_Mode> create_or_throw(std::string_view algo,
65 Cipher_Dir direction,
66 std::string_view provider = "");
67
68 protected:
69 /*
70 * Prepare for processing a message under the specified nonce
71 */
72 virtual void start_msg(const uint8_t nonce[], size_t nonce_len) = 0;
73
74 /*
75 * Process message blocks
76 * Input must be a multiple of update_granularity.
77 */
78 virtual size_t process_msg(uint8_t msg[], size_t msg_len) = 0;
79
80 /*
81 * Finishes a message
82 */
83 virtual void finish_msg(secure_vector<uint8_t>& final_block, size_t offset = 0) = 0;
84
85 public:
86 /**
87 * Begin processing a message with a fresh nonce.
88 * @param nonce the per message nonce
89 */
90 void start(std::span<const uint8_t> nonce)
91 {
92 start_msg(nonce.data(), nonce.size());
93 }
94
95 /**
96 * Begin processing a message with a fresh nonce.
97 * @param nonce the per message nonce
98 * @param nonce_len length of nonce
99 */
100 void start(const uint8_t nonce[], size_t nonce_len)
101 {
102 start_msg(nonce, nonce_len);
103 }
104
105 /**
106 * Begin processing a message.
107 *
108 * The exact semantics of this depend on the mode. For many modes, the call
109 * will fail since a nonce must be provided.
110 *
111 * For certain modes such as CBC this will instead cause the last
112 * ciphertext block to be used as the nonce of the new message; doing this
113 * isn't a good idea, but some (mostly older) protocols do this.
114 */
115 void start()
116 {
117 return start_msg(nullptr, 0);
118 }
119
120 /**
121 * Process message blocks
122 *
123 * Input must be a multiple of update_granularity
124 *
125 * Processes msg in place and returns bytes written. Normally
126 * this will be either msg_len (indicating the entire message was
127 * processed) or for certain AEAD modes zero (indicating that the
128 * mode requires the entire message be processed in one pass).
129 *
130 * @param msg the message to be processed
131 * @return bytes written in-place
132 */
133 size_t process(std::span<uint8_t> msg)
134 { return this->process_msg(msg.data(), msg.size()); }
135 size_t process(uint8_t msg[], size_t msg_len)
136 { return this->process_msg(msg, msg_len); }
137
138 /**
139 * Process some data. Input must be in size update_granularity() uint8_t blocks.
140 * @param buffer in/out parameter which will possibly be resized
141 * @param offset an offset into blocks to begin processing
142 */
143 template<concepts::resizable_byte_buffer T>
144 void update(T& buffer, size_t offset = 0)
145 {
146 BOTAN_ASSERT(buffer.size() >= offset, "Offset ok");
147 const size_t written = process(std::span(buffer).subspan(offset));
148 buffer.resize(offset + written);
149 }
150
151 /**
152 * Complete processing of a message.
153 *
154 * @param final_block in/out parameter which must be at least
155 * minimum_final_size() bytes, and will be set to any final output
156 * @param offset an offset into final_block to begin processing
157 */
158 void finish(secure_vector<uint8_t>& final_block, size_t offset = 0)
159 {
160 finish_msg(final_block, offset);
161 }
162
163 /**
164 * Complete procession of a message.
165 *
166 * Note: Using this overload with anything but a Botan::secure_vector<>
167 * is copying the bytes in the in/out buffer.
168 *
169 * @param final_block in/out parameter which must be at least
170 * minimum_final_size() bytes, and will be set to any final output
171 * @param offset an offset into final_block to begin processing
172 */
173 template<concepts::resizable_byte_buffer T>
174 void finish(T& final_block, size_t offset = 0)
175 {
176 Botan::secure_vector<uint8_t> tmp(final_block.begin(), final_block.end());
177 finish_msg(tmp, offset);
178 final_block.resize(tmp.size());
179 std::copy(tmp.begin(), tmp.end(), final_block.begin());
180 }
181
182 /**
183 * Returns the size of the output if this transform is used to process a
184 * message with input_length bytes. In most cases the answer is precise.
185 * If it is not possible to precise (namely for CBC decryption) instead an
186 * upper bound is returned.
187 */
188 virtual size_t output_length(size_t input_length) const = 0;
189
190 /**
191 * @return size of required blocks to update
192 */
193 virtual size_t update_granularity() const = 0;
194
195 /**
196 * Return an ideal granularity. This will be a multiple of the result of
197 * update_granularity but may be larger. If so it indicates that better
198 * performance may be achieved by providing buffers that are at least that
199 * size.
200 */
201 virtual size_t ideal_granularity() const = 0;
202
203 /**
204 * Certain modes require the entire message be available before
205 * any processing can occur. For such modes, input will be consumed
206 * but not returned, until `finish` is called, which returns the
207 * entire message.
208 *
209 * This function returns true if this mode has this style of
210 * operation.
211 */
212 virtual bool requires_entire_message() const { return false; }
213
214 /**
215 * @return required minimium size to finalize() - may be any
216 * length larger than this.
217 */
218 virtual size_t minimum_final_size() const = 0;
219
220 /**
221 * @return the default size for a nonce
222 */
223 virtual size_t default_nonce_length() const = 0;
224
225 /**
226 * @return true iff nonce_len is a valid length for the nonce
227 */
228 virtual bool valid_nonce_length(size_t nonce_len) const = 0;
229
230 /**
231 * Resets just the message specific state and allows encrypting again under the existing key
232 */
233 virtual void reset() = 0;
234
235 /**
236 * @return true iff this mode provides authentication as well as
237 * confidentiality.
238 */
239 bool authenticated() const { return this->tag_size() > 0; }
240
241 /**
242 * @return the size of the authentication tag used (in bytes)
243 */
244 virtual size_t tag_size() const { return 0; }
245
246 /**
247 * @return provider information about this implementation. Default is "base",
248 * might also return "sse2", "avx2", "openssl", or some other arbitrary string.
249 */
250 virtual std::string provider() const { return "base"; }
251 };
252
253/**
254* Get a cipher mode by name (eg "AES-128/CBC" or "Serpent/XTS")
255* @param algo_spec cipher name
256* @param direction Cipher_Dir::Encryption or Cipher_Dir::Decryption
257* @param provider provider implementation to choose
258*/
259BOTAN_DEPRECATED("Use Cipher_Mode::create")
260inline Cipher_Mode* get_cipher_mode(std::string_view algo_spec,
261 Cipher_Dir direction,
262 std::string_view provider = "")
263 {
264 return Cipher_Mode::create(algo_spec, direction, provider).release();
265 }
266
267}
268
269#endif
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:54
virtual void start_msg(const uint8_t nonce[], size_t nonce_len)=0
static std::unique_ptr< Cipher_Mode > create(std::string_view algo, Cipher_Dir direction, std::string_view provider="")
Definition: cipher_mode.cpp:50
virtual std::string provider() const
Definition: cipher_mode.h:250
void start(std::span< const uint8_t > nonce)
Definition: cipher_mode.h:90
bool authenticated() const
Definition: cipher_mode.h:239
virtual void finish_msg(secure_vector< uint8_t > &final_block, size_t offset=0)=0
void start(const uint8_t nonce[], size_t nonce_len)
Definition: cipher_mode.h:100
void finish(secure_vector< uint8_t > &final_block, size_t offset=0)
Definition: cipher_mode.h:158
virtual size_t default_nonce_length() const =0
size_t process(uint8_t msg[], size_t msg_len)
Definition: cipher_mode.h:135
virtual void reset()=0
virtual bool requires_entire_message() const
Definition: cipher_mode.h:212
virtual size_t ideal_granularity() const =0
void update(T &buffer, size_t offset=0)
Definition: cipher_mode.h:144
size_t process(std::span< uint8_t > msg)
Definition: cipher_mode.h:133
virtual size_t output_length(size_t input_length) const =0
void finish(T &final_block, size_t offset=0)
Definition: cipher_mode.h:174
virtual size_t tag_size() const
Definition: cipher_mode.h:244
virtual size_t process_msg(uint8_t msg[], size_t msg_len)=0
virtual size_t minimum_final_size() const =0
virtual size_t update_granularity() const =0
virtual bool valid_nonce_length(size_t nonce_len) const =0
#define BOTAN_PUBLIC_API(maj, min)
Definition: compiler.h:31
FE_25519 T
Definition: ge.cpp:36
Definition: alg_id.cpp:12
Cipher_Mode * get_cipher_mode(std::string_view algo_spec, Cipher_Dir direction, std::string_view provider="")
Definition: cipher_mode.h:260
Cipher_Dir
Definition: cipher_mode.h:26
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:64
Definition: bigint.h:1092