Coverage Report

Created: 2020-05-23 13:54

/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
#include <botan/scan_name.h>
10
#include <botan/exceptn.h>
11
12
#if defined(BOTAN_HAS_AES)
13
  #include <botan/aes.h>
14
#endif
15
16
#if defined(BOTAN_HAS_ARIA)
17
  #include <botan/aria.h>
18
#endif
19
20
#if defined(BOTAN_HAS_BLOWFISH)
21
  #include <botan/blowfish.h>
22
#endif
23
24
#if defined(BOTAN_HAS_CAMELLIA)
25
  #include <botan/camellia.h>
26
#endif
27
28
#if defined(BOTAN_HAS_CAST_128)
29
  #include <botan/cast128.h>
30
#endif
31
32
#if defined(BOTAN_HAS_CAST_256)
33
  #include <botan/cast256.h>
34
#endif
35
36
#if defined(BOTAN_HAS_CASCADE)
37
  #include <botan/cascade.h>
38
#endif
39
40
#if defined(BOTAN_HAS_DES)
41
  #include <botan/des.h>
42
  #include <botan/desx.h>
43
#endif
44
45
#if defined(BOTAN_HAS_GOST_28147_89)
46
  #include <botan/gost_28147.h>
47
#endif
48
49
#if defined(BOTAN_HAS_IDEA)
50
  #include <botan/idea.h>
51
#endif
52
53
#if defined(BOTAN_HAS_KASUMI)
54
  #include <botan/kasumi.h>
55
#endif
56
57
#if defined(BOTAN_HAS_LION)
58
  #include <botan/lion.h>
59
#endif
60
61
#if defined(BOTAN_HAS_MISTY1)
62
  #include <botan/misty1.h>
63
#endif
64
65
#if defined(BOTAN_HAS_NOEKEON)
66
  #include <botan/noekeon.h>
67
#endif
68
69
#if defined(BOTAN_HAS_SEED)
70
  #include <botan/seed.h>
71
#endif
72
73
#if defined(BOTAN_HAS_SERPENT)
74
  #include <botan/serpent.h>
75
#endif
76
77
#if defined(BOTAN_HAS_SHACAL2)
78
  #include <botan/shacal2.h>
79
#endif
80
81
#if defined(BOTAN_HAS_SM4)
82
  #include <botan/sm4.h>
83
#endif
84
85
#if defined(BOTAN_HAS_TWOFISH)
86
  #include <botan/twofish.h>
87
#endif
88
89
#if defined(BOTAN_HAS_THREEFISH_512)
90
  #include <botan/threefish_512.h>
91
#endif
92
93
#if defined(BOTAN_HAS_XTEA)
94
  #include <botan/xtea.h>
95
#endif
96
97
#if defined(BOTAN_HAS_OPENSSL)
98
  #include <botan/internal/openssl.h>
99
#endif
100
101
#if defined(BOTAN_HAS_COMMONCRYPTO)
102
  #include <botan/internal/commoncrypto.h>
