Botan 2.19.0
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_OPENSSL)
98 #include <botan/internal/openssl.h>
99#endif
100
101#if defined(BOTAN_HAS_COMMONCRYPTO)
102 #include <botan/internal/commoncrypto.h>
103#endif
104
105namespace Botan {
106
107std::unique_ptr<BlockCipher>
108BlockCipher::create(const std::string& algo,
109 const std::string& provider)
110 {
111#if defined(BOTAN_HAS_COMMONCRYPTO)
112 if(provider.empty() || provider == "commoncrypto")
113 {
114 if(auto bc = make_commoncrypto_block_cipher(algo))
115 return bc;
116
117 if(!provider.empty())
118 return nullptr;
119 }
120#endif
121
122#if defined(BOTAN_HAS_OPENSSL)
123 if(provider.empty() || provider == "openssl")
124 {
125 if(auto bc = make_openssl_block_cipher(algo))
126 return bc;
127
128 if(!provider.empty())
129 return nullptr;
130 }
131#endif
132
133 // TODO: CryptoAPI
134 // TODO: /dev/crypto
135
136 // Only base providers from here on out
137 if(provider.empty() == false && provider != "base")
138 return nullptr;
139
140#if defined(BOTAN_HAS_AES)
141 if(algo == "AES-128")
142 {
143 return std::unique_ptr<BlockCipher>(new AES_128);
144 }
145
146 if(algo == "AES-192")
147 {
148 return std::unique_ptr<BlockCipher>(new AES_192);
149 }
150
151 if(algo == "AES-256")
152 {
153 return std::unique_ptr<BlockCipher>(new AES_256);
154 }
155#endif
156
157#if defined(BOTAN_HAS_ARIA)
158 if(algo == "ARIA-128")
159 {
160 return std::unique_ptr<BlockCipher>(new ARIA_128);
161 }
162
163 if(algo == "ARIA-192")
164 {
165 return std::unique_ptr<BlockCipher>(new ARIA_192);
166 }
167
168 if(algo == "ARIA-256")
169 {
170 return std::unique_ptr<BlockCipher>(new ARIA_256);
171 }
172#endif
173
174#if defined(BOTAN_HAS_SERPENT)
175 if(algo == "Serpent")
176 {
177 return std::unique_ptr<BlockCipher>(new Serpent);
178 }
179#endif
180
181#if defined(BOTAN_HAS_SHACAL2)
182 if(algo == "SHACAL2")
183 {
184 return std::unique_ptr<BlockCipher>(new SHACAL2);
185 }
186#endif
187
188#if defined(BOTAN_HAS_TWOFISH)
189 if(algo == "Twofish")
190 {
191 return std::unique_ptr<BlockCipher>(new Twofish);
192 }
193#endif
194
195#if defined(BOTAN_HAS_THREEFISH_512)
196 if(algo == "Threefish-512")
197 {
198 return std::unique_ptr<BlockCipher>(new Threefish_512);
199 }
200#endif
201
202#if defined(BOTAN_HAS_BLOWFISH)
203 if(algo == "Blowfish")
204 {
205 return std::unique_ptr<BlockCipher>(new Blowfish);
206 }
207#endif
208
209#if defined(BOTAN_HAS_CAMELLIA)
210 if(algo == "Camellia-128")
211 {
212 return std::unique_ptr<BlockCipher>(new Camellia_128);
213 }
214
215 if(algo == "Camellia-192")
216 {
217 return std::unique_ptr<BlockCipher>(new Camellia_192);
218 }
219
220 if(algo == "Camellia-256")
221 {
222 return std::unique_ptr<BlockCipher>(new Camellia_256);
223 }
224#endif
225
226#if defined(BOTAN_HAS_DES)
227 if(algo == "DES")
228 {
229 return std::unique_ptr<BlockCipher>(new DES);
230 }
231
232 if(algo == "DESX")
233 {
234 return std::unique_ptr<BlockCipher>(new DESX);
235 }
236
237 if(algo == "TripleDES" || algo == "3DES" || algo == "DES-EDE")
238 {
239 return std::unique_ptr<BlockCipher>(new TripleDES);
240 }
241#endif
242
243#if defined(BOTAN_HAS_NOEKEON)
244 if(algo == "Noekeon")
245 {
246 return std::unique_ptr<BlockCipher>(new Noekeon);
247 }
248#endif
249
250#if defined(BOTAN_HAS_CAST_128)
251 if(algo == "CAST-128" || algo == "CAST5")
252 {
253 return std::unique_ptr<BlockCipher>(new CAST_128);
254 }
255#endif
256
257#if defined(BOTAN_HAS_CAST_256)
258 if(algo == "CAST-256")
259 {
260 return std::unique_ptr<BlockCipher>(new CAST_256);
261 }
262#endif
263
264#if defined(BOTAN_HAS_IDEA)
265 if(algo == "IDEA")
266 {
267 return std::unique_ptr<BlockCipher>(new IDEA);
268 }
269#endif
270
271#if defined(BOTAN_HAS_KASUMI)
272 if(algo == "KASUMI")
273 {
274 return std::unique_ptr<BlockCipher>(new KASUMI);
275 }
276#endif
277
278#if defined(BOTAN_HAS_MISTY1)
279 if(algo == "MISTY1")
280 {
281 return std::unique_ptr<BlockCipher>(new MISTY1);
282 }
283#endif
284
285#if defined(BOTAN_HAS_SEED)
286 if(algo == "SEED")
287 {
288 return std::unique_ptr<BlockCipher>(new SEED);
289 }
290#endif
291
292#if defined(BOTAN_HAS_SM4)
293 if(algo == "SM4")
294 {
295 return std::unique_ptr<BlockCipher>(new SM4);
296 }
297#endif
298
299#if defined(BOTAN_HAS_XTEA)
300 if(algo == "XTEA")
301 {
302 return std::unique_ptr<BlockCipher>(new XTEA);
303 }
304#endif
305
306 const SCAN_Name req(algo);
307
308#if defined(BOTAN_HAS_GOST_28147_89)
309 if(req.algo_name() == "GOST-28147-89")
310 {
311 return std::unique_ptr<BlockCipher>(new GOST_28147_89(req.arg(0, "R3411_94_TestParam")));
312 }
313#endif
314
315#if defined(BOTAN_HAS_CASCADE)
316 if(req.algo_name() == "Cascade" && req.arg_count() == 2)
317 {
318 std::unique_ptr<BlockCipher> c1(BlockCipher::create(req.arg(0)));
319 std::unique_ptr<BlockCipher> c2(BlockCipher::create(req.arg(1)));
320
321 if(c1 && c2)
322 return std::unique_ptr<BlockCipher>(new Cascade_Cipher(c1.release(), c2.release()));
323 }
324#endif
325
326#if defined(BOTAN_HAS_LION)
327 if(req.algo_name() == "Lion" && req.arg_count_between(2, 3))
328 {
329 std::unique_ptr<HashFunction> hash(HashFunction::create(req.arg(0)));
330 std::unique_ptr<StreamCipher> stream(StreamCipher::create(req.arg(1)));
331
332 if(hash && stream)
333 {
334 const size_t block_size = req.arg_as_integer(2, 1024);
335 return std::unique_ptr<BlockCipher>(new Lion(hash.release(), stream.release(), block_size));
336 }
337 }
338#endif
339
340 BOTAN_UNUSED(req);
342
343 return nullptr;
344 }
345
346//static
347std::unique_ptr<BlockCipher>
348BlockCipher::create_or_throw(const std::string& algo,
349 const std::string& provider)
350 {
351 if(auto bc = BlockCipher::create(algo, provider))
352 {
353 return bc;
354 }
355 throw Lookup_Error("Block cipher", algo, provider);
356 }
357
358std::vector<std::string> BlockCipher::providers(const std::string& algo)
359 {
360 return probe_providers_of<BlockCipher>(algo, { "base", "openssl", "commoncrypto" });
361 }
362
363}
#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:106
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_openssl_block_cipher(const std::string &name)
std::unique_ptr< BlockCipher > make_commoncrypto_block_cipher(const std::string &name)
MechanismType hash