Botan 3.10.0
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
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
109namespace Botan {
110
111std::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 if(provider.empty() == false && provider != "base") {
123 return nullptr; // unknown provider
124 }
125
126#if defined(BOTAN_HAS_SHA1)
127 if(algo_spec == "SHA-1") {
128 return std::make_unique<SHA_1>();
129 }
130#endif
131
132#if defined(BOTAN_HAS_SHA2_32)
133 if(algo_spec == "SHA-224") {
134 return std::make_unique<SHA_224>();
135 }
136
137 if(algo_spec == "SHA-256") {
138 return std::make_unique<SHA_256>();
139 }
140#endif
141
142#if defined(BOTAN_HAS_SHA2_64)
143 if(algo_spec == "SHA-384") {
144 return std::make_unique<SHA_384>();
145 }
146
147 if(algo_spec == "SHA-512") {
148 return std::make_unique<SHA_512>();
149 }
150
151 if(algo_spec == "SHA-512-256") {
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 return std::make_unique<RIPEMD_160>();
159 }
160#endif
161
162#if defined(BOTAN_HAS_WHIRLPOOL)
163 if(algo_spec == "Whirlpool") {
164 return std::make_unique<Whirlpool>();
165 }
166#endif
167
168#if defined(BOTAN_HAS_MD5)
169 if(algo_spec == "MD5") {
170 return std::make_unique<MD5>();
171 }
172#endif
173
174#if defined(BOTAN_HAS_MD4)
175 if(algo_spec == "MD4") {
176 return std::make_unique<MD4>();
177 }
178#endif
179
180#if defined(BOTAN_HAS_GOST_34_11)
181 if(algo_spec == "GOST-R-34.11-94" || algo_spec == "GOST-34.11") {
182 return std::make_unique<GOST_34_11>();
183 }
184#endif
185
186#if defined(BOTAN_HAS_ADLER32)
187 if(algo_spec == "Adler32") {
188 return std::make_unique<Adler32>();
189 }
190#endif
191
192#if defined(BOTAN_HAS_ASCON_HASH256)
193 if(algo_spec == "Ascon-Hash256") {
194 return std::make_unique<Ascon_Hash256>();
195 }
196#endif
197
198#if defined(BOTAN_HAS_CRC24)
199 if(algo_spec == "CRC24") {
200 return std::make_unique<CRC24>();
201 }
202#endif
203
204#if defined(BOTAN_HAS_CRC32)
205 if(algo_spec == "CRC32") {
206 return std::make_unique<CRC32>();
207 }
208#endif
209
210#if defined(BOTAN_HAS_STREEBOG)
211 if(algo_spec == "Streebog-256") {
212 return std::make_unique<Streebog>(256);
213 }
214 if(algo_spec == "Streebog-512") {
215 return std::make_unique<Streebog>(512);
216 }
217#endif
218
219#if defined(BOTAN_HAS_SM3)
220 if(algo_spec == "SM3") {
221 return std::make_unique<SM3>();
222 }
223#endif
224
225 const SCAN_Name req(algo_spec);
226
227#if defined(BOTAN_HAS_SKEIN_512)
228 if(req.algo_name() == "Skein-512") {
229 return std::make_unique<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 return std::make_unique<BLAKE2b>(req.arg_as_integer(0, 512));
236 }
237#endif
238
239#if defined(BOTAN_HAS_BLAKE2S)
240 if(req.algo_name() == "Blake2s" || req.algo_name() == "BLAKE2s") {
241 return std::make_unique<BLAKE2s>(req.arg_as_integer(0, 256));
242 }
243#endif
244
245#if defined(BOTAN_HAS_KECCAK)
246 if(req.algo_name() == "Keccak-1600") {
247 return std::make_unique<Keccak_1600>(req.arg_as_integer(0, 512));
248 }
249#endif
250
251#if defined(BOTAN_HAS_SHA3)
252 if(req.algo_name() == "SHA-3") {
253 return std::make_unique<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" && req.arg_count() == 1) {
259 return std::make_unique<SHAKE_128>(req.arg_as_integer(0));
260 }
261 if(req.algo_name() == "SHAKE-256" && req.arg_count() == 1) {
262 return std::make_unique<SHAKE_256>(req.arg_as_integer(0));
263 }
264#endif
265
266#if defined(BOTAN_HAS_PARALLEL_HASH)
267 if(req.algo_name() == "Parallel") {
268 std::vector<std::unique_ptr<HashFunction>> hashes;
269
270 for(size_t i = 0; i != req.arg_count(); ++i) {
271 auto h = HashFunction::create(req.arg(i));
272 if(!h) {
273 return nullptr;
274 }
275 hashes.push_back(std::move(h));
276 }
277
278 return std::make_unique<Parallel>(hashes);
279 }
280#endif
281
282#if defined(BOTAN_HAS_TRUNCATED_HASH)
283 if(req.algo_name() == "Truncated" && req.arg_count() == 2) {
284 auto hash = HashFunction::create(req.arg(0));
285 if(!hash) {
286 return nullptr;
287 }
288
289 return std::make_unique<Truncated_Hash>(std::move(hash), req.arg_as_integer(1));
290 }
291#endif
292
293#if defined(BOTAN_HAS_COMB4P)
294 if(req.algo_name() == "Comb4P" && req.arg_count() == 2) {
295 auto h1 = HashFunction::create(req.arg(0));
296 auto h2 = HashFunction::create(req.arg(1));
297
298 if(h1 && h2) {
299 return std::make_unique<Comb4P>(std::move(h1), std::move(h2));
300 }
301 }
302#endif
303
304 return nullptr;
305}
306
307//static
308std::unique_ptr<HashFunction> HashFunction::create_or_throw(std::string_view algo, std::string_view provider) {
309 if(auto hash = HashFunction::create(algo, provider)) {
310 return hash;
311 }
312 throw Lookup_Error("Hash", algo, provider);
313}
314
315std::vector<std::string> HashFunction::providers(std::string_view algo_spec) {
316 return probe_providers_of<HashFunction>(algo_spec, {"base", "commoncrypto"});
317}
318
319} // namespace Botan
static std::vector< std::string > providers(std::string_view algo_spec)
Definition hash.cpp:315
virtual std::string provider() const
Definition hash.h:49
static std::unique_ptr< HashFunction > create_or_throw(std::string_view algo_spec, std::string_view provider="")
Definition hash.cpp:308
static std::unique_ptr< HashFunction > create(std::string_view algo_spec, std::string_view provider="")
Definition hash.cpp:111
std::string arg(size_t i) const
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
std::unique_ptr< HashFunction > make_commoncrypto_hash(std::string_view name)
std::vector< std::string > probe_providers_of(std::string_view algo_spec, const std::vector< std::string > &possible={"base"})
Definition scan_name.h:105