Coverage Report

Created: 2019-09-11 14:12

/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
6.61k
   {
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
6.61k
   // TODO: CryptoAPI
134
6.61k
   // TODO: /dev/crypto
135
6.61k
136
6.61k
   // Only base providers from here on out
137
6.61k
   if(provider.empty() == false && provider != "base")
138
700
      return nullptr;
139
5.91k
140
5.91k
#if defined(BOTAN_HAS_AES)
141
5.91k
   if(algo == "AES-128")
142
772
      {
143
772
      return std::unique_ptr<BlockCipher>(new AES_128);
144
772
      }
145
5.14k
146
5.14k
   if(algo == "AES-192")
147
0
      {
148
0
      return std::unique_ptr<BlockCipher>(new AES_192);
149
0
      }
150
5.14k
151
5.14k
   if(algo == "AES-256")
152
3.83k
      {
153
3.83k
      return std::unique_ptr<BlockCipher>(new AES_256);
154
3.83k
      }
155
1.30k
#endif
156
1.30k
157
1.30k
#if defined(BOTAN_HAS_ARIA)
158
1.30k
   if(algo == "ARIA-128")
159
80
      {
160
80
      return std::unique_ptr<BlockCipher>(new ARIA_128);
161
80
      }
162
1.22k
163
1.22k
   if(algo == "ARIA-192")
164
0
      {
165
0
      return std::unique_ptr<BlockCipher>(new ARIA_192);
166
0
      }
167
1.22k
168
1.22k
   if(algo == "ARIA-256")
169
227
      {
170
227
      return std::unique_ptr<BlockCipher>(new ARIA_256);
171
227
      }
172
1.00k
#endif
173
1.00k
174
1.00k
#if defined(BOTAN_HAS_SERPENT)
175
1.00k
   if(algo == "Serpent")
176
0
      {
177
0
      return std::unique_ptr<BlockCipher>(new Serpent);
178
0
      }
179
1.00k
#endif
180
1.00k
181
1.00k
#if defined(BOTAN_HAS_SHACAL2)
182
1.00k
   if(algo == "SHACAL2")
183
0
      {
184
0
      return std::unique_ptr<BlockCipher>(new SHACAL2);
185
0
      }
186
1.00k
#endif
187
1.00k
188
1.00k
#if defined(BOTAN_HAS_TWOFISH)
189
1.00k
   if(algo == "Twofish")
190
0
      {
191
0
      return std::unique_ptr<BlockCipher>(new Twofish);
192
0
      }
193
1.00k
#endif
194
1.00k
195
1.00k
#if defined(BOTAN_HAS_THREEFISH_512)
196
1.00k
   if(algo == "Threefish-512")
197
0
      {
198
0
      return std::unique_ptr<BlockCipher>(new Threefish_512);
199
0
      }
200
1.00k
#endif
201
1.00k
202
1.00k
#if defined(BOTAN_HAS_BLOWFISH)
203
1.00k
   if(algo == "Blowfish")
204
0
      {
205
0
      return std::unique_ptr<BlockCipher>(new Blowfish);
206
0
      }
207
1.00k
#endif
208
1.00k
209
1.00k
#if defined(BOTAN_HAS_CAMELLIA)
210
1.00k
   if(algo == "Camellia-128")
211
188
      {
212
188
      return std::unique_ptr<BlockCipher>(new Camellia_128);
213
188
      }
214
812
215
812
   if(algo == "Camellia-192")
216
0
      {
217
0
      return std::unique_ptr<BlockCipher>(new Camellia_192);
218
0
      }
219
812
220
812
   if(algo == "Camellia-256")
221
351
      {
222
351
      return std::unique_ptr<BlockCipher>(new Camellia_256);
223
351
      }
224
461
#endif
225
461
226
461
#if defined(BOTAN_HAS_DES)
227
461
   if(algo == "DES")
228
0
      {
229
0
      return std::unique_ptr<BlockCipher>(new DES);
230
0
      }
231
461
232
461
   if(algo == "DESX")
233
0
      {
234
0
      return std::unique_ptr<BlockCipher>(new DESX);
235
0
      }
236
461
237
461
   if(algo == "TripleDES" || algo == "3DES" || algo == "DES-EDE")
238
371
      {
239
371
      return std::unique_ptr<BlockCipher>(new TripleDES);
240
371
      }
241
90
#endif
242
90
243
90
#if defined(BOTAN_HAS_NOEKEON)
244
90
   if(algo == "Noekeon")
245
0
      {
246
0
      return std::unique_ptr<BlockCipher>(new Noekeon);
247
0
      }
248
90
#endif
249
90
250
90
#if defined(BOTAN_HAS_CAST_128)
251
90
   if(algo == "CAST-128" || algo == "CAST5")
252
0
      {
253
0
      return std::unique_ptr<BlockCipher>(new CAST_128);
254
0
      }
255
90
#endif
256
90
257
90
#if defined(BOTAN_HAS_CAST_256)
258
90
   if(algo == "CAST-256")
259
0
      {
260
0
      return std::unique_ptr<BlockCipher>(new CAST_256);
261
0
      }
262
90
#endif
263
90
264
90
#if defined(BOTAN_HAS_IDEA)
265
90
   if(algo == "IDEA")
266
0
      {
267
0
      return std::unique_ptr<BlockCipher>(new IDEA);
268
0
      }
269
90
#endif
270
90
271
90
#if defined(BOTAN_HAS_KASUMI)
272
90
   if(algo == "KASUMI")
273
0
      {
274
0
      return std::unique_ptr<BlockCipher>(new KASUMI);
275
0
      }
276
90
#endif
277
90
278
90
#if defined(BOTAN_HAS_MISTY1)
279
90
   if(algo == "MISTY1")
280
0
      {
281
0
      return std::unique_ptr<BlockCipher>(new MISTY1);
282
0
      }
283
90
#endif
284
90
285
90
#if defined(BOTAN_HAS_SEED)
286
90
   if(algo == "SEED")
287
90
      {
288
90
      return std::unique_ptr<BlockCipher>(new SEED);
289
90
      }
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
1.19k
   {
351
1.19k
   if(auto bc = BlockCipher::create(algo, provider))
352
1.19k
      {
353
1.19k
      return bc;
354
1.19k
      }
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
}