Coverage Report

Created: 2021-02-21 07:20

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