Coverage Report

Created: 2020-10-17 06:46

/src/botan/src/lib/hash/hash.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
* Hash Functions
3
* (C) 2015 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7
8
#include <botan/hash.h>
9
#include <botan/scan_name.h>
10
#include <botan/exceptn.h>
11
12
#if defined(BOTAN_HAS_ADLER32)
13
  #include <botan/adler32.h>
14
#endif
15
16
#if defined(BOTAN_HAS_CRC24)
17
  #include <botan/crc24.h>
18
#endif
19
20
#if defined(BOTAN_HAS_CRC32)
21
  #include <botan/crc32.h>
22
#endif
23
24
#if defined(BOTAN_HAS_GOST_34_11)
25
  #include <botan/gost_3411.h>
26
#endif
27
28
#if defined(BOTAN_HAS_KECCAK)
29
  #include <botan/keccak.h>
30
#endif
31
32
#if defined(BOTAN_HAS_MD4)
33
  #include <botan/md4.h>
34
#endif
35
36
#if defined(BOTAN_HAS_MD5)
37
  #include <botan/md5.h>
38
#endif
39
40
#if defined(BOTAN_HAS_RIPEMD_160)
41
  #include <botan/rmd160.h>
42
#endif
43
44
#if defined(BOTAN_HAS_SHA1)
45
  #include <botan/sha160.h>
46
#endif
47
48
#if defined(BOTAN_HAS_SHA2_32)
49
  #include <botan/sha2_32.h>
50
#endif
51
52
#if defined(BOTAN_HAS_SHA2_64)
53
  #include <botan/sha2_64.h>
54
#endif
55
56
#if defined(BOTAN_HAS_SHA3)
57
  #include <botan/sha3.h>
58
#endif
59
60
#if defined(BOTAN_HAS_SHAKE)
61
  #include <botan/shake.h>
62
#endif
63
64
#if defined(BOTAN_HAS_SKEIN_512)
65
  #include <botan/skein_512.h>
66
#endif
67
68
#if defined(BOTAN_HAS_STREEBOG)
69
  #include <botan/streebog.h>
70
#endif
71
72
#if defined(BOTAN_HAS_SM3)
73
  #include <botan/sm3.h>
74
#endif
75
76
#if defined(BOTAN_HAS_TIGER)
77
  #include <botan/tiger.h>
78
#endif
79
80
#if defined(BOTAN_HAS_WHIRLPOOL)
81
  #include <botan/whrlpool.h>
82
#endif
83
84
#if defined(BOTAN_HAS_PARALLEL_HASH)
85
  #include <botan/par_hash.h>
86
#endif
87
88
#if defined(BOTAN_HAS_COMB4P)
89
  #include <botan/comb4p.h>
90
#endif
91
92
#if defined(BOTAN_HAS_BLAKE2B)
93
  #include <botan/blake2b.h>
94
#endif
95
96
#if defined(BOTAN_HAS_OPENSSL)
97
  #include <botan/internal/openssl.h>
98
#endif
99
100
#if defined(BOTAN_HAS_COMMONCRYPTO)
101
  #include <botan/internal/commoncrypto.h>
