]> git.proxmox.com Git - ceph.git/blob - ceph/src/auth/Crypto.h
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / auth / Crypto.h
1 // -*- mode:C; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2004-2009 Sage Weil <sage@newdream.net>
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14
15 #ifndef CEPH_AUTH_CRYPTO_H
16 #define CEPH_AUTH_CRYPTO_H
17
18 #include "include/types.h"
19 #include "include/utime.h"
20 #include "include/buffer.h"
21
22 #include <string>
23
24 class CephContext;
25 class CryptoKeyContext;
26 namespace ceph { class Formatter; }
27
28 /*
29 * Random byte stream generator suitable for cryptographic use
30 */
31 class CryptoRandom {
32 const int fd;
33 public:
34 CryptoRandom(); // throws on failure
35 ~CryptoRandom();
36
37 /// copy up to 256 random bytes into the given buffer. throws on failure
38 void get_bytes(char *buf, int len);
39 };
40
41 /*
42 * some per-key context that is specific to a particular crypto backend
43 */
44 class CryptoKeyHandler {
45 public:
46 // The maximum size of a single block for all descendants of the class.
47 static constexpr std::size_t MAX_BLOCK_SIZE {16};
48
49 // A descendant pick-ups one from these and passes it to the ctor template.
50 typedef std::integral_constant<std::size_t, 0> BLOCK_SIZE_0B;
51 typedef std::integral_constant<std::size_t, 16> BLOCK_SIZE_16B;
52
53 struct in_slice_t {
54 const std::size_t length;
55 const unsigned char* const buf;
56 };
57
58 struct out_slice_t {
59 const std::size_t max_length;
60 unsigned char* const buf;
61 };
62
63 ceph::bufferptr secret;
64
65 template <class BlockSizeT>
66 CryptoKeyHandler(BlockSizeT) {
67 static_assert(BlockSizeT::value <= MAX_BLOCK_SIZE);
68 }
69
70 virtual ~CryptoKeyHandler() {}
71
72 virtual int encrypt(const bufferlist& in,
73 bufferlist& out, std::string *error) const = 0;
74 virtual int decrypt(const bufferlist& in,
75 bufferlist& out, std::string *error) const = 0;
76
77 // TODO: provide nullptr in the out::buf to get/estimate size requirements?
78 // Or maybe dedicated methods?
79 virtual std::size_t encrypt(const in_slice_t& in,
80 const out_slice_t& out) const;
81 virtual std::size_t decrypt(const in_slice_t& in,
82 const out_slice_t& out) const;
83
84 sha256_digest_t hmac_sha256(const ceph::bufferlist& in) const;
85 };
86
87 /*
88 * match encoding of struct ceph_secret
89 */
90 class CryptoKey {
91 protected:
92 __u16 type;
93 utime_t created;
94 bufferptr secret; // must set this via set_secret()!
95
96 // cache a pointer to the implementation-specific key handler, so we
97 // don't have to create it for every crypto operation.
98 mutable std::shared_ptr<CryptoKeyHandler> ckh;
99
100 int _set_secret(int type, const bufferptr& s);
101
102 public:
103 CryptoKey() : type(0) { }
104 CryptoKey(int t, utime_t c, bufferptr& s)
105 : created(c) {
106 _set_secret(t, s);
107 }
108 ~CryptoKey() {
109 }
110
111 void encode(bufferlist& bl) const;
112 void decode(bufferlist::const_iterator& bl);
113
114 int get_type() const { return type; }
115 utime_t get_created() const { return created; }
116 void print(std::ostream& out) const;
117
118 int set_secret(int type, const bufferptr& s, utime_t created);
119 const bufferptr& get_secret() { return secret; }
120 const bufferptr& get_secret() const { return secret; }
121
122 bool empty() const { return ckh.get() == nullptr; }
123
124 void encode_base64(string& s) const {
125 bufferlist bl;
126 encode(bl);
127 bufferlist e;
128 bl.encode_base64(e);
129 e.append('\0');
130 s = e.c_str();
131 }
132 string encode_base64() const {
133 string s;
134 encode_base64(s);
135 return s;
136 }
137 void decode_base64(const string& s) {
138 bufferlist e;
139 e.append(s);
140 bufferlist bl;
141 bl.decode_base64(e);
142 auto p = std::cbegin(bl);
143 decode(p);
144 }
145
146 void encode_formatted(string label, Formatter *f, bufferlist &bl);
147 void encode_plaintext(bufferlist &bl);
148
149 // --
150 int create(CephContext *cct, int type);
151 int encrypt(CephContext *cct, const bufferlist& in, bufferlist& out,
152 std::string *error) const {
153 ceph_assert(ckh); // Bad key?
154 return ckh->encrypt(in, out, error);
155 }
156 int decrypt(CephContext *cct, const bufferlist& in, bufferlist& out,
157 std::string *error) const {
158 ceph_assert(ckh); // Bad key?
159 return ckh->decrypt(in, out, error);
160 }
161
162 using in_slice_t = CryptoKeyHandler::in_slice_t;
163 using out_slice_t = CryptoKeyHandler::out_slice_t;
164
165 std::size_t encrypt(CephContext*, const in_slice_t& in,
166 const out_slice_t& out) {
167 ceph_assert(ckh);
168 return ckh->encrypt(in, out);
169 }
170 std::size_t decrypt(CephContext*, const in_slice_t& in,
171 const out_slice_t& out) {
172 ceph_assert(ckh);
173 return ckh->encrypt(in, out);
174 }
175
176 sha256_digest_t hmac_sha256(CephContext*, const ceph::bufferlist& in) {
177 ceph_assert(ckh);
178 return ckh->hmac_sha256(in);
179 }
180
181 static constexpr std::size_t get_max_outbuf_size(std::size_t want_size) {
182 return want_size + CryptoKeyHandler::MAX_BLOCK_SIZE;
183 }
184
185 void to_str(std::string& s) const;
186 };
187 WRITE_CLASS_ENCODER(CryptoKey)
188
189 static inline ostream& operator<<(ostream& out, const CryptoKey& k)
190 {
191 k.print(out);
192 return out;
193 }
194
195
196 /*
197 * Driver for a particular algorithm
198 *
199 * To use these functions, you need to call ceph::crypto::init(), see
200 * common/ceph_crypto.h. common_init_finish does this for you.
201 */
202 class CryptoHandler {
203 public:
204 virtual ~CryptoHandler() {}
205 virtual int get_type() const = 0;
206 virtual int create(CryptoRandom *random, bufferptr& secret) = 0;
207 virtual int validate_secret(const bufferptr& secret) = 0;
208 virtual CryptoKeyHandler *get_key_handler(const bufferptr& secret,
209 string& error) = 0;
210
211 static CryptoHandler *create(int type);
212 };
213
214
215 #endif