Botan 3.3.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_CRC24)
18 #include <botan/internal/crc24.h>
19#endif
20
21#if defined(BOTAN_HAS_CRC32)
22 #include <botan/internal/crc32.h>
23#endif
24
25#if defined(BOTAN_HAS_GOST_34_11)
26 #include <botan/internal/gost_3411.h>
27#endif
28
29#if defined(BOTAN_HAS_KECCAK)
30 #include <botan/internal/keccak.h>
31#endif
32
33#if defined(BOTAN_HAS_MD4)
34 #include <botan/internal/md4.h>
35#endif
36
37#if defined(BOTAN_HAS_MD5)
38 #include <botan/internal/md5.h>
39#endif
40
41#if defined(BOTAN_HAS_RIPEMD_160)
42 #include <botan/internal/rmd160.h>
43#endif
44
45#if defined(BOTAN_HAS_SHA1)
46 #include <botan/internal/sha1.h>
47#endif
48
49#if defined(BOTAN_HAS_SHA2_32)
50 #include <botan/internal/sha2_32.h>
51#endif
52
53#if defined(BOTAN_HAS_SHA2_64)
54 #include <botan/internal/sha2_64.h>
55#endif
56
57#if defined(BOTAN_HAS_SHA3)
58 #include <botan/internal/sha3.h>
59#endif
60
61#if defined(BOTAN_HAS_SHAKE)
62 #include <botan/internal/shake.h>
63#endif
64
65#if defined(BOTAN_HAS_SKEIN_512)
66 #include <botan/internal/skein_512.h>
67#endif
68
69#if defined(BOTAN_HAS_STREEBOG)
70 #include <botan/internal/streebog.h>
71#endif
72
73#if defined(BOTAN_HAS_SM3)
74 #include <botan/internal/sm3.h>
75#endif
76
77#if defined(BOTAN_HAS_WHIRLPOOL)
78 #include <botan/internal/whirlpool.h>
79#endif
80
81#if defined(BOTAN_HAS_PARALLEL_HASH)
82 #include <botan/internal/par_hash.h>
83#endif
84
85#if defined(BOTAN_HAS_TRUNCATED_HASH)
86 #include <botan/internal/trunc_hash.h>
87#endif
88
89#if defined(BOTAN_HAS_COMB4P)
90 #include <botan/internal/comb4p.h>
91#endif
92
93#if defined(BOTAN_HAS_BLAKE2B)
94 #include <botan/internal/blake2b.h>
95#endif
96
97#if defined(BOTAN_HAS_BLAKE2S)
98 #include <botan/internal/blake2s.h>
99#endif
100
101#if defined(BOTAN_HAS_COMMONCRYPTO)
102 #include <botan/internal/commoncrypto.h>
103#endif
104
105namespace Botan {
106
107std::unique_ptr<HashFunction> HashFunction::create(std::string_view algo_spec, std::string_view provider) {
108#if defined(BOTAN_HAS_COMMONCRYPTO)
109 if(provider.empty() || provider == "commoncrypto") {
110 if(auto hash = make_commoncrypto_hash(algo_spec))
111 return hash;
112
113 if(!provider.empty())
114 return nullptr;
115 }
116#endif
117
118 if(provider.empty() == false && provider != "base") {
119 return nullptr; // unknown provider
120 }
121
122#if defined(BOTAN_HAS_SHA1)
123 if(algo_spec == "SHA-1") {
124 return std::make_unique<SHA_1>();
125 }
126#endif
127
128#if defined(BOTAN_HAS_SHA2_32)
129 if(algo_spec == "SHA-224") {
130 return std::make_unique<SHA_224>();
131 }
132
133 if(algo_spec == "SHA-256") {
134 return std::make_unique<SHA_256>();
135 }
136#endif
137
138#if defined(BOTAN_HAS_SHA2_64)
139 if(algo_spec == "SHA-384") {
140 return std::make_unique<SHA_384>();
141 }
142
143 if(algo_spec == "SHA-512") {
144 return std::make_unique<SHA_512>();
145 }
146
147 if(algo_spec == "SHA-512-256") {
148 return std::make_unique<SHA_512_256>();
149 }
150#endif
151
152#if defined(BOTAN_HAS_RIPEMD_160)
153 if(algo_spec == "RIPEMD-160") {
154 return std::make_unique<RIPEMD_160>();
155 }
156#endif
157
158#if defined(BOTAN_HAS_WHIRLPOOL)
159 if(algo_spec == "Whirlpool") {
160 return std::make_unique<Whirlpool>();
161 }
162#endif
163
164#if defined(BOTAN_HAS_MD5)
165 if(algo_spec == "MD5") {
166 return std::make_unique<MD5>();
167 }
168#endif
169
170#if defined(BOTAN_HAS_MD4)
171 if(algo_spec == "MD4") {
172 return std::make_unique<MD4>();
173 }
174#endif
175
176#if defined(BOTAN_HAS_GOST_34_11)
177 if(algo_spec == "GOST-R-34.11-94" || algo_spec == "GOST-34.11") {
178 return std::make_unique<GOST_34_11>();
179 }
180#endif
181
182#if defined(BOTAN_HAS_ADLER32)
183 if(algo_spec == "Adler32") {
184 return std::make_unique<Adler32>();
185 }
186#endif
187
188#if defined(BOTAN_HAS_CRC24)
189 if(algo_spec == "CRC24") {
190 return std::make_unique<CRC24>();
191 }
192#endif
193
194#if defined(BOTAN_HAS_CRC32)
195 if(algo_spec == "CRC32") {
196 return std::make_unique<CRC32>();
197 }
198#endif
199
200#if defined(BOTAN_HAS_STREEBOG)
201 if(algo_spec == "Streebog-256") {
202 return std::make_unique<Streebog>(256);
203 }
204 if(algo_spec == "Streebog-512") {
205 return std::make_unique<Streebog>(512);
206 }
207#endif
208
209#if defined(BOTAN_HAS_SM3)
210 if(algo_spec == "SM3") {
211 return std::make_unique<SM3>();
212 }
213#endif
214
215 const SCAN_Name req(algo_spec);
216
217#if defined(BOTAN_HAS_SKEIN_512)
218 if(req.algo_name() == "Skein-512") {
219 return std::make_unique<Skein_512>(req.arg_as_integer(0, 512), req.arg(1, ""));
220 }
221#endif
222
223#if defined(BOTAN_HAS_BLAKE2B)
224 if(req.algo_name() == "Blake2b" || req.algo_name() == "BLAKE2b") {
225 return std::make_unique<BLAKE2b>(req.arg_as_integer(0, 512));
226 }
227#endif
228
229#if defined(BOTAN_HAS_BLAKE2S)
230 if(req.algo_name() == "Blake2s" || req.algo_name() == "BLAKE2s") {
231 return std::make_unique<BLAKE2s>(req.arg_as_integer(0, 256));
232 }
233#endif
234
235#if defined(BOTAN_HAS_KECCAK)
236 if(req.algo_name() == "Keccak-1600") {
237 return std::make_unique<Keccak_1600>(req.arg_as_integer(0, 512));
238 }
239#endif
240
241#if defined(BOTAN_HAS_SHA3)
242 if(req.algo_name() == "SHA-3") {
243 return std::make_unique<SHA_3>(req.arg_as_integer(0, 512));
244 }
245#endif
246
247#if defined(BOTAN_HAS_SHAKE)
248 if(req.algo_name() == "SHAKE-128" && req.arg_count() == 1) {
249 return std::make_unique<SHAKE_128>(req.arg_as_integer(0));
250 }
251 if(req.algo_name() == "SHAKE-256" && req.arg_count() == 1) {
252 return std::make_unique<SHAKE_256>(req.arg_as_integer(0));
253 }
254#endif
255
256#if defined(BOTAN_HAS_PARALLEL_HASH)
257 if(req.algo_name() == "Parallel") {
258 std::vector<std::unique_ptr<HashFunction>> hashes;
259
260 for(size_t i = 0; i != req.arg_count(); ++i) {
261 auto h = HashFunction::create(req.arg(i));
262 if(!h) {
263 return nullptr;
264 }
265 hashes.push_back(std::move(h));
266 }
267
268 return std::make_unique<Parallel>(hashes);
269 }
270#endif
271
272#if defined(BOTAN_HAS_TRUNCATED_HASH)
273 if(req.algo_name() == "Truncated" && req.arg_count() == 2) {
274 auto hash = HashFunction::create(req.arg(0));
275 if(!hash) {
276 return nullptr;
277 }
278
279 return std::make_unique<Truncated_Hash>(std::move(hash), req.arg_as_integer(1));
280 }
281#endif
282
283#if defined(BOTAN_HAS_COMB4P)
284 if(req.algo_name() == "Comb4P" && req.arg_count() == 2) {
285 auto h1 = HashFunction::create(req.arg(0));
286 auto h2 = HashFunction::create(req.arg(1));
287
288 if(h1 && h2) {
289 return std::make_unique<Comb4P>(std::move(h1), std::move(h2));
290 }
291 }
292#endif
293
294 return nullptr;
295}
296
297//static
298std::unique_ptr<HashFunction> HashFunction::create_or_throw(std::string_view algo, std::string_view provider) {
299 if(auto hash = HashFunction::create(algo, provider)) {
300 return hash;
301 }
302 throw Lookup_Error("Hash", algo, provider);
303}
304
305std::vector<std::string> HashFunction::providers(std::string_view algo_spec) {
306 return probe_providers_of<HashFunction>(algo_spec, {"base", "commoncrypto"});
307}
308
309} // namespace Botan
static std::vector< std::string > providers(std::string_view algo_spec)
Definition hash.cpp:305
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:298
static std::unique_ptr< HashFunction > create(std::string_view algo_spec, std::string_view provider="")
Definition hash.cpp:107
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)