Coverage Report

Created: 2025-04-11 06:34

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