Botan  1.11.15
src/lib/vendor/openssl/openssl_hash.cpp
Go to the documentation of this file.
00001 /*
00002 * OpenSSL Hash Functions
00003 * (C) 1999-2007,2015 Jack Lloyd
00004 *
00005 * Botan is released under the Simplified BSD License (see license.txt)
00006 */
00007 
00008 #include <botan/internal/hash_utils.h>
00009 #include <openssl/evp.h>
00010 
00011 namespace Botan {
00012 
00013 namespace {
00014 
00015 class OpenSSL_HashFunction : public HashFunction
00016    {
00017    public:
00018       void clear()
00019          {
00020          const EVP_MD* algo = EVP_MD_CTX_md(&m_md);
00021          EVP_DigestInit_ex(&m_md, algo, nullptr);
00022          }
00023 
00024       std::string name() const { return m_name; }
00025 
00026       HashFunction* clone() const
00027          {
00028          const EVP_MD* algo = EVP_MD_CTX_md(&m_md);
00029          return new OpenSSL_HashFunction(algo, name());
00030          }
00031 
00032       size_t output_length() const
00033          {
00034          return EVP_MD_size(EVP_MD_CTX_md(&m_md));
00035          }
00036 
00037       size_t hash_block_size() const
00038          {
00039          return EVP_MD_block_size(EVP_MD_CTX_md(&m_md));
00040          }
00041 
00042       OpenSSL_HashFunction(const EVP_MD* md, const std::string& name) : m_name(name)
00043          {
00044          EVP_MD_CTX_init(&m_md);
00045          EVP_DigestInit_ex(&m_md, md, nullptr);
00046          }
00047 
00048       ~OpenSSL_HashFunction()
00049          {
00050          EVP_MD_CTX_cleanup(&m_md);
00051          }
00052 
00053    private:
00054       void add_data(const byte input[], size_t length)
00055          {
00056          EVP_DigestUpdate(&m_md, input, length);
00057          }
00058 
00059       void final_result(byte output[])
00060          {
00061          EVP_DigestFinal_ex(&m_md, output, nullptr);
00062          const EVP_MD* algo = EVP_MD_CTX_md(&m_md);
00063          EVP_DigestInit_ex(&m_md, algo, nullptr);
00064          }
00065 
00066       std::string m_name;
00067       EVP_MD_CTX m_md;
00068    };
00069 
00070 std::function<HashFunction* (const HashFunction::Spec&)>
00071 make_evp_hash_maker(const EVP_MD* md, const char* algo)
00072    {
00073    return [md,algo](const HashFunction::Spec&)
00074       {
00075       return new OpenSSL_HashFunction(md, algo);
00076       };
00077    }
00078 
00079 #define BOTAN_REGISTER_OPENSSL_EVP_HASH(NAME, EVP)                      \
00080    BOTAN_REGISTER_TYPE(HashFunction, OpenSSL_HashFunction ## EVP, NAME, \
00081                        make_evp_hash_maker(EVP(), NAME), "openssl", 32);
00082 
00083 #if !defined(OPENSSL_NO_SHA)
00084    BOTAN_REGISTER_OPENSSL_EVP_HASH("SHA-160", EVP_sha1);
00085 #endif
00086 
00087 #if !defined(OPENSSL_NO_SHA256)
00088    BOTAN_REGISTER_OPENSSL_EVP_HASH("SHA-224", EVP_sha224);
00089    BOTAN_REGISTER_OPENSSL_EVP_HASH("SHA-256", EVP_sha256);
00090 #endif
00091 
00092 #if !defined(OPENSSL_NO_SHA512)
00093    BOTAN_REGISTER_OPENSSL_EVP_HASH("SHA-384", EVP_sha384);
00094    BOTAN_REGISTER_OPENSSL_EVP_HASH("SHA-512", EVP_sha512);
00095 #endif
00096 
00097 #if !defined(OPENSSL_NO_MD2)
00098    BOTAN_REGISTER_OPENSSL_EVP_HASH("MD2", EVP_md2);
00099 #endif
00100 
00101 #if !defined(OPENSSL_NO_MD4)
00102    BOTAN_REGISTER_OPENSSL_EVP_HASH("MD4", EVP_md4);
00103 #endif
00104 
00105 #if !defined(OPENSSL_NO_MD5)
00106    BOTAN_REGISTER_OPENSSL_EVP_HASH("MD5", EVP_md5);
00107 #endif
00108 
00109 #if !defined(OPENSSL_NO_RIPEMD)
00110    BOTAN_REGISTER_OPENSSL_EVP_HASH("RIPEMD-160", EVP_ripemd160);
00111 #endif
00112 
00113 }
00114 
00115 }