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