Botan 2.19.2
Crypto and TLS for C&
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_COMMONCRYPTO)
98 #include <botan/internal/commoncrypto.h>
99#endif
100
101namespace Botan {
102
103std::unique_ptr<BlockCipher>
104BlockCipher::create(const std::string& algo,
105 const std::string& provider)
106 {
107#if defined(BOTAN_HAS_COMMONCRYPTO)
108 if(provider.empty() || provider == "commoncrypto")
109 {
110 if(auto bc = make_commoncrypto_block_cipher(algo))
111 return bc;
112
113 if(!provider.empty())
114 return nullptr;
115 }
116#endif
117
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
332std::unique_ptr<BlockCipher>
333BlockCipher::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
343std::vector<std::string> BlockCipher::providers(const std::string& algo)
344 {
345 return probe_providers_of<BlockCipher>(algo, { "base", "openssl", "commoncrypto" });
346 }
347
348}
#define BOTAN_UNUSED(...)
Definition: assert.h:142
static std::vector< std::string > providers(const std::string &algo_spec)
static std::unique_ptr< BlockCipher > create(const std::string &algo_spec, const std::string &provider="")
static std::unique_ptr< BlockCipher > create_or_throw(const std::string &algo_spec, const std::string &provider="")
virtual size_t block_size() const =0
virtual std::string provider() const
Definition: block_cipher.h:73
Definition: des.h:21
static std::unique_ptr< HashFunction > create(const std::string &algo_spec, const std::string &provider="")
Definition: hash.cpp:102
std::string arg(size_t i) const
Definition: scan_name.cpp:127
size_t arg_count() const
Definition: scan_name.h:56
const std::string & algo_name() const
Definition: scan_name.h:51
size_t arg_as_integer(size_t i, size_t def_value) const
Definition: scan_name.cpp:142
bool arg_count_between(size_t lower, size_t upper) const
Definition: scan_name.h:63
Definition: sm4.h:21
static std::unique_ptr< StreamCipher > create(const std::string &algo_spec, const std::string &provider="")
Definition: alg_id.cpp:13
std::unique_ptr< BlockCipher > make_commoncrypto_block_cipher(const std::string &name)
MechanismType hash