Botan 2.19.3
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/scan_name.h>
10#include <botan/exceptn.h>
11
12#if defined(BOTAN_HAS_ADLER32)
13 #include <botan/adler32.h>
14#endif
15
16#if defined(BOTAN_HAS_CRC24)
17 #include <botan/crc24.h>
18#endif
19
20#if defined(BOTAN_HAS_CRC32)
21 #include <botan/crc32.h>
22#endif
23
24#if defined(BOTAN_HAS_GOST_34_11)
25 #include <botan/gost_3411.h>
26#endif
27
28#if defined(BOTAN_HAS_KECCAK)
29 #include <botan/keccak.h>
30#endif
31
32#if defined(BOTAN_HAS_MD4)
33 #include <botan/md4.h>
34#endif
35
36#if defined(BOTAN_HAS_MD5)
37 #include <botan/md5.h>
38#endif
39
40#if defined(BOTAN_HAS_RIPEMD_160)
41 #include <botan/rmd160.h>
42#endif
43
44#if defined(BOTAN_HAS_SHA1)
45 #include <botan/sha160.h>
46#endif
47
48#if defined(BOTAN_HAS_SHA2_32)
49 #include <botan/sha2_32.h>
50#endif
51
52#if defined(BOTAN_HAS_SHA2_64)
53 #include <botan/sha2_64.h>
54#endif
55
56#if defined(BOTAN_HAS_SHA3)
57 #include <botan/sha3.h>
58#endif
59
60#if defined(BOTAN_HAS_SHAKE)
61 #include <botan/shake.h>
62#endif
63
64#if defined(BOTAN_HAS_SKEIN_512)
65 #include <botan/skein_512.h>
66#endif
67
68#if defined(BOTAN_HAS_STREEBOG)
69 #include <botan/streebog.h>
70#endif
71
72#if defined(BOTAN_HAS_SM3)
73 #include <botan/sm3.h>
74#endif
75
76#if defined(BOTAN_HAS_TIGER)
77 #include <botan/tiger.h>
78#endif
79
80#if defined(BOTAN_HAS_WHIRLPOOL)
81 #include <botan/whrlpool.h>
82#endif
83
84#if defined(BOTAN_HAS_PARALLEL_HASH)
85 #include <botan/par_hash.h>
86#endif
87
88#if defined(BOTAN_HAS_COMB4P)
89 #include <botan/comb4p.h>
90#endif
91
92#if defined(BOTAN_HAS_BLAKE2B)
93 #include <botan/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(const std::string& algo_spec,
103 const std::string& 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-160" ||
122 algo_spec == "SHA-1" ||
123 algo_spec == "SHA1")
124 {
125 return std::unique_ptr<HashFunction>(new SHA_160);
126 }
127#endif
128
129#if defined(BOTAN_HAS_SHA2_32)
130 if(algo_spec == "SHA-224")
131 {
132 return std::unique_ptr<HashFunction>(new SHA_224);
133 }
134
135 if(algo_spec == "SHA-256")
136 {
137 return std::unique_ptr<HashFunction>(new SHA_256);
138 }
139#endif
140
141#if defined(BOTAN_HAS_SHA2_64)
142 if(algo_spec == "SHA-384")
143 {
144 return std::unique_ptr<HashFunction>(new SHA_384);
145 }
146
147 if(algo_spec == "SHA-512")
148 {
149 return std::unique_ptr<HashFunction>(new SHA_512);
150 }
151
152 if(algo_spec == "SHA-512-256")
153 {
154 return std::unique_ptr<HashFunction>(new SHA_512_256);
155 }
156#endif
157
158#if defined(BOTAN_HAS_RIPEMD_160)
159 if(algo_spec == "RIPEMD-160")
160 {
161 return std::unique_ptr<HashFunction>(new RIPEMD_160);
162 }
163#endif
164
165#if defined(BOTAN_HAS_WHIRLPOOL)
166 if(algo_spec == "Whirlpool")
167 {
168 return std::unique_ptr<HashFunction>(new Whirlpool);
169 }
170#endif
171
172#if defined(BOTAN_HAS_MD5)
173 if(algo_spec == "MD5")
174 {
175 return std::unique_ptr<HashFunction>(new MD5);
176 }
177#endif
178
179#if defined(BOTAN_HAS_MD4)
180 if(algo_spec == "MD4")
181 {
182 return std::unique_ptr<HashFunction>(new MD4);
183 }
184#endif
185
186#if defined(BOTAN_HAS_GOST_34_11)
187 if(algo_spec == "GOST-R-34.11-94" || algo_spec == "GOST-34.11")
188 {
189 return std::unique_ptr<HashFunction>(new GOST_34_11);
190 }
191#endif
192
193#if defined(BOTAN_HAS_ADLER32)
194 if(algo_spec == "Adler32")
195 {
196 return std::unique_ptr<HashFunction>(new Adler32);
197 }
198#endif
199
200#if defined(BOTAN_HAS_CRC24)
201 if(algo_spec == "CRC24")
202 {
203 return std::unique_ptr<HashFunction>(new CRC24);
204 }
205#endif
206
207#if defined(BOTAN_HAS_CRC32)
208 if(algo_spec == "CRC32")
209 {
210 return std::unique_ptr<HashFunction>(new CRC32);
211 }
212#endif
213
214 const SCAN_Name req(algo_spec);
215
216#if defined(BOTAN_HAS_TIGER)
217 if(req.algo_name() == "Tiger")
218 {
219 return std::unique_ptr<HashFunction>(
220 new Tiger(req.arg_as_integer(0, 24),
221 req.arg_as_integer(1, 3)));
222 }
223#endif
224
225#if defined(BOTAN_HAS_SKEIN_512)
226 if(req.algo_name() == "Skein-512")
227 {
228 return std::unique_ptr<HashFunction>(
229 new Skein_512(req.arg_as_integer(0, 512), req.arg(1, "")));
230 }
231#endif
232
233#if defined(BOTAN_HAS_BLAKE2B)
234 if(req.algo_name() == "Blake2b" || req.algo_name() == "BLAKE2b")
235 {
236 return std::unique_ptr<HashFunction>(
237 new Blake2b(req.arg_as_integer(0, 512)));
238 }
239#endif
240
241#if defined(BOTAN_HAS_KECCAK)
242 if(req.algo_name() == "Keccak-1600")
243 {
244 return std::unique_ptr<HashFunction>(
245 new Keccak_1600(req.arg_as_integer(0, 512)));
246 }
247#endif
248
249#if defined(BOTAN_HAS_SHA3)
250 if(req.algo_name() == "SHA-3")
251 {
252 return std::unique_ptr<HashFunction>(
253 new SHA_3(req.arg_as_integer(0, 512)));
254 }
255#endif
256
257#if defined(BOTAN_HAS_SHAKE)
258 if(req.algo_name() == "SHAKE-128")
259 {
260 return std::unique_ptr<HashFunction>(new SHAKE_128(req.arg_as_integer(0, 128)));
261 }
262 if(req.algo_name() == "SHAKE-256")
263 {
264 return std::unique_ptr<HashFunction>(new SHAKE_256(req.arg_as_integer(0, 256)));
265 }
266#endif
267
268#if defined(BOTAN_HAS_STREEBOG)
269 if(algo_spec == "Streebog-256")
270 {
271 return std::unique_ptr<HashFunction>(new Streebog_256);
272 }
273 if(algo_spec == "Streebog-512")
274 {
275 return std::unique_ptr<HashFunction>(new Streebog_512);
276 }
277#endif
278
279#if defined(BOTAN_HAS_SM3)
280 if(algo_spec == "SM3")
281 {
282 return std::unique_ptr<HashFunction>(new SM3);
283 }
284#endif
285
286#if defined(BOTAN_HAS_WHIRLPOOL)
287 if(req.algo_name() == "Whirlpool")
288 {
289 return std::unique_ptr<HashFunction>(new Whirlpool);
290 }
291#endif
292
293#if defined(BOTAN_HAS_PARALLEL_HASH)
294 if(req.algo_name() == "Parallel")
295 {
296 std::vector<std::unique_ptr<HashFunction>> hashes;
297
298 for(size_t i = 0; i != req.arg_count(); ++i)
299 {
300 auto h = HashFunction::create(req.arg(i));
301 if(!h)
302 {
303 return nullptr;
304 }
305 hashes.push_back(std::move(h));
306 }
307
308 return std::unique_ptr<HashFunction>(new Parallel(hashes));
309 }
310#endif
311
312#if defined(BOTAN_HAS_COMB4P)
313 if(req.algo_name() == "Comb4P" && req.arg_count() == 2)
314 {
315 std::unique_ptr<HashFunction> h1(HashFunction::create(req.arg(0)));
316 std::unique_ptr<HashFunction> h2(HashFunction::create(req.arg(1)));
317
318 if(h1 && h2)
319 return std::unique_ptr<HashFunction>(new Comb4P(h1.release(), h2.release()));
320 }
321#endif
322
323
324 return nullptr;
325 }
326
327//static
328std::unique_ptr<HashFunction>
329HashFunction::create_or_throw(const std::string& algo,
330 const std::string& provider)
331 {
332 if(auto hash = HashFunction::create(algo, provider))
333 {
334 return hash;
335 }
336 throw Lookup_Error("Hash", algo, provider);
337 }
338
339std::vector<std::string> HashFunction::providers(const std::string& algo_spec)
340 {
341 return probe_providers_of<HashFunction>(algo_spec, {"base", "openssl", "commoncrypto"});
342 }
343
344}
345
static std::vector< std::string > providers(const std::string &algo_spec)
Definition hash.cpp:339
virtual std::string provider() const
Definition hash.h:58
static std::unique_ptr< HashFunction > create_or_throw(const std::string &algo_spec, const std::string &provider="")
Definition hash.cpp:329
static std::unique_ptr< HashFunction > create(const std::string &algo_spec, const std::string &provider="")
Definition hash.cpp:102
std::string arg(size_t i) const
size_t arg_count() const
Definition scan_name.h:56
const std::string & algo_name() const
Definition scan_name.h:51
size_t arg_as_integer(size_t i, size_t def_value) const
std::unique_ptr< HashFunction > make_commoncrypto_hash(const std::string &name)
BLAKE2b Blake2b
Definition blake2b.h:56
MechanismType hash