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