2 * Copyright 2016 Facebook, Inc.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <openssl/evp.h>
20 #include <openssl/hmac.h>
21 #include <openssl/sha.h>
23 #include <folly/Range.h>
24 #include <folly/io/IOBuf.h>
30 /// These functions are not thread-safe unless you initialize OpenSSL.
37 EVP_MD_CTX_init(&ctx_);
40 EVP_MD_CTX_cleanup(&ctx_);
42 void hash_init(const EVP_MD* md) {
44 check_libssl_result(1, EVP_DigestInit_ex(&ctx_, md, nullptr));
46 void hash_update(ByteRange data) {
47 check_libssl_result(1, EVP_DigestUpdate(&ctx_, data.data(), data.size()));
49 void hash_update(const IOBuf& data) {
54 void hash_final(MutableByteRange out) {
55 const auto size = EVP_MD_size(md_);
56 check_out_size(size, out);
58 check_libssl_result(1, EVP_DigestFinal_ex(&ctx_, out.data(), &len));
59 check_libssl_result(size, len);
63 const EVP_MD* md_ = nullptr;
73 hash.hash_update(data);
82 hash.hash_update(data);
85 static void sha1(MutableByteRange out, ByteRange data) {
86 hash(out, EVP_sha1(), data);
88 static void sha1(MutableByteRange out, const IOBuf& data) {
89 hash(out, EVP_sha1(), data);
91 static void sha256(MutableByteRange out, ByteRange data) {
92 hash(out, EVP_sha256(), data);
94 static void sha256(MutableByteRange out, const IOBuf& data) {
95 hash(out, EVP_sha256(), data);
101 HMAC_CTX_init(&ctx_);
104 HMAC_CTX_cleanup(&ctx_);
106 void hash_init(const EVP_MD* md, ByteRange key) {
109 1, HMAC_Init_ex(&ctx_, key.data(), key.size(), md_, nullptr));
111 void hash_update(ByteRange data) {
112 check_libssl_result(1, HMAC_Update(&ctx_, data.data(), data.size()));
114 void hash_update(const IOBuf& data) {
115 for (auto r : data) {
119 void hash_final(MutableByteRange out) {
120 const auto size = EVP_MD_size(md_);
121 check_out_size(size, out);
122 unsigned int len = 0;
123 check_libssl_result(1, HMAC_Final(&ctx_, out.data(), &len));
124 check_libssl_result(size, len);
128 const EVP_MD* md_ = nullptr;
133 MutableByteRange out,
138 hmac.hash_init(md, key);
139 hmac.hash_update(data);
140 hmac.hash_final(out);
143 MutableByteRange out,
148 hmac.hash_init(md, key);
149 hmac.hash_update(data);
150 hmac.hash_final(out);
152 static void hmac_sha1(
153 MutableByteRange out, ByteRange key, ByteRange data) {
154 hmac(out, EVP_sha1(), key, data);
156 static void hmac_sha1(
157 MutableByteRange out, ByteRange key, const IOBuf& data) {
158 hmac(out, EVP_sha1(), key, data);
160 static void hmac_sha256(
161 MutableByteRange out, ByteRange key, ByteRange data) {
162 hmac(out, EVP_sha256(), key, data);
164 static void hmac_sha256(
165 MutableByteRange out, ByteRange key, const IOBuf& data) {
166 hmac(out, EVP_sha256(), key, data);
170 static inline void check_out_size(size_t size, MutableByteRange out) {
171 if (LIKELY(size == out.size())) {
174 check_out_size_throw(size, out);
176 static void check_out_size_throw(size_t size, MutableByteRange out);
178 static inline void check_libssl_result(int expected, int result) {
179 if (LIKELY(result == expected)) {
182 check_libssl_result_throw();
184 static void check_libssl_result_throw();