Kea  1.9.9-git
openssl_hash.cc
Go to the documentation of this file.
1 // Copyright (C) 2014-2020 Internet Systems Consortium, Inc. ("ISC")
2 //
3 // This Source Code Form is subject to the terms of the Mozilla Public
4 // License, v. 2.0. If a copy of the MPL was not distributed with this
5 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 
7 #include <config.h>
8 
9 #include <cryptolink.h>
10 #include <cryptolink/crypto_hash.h>
11 
12 #include <boost/scoped_ptr.hpp>
13 
14 #include <openssl/evp.h>
15 
17 #define KEA_HASH
19 
20 #include <cstring>
21 
22 namespace isc {
23 namespace cryptolink {
24 
25 const EVP_MD*
27  switch (algorithm) {
29  return (EVP_md5());
31  return (EVP_sha1());
33  return (EVP_sha256());
35  return (EVP_sha224());
37  return (EVP_sha384());
39  return (EVP_sha512());
41  return (0);
42  }
43  // compiler should have prevented us to reach this, since we have
44  // no default. But we need a return value anyway
45  return (0);
46 }
47 
50 class HashImpl {
51 public:
52 
56  explicit HashImpl(const HashAlgorithm hash_algorithm)
57  : hash_algorithm_(hash_algorithm), md_(0) {
58  const EVP_MD* algo = ossl::getHashAlgorithm(hash_algorithm);
59  if (algo == 0) {
61  "Unknown hash algorithm: " <<
62  static_cast<int>(hash_algorithm));
63  }
64 
65  md_ = EVP_MD_CTX_new();
66  if (md_ == 0) {
68  "OpenSSL EVP_MD_CTX_new() failed");
69  }
70 
71  EVP_DigestInit_ex(md_, algo, NULL);
72  }
73 
76  if (md_) {
77  EVP_MD_CTX_free(md_);
78  }
79  md_ = 0;
80  }
81 
84  return (hash_algorithm_);
85  }
86 
90  size_t getOutputLength() const {
91  return (EVP_MD_CTX_size(md_));
92  }
93 
97  void update(const void* data, const size_t len) {
98  EVP_DigestUpdate(md_, data, len);
99  }
100 
104  void final(isc::util::OutputBuffer& result, size_t len) {
105  size_t size = getOutputLength();
106  std::vector<unsigned char> digest(size);
107  EVP_DigestFinal_ex(md_, &digest[0], NULL);
108  if (len > size) {
109  len = size;
110  }
111  result.writeData(&digest[0], len);
112  }
113 
117  void final(void* result, size_t len) {
118  size_t size = getOutputLength();
119  std::vector<unsigned char> digest(size);
120  EVP_DigestFinal_ex(md_, &digest[0], NULL);
121  if (len > size) {
122  len = size;
123  }
124  std::memcpy(result, &digest[0], len);
125  }
126 
130  std::vector<uint8_t> final(size_t len) {
131  size_t size = getOutputLength();
132  std::vector<unsigned char> digest(size);
133  EVP_DigestFinal_ex(md_, &digest[0], NULL);
134  if (len < size) {
135  digest.resize(len);
136  }
137  return (std::vector<uint8_t>(digest.begin(), digest.end()));
138  }
139 
140 private:
142  HashAlgorithm hash_algorithm_;
143 
145  EVP_MD_CTX* md_;
146 };
147 
148 Hash::Hash(const HashAlgorithm hash_algorithm)
149 {
150  impl_ = new HashImpl(hash_algorithm);
151 }
152 
153 Hash::~Hash() {
154  delete impl_;
155 }
156 
158 Hash::getHashAlgorithm() const {
159  return (impl_->getHashAlgorithm());
160 }
161 
162 size_t
163 Hash::getOutputLength() const {
164  return (impl_->getOutputLength());
165 }
166 
167 void
168 Hash::update(const void* data, const size_t len) {
169  impl_->update(data, len);
170 }
171 
172 void
173 Hash::final(isc::util::OutputBuffer& result, size_t len) {
174  impl_->final(result, len);
175 }
176 
177 void
178 Hash::final(void* result, size_t len) {
179  impl_->final(result, len);
180 }
181 
182 std::vector<uint8_t>
183 Hash::final(size_t len) {
184  return impl_->final(len);
185 }
186 
187 } // namespace cryptolink
188 } // namespace isc
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
Definition: buffer.h:294
Defines the logger used by the top-level component of kea-dhcp-ddns.