Coverage Report

Created: 2025-04-11 06:34

/src/botan/src/lib/block/block_cipher.cpp
Line
Count
Source (jump to first uncovered line)
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
90
namespace Botan {
91
92
1.09k
std::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
1.09k
   if(provider.empty() == false && provider != "base") {
108
176
      return nullptr;
109
176
   }
110
111
918
#if defined(BOTAN_HAS_AES)
112
918
   if(algo == "AES-128") {
113
249
      return std::make_unique<AES_128>();
114
249
   }
115
116
669
   if(algo == "AES-192") {
117
0
      return std::make_unique<AES_192>();
118
0
   }
119
120
669
   if(algo == "AES-256") {
121
260
      return std::make_unique<AES_256>();
122
260
   }
123
409
#endif
124
125
409
#if defined(BOTAN_HAS_ARIA)
126
409
   if(algo == "ARIA-128") {
127
47
      return std::make_unique<ARIA_128>();
128
47
   }
129
130
362
   if(algo == "ARIA-192") {
131
0
      return std::make_unique<ARIA_192>();
132
0
   }
133
134
362
   if(algo == "ARIA-256") {
135
81
      return std::make_unique<ARIA_256>();
136
81
   }
137
281
#endif
138
139
281
#if defined(BOTAN_HAS_SERPENT)
140
281
   if(algo == "Serpent") {
141
0
      return std::make_unique<Serpent>();
142
0
   }
143
281
#endif
144
145
281
#if defined(BOTAN_HAS_SHACAL2)
146
281
   if(algo == "SHACAL2") {
147
0
      return std::make_unique<SHACAL2>();
148
0
   }
149
281
#endif
150
151
281
#if defined(BOTAN_HAS_TWOFISH)
152
281
   if(algo == "Twofish") {
153
0
      return std::make_unique<Twofish>();
154
0
   }
155
281
#endif
156
157
281
#if defined(BOTAN_HAS_THREEFISH_512)
158
281
   if(algo == "Threefish-512") {
159
0
      return std::make_unique<Threefish_512>();
160
0
   }
161
281
#endif
162
163
281
#if defined(BOTAN_HAS_BLOWFISH)
164
281
   if(algo == "Blowfish") {
165
0
      return std::make_unique<Blowfish>();
166
0
   }
167
281
#endif
168
169
281
#if defined(BOTAN_HAS_CAMELLIA)
170
281
   if(algo == "Camellia-128") {
171
41
      return std::make_unique<Camellia_128>();
172
41
   }
173
174
240
   if(algo == "Camellia-192") {
175
0
      return std::make_unique<Camellia_192>();
176
0
   }
177
178
240
   if(algo == "Camellia-256") {
179
152
      return std::make_unique<Camellia_256>();
180
152
   }
181
88
#endif
182
183
88
#if defined(BOTAN_HAS_DES)
184
88
   if(algo == "DES") {
185
0
      return std::make_unique<DES>();
186
0
   }
187
188
88
   if(algo == "TripleDES" || algo == "3DES" || algo == "DES-EDE") {
189
88
      return std::make_unique<TripleDES>();
190
88
   }
191
0
#endif
192
193
0
#if defined(BOTAN_HAS_NOEKEON)
194
0
   if(algo == "Noekeon") {
195
0
      return std::make_unique<Noekeon>();
196
0
   }
197
0
#endif
198
199
0
#if defined(BOTAN_HAS_CAST_128)
200
0
   if(algo == "CAST-128" || algo == "CAST5") {
201
0
      return std::make_unique<CAST_128>();
202
0
   }
203
0
#endif
204
205
0
#if defined(BOTAN_HAS_IDEA)
206
0
   if(algo == "IDEA") {
207
0
      return std::make_unique<IDEA>();
208
0
   }
209
0
#endif
210
211
0
#if defined(BOTAN_HAS_KUZNYECHIK)
212
0
   if(algo == "Kuznyechik") {
213
0
      return std::make_unique<Kuznyechik>();
214
0
   }
215
0
#endif
216
217
0
#if defined(BOTAN_HAS_SEED)
218
0
   if(algo == "SEED") {
219
0
      return std::make_unique<SEED>();
220
0
   }
221
0
#endif
222
223
0
#if defined(BOTAN_HAS_SM4)
224
0
   if(algo == "SM4") {
225
0
      return std::make_unique<SM4>();
226
0
   }
227
0
#endif
228
229
0
   const SCAN_Name req(algo);
230
231
0
#if defined(BOTAN_HAS_GOST_28147_89)
232
0
   if(req.algo_name() == "GOST-28147-89") {
233
0
      return std::make_unique<GOST_28147_89>(req.arg(0, "R3411_94_TestParam"));
234
0
   }
235
0
#endif
236
237
0
#if defined(BOTAN_HAS_CASCADE)
238
0
   if(req.algo_name() == "Cascade" && req.arg_count() == 2) {
239
0
      auto c1 = BlockCipher::create(req.arg(0));
240
0
      auto c2 = BlockCipher::create(req.arg(1));
241
242
0
      if(c1 && c2) {
243
0
         return std::make_unique<Cascade_Cipher>(std::move(c1), std::move(c2));
244
0
      }
245
0
   }
246
0
#endif
247
248
0
#if defined(BOTAN_HAS_LION)
249
0
   if(req.algo_name() == "Lion" && req.arg_count_between(2, 3)) {
250
0
      auto hash = HashFunction::create(req.arg(0));
251
0
      auto stream = StreamCipher::create(req.arg(1));
252
253
0
      if(hash && stream) {
254
0
         const size_t block_size = req.arg_as_integer(2, 1024);
255
0
         return std::make_unique<Lion>(std::move(hash), std::move(stream), block_size);
256
0
      }
257
0
   }
258
0
#endif
259
260
0
   BOTAN_UNUSED(req);
261
0
   BOTAN_UNUSED(provider);
262
263
0
   return nullptr;
264
0
}
265
266
//static
267
211
std::unique_ptr<BlockCipher> BlockCipher::create_or_throw(std::string_view algo, std::string_view provider) {
268
211
   if(auto bc = BlockCipher::create(algo, provider)) {
269
211
      return bc;
270
211
   }
271
0
   throw Lookup_Error("Block cipher", algo, provider);
272
211
}
273
274
176
std::vector<std::string> BlockCipher::providers(std::string_view algo) {
275
176
   return probe_providers_of<BlockCipher>(algo, {"base", "commoncrypto"});
276
176
}
277
278
}  // namespace Botan