]> git.proxmox.com Git - ceph.git/blame - ceph/src/common/ceph_crypto.h
Add patch for failing prerm scripts
[ceph.git] / ceph / src / common / ceph_crypto.h
CommitLineData
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
FG
7
8#define CEPH_CRYPTO_MD5_DIGESTSIZE 16
9#define CEPH_CRYPTO_HMACSHA1_DIGESTSIZE 20
10#define CEPH_CRYPTO_SHA1_DIGESTSIZE 20
11#define CEPH_CRYPTO_HMACSHA256_DIGESTSIZE 32
12#define CEPH_CRYPTO_SHA256_DIGESTSIZE 32
13
11fdf7f2 14#ifdef USE_NSS
7c673cae
FG
15// you *must* use CRYPTO_CXXFLAGS in CMakeLists.txt for including this include
16# include <nss.h>
17# include <pk11pub.h>
18
19// NSS thinks a lot of fairly fundamental operations might potentially
20// fail, because it has been written to support e.g. smartcards doing all
21// the crypto operations. We don't want to contaminate too much code
22// with error checking, and just say these really should never fail.
23// This assert MUST NOT be compiled out, even on non-debug builds.
11fdf7f2
TL
24# include "include/ceph_assert.h"
25#endif /*USE_NSS*/
7c673cae 26
11fdf7f2
TL
27#ifdef USE_OPENSSL
28#include <openssl/evp.h>
29#include <openssl/ossl_typ.h>
30#include <openssl/hmac.h>
a8e16298 31
11fdf7f2
TL
32extern "C" {
33 const EVP_MD *EVP_md5(void);
34 const EVP_MD *EVP_sha1(void);
35 const EVP_MD *EVP_sha256(void);
36}
37#endif /*USE_OPENSSL*/
a8e16298 38
7c673cae
FG
39namespace ceph {
40 namespace crypto {
41 void assert_init();
42 void init(CephContext *cct);
43 void shutdown(bool shared=true);
11fdf7f2
TL
44 }
45}
46
47#ifdef USE_NSS
48namespace ceph {
49 namespace crypto {
81eedcae
TL
50
51 class DigestException : public std::runtime_error
52 {
53 public:
54 DigestException(const char* what_arg) : runtime_error(what_arg)
55 {}
56 };
57
11fdf7f2 58 namespace nss {
81eedcae 59
11fdf7f2
TL
60 class NSSDigest {
61 private:
62 PK11Context *ctx;
63 size_t digest_size;
64 public:
65 NSSDigest (SECOidTag _type, size_t _digest_size)
66 : digest_size(_digest_size) {
67 ctx = PK11_CreateDigestContext(_type);
81eedcae
TL
68 if (! ctx) {
69 throw DigestException("PK11_CreateDigestContext() failed");
70 }
11fdf7f2 71 Restart();
7c673cae 72 }
11fdf7f2
TL
73 ~NSSDigest () {
74 PK11_DestroyContext(ctx, PR_TRUE);
75 }
76 void Restart() {
77 SECStatus s;
78 s = PK11_DigestBegin(ctx);
81eedcae
TL
79 if (s != SECSuccess) {
80 throw DigestException("PK11_DigestBegin() failed");
81 }
11fdf7f2
TL
82 }
83 void Update (const unsigned char *input, size_t length) {
84 if (length) {
85 SECStatus s;
86 s = PK11_DigestOp(ctx, input, length);
81eedcae
TL
87 if (s != SECSuccess) {
88 throw DigestException("PK11_DigestOp() failed");
89 }
11fdf7f2
TL
90 }
91 }
92 void Final (unsigned char *digest) {
93 SECStatus s;
94 unsigned int dummy;
95 s = PK11_DigestFinal(ctx, digest, &dummy, digest_size);
81eedcae
TL
96 if (! (s == SECSuccess) &&
97 (dummy == digest_size)) {
98 throw DigestException("PK11_DigestFinal() failed");
99 }
11fdf7f2
TL
100 Restart();
101 }
102 };
7c673cae 103
11fdf7f2
TL
104 class MD5 : public NSSDigest {
105 public:
106 MD5 () : NSSDigest(SEC_OID_MD5, CEPH_CRYPTO_MD5_DIGESTSIZE) { }
107 };
7c673cae 108
11fdf7f2
TL
109 class SHA1 : public NSSDigest {
110 public:
111 SHA1 () : NSSDigest(SEC_OID_SHA1, CEPH_CRYPTO_SHA1_DIGESTSIZE) { }
112 };
113
114 class SHA256 : public NSSDigest {
115 public:
116 SHA256 () : NSSDigest(SEC_OID_SHA256, CEPH_CRYPTO_SHA256_DIGESTSIZE) { }
117 };
118 }
119 }
120}
121#endif /*USE_NSS*/
122
123#ifdef USE_OPENSSL
124namespace ceph {
125 namespace crypto {
126 namespace ssl {
127 class OpenSSLDigest {
128 private:
129 EVP_MD_CTX *mpContext;
130 const EVP_MD *mpType;
131 public:
132 OpenSSLDigest (const EVP_MD *_type);
133 ~OpenSSLDigest ();
134 void Restart();
135 void Update (const unsigned char *input, size_t length);
136 void Final (unsigned char *digest);
137 };
138
139 class MD5 : public OpenSSLDigest {
140 public:
141 MD5 () : OpenSSLDigest(EVP_md5()) { }
142 };
7c673cae 143
11fdf7f2
TL
144 class SHA1 : public OpenSSLDigest {
145 public:
146 SHA1 () : OpenSSLDigest(EVP_sha1()) { }
147 };
148
149 class SHA256 : public OpenSSLDigest {
150 public:
151 SHA256 () : OpenSSLDigest(EVP_sha256()) { }
152 };
153 }
154 }
155}
156#endif /*USE_OPENSSL*/
157
158
159#ifdef USE_NSS
160namespace ceph {
161 namespace crypto::nss {
7c673cae
FG
162 class HMAC {
163 private:
164 PK11SlotInfo *slot;
165 PK11SymKey *symkey;
166 PK11Context *ctx;
167 unsigned int digest_size;
168 public:
11fdf7f2 169 HMAC (CK_MECHANISM_TYPE cktype, unsigned int digestsize, const unsigned char *key, size_t length) {
7c673cae
FG
170 digest_size = digestsize;
171 slot = PK11_GetBestSlot(cktype, NULL);
81eedcae
TL
172 if (! slot) {
173 throw DigestException("PK11_GetBestSlot() failed");
174 }
7c673cae
FG
175 SECItem keyItem;
176 keyItem.type = siBuffer;
177 keyItem.data = (unsigned char*)key;
178 keyItem.len = length;
11fdf7f2
TL
179 symkey = PK11_ImportSymKey(slot, cktype, PK11_OriginUnwrap,
180 CKA_SIGN, &keyItem, NULL);
81eedcae
TL
181 if (! symkey) {
182 throw DigestException("PK11_ImportSymKey() failed");
183 }
7c673cae
FG
184 SECItem param;
185 param.type = siBuffer;
186 param.data = NULL;
187 param.len = 0;
188 ctx = PK11_CreateContextBySymKey(cktype, CKA_SIGN, symkey, &param);
81eedcae
TL
189 if (! ctx) {
190 throw DigestException("PK11_CreateContextBySymKey() failed");
191 }
7c673cae
FG
192 Restart();
193 }
194 ~HMAC ();
195 void Restart() {
196 SECStatus s;
197 s = PK11_DigestBegin(ctx);
81eedcae
TL
198 if (s != SECSuccess) {
199 throw DigestException("PK11_DigestBegin() failed");
200 }
7c673cae 201 }
11fdf7f2 202 void Update (const unsigned char *input, size_t length) {
7c673cae
FG
203 SECStatus s;
204 s = PK11_DigestOp(ctx, input, length);
81eedcae
TL
205 if (s != SECSuccess) {
206 throw DigestException("PK11_DigestOp() failed");
207 }
7c673cae 208 }
11fdf7f2 209 void Final (unsigned char *digest) {
7c673cae
FG
210 SECStatus s;
211 unsigned int dummy;
212 s = PK11_DigestFinal(ctx, digest, &dummy, digest_size);
81eedcae
TL
213 if (! (s == SECSuccess) &&
214 (dummy == digest_size)) {
215 throw DigestException("PK11_DigestFinal() failed");
216 }
7c673cae
FG
217 Restart();
218 }
219 };
220
221 class HMACSHA1 : public HMAC {
222 public:
11fdf7f2 223 HMACSHA1 (const unsigned char *key, size_t length) : HMAC(CKM_SHA_1_HMAC, CEPH_CRYPTO_HMACSHA1_DIGESTSIZE, key, length) { }
7c673cae
FG
224 };
225
226 class HMACSHA256 : public HMAC {
227 public:
11fdf7f2 228 HMACSHA256 (const unsigned char *key, size_t length) : HMAC(CKM_SHA256_HMAC, CEPH_CRYPTO_HMACSHA256_DIGESTSIZE, key, length) { }
7c673cae
FG
229 };
230 }
231}
11fdf7f2
TL
232#endif
233
234#ifdef USE_OPENSSL
235namespace ceph::crypto::ssl {
236# if OPENSSL_VERSION_NUMBER < 0x10100000L
237 class HMAC {
238 private:
239 HMAC_CTX mContext;
240 const EVP_MD *mpType;
241
242 public:
243 HMAC (const EVP_MD *type, const unsigned char *key, size_t length)
244 : mpType(type) {
245 ::memset(&mContext, 0, sizeof(mContext));
246 const auto r = HMAC_Init_ex(&mContext, key, length, mpType, nullptr);
81eedcae
TL
247 if (r != 1) {
248 throw DigestException("HMAC_Init_ex() failed");
249 }
11fdf7f2
TL
250 }
251 ~HMAC () {
252 HMAC_CTX_cleanup(&mContext);
253 }
254
255 void Restart () {
256 const auto r = HMAC_Init_ex(&mContext, nullptr, 0, mpType, nullptr);
81eedcae
TL
257 if (r != 1) {
258 throw DigestException("HMAC_Init_ex() failed");
259 }
11fdf7f2
TL
260 }
261 void Update (const unsigned char *input, size_t length) {
262 if (length) {
263 const auto r = HMAC_Update(&mContext, input, length);
81eedcae
TL
264 if (r != 1) {
265 throw DigestException("HMAC_Update() failed");
266 }
11fdf7f2
TL
267 }
268 }
269 void Final (unsigned char *digest) {
270 unsigned int s;
271 const auto r = HMAC_Final(&mContext, digest, &s);
81eedcae
TL
272 if (r != 1) {
273 throw DigestException("HMAC_Final() failed");
274 }
11fdf7f2
TL
275 }
276 };
277# else
278 class HMAC {
279 private:
280 HMAC_CTX *mpContext;
281
282 public:
283 HMAC (const EVP_MD *type, const unsigned char *key, size_t length)
284 : mpContext(HMAC_CTX_new()) {
285 const auto r = HMAC_Init_ex(mpContext, key, length, type, nullptr);
81eedcae
TL
286 if (r != 1) {
287 throw DigestException("HMAC_Init_ex() failed");
288 }
11fdf7f2
TL
289 }
290 ~HMAC () {
291 HMAC_CTX_free(mpContext);
292 }
293
294 void Restart () {
295 const EVP_MD * const type = HMAC_CTX_get_md(mpContext);
296 const auto r = HMAC_Init_ex(mpContext, nullptr, 0, type, nullptr);
81eedcae
TL
297 if (r != 1) {
298 throw DigestException("HMAC_Init_ex() failed");
299 }
11fdf7f2
TL
300 }
301 void Update (const unsigned char *input, size_t length) {
302 if (length) {
303 const auto r = HMAC_Update(mpContext, input, length);
81eedcae
TL
304 if (r != 1) {
305 throw DigestException("HMAC_Update() failed");
306 }
11fdf7f2
TL
307 }
308 }
309 void Final (unsigned char *digest) {
310 unsigned int s;
311 const auto r = HMAC_Final(mpContext, digest, &s);
81eedcae
TL
312 if (r != 1) {
313 throw DigestException("HMAC_Final() failed");
314 }
11fdf7f2
TL
315 }
316 };
317# endif // OPENSSL_VERSION_NUMBER < 0x10100000L
318
319 struct HMACSHA1 : public HMAC {
320 HMACSHA1 (const unsigned char *key, size_t length)
321 : HMAC(EVP_sha1(), key, length) {
322 }
323 };
324
325 struct HMACSHA256 : public HMAC {
326 HMACSHA256 (const unsigned char *key, size_t length)
327 : HMAC(EVP_sha256(), key, length) {
328 }
329 };
330}
331#endif /*USE_OPENSSL*/
332
7c673cae 333
11fdf7f2
TL
334#if defined(USE_OPENSSL)
335namespace ceph {
336 namespace crypto {
337 using ceph::crypto::ssl::SHA256;
338 using ceph::crypto::ssl::MD5;
339 using ceph::crypto::ssl::SHA1;
340
341 using ceph::crypto::ssl::HMACSHA256;
342 using ceph::crypto::ssl::HMACSHA1;
343 }
344}
345#elif defined(USE_NSS)
346namespace ceph {
347 namespace crypto {
348 using ceph::crypto::nss::SHA256;
349 using ceph::crypto::nss::MD5;
350 using ceph::crypto::nss::SHA1;
351
352 using ceph::crypto::nss::HMACSHA256;
353 using ceph::crypto::nss::HMACSHA1;
354 }
355}
7c673cae
FG
356#else
357// cppcheck-suppress preprocessorErrorDirective
358# error "No supported crypto implementation found."
359#endif
360
361#endif