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