Botan 2.13.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

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", ERR_get_error());
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::unique_ptr<HashFunction>(copy.release());
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
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", ERR_get_error());
63 EVP_MD_CTX_init(m_md);
64 if(md && !EVP_DigestInit_ex(m_md, md, nullptr))
65 throw OpenSSL_Error("EVP_DigestInit_ex", ERR_get_error());
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
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", ERR_get_error());
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", ERR_get_error());
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", ERR_get_error());
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 #if defined(BOTAN_HAS_WHIRLPOOL) && !defined(OPENSSL_NO_WHIRLPOOL)
144 if(name == "Whirlpool")
145 return MAKE_OPENSSL_HASH(EVP_whirlpool);
146 #endif
147
148 return nullptr;
149 }
150
151 }
m_name
std::string m_name
Definition: openssl_hash.cpp:97
MAKE_OPENSSL_HASH
#define MAKE_OPENSSL_HASH(fn)
final
int(* final)(unsigned char *, CTX *)
Definition: commoncrypto_hash.cpp:28
name
std::string name
Definition: commoncrypto_hash.cpp:23
Botan::make_openssl_hash
std::unique_ptr< HashFunction > make_openssl_hash(const std::string &name)
Definition: openssl_hash.cpp:104
Botan
Definition: alg_id.cpp:13
m_md
EVP_MD_CTX * m_md
Definition: openssl_hash.cpp:98