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