Source code

Revision control

Copy as Markdown

Other Tools

/*
* Hash Functions
* (C) 2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#include <botan/hash.h>
#include <botan/scan_name.h>
#include <botan/exceptn.h>
#if defined(BOTAN_HAS_ADLER32)
#include <botan/adler32.h>
#endif
#if defined(BOTAN_HAS_CRC24)
#include <botan/crc24.h>
#endif
#if defined(BOTAN_HAS_CRC32)
#include <botan/crc32.h>
#endif
#if defined(BOTAN_HAS_GOST_34_11)
#include <botan/gost_3411.h>
#endif
#if defined(BOTAN_HAS_KECCAK)
#include <botan/keccak.h>
#endif
#if defined(BOTAN_HAS_MD4)
#include <botan/md4.h>
#endif
#if defined(BOTAN_HAS_MD5)
#include <botan/md5.h>
#endif
#if defined(BOTAN_HAS_RIPEMD_160)
#include <botan/rmd160.h>
#endif
#if defined(BOTAN_HAS_SHA1)
#include <botan/sha160.h>
#endif
#if defined(BOTAN_HAS_SHA2_32)
#include <botan/sha2_32.h>
#endif
#if defined(BOTAN_HAS_SHA2_64)
#include <botan/sha2_64.h>
#endif
#if defined(BOTAN_HAS_SHA3)
#include <botan/sha3.h>
#endif
#if defined(BOTAN_HAS_SHAKE)
#include <botan/shake.h>
#endif
#if defined(BOTAN_HAS_SKEIN_512)
#include <botan/skein_512.h>
#endif
#if defined(BOTAN_HAS_STREEBOG)
#include <botan/streebog.h>
#endif
#if defined(BOTAN_HAS_SM3)
#include <botan/sm3.h>
#endif
#if defined(BOTAN_HAS_TIGER)
#include <botan/tiger.h>
#endif
#if defined(BOTAN_HAS_WHIRLPOOL)
#include <botan/whrlpool.h>
#endif
#if defined(BOTAN_HAS_PARALLEL_HASH)
#include <botan/par_hash.h>
#endif
#if defined(BOTAN_HAS_COMB4P)
#include <botan/comb4p.h>
#endif
#if defined(BOTAN_HAS_BLAKE2B)
#include <botan/blake2b.h>
#endif
#if defined(BOTAN_HAS_OPENSSL)
#include <botan/internal/openssl.h>
#endif
#if defined(BOTAN_HAS_COMMONCRYPTO)
#include <botan/internal/commoncrypto.h>
#endif
namespace Botan {
std::unique_ptr<HashFunction> HashFunction::create(const std::string& algo_spec,
const std::string& provider)
{
#if defined(BOTAN_HAS_COMMONCRYPTO)
if(provider.empty() || provider == "commoncrypto")
{
if(auto hash = make_commoncrypto_hash(algo_spec))
return hash;
if(!provider.empty())
return nullptr;
}
#endif
#if defined(BOTAN_HAS_OPENSSL)
if(provider.empty() || provider == "openssl")
{
if(auto hash = make_openssl_hash(algo_spec))
return hash;
if(!provider.empty())
return nullptr;
}
#endif
if(provider.empty() == false && provider != "base")
return nullptr; // unknown provider
#if defined(BOTAN_HAS_SHA1)
if(algo_spec == "SHA-160" ||
algo_spec == "SHA-1" ||
algo_spec == "SHA1")
{
return std::unique_ptr<HashFunction>(new SHA_160);
}
#endif
#if defined(BOTAN_HAS_SHA2_32)
if(algo_spec == "SHA-224")
{
return std::unique_ptr<HashFunction>(new SHA_224);
}
if(algo_spec == "SHA-256")
{
return std::unique_ptr<HashFunction>(new SHA_256);
}
#endif
#if defined(BOTAN_HAS_SHA2_64)
if(algo_spec == "SHA-384")
{
return std::unique_ptr<HashFunction>(new SHA_384);
}
if(algo_spec == "SHA-512")
{
return std::unique_ptr<HashFunction>(new SHA_512);
}
if(algo_spec == "SHA-512-256")
{
return std::unique_ptr<HashFunction>(new SHA_512_256);
}
#endif
#if defined(BOTAN_HAS_RIPEMD_160)
if(algo_spec == "RIPEMD-160")
{
return std::unique_ptr<HashFunction>(new RIPEMD_160);
}
#endif
#if defined(BOTAN_HAS_WHIRLPOOL)
if(algo_spec == "Whirlpool")
{
return std::unique_ptr<HashFunction>(new Whirlpool);
}
#endif
#if defined(BOTAN_HAS_MD5)
if(algo_spec == "MD5")
{
return std::unique_ptr<HashFunction>(new MD5);
}
#endif
#if defined(BOTAN_HAS_MD4)
if(algo_spec == "MD4")
{
return std::unique_ptr<HashFunction>(new MD4);
}
#endif
#if defined(BOTAN_HAS_GOST_34_11)
if(algo_spec == "GOST-R-34.11-94" || algo_spec == "GOST-34.11")
{
return std::unique_ptr<HashFunction>(new GOST_34_11);
}
#endif
#if defined(BOTAN_HAS_ADLER32)
if(algo_spec == "Adler32")
{
return std::unique_ptr<HashFunction>(new Adler32);
}
#endif
#if defined(BOTAN_HAS_CRC24)
if(algo_spec == "CRC24")
{
return std::unique_ptr<HashFunction>(new CRC24);
}
#endif
#if defined(BOTAN_HAS_CRC32)
if(algo_spec == "CRC32")
{
return std::unique_ptr<HashFunction>(new CRC32);
}
#endif
const SCAN_Name req(algo_spec);
#if defined(BOTAN_HAS_TIGER)
if(req.algo_name() == "Tiger")
{
return std::unique_ptr<HashFunction>(
new Tiger(req.arg_as_integer(0, 24),
req.arg_as_integer(1, 3)));
}
#endif
#if defined(BOTAN_HAS_SKEIN_512)
if(req.algo_name() == "Skein-512")
{
return std::unique_ptr<HashFunction>(
new Skein_512(req.arg_as_integer(0, 512), req.arg(1, "")));
}
#endif
#if defined(BOTAN_HAS_BLAKE2B)
if(req.algo_name() == "Blake2b" || req.algo_name() == "BLAKE2b")
{
return std::unique_ptr<HashFunction>(
new Blake2b(req.arg_as_integer(0, 512)));
}
#endif
#if defined(BOTAN_HAS_KECCAK)
if(req.algo_name() == "Keccak-1600")
{
return std::unique_ptr<HashFunction>(
new Keccak_1600(req.arg_as_integer(0, 512)));
}
#endif
#if defined(BOTAN_HAS_SHA3)
if(req.algo_name() == "SHA-3")
{
return std::unique_ptr<HashFunction>(
new SHA_3(req.arg_as_integer(0, 512)));
}
#endif
#if defined(BOTAN_HAS_SHAKE)
if(req.algo_name() == "SHAKE-128")
{
return std::unique_ptr<HashFunction>(new SHAKE_128(req.arg_as_integer(0, 128)));
}
if(req.algo_name() == "SHAKE-256")
{
return std::unique_ptr<HashFunction>(new SHAKE_256(req.arg_as_integer(0, 256)));
}
#endif
#if defined(BOTAN_HAS_STREEBOG)
if(algo_spec == "Streebog-256")
{
return std::unique_ptr<HashFunction>(new Streebog_256);
}
if(algo_spec == "Streebog-512")
{
return std::unique_ptr<HashFunction>(new Streebog_512);
}
#endif
#if defined(BOTAN_HAS_SM3)
if(algo_spec == "SM3")
{
return std::unique_ptr<HashFunction>(new SM3);
}
#endif
#if defined(BOTAN_HAS_WHIRLPOOL)
if(req.algo_name() == "Whirlpool")
{
return std::unique_ptr<HashFunction>(new Whirlpool);
}
#endif
#if defined(BOTAN_HAS_PARALLEL_HASH)
if(req.algo_name() == "Parallel")
{
std::vector<std::unique_ptr<HashFunction>> hashes;
for(size_t i = 0; i != req.arg_count(); ++i)
{
auto h = HashFunction::create(req.arg(i));
if(!h)
{
return nullptr;
}
hashes.push_back(std::move(h));
}
return std::unique_ptr<HashFunction>(new Parallel(hashes));
}
#endif
#if defined(BOTAN_HAS_COMB4P)
if(req.algo_name() == "Comb4P" && req.arg_count() == 2)
{
std::unique_ptr<HashFunction> h1(HashFunction::create(req.arg(0)));
std::unique_ptr<HashFunction> h2(HashFunction::create(req.arg(1)));
if(h1 && h2)
return std::unique_ptr<HashFunction>(new Comb4P(h1.release(), h2.release()));
}
#endif
return nullptr;
}
//static
std::unique_ptr<HashFunction>
HashFunction::create_or_throw(const std::string& algo,
const std::string& provider)
{
if(auto hash = HashFunction::create(algo, provider))
{
return hash;
}
throw Lookup_Error("Hash", algo, provider);
}
std::vector<std::string> HashFunction::providers(const std::string& algo_spec)
{
return probe_providers_of<HashFunction>(algo_spec, {"base", "openssl", "commoncrypto"});
}
}