Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / common / ceph_crypto.h
1 #ifndef CEPH_CRYPTO_H
2 #define CEPH_CRYPTO_H
3
4 #include "acconfig.h"
5
6 #define CEPH_CRYPTO_MD5_DIGESTSIZE 16
7 #define CEPH_CRYPTO_HMACSHA1_DIGESTSIZE 20
8 #define CEPH_CRYPTO_SHA1_DIGESTSIZE 20
9 #define CEPH_CRYPTO_HMACSHA256_DIGESTSIZE 32
10 #define CEPH_CRYPTO_SHA256_DIGESTSIZE 32
11
12 #ifdef USE_CRYPTOPP
13 # define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
14 #include <string.h>
15 #include <cryptopp/md5.h>
16 #include <cryptopp/sha.h>
17 #include <cryptopp/hmac.h>
18
19 // reinclude our assert to clobber the system one
20 # include "include/assert.h"
21
22 namespace ceph {
23   namespace crypto {
24     void assert_init();
25     void init(CephContext *cct);
26     // @param shared true if the the underlying crypto library could be shared
27     //               with the application linked against the Ceph library.
28     // @note we do extra global cleanup specific to the underlying crypto
29     //       library, if @c shared is @c false.
30     void shutdown(bool shared=true);
31
32     using CryptoPP::Weak::MD5;
33     using CryptoPP::SHA1;
34     using CryptoPP::SHA256;
35
36     class HMACSHA1: public CryptoPP::HMAC<CryptoPP::SHA1> {
37     public:
38       HMACSHA1 (const byte *key, size_t length)
39         : CryptoPP::HMAC<CryptoPP::SHA1>(key, length)
40         {
41         }
42       ~HMACSHA1();
43     };
44
45     class HMACSHA256: public CryptoPP::HMAC<CryptoPP::SHA256> {
46     public:
47       HMACSHA256 (const byte *key, size_t length)
48         : CryptoPP::HMAC<CryptoPP::SHA256>(key, length)
49         {
50         }
51       ~HMACSHA256();
52     };
53   }
54 }
55 #elif defined(USE_NSS)
56 // you *must* use CRYPTO_CXXFLAGS in CMakeLists.txt for including this include
57 # include <nss.h>
58 # include <pk11pub.h>
59
60 // NSS thinks a lot of fairly fundamental operations might potentially
61 // fail, because it has been written to support e.g. smartcards doing all
62 // the crypto operations. We don't want to contaminate too much code
63 // with error checking, and just say these really should never fail.
64 // This assert MUST NOT be compiled out, even on non-debug builds.
65 # include "include/assert.h"
66
67 // ugly bit of CryptoPP that we have to emulate here :(
68 typedef unsigned char byte;
69
70 namespace ceph {
71   namespace crypto {
72     void assert_init();
73     void init(CephContext *cct);
74     void shutdown(bool shared=true);
75     class Digest {
76     private:
77       PK11Context *ctx;
78       size_t digest_size;
79     public:
80       Digest (SECOidTag _type, size_t _digest_size) : digest_size(_digest_size) {
81         ctx = PK11_CreateDigestContext(_type);
82         assert(ctx);
83         Restart();
84       }
85       ~Digest () {
86         PK11_DestroyContext(ctx, PR_TRUE);
87       }
88       void Restart() {
89         SECStatus s;
90         s = PK11_DigestBegin(ctx);
91         assert(s == SECSuccess);
92       }
93       void Update (const byte *input, size_t length) {
94         if (length) {
95           SECStatus s;
96           s = PK11_DigestOp(ctx, input, length);
97           assert(s == SECSuccess);
98         }
99       }
100       void Final (byte *digest) {
101         SECStatus s;
102         unsigned int dummy;
103         s = PK11_DigestFinal(ctx, digest, &dummy, digest_size);
104         assert(s == SECSuccess);
105         assert(dummy == digest_size);
106         Restart();
107       }
108     };
109     class MD5 : public Digest {
110     public:
111       MD5 () : Digest(SEC_OID_MD5, CEPH_CRYPTO_MD5_DIGESTSIZE) { }
112     };
113
114     class SHA1 : public Digest {
115     public:
116       SHA1 () : Digest(SEC_OID_SHA1, CEPH_CRYPTO_SHA1_DIGESTSIZE) { }
117     };
118
119     class SHA256 : public Digest {
120     public:
121       SHA256 () : Digest(SEC_OID_SHA256, CEPH_CRYPTO_SHA256_DIGESTSIZE) { }
122     };
123
124     class HMAC {
125     private:
126       PK11SlotInfo *slot;
127       PK11SymKey *symkey;
128       PK11Context *ctx;
129       unsigned int digest_size;
130     public:
131       HMAC (CK_MECHANISM_TYPE cktype, unsigned int digestsize, const byte *key, size_t length) {
132         digest_size = digestsize;
133         slot = PK11_GetBestSlot(cktype, NULL);
134         assert(slot);
135         SECItem keyItem;
136         keyItem.type = siBuffer;
137         keyItem.data = (unsigned char*)key;
138         keyItem.len = length;
139         symkey = PK11_ImportSymKey(slot, cktype, PK11_OriginUnwrap,
140                                    CKA_SIGN,  &keyItem, NULL);
141         assert(symkey);
142         SECItem param;
143         param.type = siBuffer;
144         param.data = NULL;
145         param.len = 0;
146         ctx = PK11_CreateContextBySymKey(cktype, CKA_SIGN, symkey, &param);
147         assert(ctx);
148         Restart();
149       }
150       ~HMAC ();
151       void Restart() {
152         SECStatus s;
153         s = PK11_DigestBegin(ctx);
154         assert(s == SECSuccess);
155       }
156       void Update (const byte *input, size_t length) {
157         SECStatus s;
158         s = PK11_DigestOp(ctx, input, length);
159         assert(s == SECSuccess);
160       }
161       void Final (byte *digest) {
162         SECStatus s;
163         unsigned int dummy;
164         s = PK11_DigestFinal(ctx, digest, &dummy, digest_size);
165         assert(s == SECSuccess);
166         assert(dummy == digest_size);
167         Restart();
168       }
169     };
170
171     class HMACSHA1 : public HMAC {
172     public:
173       HMACSHA1 (const byte *key, size_t length) : HMAC(CKM_SHA_1_HMAC, CEPH_CRYPTO_HMACSHA1_DIGESTSIZE, key, length) { }
174     };
175
176     class HMACSHA256 : public HMAC {
177     public:
178       HMACSHA256 (const byte *key, size_t length) : HMAC(CKM_SHA256_HMAC, CEPH_CRYPTO_HMACSHA256_DIGESTSIZE, key, length) { }
179     };
180   }
181 }
182
183 #else
184 // cppcheck-suppress preprocessorErrorDirective
185 # error "No supported crypto implementation found."
186 #endif
187
188 #endif