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