Coverage Report

Created: 2022-06-23 06:44

/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_COMMONCRYPTO)
93
  #include <botan/internal/commoncrypto.h>
94
#endif
95
96
namespace Botan {
97
98
std::unique_ptr<HashFunction> HashFunction::create(const std::string& algo_spec,
99
                                                   const std::string& provider)
100
107k
   {
101
102
#if defined(BOTAN_HAS_COMMONCRYPTO)
103
   if(provider.empty() || provider == "commoncrypto")
104
      {
105
      if(auto hash = make_commoncrypto_hash(algo_spec))
106
         return hash;
107
108
      if(!provider.empty())
109
         return nullptr;
110
      }
111
#endif
112
113
107k
   if(provider.empty() == false && provider != "base")
114
250
      return nullptr; // unknown provider
115
116
107k
#if defined(BOTAN_HAS_SHA1)
117
107k
   if(algo_spec == "SHA-160" ||
118
107k
      algo_spec == "SHA-1" ||
119
107k
      algo_spec == "SHA1")
120
20.9k
      {
121
20.9k
      return std::make_unique<SHA_160>();
122
20.9k
      }
123
86.6k
#endif
124
125
86.6k
#if defined(BOTAN_HAS_SHA2_32)
126
86.6k
   if(algo_spec == "SHA-224")
127
19
      {
128
19
      return std::make_unique<SHA_224>();
129
19
      }
130
131
86.5k
   if(algo_spec == "SHA-256")
132
81.7k
      {
133
81.7k
      return std::make_unique<SHA_256>();
134
81.7k
      }
135
4.82k
#endif
136
137
4.82k
#if defined(BOTAN_HAS_SHA2_64)
138
4.82k
   if(algo_spec == "SHA-384")
139
4.14k
      {
140
4.14k
      return std::make_unique<SHA_384>();
141
4.14k
      }
142
143
682
   if(algo_spec == "SHA-512")
144
124
      {
145
124
      return std::make_unique<SHA_512>();
146
124
      }
147
148
558
   if(algo_spec == "SHA-512-256")
149
240
      {
150
240
      return std::make_unique<SHA_512_256>();
151
240
      }
152
318
#endif
153
154
318
#if defined(BOTAN_HAS_RIPEMD_160)
155
318
   if(algo_spec == "RIPEMD-160")
156
0
      {
157
0
      return std::make_unique<RIPEMD_160>();
158
0
      }
159
318
#endif
160
161
318
#if defined(BOTAN_HAS_WHIRLPOOL)
162
318
   if(algo_spec == "Whirlpool")
163
0
      {
164
0
      return std::make_unique<Whirlpool>();
165
0
      }
166
318
#endif
167
168
318
#if defined(BOTAN_HAS_MD5)
169
318
   if(algo_spec == "MD5")
170
311
      {
171
311
      return std::make_unique<MD5>();
172
311
      }
173
7
#endif
174
175
7
#if defined(BOTAN_HAS_MD4)
176
7
   if(algo_spec == "MD4")
177
0
      {
178
0
      return std::make_unique<MD4>();
179
0
      }
180
7
#endif
181
182
7
#if defined(BOTAN_HAS_GOST_34_11)
183
7
   if(algo_spec == "GOST-R-34.11-94" || algo_spec == "GOST-34.11")
184
0
      {
185
0
      return std::make_unique<GOST_34_11>();
186
0
      }
187
7
#endif
188
189
7
#if defined(BOTAN_HAS_ADLER32)
190
7
   if(algo_spec == "Adler32")
191
0
      {
192
0
      return std::make_unique<Adler32>();
193
0
      }
194
7
#endif
195
196
7
#if defined(BOTAN_HAS_CRC24)
197
7
   if(algo_spec == "CRC24")
198
0
      {
199
0
      return std::make_unique<CRC24>();
200
0
      }
201
7
#endif
202
203
7
#if defined(BOTAN_HAS_CRC32)
204
7
   if(algo_spec == "CRC32")
205
0
      {
206
0
      return std::make_unique<CRC32>();
207
0
      }
208
7
#endif
209
210
7
   const SCAN_Name req(algo_spec);
211
212
7
#if defined(BOTAN_HAS_SKEIN_512)
213
7
   if(req.algo_name() == "Skein-512")
214
0
      {
215
0
      return std::make_unique<Skein_512>(req.arg_as_integer(0, 512), req.arg(1, ""));
216
0
      }
217
7
#endif
218
219
7
#if defined(BOTAN_HAS_BLAKE2B)
220
7
   if(req.algo_name() == "Blake2b" || req.algo_name() == "BLAKE2b")
221
0
      {
222
0
      return std::make_unique<Blake2b>(req.arg_as_integer(0, 512));
223
0
   }
224
7
#endif
225
226
7
#if defined(BOTAN_HAS_KECCAK)
227
7
   if(req.algo_name() == "Keccak-1600")
228
0
      {
229
0
      return std::make_unique<Keccak_1600>(req.arg_as_integer(0, 512));
230
0
      }
231
7
#endif
232
233
7
#if defined(BOTAN_HAS_SHA3)
234
7
   if(req.algo_name() == "SHA-3")
235
0
      {
236
0
      return std::make_unique<SHA_3>(req.arg_as_integer(0, 512));
237
0
      }
238
7
#endif
239
240
7
#if defined(BOTAN_HAS_SHAKE)
241
7
   if(req.algo_name() == "SHAKE-128" && req.arg_count() == 1)
242
0
      {
243
0
      return std::make_unique<SHAKE_128>(req.arg_as_integer(0));
244
0
      }
245
7
   if(req.algo_name() == "SHAKE-256" && req.arg_count() == 1)
246
0
      {
247
0
      return std::make_unique<SHAKE_256>(req.arg_as_integer(0));
248
0
      }
249
7
#endif
250
251
7
#if defined(BOTAN_HAS_STREEBOG)
252
7
   if(algo_spec == "Streebog-256")
253
7
      {
254
7
      return std::make_unique<Streebog>(256);
255
7
      }
256
0
   if(algo_spec == "Streebog-512")
257
0
      {
258
0
      return std::make_unique<Streebog>(512);
259
0
      }
260
0
#endif
261
262
0
#if defined(BOTAN_HAS_SM3)
263
0
   if(algo_spec == "SM3")
264
0
      {
265
0
      return std::make_unique<SM3>();
266
0
      }
267
0
#endif
268
269
0
#if defined(BOTAN_HAS_WHIRLPOOL)
270
0
   if(req.algo_name() == "Whirlpool")
271
0
      {
272
0
      return std::make_unique<Whirlpool>();
273
0
      }
274
0
#endif
275
276
0
#if defined(BOTAN_HAS_PARALLEL_HASH)
277
0
   if(req.algo_name() == "Parallel")
278
0
      {
279
0
      std::vector<std::unique_ptr<HashFunction>> hashes;
280
281
0
      for(size_t i = 0; i != req.arg_count(); ++i)
282
0
         {
283
0
         auto h = HashFunction::create(req.arg(i));
284
0
         if(!h)
285
0
            {
286
0
            return nullptr;
287
0
            }
288
0
         hashes.push_back(std::move(h));
289
0
         }
290
291
0
      return std::make_unique<Parallel>(hashes);
292
0
      }
293
0
#endif
294
295
0
#if defined(BOTAN_HAS_COMB4P)
296
0
   if(req.algo_name() == "Comb4P" && req.arg_count() == 2)
297
0
      {
298
0
      std::unique_ptr<HashFunction> h1 = HashFunction::create(req.arg(0));
299
0
      std::unique_ptr<HashFunction> h2 = HashFunction::create(req.arg(1));
300
301
0
      if(h1 && h2)
302
0
         return std::make_unique<Comb4P>(std::move(h1), std::move(h2));
303
0
      }
304
0
#endif
305
306
307
0
   return nullptr;
308
0
   }
309
310
//static
311
std::unique_ptr<HashFunction>
312
HashFunction::create_or_throw(const std::string& algo,
313
                              const std::string& provider)
314
64.1k
   {
315
64.1k
   if(auto hash = HashFunction::create(algo, provider))
316
64.1k
      {
317
64.1k
      return hash;
318
64.1k
      }
319
0
   throw Lookup_Error("Hash", algo, provider);
320
64.1k
   }
321
322
std::vector<std::string> HashFunction::providers(const std::string& algo_spec)
323
250
   {
324
250
   return probe_providers_of<HashFunction>(algo_spec, {"base", "commoncrypto"});
325
250
   }
326
327
}
328