Botan  2.1.0
Crypto and TLS for C++11
openssl_hash.cpp
Go to the documentation of this file.
1 /*
2 * OpenSSL Hash Functions
3 * (C) 1999-2007,2015 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #include <botan/hash.h>
9 #include <botan/internal/openssl.h>
10 #include <openssl/evp.h>
11 #include <unordered_map>
12 
13 namespace Botan {
14 
15 namespace {
16 
17 class OpenSSL_HashFunction : public HashFunction
18  {
19  public:
20  void clear() override
21  {
22  const EVP_MD* algo = EVP_MD_CTX_md(&m_md);
23  EVP_DigestInit_ex(&m_md, algo, nullptr);
24  }
25 
26  std::string provider() const override { return "openssl"; }
27  std::string name() const override { return m_name; }
28 
29  HashFunction* clone() const override
30  {
31  const EVP_MD* algo = EVP_MD_CTX_md(&m_md);
32  return new OpenSSL_HashFunction(name(), algo);
33  }
34 
35  size_t output_length() const override
36  {
37  return EVP_MD_size(EVP_MD_CTX_md(&m_md));
38  }
39 
40  size_t hash_block_size() const override
41  {
42  return EVP_MD_block_size(EVP_MD_CTX_md(&m_md));
43  }
44 
45  OpenSSL_HashFunction(const std::string& name, const EVP_MD* md) : m_name(name)
46  {
47  EVP_MD_CTX_init(&m_md);
48  EVP_DigestInit_ex(&m_md, md, nullptr);
49  }
50 
51  ~OpenSSL_HashFunction()
52  {
53  EVP_MD_CTX_cleanup(&m_md);
54  }
55 
56  private:
57  void add_data(const uint8_t input[], size_t length) override
58  {
59  EVP_DigestUpdate(&m_md, input, length);
60  }
61 
62  void final_result(uint8_t output[]) override
63  {
64  EVP_DigestFinal_ex(&m_md, output, nullptr);
65  const EVP_MD* algo = EVP_MD_CTX_md(&m_md);
66  EVP_DigestInit_ex(&m_md, algo, nullptr);
67  }
68 
69  std::string m_name;
70  EVP_MD_CTX m_md;
71  };
72 
73 }
74 
75 std::unique_ptr<HashFunction>
76 make_openssl_hash(const std::string& name)
77  {
78 #define MAKE_OPENSSL_HASH(fn) \
79  std::unique_ptr<HashFunction>(new OpenSSL_HashFunction(name, fn ()))
80 
81 #if defined(BOTAN_HAS_SHA2_32) && !defined(OPENSSL_NO_SHA256)
82  if(name == "SHA-224")
83  return MAKE_OPENSSL_HASH(EVP_sha224);
84  if(name == "SHA-256")
85  return MAKE_OPENSSL_HASH(EVP_sha256);
86 #endif
87 
88 #if defined(BOTAN_HAS_SHA2_64) && !defined(OPENSSL_NO_SHA512)
89  if(name == "SHA-384")
90  return MAKE_OPENSSL_HASH(EVP_sha384);
91  if(name == "SHA-512")
92  return MAKE_OPENSSL_HASH(EVP_sha512);
93 #endif
94 
95 #if defined(BOTAN_HAS_SHA1) && !defined(OPENSSL_NO_SHA)
96  if(name == "SHA-160")
97  return MAKE_OPENSSL_HASH(EVP_sha1);
98 #endif
99 
100 #if defined(BOTAN_HAS_RIPEMD_160) && !defined(OPENSSL_NO_RIPEMD)
101  if(name == "RIPEMD-160")
102  return MAKE_OPENSSL_HASH(EVP_ripemd160);
103 #endif
104 
105 #if defined(BOTAN_HAS_MD5) && !defined(OPENSSL_NO_MD5)
106  if(name == "MD5")
107  return MAKE_OPENSSL_HASH(EVP_md5);
108  #endif
109 
110 #if defined(BOTAN_HAS_MD4) && !defined(OPENSSL_NO_MD4)
111  if(name == "MD4")
112  return MAKE_OPENSSL_HASH(EVP_md4);
113 #endif
114 
115  return nullptr;
116  }
117 
118 }
std::string m_name
#define MAKE_OPENSSL_HASH(fn)
EVP_MD_CTX m_md
std::unique_ptr< HashFunction > make_openssl_hash(const std::string &name)
Definition: alg_id.cpp:13