]> git.proxmox.com Git - ceph.git/blame - ceph/src/common/ceph_crypto.h
bump version to 18.2.2-pve1
[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 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
31extern "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
38namespace 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
199template<class Digest>
200auto 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