Coverage Report

Created: 2023-02-13 06:21

/src/botan/build/include/botan/cipher_mode.h
Line
Count
Source (jump to first uncovered line)
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/sym_algo.h>
13
#include <botan/exceptn.h>
14
#include <string>
15
#include <vector>
16
17
namespace Botan {
18
19
/**
20
* The two possible directions for cipher filters, determining whether they
21
* actually perform encryption or decryption.
22
*/
23
enum class Cipher_Dir : int {
24
   Encryption,
25
   Decryption,
26
27
   ENCRYPTION BOTAN_DEPRECATED("Use Cipher_Dir::Encryption") = Encryption,
28
   DECRYPTION BOTAN_DEPRECATED("Use Cipher_Dir::Decryption") = Decryption,
29
};
30
31
/**
32
* Interface for cipher modes
33
*/
34
class BOTAN_PUBLIC_API(2,0) Cipher_Mode : public SymmetricAlgorithm
35
   {
36
   public:
37
      /**
38
      * @return list of available providers for this algorithm, empty if not available
39
      * @param algo_spec algorithm name
40
      */
41
      static std::vector<std::string> providers(const std::string& algo_spec);
42
43
      /**
44
      * Create an AEAD mode
45
      * @param algo the algorithm to create
46
      * @param direction specify if this should be an encryption or decryption AEAD
47
      * @param provider optional specification for provider to use
48
      * @return an AEAD mode or a null pointer if not available
49
      */
50
      static std::unique_ptr<Cipher_Mode> create(const std::string& algo,
51
                                                 Cipher_Dir direction,
52
                                                 const std::string& provider = "");
53
54
      /**
55
      * Create an AEAD mode, or throw
56
      * @param algo the algorithm to create
57
      * @param direction specify if this should be an encryption or decryption AEAD
58
      * @param provider optional specification for provider to use
59
      * @return an AEAD mode, or throw an exception
60
      */
61
      static std::unique_ptr<Cipher_Mode> create_or_throw(const std::string& algo,
62
                                                          Cipher_Dir direction,
63
                                                          const std::string& provider = "");
64
65
      /*
66
      * Prepare for processing a message under the specified nonce
67
      */
68
      virtual void start_msg(const uint8_t nonce[], size_t nonce_len) = 0;
69
70
      /**
71
      * Begin processing a message with a fresh nonce.
72
      * @param nonce the per message nonce
73
      */
74
      template<typename Alloc>
75
      void start(const std::vector<uint8_t, Alloc>& nonce)
76
1.20k
         {
77
1.20k
         start_msg(nonce.data(), nonce.size());
78
1.20k
         }
void Botan::Cipher_Mode::start<std::__1::allocator<unsigned char> >(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > const&)
Line
Count
Source
76
983
         {
77
983
         start_msg(nonce.data(), nonce.size());
78
983
         }
void Botan::Cipher_Mode::start<Botan::secure_allocator<unsigned char> >(std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&)
Line
Count
Source
76
217
         {
77
217
         start_msg(nonce.data(), nonce.size());
78
217
         }
79
80
      /**
81
      * Begin processing a message with a fresh nonce.
82
      * @param nonce the per message nonce
83
      * @param nonce_len length of nonce
84
      */
85
      void start(const uint8_t nonce[], size_t nonce_len)
86
0
         {
87
0
         start_msg(nonce, nonce_len);
88
0
         }
89
90
      /**
91
      * Begin processing a message.
92
      *
93
      * The exact semantics of this depend on the mode. For many modes, the call
94
      * will fail since a nonce must be provided.
95
      *
96
      * For certain modes such as CBC this will instead cause the last
97
      * ciphertext block to be used as the nonce of the new message; doing this
98
      * isn't a good idea, but some (mostly older) protocols do this.
99
      */
100
      void start()
101
0
         {
102
0
         return start_msg(nullptr, 0);
103
0
         }
104
105
      /**
106
      * Process message blocks
107
      *
108
      * Input must be a multiple of update_granularity
109
      *
110
      * Processes msg in place and returns bytes written. Normally
111
      * this will be either msg_len (indicating the entire message was
112
      * processed) or for certain AEAD modes zero (indicating that the
113
      * mode requires the entire message be processed in one pass).
114
      *
115
      * @param msg the message to be processed
116
      * @param msg_len length of the message in bytes
117
      */
118
      virtual size_t process(uint8_t msg[], size_t msg_len) = 0;
119
120
      /**
121
      * Process some data. Input must be in size update_granularity() uint8_t blocks.
122
      * @param buffer in/out parameter which will possibly be resized
123
      * @param offset an offset into blocks to begin processing
124
      */
125
      void update(secure_vector<uint8_t>& buffer, size_t offset = 0)
126
306
         {
127
306
         BOTAN_ASSERT(buffer.size() >= offset, "Offset ok");
128
306
         uint8_t* buf = buffer.data() + offset;
129
306
         const size_t buf_size = buffer.size() - offset;
130
131
306
         const size_t written = process(buf, buf_size);
132
306
         buffer.resize(offset + written);
133
306
         }
134
135
      /**
136
      * Complete processing of a message.
137
      *
138
      * @param final_block in/out parameter which must be at least
139
      *        minimum_final_size() bytes, and will be set to any final output
140
      * @param offset an offset into final_block to begin processing
141
      */
142
      virtual void finish(secure_vector<uint8_t>& final_block, size_t offset = 0) = 0;
143
144
      /**
145
      * Returns the size of the output if this transform is used to process a
146
      * message with input_length bytes. In most cases the answer is precise.
147
      * If it is not possible to precise (namely for CBC decryption) instead an
148
      * upper bound is returned.
149
      */
150
      virtual size_t output_length(size_t input_length) const = 0;
151
152
      /**
153
      * @return size of required blocks to update
154
      */
155
      virtual size_t update_granularity() const = 0;
156
157
      /**
158
      * Return an ideal granularity. This will be a multiple of the result of
159
      * update_granularity but may be larger. If so it indicates that better
160
      * performance may be achieved by providing buffers that are at least that
161
      * size.
162
      */
163
      virtual size_t ideal_granularity() const = 0;
164
165
      /**
166
      * Certain modes require the entire message be available before
167
      * any processing can occur. For such modes, input will be consumed
168
      * but not returned, until `finish` is called, which returns the
169
      * entire message.
170
      *
171
      * This function returns true if this mode has this style of
172
      * operation.
173
      */
174
0
      virtual bool requires_entire_message() const { return false; }
175
176
      /**
177
      * @return required minimium size to finalize() - may be any
178
      *         length larger than this.
179
      */
180
      virtual size_t minimum_final_size() const = 0;
181
182
      /**
183
      * @return the default size for a nonce
184
      */
185
      virtual size_t default_nonce_length() const = 0;
186
187
      /**
188
      * @return true iff nonce_len is a valid length for the nonce
189
      */
190
      virtual bool valid_nonce_length(size_t nonce_len) const = 0;
191
192
      /**
193
      * Resets just the message specific state and allows encrypting again under the existing key
194
      */
195
      virtual void reset() = 0;
196
197
      /**
198
      * @return true iff this mode provides authentication as well as
199
      * confidentiality.
200
      */
201
0
      bool authenticated() const { return this->tag_size() > 0; }
202
203
      /**
204
      * @return the size of the authentication tag used (in bytes)
205
      */
206
0
      virtual size_t tag_size() const { return 0; }
207
208
      /**
209
      * @return provider information about this implementation. Default is "base",
210
      * might also return "sse2", "avx2", "openssl", or some other arbitrary string.
211
      */
212
0
      virtual std::string provider() const { return "base"; }
213
   };
214
215
/**
216
* Get a cipher mode by name (eg "AES-128/CBC" or "Serpent/XTS")
217
* @param algo_spec cipher name
218
* @param direction Cipher_Dir::Encryption or Cipher_Dir::Decryption
219
* @param provider provider implementation to choose
220
*/
221
BOTAN_DEPRECATED("Use Cipher_Mode::create")
222
inline Cipher_Mode* get_cipher_mode(const std::string& algo_spec,
223
                                    Cipher_Dir direction,
224
                                    const std::string& provider = "")
225
0
   {
226
0
   return Cipher_Mode::create(algo_spec, direction, provider).release();
227
0
   }
228
229
}
230
231
#endif