Botan  2.6.0
Crypto and TLS for C++11
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/secmem.h>
12 #include <botan/key_spec.h>
13 #include <botan/exceptn.h>
14 #include <botan/symkey.h>
15 #include <string>
16 #include <vector>
17 
18 namespace Botan {
19 
20 /**
21 * The two possible directions for cipher filters, determining whether they
22 * actually perform encryption or decryption.
23 */
25 
26 /**
27 * Interface for cipher modes
28 */
30  {
31  public:
32  virtual ~Cipher_Mode() = default;
33 
34  /**
35  * @return list of available providers for this algorithm, empty if not available
36  * @param algo_spec algorithm name
37  */
38  static std::vector<std::string> providers(const std::string& algo_spec);
39 
40  /**
41  * Create an AEAD mode
42  * @param algo the algorithm to create
43  * @param direction specify if this should be an encryption or decryption AEAD
44  * @param provider optional specification for provider to use
45  * @return an AEAD mode or a null pointer if not available
46  */
47  static std::unique_ptr<Cipher_Mode> create(const std::string& algo,
48  Cipher_Dir direction,
49  const std::string& provider = "");
50 
51  /**
52  * Create an AEAD mode, or throw
53  * @param algo the algorithm to create
54  * @param direction specify if this should be an encryption or decryption AEAD
55  * @param provider optional specification for provider to use
56  * @return an AEAD mode, or throw an exception
57  */
58  static std::unique_ptr<Cipher_Mode> create_or_throw(const std::string& algo,
59  Cipher_Dir direction,
60  const std::string& provider = "");
61 
62  /*
63  * Prepare for processing a message under the specified nonce
64  */
65  virtual void start_msg(const uint8_t nonce[], size_t nonce_len) = 0;
66 
67  /**
68  * Begin processing a message.
69  * @param nonce the per message nonce
70  */
71  template<typename Alloc>
72  void start(const std::vector<uint8_t, Alloc>& nonce)
73  {
74  start_msg(nonce.data(), nonce.size());
75  }
76 
77  /**
78  * Begin processing a message.
79  * @param nonce the per message nonce
80  * @param nonce_len length of nonce
81  */
82  void start(const uint8_t nonce[], size_t nonce_len)
83  {
84  start_msg(nonce, nonce_len);
85  }
86 
87  /**
88  * Begin processing a message.
89  */
90  void start()
91  {
92  return start_msg(nullptr, 0);
93  }
94 
95  /**
96  * Process message blocks
97  *
98  * Input must be a multiple of update_granularity
99  *
100  * Processes msg in place and returns bytes written. Normally
101  * this will be either msg_len (indicating the entire message was
102  * processed) or for certain AEAD modes zero (indicating that the
103  * mode requires the entire message be processed in one pass).
104  *
105  * @param msg the message to be processed
106  * @param msg_len length of the message in bytes
107  */
108  virtual size_t process(uint8_t msg[], size_t msg_len) = 0;
109 
110  /**
111  * Process some data. Input must be in size update_granularity() uint8_t blocks.
112  * @param buffer in/out parameter which will possibly be resized
113  * @param offset an offset into blocks to begin processing
114  */
115  void update(secure_vector<uint8_t>& buffer, size_t offset = 0)
116  {
117  BOTAN_ASSERT(buffer.size() >= offset, "Offset ok");
118  uint8_t* buf = buffer.data() + offset;
119  const size_t buf_size = buffer.size() - offset;
120 
121  const size_t written = process(buf, buf_size);
122  buffer.resize(offset + written);
123  }
124 
125  /**
126  * Complete processing of a message.
127  *
128  * @param final_block in/out parameter which must be at least
129  * minimum_final_size() bytes, and will be set to any final output
130  * @param offset an offset into final_block to begin processing
131  */
132  virtual void finish(secure_vector<uint8_t>& final_block, size_t offset = 0) = 0;
133 
134  /**
135  * Returns the size of the output if this transform is used to process a
136  * message with input_length bytes. Will throw if unable to give a precise
137  * answer.
138  */
139  virtual size_t output_length(size_t input_length) const = 0;
140 
141  /**
142  * @return size of required blocks to update
143  */
144  virtual size_t update_granularity() const = 0;
145 
146  /**
147  * @return required minimium size to finalize() - may be any
148  * length larger than this.
149  */
150  virtual size_t minimum_final_size() const = 0;
151 
152  /**
153  * @return the default size for a nonce
154  */
155  virtual size_t default_nonce_length() const = 0;
156 
157  /**
158  * @return true iff nonce_len is a valid length for the nonce
159  */
160  virtual bool valid_nonce_length(size_t nonce_len) const = 0;
161 
162  virtual std::string name() const = 0;
163 
164  /**
165  * Zeroise all state
166  * See also reset_msg()
167  */
168  virtual void clear() = 0;
169 
170  /**
171  * Resets just the message specific state and allows encrypting again under the existing key
172  */
173  virtual void reset() = 0;
174 
175  /**
176  * @return true iff this mode provides authentication as well as
177  * confidentiality.
178  */
179  virtual bool authenticated() const { return false; }
180 
181  /**
182  * @return the size of the authentication tag used (in bytes)
183  */
184  virtual size_t tag_size() const { return 0; }
185 
186  /**
187  * @return object describing limits on key size
188  */
189  virtual Key_Length_Specification key_spec() const = 0;
190 
191  /**
192  * Check whether a given key length is valid for this algorithm.
193  * @param length the key length to be checked.
194  * @return true if the key length is valid.
195  */
196  bool valid_keylength(size_t length) const
197  {
198  return key_spec().valid_keylength(length);
199  }
200 
201  /**
202  * Set the symmetric key of this transform
203  * @param key contains the key material
204  */
205  template<typename Alloc>
206  void set_key(const std::vector<uint8_t, Alloc>& key)
207  {
208  set_key(key.data(), key.size());
209  }
210 
211  /**
212  * Set the symmetric key of this transform
213  * @param key contains the key material
214  */
215  void set_key(const SymmetricKey& key)
216  {
217  set_key(key.begin(), key.length());
218  }
219 
220  /**
221  * Set the symmetric key of this transform
222  * @param key contains the key material
223  * @param length in bytes of key param
224  */
225  void set_key(const uint8_t key[], size_t length)
226  {
227  if(!valid_keylength(length))
228  throw Invalid_Key_Length(name(), length);
229  key_schedule(key, length);
230  }
231 
232  /**
233  * @return provider information about this implementation. Default is "base",
234  * might also return "sse2", "avx2", "openssl", or some other arbitrary string.
235  */
236  virtual std::string provider() const { return "base"; }
237 
238  private:
239  virtual void key_schedule(const uint8_t key[], size_t length) = 0;
240  };
241 
242 /**
243 * Get a cipher mode by name (eg "AES-128/CBC" or "Serpent/XTS")
244 * @param algo_spec cipher name
245 * @param direction ENCRYPTION or DECRYPTION
246 * @param provider provider implementation to choose
247 */
248 inline Cipher_Mode* get_cipher_mode(const std::string& algo_spec,
249  Cipher_Dir direction,
250  const std::string& provider = "")
251  {
252  return Cipher_Mode::create(algo_spec, direction, provider).release();
253  }
254 
255 }
256 
257 #endif
virtual bool authenticated() const
Definition: cipher_mode.h:179
void set_key(const uint8_t key[], size_t length)
Definition: cipher_mode.h:225
void update(secure_vector< uint8_t > &buffer, size_t offset=0)
Definition: cipher_mode.h:115
#define BOTAN_PUBLIC_API(maj, min)
Definition: compiler.h:27
virtual size_t tag_size() const
Definition: cipher_mode.h:184
void start(const std::vector< uint8_t, Alloc > &nonce)
Definition: cipher_mode.h:72
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:30
void start(const uint8_t nonce[], size_t nonce_len)
Definition: cipher_mode.h:82
Definition: alg_id.cpp:13
Cipher_Mode * get_cipher_mode(const std::string &algo_spec, Cipher_Dir direction, const std::string &provider="")
Definition: cipher_mode.h:248
size_t length() const
Definition: symkey.h:25
const uint8_t * begin() const
Definition: symkey.h:36
void set_key(const SymmetricKey &key)
Definition: cipher_mode.h:215
void set_key(const std::vector< uint8_t, Alloc > &key)
Definition: cipher_mode.h:206
static std::unique_ptr< Cipher_Mode > create(const std::string &algo, Cipher_Dir direction, const std::string &provider="")
Definition: cipher_mode.cpp:50
Cipher_Dir
Definition: cipher_mode.h:24
virtual std::string provider() const
Definition: cipher_mode.h:236
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:88
bool valid_keylength(size_t length) const
Definition: cipher_mode.h:196