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