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