102
#endif
103
104
namespace Botan {
105
106
std::unique_ptr<HashFunction> HashFunction::create(const std::string& algo_spec,
107
                                                   const std::string& provider)
108
143k
   {
109
143k
110
#if defined(BOTAN_HAS_COMMONCRYPTO)
111
   if(provider.empty() || provider == "commoncrypto")
112
      {
113
      if(auto hash = make_commoncrypto_hash(algo_spec))
114
         return hash;
115
116
      if(!provider.empty())
117
         return nullptr;
118
      }
119
#endif
120
143k
121
#if defined(BOTAN_HAS_OPENSSL)
122
   if(provider.empty() || provider == "openssl")
123
      {
124
      if(auto hash = make_openssl_hash(algo_spec))
125
         return hash;
126
127
      if(!provider.empty())
128
         return nullptr;
129
      }
130
#endif
131
143k
132
143k
   if(provider.empty() == false && provider != "base")
133
1.08k
      return nullptr; // unknown provider
134
142k
135
142k
#if defined(BOTAN_HAS_SHA1)
136
142k
   if(algo_spec == "SHA-160" ||
137
141k
      algo_spec == "SHA-1" ||
138
117k
      algo_spec == "SHA1")
139
24.7k
      {
140
24.7k
      return std::unique_ptr<HashFunction>(new SHA_160);
141
24.7k
      }
142
117k
#endif
143
117k
144
117k
#if defined(BOTAN_HAS_SHA2_32)
145
117k
   if(algo_spec == "SHA-224")
146
124
      {
147
124
      return std::unique_ptr<HashFunction>(new SHA_224);
148
124
      }
149
117k
150
117k
   if(algo_spec == "SHA-256")
151
108k
      {
152
108k
      return std::unique_ptr<HashFunction>(new SHA_256);
153
108k
      }
154
8.63k
#endif
155
8.63k
156
8.63k
#if defined(BOTAN_HAS_SHA2_64)
157
8.63k
   if(algo_spec == "SHA-384")
158
8.09k
      {
159
8.09k
      return std::unique_ptr<HashFunction>(new SHA_384);
160
8.09k
      }
161
540
162
540
   if(algo_spec == "SHA-512")
163
96
      {
164
96
      return std::unique_ptr<HashFunction>(new SHA_512);
165
96
      }
166
444
167
444
   if(algo_spec == "SHA-512-256")
168
351
      {
169
351
      return std::unique_ptr<HashFunction>(new SHA_512_256);
170
351
      }
171
93
#endif
172
93
173
93
#if defined(BOTAN_HAS_RIPEMD_160)
174
93
   if(algo_spec == "RIPEMD-160")
175
0
      {
176
0
      return std::unique_ptr<HashFunction>(new RIPEMD_160);
177
0
      }
178
93
#endif
179
93
180
93
#if defined(BOTAN_HAS_WHIRLPOOL)
181
93
   if(algo_spec == "Whirlpool")
182
0
      {
183
0
      return std::unique_ptr<HashFunction>(new Whirlpool);
184
0
      }
185
93
#endif
186
93
187
93
#if defined(BOTAN_HAS_MD5)
188
93
   if(algo_spec == "MD5")
189
93
      {
190
93
      return std::unique_ptr<HashFunction>(new MD5);
191
93
      }
192
0
#endif
193
0
194
0
#if defined(BOTAN_HAS_MD4)
195
0
   if(algo_spec == "MD4")
196
0
      {
197
0
      return std::unique_ptr<HashFunction>(new MD4);
198
0
      }
199
0
#endif
200
0
201
0
#if defined(BOTAN_HAS_GOST_34_11)
202
0
   if(algo_spec == "GOST-R-34.11-94" || algo_spec == "GOST-34.11")
203
0
      {
204
0
      return std::unique_ptr<HashFunction>(new GOST_34_11);
205
0
      }
206
0
#endif
207
0
208
0
#if defined(BOTAN_HAS_ADLER32)
209
0
   if(algo_spec == "Adler32")
210
0
      {
211
0
      return std::unique_ptr<HashFunction>(new Adler32);
212
0
      }
213
0
#endif
214
0
215
0
#if defined(BOTAN_HAS_CRC24)
216
0
   if(algo_spec == "CRC24")
217
0
      {
218
0
      return std::unique_ptr<HashFunction>(new CRC24);
219
0
      }
220
0
#endif
221
0
222
0
#if defined(BOTAN_HAS_CRC32)
223
0
   if(algo_spec == "CRC32")
224
0
      {
225
0
      return std::unique_ptr<HashFunction>(new CRC32);
226
0
      }
227
0
#endif
228
0
229
0
   const SCAN_Name req(algo_spec);
230
0
231
0
#if defined(BOTAN_HAS_TIGER)
232
0
   if(req.algo_name() == "Tiger")
233
0
      {
234
0
      return std::unique_ptr<HashFunction>(
235
0
         new Tiger(req.arg_as_integer(0, 24),
236
0
                   req.arg_as_integer(1, 3)));
237
0
      }
238
0
#endif
239
0
240
0
#if defined(BOTAN_HAS_SKEIN_512)
241
0
   if(req.algo_name() == "Skein-512")
242
0
      {
243
0
      return std::unique_ptr<HashFunction>(
244
0
         new Skein_512(req.arg_as_integer(0, 512), req.arg(1, "")));
245
0
      }
246
0
#endif
247
0
248
0
#if defined(BOTAN_HAS_BLAKE2B)
249
0
   if(req.algo_name() == "Blake2b" || req.algo_name() == "BLAKE2b")
250
0
      {
251
0
      return std::unique_ptr<HashFunction>(
252
0
         new Blake2b(req.arg_as_integer(0, 512)));
253
0
   }
254
0
#endif
255
0
256
0
#if defined(BOTAN_HAS_KECCAK)
257
0
   if(req.algo_name() == "Keccak-1600")
258
0
      {
259
0
      return std::unique_ptr<HashFunction>(
260
0
         new Keccak_1600(req.arg_as_integer(0, 512)));
261
0
      }
262
0
#endif
263
0
264
0
#if defined(BOTAN_HAS_SHA3)
265
0
   if(req.algo_name() == "SHA-3")
266
0
      {
267
0
      return std::unique_ptr<HashFunction>(
268
0
         new SHA_3(req.arg_as_integer(0, 512)));
269
0
      }
270
0
#endif
271
0
272
0
#if defined(BOTAN_HAS_SHAKE)
273
0
   if(req.algo_name() == "SHAKE-128")
274
0
      {
275
0
      return std::unique_ptr<HashFunction>(new SHAKE_128(req.arg_as_integer(0, 128)));
276
0
      }
277
0
   if(req.algo_name() == "SHAKE-256")
278
0
      {
279
0
      return std::unique_ptr<HashFunction>(new SHAKE_256(req.arg_as_integer(0, 256)));
280
0
      }
281
0
#endif
282
0
283
0
#if defined(BOTAN_HAS_STREEBOG)
284
0
   if(algo_spec == "Streebog-256")
285
0
      {
286
0
      return std::unique_ptr<HashFunction>(new Streebog_256);
287
0
      }
288
0
   if(algo_spec == "Streebog-512")
289
0
      {
290
0
      return std::unique_ptr<HashFunction>(new Streebog_512);
291
0
      }
292
0
#endif
293
0
294
0
#if defined(BOTAN_HAS_SM3)
295
0
   if(algo_spec == "SM3")
296
0
      {
297
0
      return std::unique_ptr<HashFunction>(new SM3);
298
0
      }
299
0
#endif
300
0
301
0
#if defined(BOTAN_HAS_WHIRLPOOL)
302
0
   if(req.algo_name() == "Whirlpool")
303
0
      {
304
0
      return std::unique_ptr<HashFunction>(new Whirlpool);
305
0
      }
306
0
#endif
307
0
308
0
#if defined(BOTAN_HAS_PARALLEL_HASH)
309
0
   if(req.algo_name() == "Parallel")
310
0
      {
311
0
      std::vector<std::unique_ptr<HashFunction>> hashes;
312
0
313
0
      for(size_t i = 0; i != req.arg_count(); ++i)
314
0
         {
315
0
         auto h = HashFunction::create(req.arg(i));
316
0
         if(!h)
317
0
            {
318
0
            return nullptr;
319
0
            }
320
0
         hashes.push_back(std::move(h));
321
0
         }
322
0
323
0
      return std::unique_ptr<HashFunction>(new Parallel(hashes));
324
0
      }
325
0
#endif
326
0
327
0
#if defined(BOTAN_HAS_COMB4P)
328
0
   if(req.algo_name() == "Comb4P" && req.arg_count() == 2)
329
0
      {
330
0
      std::unique_ptr<HashFunction> h1(HashFunction::create(req.arg(0)));
331
0
      std::unique_ptr<HashFunction> h2(HashFunction::create(req.arg(1)));
332
0
333
0
      if(h1 && h2)
334
0
         return std::unique_ptr<HashFunction>(new Comb4P(h1.release(), h2.release()));
335
0
      }
336
0
#endif
337
0
338
0
339
0
   return nullptr;
340
0
   }
341
342
//static
343
std::unique_ptr<HashFunction>
344
HashFunction::create_or_throw(const std::string& algo,
345
                              const std::string& provider)
346
85.6k
   {
347
85.6k
   if(auto hash = HashFunction::create(algo, provider))
348
85.6k
      {
349
85.6k
      return hash;
350
85.6k
      }
351
0
   throw Lookup_Error("Hash", algo, provider);
352
0
   }
353
354
std::vector<std::string> HashFunction::providers(const std::string& algo_spec)
355
540
   {
356
540
   return probe_providers_of<HashFunction>(algo_spec, {"base", "openssl", "commoncrypto"});
357
540
   }
358
359
}
360