Coverage Report

Created: 2026-09-03 07:16

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