proxygen
OpenSSLHash.h
Go to the documentation of this file.
1 /*
2  * Copyright 2016-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <folly/Range.h>
20 #include <folly/io/IOBuf.h>
23 
24 namespace folly {
25 namespace ssl {
26 
29 class OpenSSLHash {
30  public:
31  class Digest {
32  public:
34 
35  Digest(const Digest& other) {
37  if (other.md_ != nullptr) {
38  hash_init(other.md_);
40  1, EVP_MD_CTX_copy_ex(ctx_.get(), other.ctx_.get()));
41  }
42  }
43 
44  Digest& operator=(const Digest& other) {
45  this->~Digest();
46  return *new (this) Digest(other);
47  }
48 
49  void hash_init(const EVP_MD* md) {
50  md_ = md;
51  check_libssl_result(1, EVP_DigestInit_ex(ctx_.get(), md, nullptr));
52  }
55  1, EVP_DigestUpdate(ctx_.get(), data.data(), data.size()));
56  }
57  void hash_update(const IOBuf& data) {
58  for (auto r : data) {
59  hash_update(r);
60  }
61  }
63  const auto size = EVP_MD_size(md_);
64  check_out_size(size_t(size), out);
65  unsigned int len = 0;
66  check_libssl_result(1, EVP_DigestFinal_ex(ctx_.get(), out.data(), &len));
67  check_libssl_result(size, int(len));
68  md_ = nullptr;
69  }
70 
71  private:
72  const EVP_MD* md_ = nullptr;
74  };
75 
76  static void hash(MutableByteRange out, const EVP_MD* md, ByteRange data) {
77  Digest hash;
78  hash.hash_init(md);
79  hash.hash_update(data);
80  hash.hash_final(out);
81  }
82  static void hash(MutableByteRange out, const EVP_MD* md, const IOBuf& data) {
83  Digest hash;
84  hash.hash_init(md);
85  hash.hash_update(data);
86  hash.hash_final(out);
87  }
88  static void sha1(MutableByteRange out, ByteRange data) {
89  hash(out, EVP_sha1(), data);
90  }
91  static void sha1(MutableByteRange out, const IOBuf& data) {
92  hash(out, EVP_sha1(), data);
93  }
94  static void sha256(MutableByteRange out, ByteRange data) {
95  hash(out, EVP_sha256(), data);
96  }
97  static void sha256(MutableByteRange out, const IOBuf& data) {
98  hash(out, EVP_sha256(), data);
99  }
100 
101  class Hmac {
102  public:
104 
105  void hash_init(const EVP_MD* md, ByteRange key) {
106  md_ = md;
108  1,
109  HMAC_Init_ex(ctx_.get(), key.data(), int(key.size()), md_, nullptr));
110  }
112  check_libssl_result(1, HMAC_Update(ctx_.get(), data.data(), data.size()));
113  }
114  void hash_update(const IOBuf& data) {
115  for (auto r : data) {
116  hash_update(r);
117  }
118  }
120  const auto size = EVP_MD_size(md_);
121  check_out_size(size_t(size), out);
122  unsigned int len = 0;
123  check_libssl_result(1, HMAC_Final(ctx_.get(), out.data(), &len));
124  check_libssl_result(size, int(len));
125  md_ = nullptr;
126  }
127 
128  private:
129  const EVP_MD* md_ = nullptr;
131  };
132 
133  static void
134  hmac(MutableByteRange out, const EVP_MD* md, ByteRange key, ByteRange data) {
135  Hmac hmac;
136  hmac.hash_init(md, key);
137  hmac.hash_update(data);
138  hmac.hash_final(out);
139  }
140  static void hmac(
141  MutableByteRange out,
142  const EVP_MD* md,
143  ByteRange key,
144  const IOBuf& data) {
145  Hmac hmac;
146  hmac.hash_init(md, key);
147  hmac.hash_update(data);
148  hmac.hash_final(out);
149  }
151  hmac(out, EVP_sha1(), key, data);
152  }
153  static void
155  hmac(out, EVP_sha1(), key, data);
156  }
158  hmac(out, EVP_sha256(), key, data);
159  }
160  static void
162  hmac(out, EVP_sha256(), key, data);
163  }
164 
165  private:
166  static inline void check_out_size(size_t size, MutableByteRange out) {
167  if (LIKELY(size == out.size())) {
168  return;
169  }
170  check_out_size_throw(size, out);
171  }
172  [[noreturn]] static void check_out_size_throw(
173  size_t size,
174  MutableByteRange out);
175 
176  static inline void check_libssl_result(int expected, int result) {
177  if (LIKELY(result == expected)) {
178  return;
179  }
180  throw_exception<std::runtime_error>("openssl crypto function failed");
181  }
182 };
183 
184 } // namespace ssl
185 } // namespace folly
static void hmac(MutableByteRange out, const EVP_MD *md, ByteRange key, ByteRange data)
Definition: OpenSSLHash.h:134
static void check_out_size_throw(size_t size, MutableByteRange out)
Definition: OpenSSLHash.cpp:24
std::unique_ptr< HMAC_CTX, HmacCtxDeleter > HmacCtxUniquePtr
void hash_init(const EVP_MD *md)
Definition: OpenSSLHash.h:49
#define LIKELY(x)
Definition: Likely.h:47
constexpr size_type size() const
Definition: Range.h:431
void hash_update(const IOBuf &data)
Definition: OpenSSLHash.h:114
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
static void sha256(MutableByteRange out, ByteRange data)
Definition: OpenSSLHash.h:94
Digest(const Digest &other)
Definition: OpenSSLHash.h:35
constexpr auto size(C const &c) -> decltype(c.size())
Definition: Access.h:45
HMAC_CTX * HMAC_CTX_new()
Definition: OpenSSL.cpp:337
void hash_final(MutableByteRange out)
Definition: OpenSSLHash.h:62
static void check_libssl_result(int expected, int result)
Definition: OpenSSLHash.h:176
void hash_update(ByteRange data)
Definition: OpenSSLHash.h:53
void hash_update(ByteRange data)
Definition: OpenSSLHash.h:111
Digest & operator=(const Digest &other)
Definition: OpenSSLHash.h:44
constexpr Iter data() const
Definition: Range.h:446
constexpr auto data(C &c) -> decltype(c.data())
Definition: Access.h:71
static void hmac(MutableByteRange out, const EVP_MD *md, ByteRange key, const IOBuf &data)
Definition: OpenSSLHash.h:140
static void hmac_sha256(MutableByteRange out, ByteRange key, const IOBuf &data)
Definition: OpenSSLHash.h:161
static void hash(MutableByteRange out, const EVP_MD *md, const IOBuf &data)
Definition: OpenSSLHash.h:82
static void hmac_sha256(MutableByteRange out, ByteRange key, ByteRange data)
Definition: OpenSSLHash.h:157
void hash_init(const EVP_MD *md, ByteRange key)
Definition: OpenSSLHash.h:105
static void sha1(MutableByteRange out, const IOBuf &data)
Definition: OpenSSLHash.h:91
static void hmac_sha1(MutableByteRange out, ByteRange key, const IOBuf &data)
Definition: OpenSSLHash.h:154
static void hmac_sha1(MutableByteRange out, ByteRange key, ByteRange data)
Definition: OpenSSLHash.h:150
EVP_MD_CTX * EVP_MD_CTX_new()
Definition: OpenSSL.cpp:321
void hash_update(const IOBuf &data)
Definition: OpenSSLHash.h:57
void hash_final(MutableByteRange out)
Definition: OpenSSLHash.h:119
static void hash(MutableByteRange out, const EVP_MD *md, ByteRange data)
Definition: OpenSSLHash.h:76
static void sha256(MutableByteRange out, const IOBuf &data)
Definition: OpenSSLHash.h:97
std::unique_ptr< EVP_MD_CTX, EvpMdCtxDeleter > EvpMdCtxUniquePtr
static void sha1(MutableByteRange out, ByteRange data)
Definition: OpenSSLHash.h:88
static void check_out_size(size_t size, MutableByteRange out)
Definition: OpenSSLHash.h:166