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