Botan  2.4.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 final : public HashFunction
18  {
19  public:
20  void clear() override
21  {
22  const EVP_MD* algo = EVP_MD_CTX_md(m_md);
23  if(!EVP_DigestInit_ex(m_md, algo, nullptr))
24  throw OpenSSL_Error("EVP_DigestInit_ex");
25  }
26 
27  std::string provider() const override { return "openssl"; }
28  std::string name() const override { return m_name; }
29 
30  HashFunction* clone() const override
31  {
32  const EVP_MD* algo = EVP_MD_CTX_md(m_md);
33  return new OpenSSL_HashFunction(name(), algo);
34  }
35 
36  std::unique_ptr<HashFunction> copy_state() const override
37  {
38  std::unique_ptr<OpenSSL_HashFunction> copy(new OpenSSL_HashFunction(m_name, nullptr));
39  EVP_MD_CTX_copy(copy->m_md, m_md);
40  return std::move(copy);
41  }
42 
43  size_t output_length() const override
44  {
45  return EVP_MD_size(EVP_MD_CTX_md(m_md));
46  }
47 
48  size_t hash_block_size() const override
49  {
50  return EVP_MD_block_size(EVP_MD_CTX_md(m_md));
51  }
52 
53  OpenSSL_HashFunction(const std::string& name, const EVP_MD* md) : m_name(name)
54  {
55 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
56  m_md = EVP_MD_CTX_create();
57 #else
58  m_md = EVP_MD_CTX_new();
59 #endif
60 
61  if(m_md == nullptr)
62  throw OpenSSL_Error("Can't allocate new context");
63  EVP_MD_CTX_init(m_md);
64  if(md && !EVP_DigestInit_ex(m_md, md, nullptr))
65  throw OpenSSL_Error("EVP_DigestInit_ex");
66  }
67 
68  OpenSSL_HashFunction(EVP_MD_CTX* ctx) : m_md(ctx)
69  {
70  }
71 
72  ~OpenSSL_HashFunction()
73  {
74 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
75  EVP_MD_CTX_destroy(m_md);
76 #else
77  EVP_MD_CTX_free(m_md);
78 #endif
79  }
80 
81  private:
82  void add_data(const uint8_t input[], size_t length) override
83  {
84  if(!EVP_DigestUpdate(m_md, input, length))
85  throw OpenSSL_Error("EVP_DigestUpdate");
86  }
87 
88  void final_result(uint8_t output[]) override
89  {
90  if(!EVP_DigestFinal_ex(m_md, output, nullptr))
91  throw OpenSSL_Error("EVP_DigestFinal_ex");
92  const EVP_MD* algo = EVP_MD_CTX_md(m_md);
93  if(!EVP_DigestInit_ex(m_md, algo, nullptr))
94  throw OpenSSL_Error("EVP_DigestInit_ex");
95  }
96 
97  std::string m_name;
98  EVP_MD_CTX* m_md;
99  };
100 
101 }
102 
103 std::unique_ptr<HashFunction>
104 make_openssl_hash(const std::string& name)
105  {
106 #define MAKE_OPENSSL_HASH(fn) \
107  std::unique_ptr<HashFunction>(new OpenSSL_HashFunction(name, fn ()))
108 
109 #if defined(BOTAN_HAS_SHA2_32) && !defined(OPENSSL_NO_SHA256)
110  if(name == "SHA-224")
111  return MAKE_OPENSSL_HASH(EVP_sha224);
112  if(name == "SHA-256")
113  return MAKE_OPENSSL_HASH(EVP_sha256);
114 #endif
115 
116 #if defined(BOTAN_HAS_SHA2_64) && !defined(OPENSSL_NO_SHA512)
117  if(name == "SHA-384")
118  return MAKE_OPENSSL_HASH(EVP_sha384);
119  if(name == "SHA-512")
120  return MAKE_OPENSSL_HASH(EVP_sha512);
121 #endif
122 
123 #if defined(BOTAN_HAS_SHA1) && !defined(OPENSSL_NO_SHA)
124  if(name == "SHA-160" || name == "SHA-1" || name == "SHA1")
125  return MAKE_OPENSSL_HASH(EVP_sha1);
126 #endif
127 
128 #if defined(BOTAN_HAS_RIPEMD_160) && !defined(OPENSSL_NO_RIPEMD)
129  if(name == "RIPEMD-160")
130  return MAKE_OPENSSL_HASH(EVP_ripemd160);
131 #endif
132 
133 #if defined(BOTAN_HAS_MD5) && !defined(OPENSSL_NO_MD5)
134  if(name == "MD5")
135  return MAKE_OPENSSL_HASH(EVP_md5);
136  #endif
137 
138 #if defined(BOTAN_HAS_MD4) && !defined(OPENSSL_NO_MD4)
139  if(name == "MD4")
140  return MAKE_OPENSSL_HASH(EVP_md4);
141 #endif
142 
143  return nullptr;
144  }
145 
146 }
#define MAKE_OPENSSL_HASH(fn)
std::unique_ptr< HashFunction > make_openssl_hash(const std::string &name)
Definition: alg_id.cpp:13