Coverage Report

Created: 2021-02-21 07:20

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