Botan  2.6.0
Crypto and TLS for C++11
block_cipher.cpp
Go to the documentation of this file.
1 /*
2 * Block Ciphers
3 * (C) 2015 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #include <botan/block_cipher.h>
9 #include <botan/scan_name.h>
10 
11 #if defined(BOTAN_HAS_AES)
12  #include <botan/aes.h>
13 #endif
14 
15 #if defined(BOTAN_HAS_ARIA)
16  #include <botan/aria.h>
17 #endif
18 
19 #if defined(BOTAN_HAS_BLOWFISH)
20  #include <botan/blowfish.h>
21 #endif
22 
23 #if defined(BOTAN_HAS_CAMELLIA)
24  #include <botan/camellia.h>
25 #endif
26 
27 #if defined(BOTAN_HAS_CAST_128)
28  #include <botan/cast128.h>
29 #endif
30 
31 #if defined(BOTAN_HAS_CAST_256)
32  #include <botan/cast256.h>
33 #endif
34 
35 #if defined(BOTAN_HAS_CASCADE)
36  #include <botan/cascade.h>
37 #endif
38 
39 #if defined(BOTAN_HAS_DES)
40  #include <botan/des.h>
41  #include <botan/desx.h>
42 #endif
43 
44 #if defined(BOTAN_HAS_GOST_28147_89)
45  #include <botan/gost_28147.h>
46 #endif
47 
48 #if defined(BOTAN_HAS_IDEA)
49  #include <botan/idea.h>
50 #endif
51 
52 #if defined(BOTAN_HAS_KASUMI)
53  #include <botan/kasumi.h>
54 #endif
55 
56 #if defined(BOTAN_HAS_LION)
57  #include <botan/lion.h>
58 #endif
59 
60 #if defined(BOTAN_HAS_MISTY1)
61  #include <botan/misty1.h>
62 #endif
63 
64 #if defined(BOTAN_HAS_NOEKEON)
65  #include <botan/noekeon.h>
66 #endif
67 
68 #if defined(BOTAN_HAS_SEED)
69  #include <botan/seed.h>
70 #endif
71 
72 #if defined(BOTAN_HAS_SERPENT)
73  #include <botan/serpent.h>
74 #endif
75 
76 #if defined(BOTAN_HAS_SHACAL2)
77  #include <botan/shacal2.h>
78 #endif
79 
80 #if defined(BOTAN_HAS_SM4)
81  #include <botan/sm4.h>
82 #endif
83 
84 #if defined(BOTAN_HAS_TWOFISH)
85  #include <botan/twofish.h>
86 #endif
87 
88 #if defined(BOTAN_HAS_THREEFISH_512)
89  #include <botan/threefish_512.h>
90 #endif
91 
92 #if defined(BOTAN_HAS_XTEA)
93  #include <botan/xtea.h>
94 #endif
95 
96 #if defined(BOTAN_HAS_OPENSSL)
97  #include <botan/internal/openssl.h>
98 #endif
99 
100 namespace Botan {
101 
102 std::unique_ptr<BlockCipher>
103 BlockCipher::create(const std::string& algo,
104  const std::string& provider)
105  {
106 #if defined(BOTAN_HAS_OPENSSL)
107  if(provider.empty() || provider == "openssl")
108  {
109  if(auto bc = make_openssl_block_cipher(algo))
110  return bc;
111 
112  if(!provider.empty())
113  return nullptr;
114  }
115 #endif
116 
117  // TODO: CommonCrypto
118  // TODO: CryptoAPI
119  // TODO: /dev/crypto
120 
121  // Only base providers from here on out
122  if(provider.empty() == false && provider != "base")
123  return nullptr;
124 
125 #if defined(BOTAN_HAS_AES)
126  if(algo == "AES-128")
127  {
128  return std::unique_ptr<BlockCipher>(new AES_128);
129  }
130 
131  if(algo == "AES-192")
132  {
133  return std::unique_ptr<BlockCipher>(new AES_192);
134  }
135 
136  if(algo == "AES-256")
137  {
138  return std::unique_ptr<BlockCipher>(new AES_256);
139  }
140 #endif
141 
142 #if defined(BOTAN_HAS_ARIA)
143  if(algo == "ARIA-128")
144  {
145  return std::unique_ptr<BlockCipher>(new ARIA_128);
146  }
147 
148  if(algo == "ARIA-192")
149  {
150  return std::unique_ptr<BlockCipher>(new ARIA_192);
151  }
152 
153  if(algo == "ARIA-256")
154  {
155  return std::unique_ptr<BlockCipher>(new ARIA_256);
156  }
157 #endif
158 
159 #if defined(BOTAN_HAS_SERPENT)
160  if(algo == "Serpent")
161  {
162  return std::unique_ptr<BlockCipher>(new Serpent);
163  }
164 #endif
165 
166 #if defined(BOTAN_HAS_SHACAL2)
167  if(algo == "SHACAL2")
168  {
169  return std::unique_ptr<BlockCipher>(new SHACAL2);
170  }
171 #endif
172 
173 #if defined(BOTAN_HAS_TWOFISH)
174  if(algo == "Twofish")
175  {
176  return std::unique_ptr<BlockCipher>(new Twofish);
177  }
178 #endif
179 
180 #if defined(BOTAN_HAS_THREEFISH_512)
181  if(algo == "Threefish-512")
182  {
183  return std::unique_ptr<BlockCipher>(new Threefish_512);
184  }
185 #endif
186 
187 #if defined(BOTAN_HAS_BLOWFISH)
188  if(algo == "Blowfish")
189  {
190  return std::unique_ptr<BlockCipher>(new Blowfish);
191  }
192 #endif
193 
194 #if defined(BOTAN_HAS_CAMELLIA)
195  if(algo == "Camellia-128")
196  {
197  return std::unique_ptr<BlockCipher>(new Camellia_128);
198  }
199 
200  if(algo == "Camellia-192")
201  {
202  return std::unique_ptr<BlockCipher>(new Camellia_192);
203  }
204 
205  if(algo == "Camellia-256")
206  {
207  return std::unique_ptr<BlockCipher>(new Camellia_256);
208  }
209 #endif
210 
211 #if defined(BOTAN_HAS_DES)
212  if(algo == "DES")
213  {
214  return std::unique_ptr<BlockCipher>(new DES);
215  }
216 
217  if(algo == "DESX")
218  {
219  return std::unique_ptr<BlockCipher>(new DESX);
220  }
221 
222  if(algo == "TripleDES" || algo == "3DES" || algo == "DES-EDE")
223  {
224  return std::unique_ptr<BlockCipher>(new TripleDES);
225  }
226 #endif
227 
228 #if defined(BOTAN_HAS_NOEKEON)
229  if(algo == "Noekeon")
230  {
231  return std::unique_ptr<BlockCipher>(new Noekeon);
232  }
233 #endif
234 
235 #if defined(BOTAN_HAS_CAST_128)
236  if(algo == "CAST-128" || algo == "CAST5")
237  {
238  return std::unique_ptr<BlockCipher>(new CAST_128);
239  }
240 #endif
241 
242 #if defined(BOTAN_HAS_CAST_256)
243  if(algo == "CAST-256")
244  {
245  return std::unique_ptr<BlockCipher>(new CAST_256);
246  }
247 #endif
248 
249 #if defined(BOTAN_HAS_IDEA)
250  if(algo == "IDEA")
251  {
252  return std::unique_ptr<BlockCipher>(new IDEA);
253  }
254 #endif
255 
256 #if defined(BOTAN_HAS_KASUMI)
257  if(algo == "KASUMI")
258  {
259  return std::unique_ptr<BlockCipher>(new KASUMI);
260  }
261 #endif
262 
263 #if defined(BOTAN_HAS_MISTY1)
264  if(algo == "MISTY1")
265  {
266  return std::unique_ptr<BlockCipher>(new MISTY1);
267  }
268 #endif
269 
270 #if defined(BOTAN_HAS_SEED)
271  if(algo == "SEED")
272  {
273  return std::unique_ptr<BlockCipher>(new SEED);
274  }
275 #endif
276 
277 #if defined(BOTAN_HAS_SM4)
278  if(algo == "SM4")
279  {
280  return std::unique_ptr<BlockCipher>(new SM4);
281  }
282 #endif
283 
284 #if defined(BOTAN_HAS_XTEA)
285  if(algo == "XTEA")
286  {
287  return std::unique_ptr<BlockCipher>(new XTEA);
288  }
289 #endif
290 
291  const SCAN_Name req(algo);
292 
293 #if defined(BOTAN_HAS_GOST_28147_89)
294  if(req.algo_name() == "GOST-28147-89")
295  {
296  return std::unique_ptr<BlockCipher>(new GOST_28147_89(req.arg(0, "R3411_94_TestParam")));
297  }
298 #endif
299 
300 #if defined(BOTAN_HAS_CASCADE)
301  if(req.algo_name() == "Cascade" && req.arg_count() == 2)
302  {
303  std::unique_ptr<BlockCipher> c1(BlockCipher::create(req.arg(0)));
304  std::unique_ptr<BlockCipher> c2(BlockCipher::create(req.arg(1)));
305 
306  if(c1 && c2)
307  return std::unique_ptr<BlockCipher>(new Cascade_Cipher(c1.release(), c2.release()));
308  }
309 #endif
310 
311 #if defined(BOTAN_HAS_LION)
312  if(req.algo_name() == "Lion" && req.arg_count_between(2, 3))
313  {
314  std::unique_ptr<HashFunction> hash(HashFunction::create(req.arg(0)));
315  std::unique_ptr<StreamCipher> stream(StreamCipher::create(req.arg(1)));
316 
317  if(hash && stream)
318  {
319  const size_t block_size = req.arg_as_integer(2, 1024);
320  return std::unique_ptr<BlockCipher>(new Lion(hash.release(), stream.release(), block_size));
321  }
322  }
323 #endif
324 
325  BOTAN_UNUSED(req);
327 
328  return nullptr;
329  }
330 
331 //static
332 std::unique_ptr<BlockCipher>
333 BlockCipher::create_or_throw(const std::string& algo,
334  const std::string& provider)
335  {
336  if(auto bc = BlockCipher::create(algo, provider))
337  {
338  return bc;
339  }
340  throw Lookup_Error("Block cipher", algo, provider);
341  }
342 
343 std::vector<std::string> BlockCipher::providers(const std::string& algo)
344  {
345  return probe_providers_of<BlockCipher>(algo, { "base", "openssl" });
346  }
347 
348 }
size_t arg_count() const
Definition: scan_name.h:49
size_t arg_as_integer(size_t i, size_t def_value) const
Definition: scan_name.cpp:137
static std::vector< std::string > providers(const std::string &algo_spec)
Definition: sm4.h:18
std::string arg(size_t i) const
Definition: scan_name.cpp:122
static std::unique_ptr< HashFunction > create(const std::string &algo_spec, const std::string &provider="")
Definition: hash.cpp:106
Definition: alg_id.cpp:13
#define BOTAN_UNUSED(...)
Definition: assert.h:117
static std::unique_ptr< BlockCipher > create_or_throw(const std::string &algo_spec, const std::string &provider="")
static std::unique_ptr< BlockCipher > create(const std::string &algo_spec, const std::string &provider="")
const std::string & algo_name() const
Definition: scan_name.h:44
bool arg_count_between(size_t lower, size_t upper) const
Definition: scan_name.h:56
static std::unique_ptr< StreamCipher > create(const std::string &algo_spec, const std::string &provider="")
Definition: des.h:18
std::unique_ptr< BlockCipher > make_openssl_block_cipher(const std::string &name)
virtual std::string provider() const
Definition: block_cipher.h:72
virtual size_t block_size() const =0
MechanismType hash