103
#endif
104
105
namespace Botan {
106
107
std::unique_ptr<BlockCipher>
108
BlockCipher::create(const std::string& algo,
109
                    const std::string& provider)
110
3.68k
   {
111
#if defined(BOTAN_HAS_COMMONCRYPTO)
112
   if(provider.empty() || provider == "commoncrypto")
113
      {
114
      if(auto bc = make_commoncrypto_block_cipher(algo))
115
         return bc;
116
117
      if(!provider.empty())
118
         return nullptr;
119
      }
120
#endif
121
122
#if defined(BOTAN_HAS_OPENSSL)
123
   if(provider.empty() || provider == "openssl")
124
      {
125
      if(auto bc = make_openssl_block_cipher(algo))
126
         return bc;
127
128
      if(!provider.empty())
129
         return nullptr;
130
      }
131
#endif
132
133
3.68k
   // TODO: CryptoAPI
134
3.68k
   // TODO: /dev/crypto
135
3.68k
136
3.68k
   // Only base providers from here on out
137
3.68k
   if(provider.empty() == false && provider != "base")
138
700
      return nullptr;
139
2.98k
140
2.98k
#if defined(BOTAN_HAS_AES)
141
2.98k
   if(algo == "AES-128")
142
695
      {
143
695
      return std::unique_ptr<BlockCipher>(new AES_128);
144
695
      }
145
2.29k
146
2.29k
   if(algo == "AES-192")
147
0
      {
148
0
      return std::unique_ptr<BlockCipher>(new AES_192);
149
0
      }
150
2.29k
151
2.29k
   if(algo == "AES-256")
152
1.06k
      {
153
1.06k
      return std::unique_ptr<BlockCipher>(new AES_256);
154
1.06k
      }
155
1.22k
#endif
156
1.22k
157
1.22k
#if defined(BOTAN_HAS_ARIA)
158
1.22k
   if(algo == "ARIA-128")
159
107
      {
160
107
      return std::unique_ptr<BlockCipher>(new ARIA_128);
161
107
      }
162
1.11k
163
1.11k
   if(algo == "ARIA-192")
164
0
      {
165
0
      return std::unique_ptr<BlockCipher>(new ARIA_192);
166
0
      }
167
1.11k
168
1.11k
   if(algo == "ARIA-256")
169
233
      {
170
233
      return std::unique_ptr<BlockCipher>(new ARIA_256);
171
233
      }
172
883
#endif
173
883
174
883
#if defined(BOTAN_HAS_SERPENT)
175
883
   if(algo == "Serpent")
176
0
      {
177
0
      return std::unique_ptr<BlockCipher>(new Serpent);
178
0
      }
179
883
#endif
180
883
181
883
#if defined(BOTAN_HAS_SHACAL2)
182
883
   if(algo == "SHACAL2")
183
0
      {
184
0
      return std::unique_ptr<BlockCipher>(new SHACAL2);
185
0
      }
186
883
#endif
187
883
188
883
#if defined(BOTAN_HAS_TWOFISH)
189
883
   if(algo == "Twofish")
190
0
      {
191
0
      return std::unique_ptr<BlockCipher>(new Twofish);
192
0
      }
193
883
#endif
194
883
195
883
#if defined(BOTAN_HAS_THREEFISH_512)
196
883
   if(algo == "Threefish-512")
197
0
      {
198
0
      return std::unique_ptr<BlockCipher>(new Threefish_512);
199
0
      }
200
883
#endif
201
883
202
883
#if defined(BOTAN_HAS_BLOWFISH)
203
883
   if(algo == "Blowfish")
204
0
      {
205
0
      return std::unique_ptr<BlockCipher>(new Blowfish);
206
0
      }
207
883
#endif
208
883
209
883
#if defined(BOTAN_HAS_CAMELLIA)
210
883
   if(algo == "Camellia-128")
211
179
      {
212
179
      return std::unique_ptr<BlockCipher>(new Camellia_128);
213
179
      }
214
704
215
704
   if(algo == "Camellia-192")
216
0
      {
217
0
      return std::unique_ptr<BlockCipher>(new Camellia_192);
218
0
      }
219
704
220
704
   if(algo == "Camellia-256")
221
303
      {
222
303
      return std::unique_ptr<BlockCipher>(new Camellia_256);
223
303
      }
224
401
#endif
225
401
226
401
#if defined(BOTAN_HAS_DES)
227
401
   if(algo == "DES")
228
0
      {
229
0
      return std::unique_ptr<BlockCipher>(new DES);
230
0
      }
231
401
232
401
   if(algo == "DESX")
233
0
      {
234
0
      return std::unique_ptr<BlockCipher>(new DESX);
235
0
      }
236
401
237
401
   if(algo == "TripleDES" || algo == "3DES" || algo == "DES-EDE")
238
321
      {
239
321
      return std::unique_ptr<BlockCipher>(new TripleDES);
240
321
      }
241
80
#endif
242
80
243
80
#if defined(BOTAN_HAS_NOEKEON)
244
80
   if(algo == "Noekeon")
245
0
      {
246
0
      return std::unique_ptr<BlockCipher>(new Noekeon);
247
0
      }
248
80
#endif
249
80
250
80
#if defined(BOTAN_HAS_CAST_128)
251
80
   if(algo == "CAST-128" || algo == "CAST5")
252
0
      {
253
0
      return std::unique_ptr<BlockCipher>(new CAST_128);
254
0
      }
255
80
#endif
256
80
257
80
#if defined(BOTAN_HAS_CAST_256)
258
80
   if(algo == "CAST-256")
259
0
      {
260
0
      return std::unique_ptr<BlockCipher>(new CAST_256);
261
0
      }
262
80
#endif
263
80
264
80
#if defined(BOTAN_HAS_IDEA)
265
80
   if(algo == "IDEA")
266
0
      {
267
0
      return std::unique_ptr<BlockCipher>(new IDEA);
268
0
      }
269
80
#endif
270
80
271
80
#if defined(BOTAN_HAS_KASUMI)
272
80
   if(algo == "KASUMI")
273
0
      {
274
0
      return std::unique_ptr<BlockCipher>(new KASUMI);
275
0
      }
276
80
#endif
277
80
278
80
#if defined(BOTAN_HAS_MISTY1)
279
80
   if(algo == "MISTY1")
280
0
      {
281
0
      return std::unique_ptr<BlockCipher>(new MISTY1);
282
0
      }
283
80
#endif
284
80
285
80
#if defined(BOTAN_HAS_SEED)
286
80
   if(algo == "SEED")
287
80
      {
288
80
      return std::unique_ptr<BlockCipher>(new SEED);
289
80
      }
290
0
#endif
291
0
292
0
#if defined(BOTAN_HAS_SM4)
293
0
   if(algo == "SM4")
294
0
      {
295
0
      return std::unique_ptr<BlockCipher>(new SM4);
296
0
      }
297
0
#endif
298
0
299
0
#if defined(BOTAN_HAS_XTEA)
300
0
   if(algo == "XTEA")
301
0
      {
302
0
      return std::unique_ptr<BlockCipher>(new XTEA);
303
0
      }
304
0
#endif
305
0
306
0
   const SCAN_Name req(algo);
307
0
308
0
#if defined(BOTAN_HAS_GOST_28147_89)
309
0
   if(req.algo_name() == "GOST-28147-89")
310
0
      {
311
0
      return std::unique_ptr<BlockCipher>(new GOST_28147_89(req.arg(0, "R3411_94_TestParam")));
312
0
      }
313
0
#endif
314
0
315
0
#if defined(BOTAN_HAS_CASCADE)
316
0
   if(req.algo_name() == "Cascade" && req.arg_count() == 2)
317
0
      {
318
0
      std::unique_ptr<BlockCipher> c1(BlockCipher::create(req.arg(0)));
319
0
      std::unique_ptr<BlockCipher> c2(BlockCipher::create(req.arg(1)));
320
0
321
0
      if(c1 && c2)
322
0
         return std::unique_ptr<BlockCipher>(new Cascade_Cipher(c1.release(), c2.release()));
323
0
      }
324
0
#endif
325
0
326
0
#if defined(BOTAN_HAS_LION)
327
0
   if(req.algo_name() == "Lion" && req.arg_count_between(2, 3))
328
0
      {
329
0
      std::unique_ptr<HashFunction> hash(HashFunction::create(req.arg(0)));
330
0
      std::unique_ptr<StreamCipher> stream(StreamCipher::create(req.arg(1)));
331
0
332
0
      if(hash && stream)
333
0
         {
334
0
         const size_t block_size = req.arg_as_integer(2, 1024);
335
0
         return std::unique_ptr<BlockCipher>(new Lion(hash.release(), stream.release(), block_size));
336
0
         }
337
0
      }
338
0
#endif
339
0
340
0
   BOTAN_UNUSED(req);
341
0
   BOTAN_UNUSED(provider);
342
0
343
0
   return nullptr;
344
0
   }
345
346
//static
347
std::unique_ptr<BlockCipher>
348
BlockCipher::create_or_throw(const std::string& algo,
349
                             const std::string& provider)
350
937
   {
351
937
   if(auto bc = BlockCipher::create(algo, provider))
352
937
      {
353
937
      return bc;
354
937
      }
355
0
   throw Lookup_Error("Block cipher", algo, provider);
356
0
   }
357
358
std::vector<std::string> BlockCipher::providers(const std::string& algo)
359
350
   {
360
350
   return probe_providers_of<BlockCipher>(algo, { "base", "openssl", "commoncrypto" });
361
350
   }
362
363
}