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