Coverage Report

Created: 2021-06-10 10:30

/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
136k
#if defined(BOTAN_HAS_SHA1)
132
136k
   if(algo_spec == "SHA-160" ||
133
136k
      algo_spec == "SHA-1" ||
134
116k
      algo_spec == "SHA1")
135
19.8k
      {
136
19.8k
      return std::make_unique<SHA_160>();
137
19.8k
      }
138
116k
#endif
139
140
116k
#if defined(BOTAN_HAS_SHA2_32)
141
116k
   if(algo_spec == "SHA-224")
142
65
      {
143
65
      return std::make_unique<SHA_224>();
144
65
      }
145
146
116k
   if(algo_spec == "SHA-256")
147
113k
      {
148
113k
      return std::make_unique<SHA_256>();
149
113k
      }
150
3.29k
#endif
151
152
3.29k
#if defined(BOTAN_HAS_SHA2_64)
153
3.29k
   if(algo_spec == "SHA-384")
154
2.70k
      {
155
2.70k
      return std::make_unique<SHA_384>();
156
2.70k
      }
157
158
590
   if(algo_spec == "SHA-512")
159
9
      {
160
9
      return std::make_unique<SHA_512>();
161
9
      }
162
163
581
   if(algo_spec == "SHA-512-256")
164
479
      {
165
479
      return std::make_unique<SHA_512_256>();
166
479
      }
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::make_unique<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::make_unique<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::make_unique<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::make_unique<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::make_unique<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::make_unique<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::make_unique<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::make_unique<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::make_unique<Skein_512>(req.arg_as_integer(0, 512), req.arg(1, ""));
231
0
      }
232
0
#endif
233
234
0
#if defined(BOTAN_HAS_BLAKE2B)
235
0
   if(req.algo_name() == "Blake2b" || req.algo_name() == "BLAKE2b")
236
0
      {
237
0
      return std::make_unique<Blake2b>(req.arg_as_integer(0, 512));
238
0
   }
239
0
#endif
240
241
0
#if defined(BOTAN_HAS_KECCAK)
242
0
   if(req.algo_name() == "Keccak-1600")
243
0
      {
244
0
      return std::make_unique<Keccak_1600>(req.arg_as_integer(0, 512));
245
0
      }
246
0
#endif
247
248
0
#if defined(BOTAN_HAS_SHA3)
249
0
   if(req.algo_name() == "SHA-3")
250
0
      {
251
0
      return std::make_unique<SHA_3>(req.arg_as_integer(0, 512));
252
0
      }
253
0
#endif
254
255
0
#if defined(BOTAN_HAS_SHAKE)
256
0
   if(req.algo_name() == "SHAKE-128" && req.arg_count() == 1)
257
0
      {
258
0
      return std::make_unique<SHAKE_128>(req.arg_as_integer(0));
259
0
      }
260
0
   if(req.algo_name() == "SHAKE-256" && req.arg_count() == 1)
261
0
      {
262
0
      return std::make_unique<SHAKE_256>(req.arg_as_integer(0));
263
0
      }
264
0
#endif
265
266
0
#if defined(BOTAN_HAS_STREEBOG)
267
0
   if(algo_spec == "Streebog-256")
268
0
      {
269
0
      return std::make_unique<Streebog_256>();
270
0
      }
271
0
   if(algo_spec == "Streebog-512")
272
0
      {
273
0
      return std::make_unique<Streebog_512>();
274
0
      }
275
0
#endif
276
277
0
#if defined(BOTAN_HAS_SM3)
278
0
   if(algo_spec == "SM3")
279
0
      {
280
0
      return std::make_unique<SM3>();
281
0
      }
282
0
#endif
283
284
0
#if defined(BOTAN_HAS_WHIRLPOOL)
285
0
   if(req.algo_name() == "Whirlpool")
286
0
      {
287
0
      return std::make_unique<Whirlpool>();
288
0
      }
289
0
#endif
290
291
0
#if defined(BOTAN_HAS_PARALLEL_HASH)
292
0
   if(req.algo_name() == "Parallel")
293
0
      {
294
0
      std::vector<std::unique_ptr<HashFunction>> hashes;
295
296
0
      for(size_t i = 0; i != req.arg_count(); ++i)
297
0
         {
298
0
         auto h = HashFunction::create(req.arg(i));
299
0
         if(!h)
300
0
            {
301
0
            return nullptr;
302
0
            }
303
0
         hashes.push_back(std::move(h));
304
0
         }
305
306
0
      return std::make_unique<Parallel>(hashes);
307
0
      }
308
0
#endif
309
310
0
#if defined(BOTAN_HAS_COMB4P)
311
0
   if(req.algo_name() == "Comb4P" && req.arg_count() == 2)
312
0
      {
313
0
      std::unique_ptr<HashFunction> h1 = HashFunction::create(req.arg(0));
314
0
      std::unique_ptr<HashFunction> h2 = HashFunction::create(req.arg(1));
315
316
0
      if(h1 && h2)
317
0
         return std::make_unique<Comb4P>(std::move(h1), std::move(h2));
318
0
      }
319
0
#endif
320
321
322
0
   return nullptr;
323
0
   }
324
325
//static
326
std::unique_ptr<HashFunction>
327
HashFunction::create_or_throw(const std::string& algo,
328
                              const std::string& provider)
329
84.7k
   {
330
84.7k
   if(auto hash = HashFunction::create(algo, provider))
331
84.7k
      {
332
84.7k
      return hash;
333
84.7k
      }
334
0
   throw Lookup_Error("Hash", algo, provider);
335
0
   }
336
337
std::vector<std::string> HashFunction::providers(const std::string& algo_spec)
338
250
   {
339
250
   return probe_providers_of<HashFunction>(algo_spec, {"base", "openssl", "commoncrypto"});
340
250
   }
341
342
}
343