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