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