]>
Commit | Line | Data |
---|---|---|
11fdf7f2 | 1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
7c673cae FG |
2 | #ifndef CEPH_CRYPTO_H |
3 | #define CEPH_CRYPTO_H | |
4 | ||
5 | #include "acconfig.h" | |
81eedcae | 6 | #include <stdexcept> |
7c673cae | 7 | |
9f95a23c TL |
8 | #include "include/common_fwd.h" |
9 | #include "include/buffer.h" | |
10 | #include "include/types.h" | |
11 | ||
7c673cae FG |
12 | #define CEPH_CRYPTO_MD5_DIGESTSIZE 16 |
13 | #define CEPH_CRYPTO_HMACSHA1_DIGESTSIZE 20 | |
14 | #define CEPH_CRYPTO_SHA1_DIGESTSIZE 20 | |
15 | #define CEPH_CRYPTO_HMACSHA256_DIGESTSIZE 32 | |
16 | #define CEPH_CRYPTO_SHA256_DIGESTSIZE 32 | |
9f95a23c | 17 | #define CEPH_CRYPTO_SHA512_DIGESTSIZE 64 |
7c673cae | 18 | |
11fdf7f2 TL |
19 | #include <openssl/evp.h> |
20 | #include <openssl/ossl_typ.h> | |
21 | #include <openssl/hmac.h> | |
a8e16298 | 22 | |
9f95a23c TL |
23 | #include "include/ceph_assert.h" |
24 | ||
2a845540 TL |
25 | #pragma GCC diagnostic push |
26 | #pragma GCC diagnostic ignored "-Wdeprecated-declarations" | |
27 | ||
28 | #pragma clang diagnostic push | |
29 | #pragma clang diagnostic ignored "-Wdeprecated-declarations" | |
30 | ||
11fdf7f2 TL |
31 | extern "C" { |
32 | const EVP_MD *EVP_md5(void); | |
33 | const EVP_MD *EVP_sha1(void); | |
34 | const EVP_MD *EVP_sha256(void); | |
9f95a23c | 35 | const EVP_MD *EVP_sha512(void); |
11fdf7f2 | 36 | } |
a8e16298 | 37 | |
9f95a23c TL |
38 | namespace TOPNSPC::crypto { |
39 | void assert_init(); | |
40 | void init(); | |
41 | void shutdown(bool shared=true); | |
11fdf7f2 | 42 | |
9f95a23c | 43 | void zeroize_for_security(void *s, size_t n); |
81eedcae | 44 | |
9f95a23c TL |
45 | class DigestException : public std::runtime_error |
46 | { | |
81eedcae TL |
47 | public: |
48 | DigestException(const char* what_arg) : runtime_error(what_arg) | |
49 | {} | |
9f95a23c | 50 | }; |
11fdf7f2 | 51 | |
9f95a23c TL |
52 | namespace ssl { |
53 | class OpenSSLDigest { | |
11fdf7f2 TL |
54 | private: |
55 | EVP_MD_CTX *mpContext; | |
56 | const EVP_MD *mpType; | |
57 | public: | |
58 | OpenSSLDigest (const EVP_MD *_type); | |
59 | ~OpenSSLDigest (); | |
60 | void Restart(); | |
20effc67 | 61 | void SetFlags(int flags); |
11fdf7f2 TL |
62 | void Update (const unsigned char *input, size_t length); |
63 | void Final (unsigned char *digest); | |
9f95a23c | 64 | }; |
11fdf7f2 | 65 | |
9f95a23c | 66 | class MD5 : public OpenSSLDigest { |
11fdf7f2 | 67 | public: |
9f95a23c | 68 | static constexpr size_t digest_size = CEPH_CRYPTO_MD5_DIGESTSIZE; |
11fdf7f2 | 69 | MD5 () : OpenSSLDigest(EVP_md5()) { } |
9f95a23c | 70 | }; |
7c673cae | 71 | |
9f95a23c | 72 | class SHA1 : public OpenSSLDigest { |
11fdf7f2 | 73 | public: |
9f95a23c | 74 | static constexpr size_t digest_size = CEPH_CRYPTO_SHA1_DIGESTSIZE; |
11fdf7f2 | 75 | SHA1 () : OpenSSLDigest(EVP_sha1()) { } |
9f95a23c | 76 | }; |
11fdf7f2 | 77 | |
9f95a23c | 78 | class SHA256 : public OpenSSLDigest { |
11fdf7f2 | 79 | public: |
9f95a23c | 80 | static constexpr size_t digest_size = CEPH_CRYPTO_SHA256_DIGESTSIZE; |
11fdf7f2 | 81 | SHA256 () : OpenSSLDigest(EVP_sha256()) { } |
7c673cae FG |
82 | }; |
83 | ||
9f95a23c TL |
84 | class SHA512 : public OpenSSLDigest { |
85 | public: | |
86 | static constexpr size_t digest_size = CEPH_CRYPTO_SHA512_DIGESTSIZE; | |
87 | SHA512 () : OpenSSLDigest(EVP_sha512()) { } | |
7c673cae FG |
88 | }; |
89 | ||
11fdf7f2 | 90 | |
11fdf7f2 TL |
91 | # if OPENSSL_VERSION_NUMBER < 0x10100000L |
92 | class HMAC { | |
93 | private: | |
94 | HMAC_CTX mContext; | |
95 | const EVP_MD *mpType; | |
96 | ||
97 | public: | |
98 | HMAC (const EVP_MD *type, const unsigned char *key, size_t length) | |
99 | : mpType(type) { | |
92f5a8d4 TL |
100 | // the strict FIPS zeroization doesn't seem to be necessary here. |
101 | // just in the case. | |
9f95a23c | 102 | ::TOPNSPC::crypto::zeroize_for_security(&mContext, sizeof(mContext)); |
11fdf7f2 | 103 | const auto r = HMAC_Init_ex(&mContext, key, length, mpType, nullptr); |
81eedcae TL |
104 | if (r != 1) { |
105 | throw DigestException("HMAC_Init_ex() failed"); | |
106 | } | |
11fdf7f2 TL |
107 | } |
108 | ~HMAC () { | |
109 | HMAC_CTX_cleanup(&mContext); | |
110 | } | |
111 | ||
112 | void Restart () { | |
113 | const auto r = HMAC_Init_ex(&mContext, nullptr, 0, mpType, nullptr); | |
81eedcae TL |
114 | if (r != 1) { |
115 | throw DigestException("HMAC_Init_ex() failed"); | |
116 | } | |
11fdf7f2 TL |
117 | } |
118 | void Update (const unsigned char *input, size_t length) { | |
119 | if (length) { | |
120 | const auto r = HMAC_Update(&mContext, input, length); | |
81eedcae TL |
121 | if (r != 1) { |
122 | throw DigestException("HMAC_Update() failed"); | |
123 | } | |
11fdf7f2 TL |
124 | } |
125 | } | |
126 | void Final (unsigned char *digest) { | |
127 | unsigned int s; | |
128 | const auto r = HMAC_Final(&mContext, digest, &s); | |
81eedcae TL |
129 | if (r != 1) { |
130 | throw DigestException("HMAC_Final() failed"); | |
131 | } | |
11fdf7f2 TL |
132 | } |
133 | }; | |
134 | # else | |
135 | class HMAC { | |
136 | private: | |
137 | HMAC_CTX *mpContext; | |
138 | ||
139 | public: | |
140 | HMAC (const EVP_MD *type, const unsigned char *key, size_t length) | |
141 | : mpContext(HMAC_CTX_new()) { | |
142 | const auto r = HMAC_Init_ex(mpContext, key, length, type, nullptr); | |
81eedcae TL |
143 | if (r != 1) { |
144 | throw DigestException("HMAC_Init_ex() failed"); | |
145 | } | |
11fdf7f2 TL |
146 | } |
147 | ~HMAC () { | |
148 | HMAC_CTX_free(mpContext); | |
149 | } | |
150 | ||
151 | void Restart () { | |
152 | const EVP_MD * const type = HMAC_CTX_get_md(mpContext); | |
153 | const auto r = HMAC_Init_ex(mpContext, nullptr, 0, type, nullptr); | |
81eedcae TL |
154 | if (r != 1) { |
155 | throw DigestException("HMAC_Init_ex() failed"); | |
156 | } | |
11fdf7f2 TL |
157 | } |
158 | void Update (const unsigned char *input, size_t length) { | |
159 | if (length) { | |
160 | const auto r = HMAC_Update(mpContext, input, length); | |
81eedcae TL |
161 | if (r != 1) { |
162 | throw DigestException("HMAC_Update() failed"); | |
163 | } | |
11fdf7f2 TL |
164 | } |
165 | } | |
166 | void Final (unsigned char *digest) { | |
167 | unsigned int s; | |
168 | const auto r = HMAC_Final(mpContext, digest, &s); | |
81eedcae TL |
169 | if (r != 1) { |
170 | throw DigestException("HMAC_Final() failed"); | |
171 | } | |
11fdf7f2 TL |
172 | } |
173 | }; | |
174 | # endif // OPENSSL_VERSION_NUMBER < 0x10100000L | |
175 | ||
176 | struct HMACSHA1 : public HMAC { | |
177 | HMACSHA1 (const unsigned char *key, size_t length) | |
178 | : HMAC(EVP_sha1(), key, length) { | |
179 | } | |
180 | }; | |
181 | ||
182 | struct HMACSHA256 : public HMAC { | |
183 | HMACSHA256 (const unsigned char *key, size_t length) | |
184 | : HMAC(EVP_sha256(), key, length) { | |
185 | } | |
186 | }; | |
187 | } | |
11fdf7f2 | 188 | |
7c673cae | 189 | |
9f95a23c TL |
190 | using ssl::SHA256; |
191 | using ssl::MD5; | |
192 | using ssl::SHA1; | |
193 | using ssl::SHA512; | |
11fdf7f2 | 194 | |
9f95a23c TL |
195 | using ssl::HMACSHA256; |
196 | using ssl::HMACSHA1; | |
11fdf7f2 | 197 | |
9f95a23c TL |
198 | template<class Digest> |
199 | auto digest(const ceph::buffer::list& bl) | |
200 | { | |
201 | unsigned char fingerprint[Digest::digest_size]; | |
202 | Digest gen; | |
203 | for (auto& p : bl.buffers()) { | |
204 | gen.Update((const unsigned char *)p.c_str(), p.length()); | |
11fdf7f2 | 205 | } |
9f95a23c TL |
206 | gen.Final(fingerprint); |
207 | return sha_digest_t<Digest::digest_size>{fingerprint}; | |
208 | } | |
11fdf7f2 | 209 | } |
7c673cae | 210 | |
2a845540 TL |
211 | #pragma clang diagnostic pop |
212 | #pragma GCC diagnostic pop | |
213 | ||
7c673cae | 214 | #endif |