]>
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; | |
1e59de90 | 57 | EVP_MD *mpType_FIPS = nullptr; |
11fdf7f2 TL |
58 | public: |
59 | OpenSSLDigest (const EVP_MD *_type); | |
60 | ~OpenSSLDigest (); | |
61 | void Restart(); | |
20effc67 | 62 | void SetFlags(int flags); |
11fdf7f2 TL |
63 | void Update (const unsigned char *input, size_t length); |
64 | void Final (unsigned char *digest); | |
9f95a23c | 65 | }; |
11fdf7f2 | 66 | |
9f95a23c | 67 | class MD5 : public OpenSSLDigest { |
11fdf7f2 | 68 | public: |
9f95a23c | 69 | static constexpr size_t digest_size = CEPH_CRYPTO_MD5_DIGESTSIZE; |
11fdf7f2 | 70 | MD5 () : OpenSSLDigest(EVP_md5()) { } |
9f95a23c | 71 | }; |
7c673cae | 72 | |
9f95a23c | 73 | class SHA1 : public OpenSSLDigest { |
11fdf7f2 | 74 | public: |
9f95a23c | 75 | static constexpr size_t digest_size = CEPH_CRYPTO_SHA1_DIGESTSIZE; |
11fdf7f2 | 76 | SHA1 () : OpenSSLDigest(EVP_sha1()) { } |
9f95a23c | 77 | }; |
11fdf7f2 | 78 | |
9f95a23c | 79 | class SHA256 : public OpenSSLDigest { |
11fdf7f2 | 80 | public: |
9f95a23c | 81 | static constexpr size_t digest_size = CEPH_CRYPTO_SHA256_DIGESTSIZE; |
11fdf7f2 | 82 | SHA256 () : OpenSSLDigest(EVP_sha256()) { } |
7c673cae FG |
83 | }; |
84 | ||
9f95a23c TL |
85 | class SHA512 : public OpenSSLDigest { |
86 | public: | |
87 | static constexpr size_t digest_size = CEPH_CRYPTO_SHA512_DIGESTSIZE; | |
88 | SHA512 () : OpenSSLDigest(EVP_sha512()) { } | |
7c673cae FG |
89 | }; |
90 | ||
11fdf7f2 | 91 | |
11fdf7f2 TL |
92 | # if OPENSSL_VERSION_NUMBER < 0x10100000L |
93 | class HMAC { | |
94 | private: | |
95 | HMAC_CTX mContext; | |
96 | const EVP_MD *mpType; | |
97 | ||
98 | public: | |
99 | HMAC (const EVP_MD *type, const unsigned char *key, size_t length) | |
100 | : mpType(type) { | |
92f5a8d4 TL |
101 | // the strict FIPS zeroization doesn't seem to be necessary here. |
102 | // just in the case. | |
9f95a23c | 103 | ::TOPNSPC::crypto::zeroize_for_security(&mContext, sizeof(mContext)); |
11fdf7f2 | 104 | const auto r = HMAC_Init_ex(&mContext, key, length, mpType, nullptr); |
81eedcae TL |
105 | if (r != 1) { |
106 | throw DigestException("HMAC_Init_ex() failed"); | |
107 | } | |
11fdf7f2 TL |
108 | } |
109 | ~HMAC () { | |
110 | HMAC_CTX_cleanup(&mContext); | |
111 | } | |
112 | ||
113 | void Restart () { | |
114 | const auto r = HMAC_Init_ex(&mContext, nullptr, 0, mpType, nullptr); | |
81eedcae TL |
115 | if (r != 1) { |
116 | throw DigestException("HMAC_Init_ex() failed"); | |
117 | } | |
11fdf7f2 TL |
118 | } |
119 | void Update (const unsigned char *input, size_t length) { | |
120 | if (length) { | |
121 | const auto r = HMAC_Update(&mContext, input, length); | |
81eedcae TL |
122 | if (r != 1) { |
123 | throw DigestException("HMAC_Update() failed"); | |
124 | } | |
11fdf7f2 TL |
125 | } |
126 | } | |
127 | void Final (unsigned char *digest) { | |
128 | unsigned int s; | |
129 | const auto r = HMAC_Final(&mContext, digest, &s); | |
81eedcae TL |
130 | if (r != 1) { |
131 | throw DigestException("HMAC_Final() failed"); | |
132 | } | |
11fdf7f2 TL |
133 | } |
134 | }; | |
135 | # else | |
136 | class HMAC { | |
137 | private: | |
138 | HMAC_CTX *mpContext; | |
139 | ||
140 | public: | |
141 | HMAC (const EVP_MD *type, const unsigned char *key, size_t length) | |
142 | : mpContext(HMAC_CTX_new()) { | |
143 | const auto r = HMAC_Init_ex(mpContext, key, length, type, nullptr); | |
81eedcae TL |
144 | if (r != 1) { |
145 | throw DigestException("HMAC_Init_ex() failed"); | |
146 | } | |
11fdf7f2 TL |
147 | } |
148 | ~HMAC () { | |
149 | HMAC_CTX_free(mpContext); | |
150 | } | |
151 | ||
152 | void Restart () { | |
153 | const EVP_MD * const type = HMAC_CTX_get_md(mpContext); | |
154 | const auto r = HMAC_Init_ex(mpContext, nullptr, 0, type, nullptr); | |
81eedcae TL |
155 | if (r != 1) { |
156 | throw DigestException("HMAC_Init_ex() failed"); | |
157 | } | |
11fdf7f2 TL |
158 | } |
159 | void Update (const unsigned char *input, size_t length) { | |
160 | if (length) { | |
161 | const auto r = HMAC_Update(mpContext, input, length); | |
81eedcae TL |
162 | if (r != 1) { |
163 | throw DigestException("HMAC_Update() failed"); | |
164 | } | |
11fdf7f2 TL |
165 | } |
166 | } | |
167 | void Final (unsigned char *digest) { | |
168 | unsigned int s; | |
169 | const auto r = HMAC_Final(mpContext, digest, &s); | |
81eedcae TL |
170 | if (r != 1) { |
171 | throw DigestException("HMAC_Final() failed"); | |
172 | } | |
11fdf7f2 TL |
173 | } |
174 | }; | |
175 | # endif // OPENSSL_VERSION_NUMBER < 0x10100000L | |
176 | ||
177 | struct HMACSHA1 : public HMAC { | |
178 | HMACSHA1 (const unsigned char *key, size_t length) | |
179 | : HMAC(EVP_sha1(), key, length) { | |
180 | } | |
181 | }; | |
182 | ||
183 | struct HMACSHA256 : public HMAC { | |
184 | HMACSHA256 (const unsigned char *key, size_t length) | |
185 | : HMAC(EVP_sha256(), key, length) { | |
186 | } | |
187 | }; | |
188 | } | |
11fdf7f2 | 189 | |
7c673cae | 190 | |
9f95a23c TL |
191 | using ssl::SHA256; |
192 | using ssl::MD5; | |
193 | using ssl::SHA1; | |
194 | using ssl::SHA512; | |
11fdf7f2 | 195 | |
9f95a23c TL |
196 | using ssl::HMACSHA256; |
197 | using ssl::HMACSHA1; | |
11fdf7f2 | 198 | |
9f95a23c TL |
199 | template<class Digest> |
200 | auto digest(const ceph::buffer::list& bl) | |
201 | { | |
202 | unsigned char fingerprint[Digest::digest_size]; | |
203 | Digest gen; | |
204 | for (auto& p : bl.buffers()) { | |
205 | gen.Update((const unsigned char *)p.c_str(), p.length()); | |
11fdf7f2 | 206 | } |
9f95a23c TL |
207 | gen.Final(fingerprint); |
208 | return sha_digest_t<Digest::digest_size>{fingerprint}; | |
209 | } | |
11fdf7f2 | 210 | } |
7c673cae | 211 | |
2a845540 TL |
212 | #pragma clang diagnostic pop |
213 | #pragma GCC diagnostic pop | |
214 | ||
7c673cae | 215 | #endif |