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