Coverage Report

Created: 2023-02-22 06:39

/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/sha1.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_TRUNCATED_HASH)
85
  #include <botan/internal/trunc_hash.h>
86
#endif
87
88
#if defined(BOTAN_HAS_COMB4P)
89
  #include <botan/internal/comb4p.h>
90
#endif
91
92
#if defined(BOTAN_HAS_BLAKE2B)
93
  #include <botan/internal/blake2b.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
1.23k
   {
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
1.23k
   if(provider.empty() == false && provider != "base")
118
0
      return nullptr; // unknown provider
119
120
1.23k
#if defined(BOTAN_HAS_SHA1)
121
1.23k
   if(algo_spec == "SHA-1")
122
0
      {
123
0
      return std::make_unique<SHA_1>();
124
0
      }
125
1.23k
#endif
126
127
1.23k
#if defined(BOTAN_HAS_SHA2_32)
128
1.23k
   if(algo_spec == "SHA-224")
129
92
      {
130
92
      return std::make_unique<SHA_224>();
131
92
      }
132
133
1.14k
   if(algo_spec == "SHA-256")
134
406
      {
135
406
      return std::make_unique<SHA_256>();
136
406
      }
137
736
#endif
138
139
736
#if defined(BOTAN_HAS_SHA2_64)
140
736
   if(algo_spec == "SHA-384")
141
101
      {
142
101
      return std::make_unique<SHA_384>();
143
101
      }
144
145
635
   if(algo_spec == "SHA-512")
146
66
      {
147
66
      return std::make_unique<SHA_512>();
148
66
      }
149
150
569
   if(algo_spec == "SHA-512-256")
151
23
      {
152
23
      return std::make_unique<SHA_512_256>();
153
23
      }
154
546
#endif
155
156
546
#if defined(BOTAN_HAS_RIPEMD_160)
157
546
   if(algo_spec == "RIPEMD-160")
158
90
      {
159
90
      return std::make_unique<RIPEMD_160>();
160
90
      }
161
456
#endif
162
163
456
#if defined(BOTAN_HAS_WHIRLPOOL)
164
456
   if(algo_spec == "Whirlpool")
165
0
      {
166
0
      return std::make_unique<Whirlpool>();
167
0
      }
168
456
#endif
169
170
456
#if defined(BOTAN_HAS_MD5)
171
456
   if(algo_spec == "MD5")
172
0
      {
173
0
      return std::make_unique<MD5>();
174
0
      }
175
456
#endif
176
177
456
#if defined(BOTAN_HAS_MD4)
178
456
   if(algo_spec == "MD4")
179
0
      {
180
0
      return std::make_unique<MD4>();
181
0
      }
182
456
#endif
183
184
456
#if defined(BOTAN_HAS_GOST_34_11)
185
456
   if(algo_spec == "GOST-R-34.11-94" || algo_spec == "GOST-34.11")
186
0
      {
187
0
      return std::make_unique<GOST_34_11>();
188
0
      }
189
456
#endif
190
191
456
#if defined(BOTAN_HAS_ADLER32)
192
456
   if(algo_spec == "Adler32")
193
0
      {
194
0
      return std::make_unique<Adler32>();
195
0
      }
196
456
#endif
197
198
456
#if defined(BOTAN_HAS_CRC24)
199
456
   if(algo_spec == "CRC24")
200
0
      {
201
0
      return std::make_unique<CRC24>();
202
0
      }
203
456
#endif
204
205
456
#if defined(BOTAN_HAS_CRC32)
206
456
   if(algo_spec == "CRC32")
207
0
      {
208
0
      return std::make_unique<CRC32>();
209
0
      }
210
456
#endif
211
212
456
   const SCAN_Name req(algo_spec);
213
214
456
#if defined(BOTAN_HAS_SKEIN_512)
215
456
   if(req.algo_name() == "Skein-512")
216
0
      {
217
0
      return std::make_unique<Skein_512>(req.arg_as_integer(0, 512), req.arg(1, ""));
218
0
      }
219
456
#endif
220
221
456
#if defined(BOTAN_HAS_BLAKE2B)
222
456
   if(req.algo_name() == "Blake2b" || req.algo_name() == "BLAKE2b")
223
0
      {
224
0
      return std::make_unique<BLAKE2b>(req.arg_as_integer(0, 512));
225
0
   }
226
456
#endif
227
228
456
#if defined(BOTAN_HAS_KECCAK)
229
456
   if(req.algo_name() == "Keccak-1600")
230
0
      {
231
0
      return std::make_unique<Keccak_1600>(req.arg_as_integer(0, 512));
232
0
      }
233
456
#endif
234
235
456
#if defined(BOTAN_HAS_SHA3)
236
456
   if(req.algo_name() == "SHA-3")
237
229
      {
238
229
      return std::make_unique<SHA_3>(req.arg_as_integer(0, 512));
239
229
      }
240
227
#endif
241
242
227
#if defined(BOTAN_HAS_SHAKE)
243
227
   if(req.algo_name() == "SHAKE-128" && req.arg_count() == 1)
244
0
      {
245
0
      return std::make_unique<SHAKE_128>(req.arg_as_integer(0));
246
0
      }
247
227
   if(req.algo_name() == "SHAKE-256" && req.arg_count() == 1)
248
0
      {
249
0
      return std::make_unique<SHAKE_256>(req.arg_as_integer(0));
250
0
      }
251
227
#endif
252
253
227
#if defined(BOTAN_HAS_STREEBOG)
254
227
   if(algo_spec == "Streebog-256")
255
60
      {
256
60
      return std::make_unique<Streebog>(256);
257
60
      }
258
167
   if(algo_spec == "Streebog-512")
259
93
      {
260
93
      return std::make_unique<Streebog>(512);
261
93
      }
262
74
#endif
263
264
74
#if defined(BOTAN_HAS_SM3)
265
74
   if(algo_spec == "SM3")
266
74
      {
267
74
      return std::make_unique<SM3>();
268
74
      }
269
0
#endif
270
271
0
#if defined(BOTAN_HAS_WHIRLPOOL)
272
0
   if(req.algo_name() == "Whirlpool")
273
0
      {
274
0
      return std::make_unique<Whirlpool>();
275
0
      }
276
0
#endif
277
278
0
#if defined(BOTAN_HAS_PARALLEL_HASH)
279
0
   if(req.algo_name() == "Parallel")
280
0
      {
281
0
      std::vector<std::unique_ptr<HashFunction>> hashes;
282
283
0
      for(size_t i = 0; i != req.arg_count(); ++i)
284
0
         {
285
0
         auto h = HashFunction::create(req.arg(i));
286
0
         if(!h)
287
0
            {
288
0
            return nullptr;
289
0
            }
290
0
         hashes.push_back(std::move(h));
291
0
         }
292
293
0
      return std::make_unique<Parallel>(hashes);
294
0
      }
295
0
#endif
296
297
0
#if defined(BOTAN_HAS_TRUNCATED_HASH)
298
0
   if(req.algo_name() == "Truncated" && req.arg_count() == 2)
299
0
      {
300
0
      auto hash = HashFunction::create(req.arg(0));
301
0
      if(!hash)
302
0
         {
303
0
         return nullptr;
304
0
         }
305
306
0
      return std::make_unique<Truncated_Hash>(std::move(hash), req.arg_as_integer(1));
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
0
   {
330
0
   if(auto hash = HashFunction::create(algo, provider))
331
0
      {
332
0
      return hash;
333
0
      }
334
0
   throw Lookup_Error("Hash", algo, provider);
335
0
   }
336
337
std::vector<std::string> HashFunction::providers(const std::string& algo_spec)
338
0
   {
339
0
   return probe_providers_of<HashFunction>(algo_spec, {"base", "commoncrypto"});
340
0
   }
341
342
}
343