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