]>
git.proxmox.com Git - ceph.git/blob - 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
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2004-2009 Sage Weil <sage@newdream.net>
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.
15 #ifndef CEPH_AUTH_CRYPTO_H
16 #define CEPH_AUTH_CRYPTO_H
18 #include "include/common_fwd.h"
19 #include "include/types.h"
20 #include "include/utime.h"
21 #include "include/buffer.h"
25 class CryptoKeyContext
;
26 namespace ceph
{ class Formatter
; }
29 * Random byte stream generator suitable for cryptographic use
33 CryptoRandom(); // throws on failure
35 /// copy up to 256 random bytes into the given buffer. throws on failure
36 void get_bytes(char *buf
, int len
);
38 static int open_urandom();
43 * some per-key context that is specific to a particular crypto backend
45 class CryptoKeyHandler
{
47 // The maximum size of a single block for all descendants of the class.
48 static constexpr std::size_t MAX_BLOCK_SIZE
{16};
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
;
55 const std::size_t length
;
56 const unsigned char* const buf
;
60 const std::size_t max_length
;
61 unsigned char* const buf
;
64 ceph::bufferptr secret
;
66 template <class BlockSizeT
>
67 CryptoKeyHandler(BlockSizeT
) {
68 static_assert(BlockSizeT::value
<= MAX_BLOCK_SIZE
);
71 virtual ~CryptoKeyHandler() {}
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;
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;
85 sha256_digest_t
hmac_sha256(const ceph::bufferlist
& in
) const;
89 * match encoding of struct ceph_secret
95 ceph::buffer::ptr secret
; // must set this via set_secret()!
97 // cache a pointer to the implementation-specific key handler, so we
98 // don't have to create it for every crypto operation.
99 mutable std::shared_ptr
<CryptoKeyHandler
> ckh
;
101 int _set_secret(int type
, const ceph::buffer::ptr
& s
);
104 CryptoKey() : type(0) { }
105 CryptoKey(int t
, utime_t c
, ceph::buffer::ptr
& s
)
112 void encode(ceph::buffer::list
& bl
) const;
113 void decode(ceph::buffer::list::const_iterator
& bl
);
115 int get_type() const { return type
; }
116 utime_t
get_created() const { return created
; }
117 void print(std::ostream
& out
) const;
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
; }
123 bool empty() const { return ckh
.get() == nullptr; }
125 void encode_base64(std::string
& s
) const {
126 ceph::buffer::list bl
;
133 std::string
encode_base64() const {
138 void decode_base64(const std::string
& s
) {
139 ceph::buffer::list e
;
141 ceph::buffer::list bl
;
143 auto p
= std::cbegin(bl
);
147 void encode_formatted(std::string label
, ceph::Formatter
*f
,
148 ceph::buffer::list
&bl
);
149 void encode_plaintext(ceph::buffer::list
&bl
);
152 int create(CephContext
*cct
, int type
);
153 int encrypt(CephContext
*cct
, const ceph::buffer::list
& in
,
154 ceph::buffer::list
& out
,
155 std::string
*error
) const {
156 ceph_assert(ckh
); // Bad key?
157 return ckh
->encrypt(in
, out
, error
);
159 int decrypt(CephContext
*cct
, const ceph::buffer::list
& in
,
160 ceph::buffer::list
& out
,
161 std::string
*error
) const {
162 ceph_assert(ckh
); // Bad key?
163 return ckh
->decrypt(in
, out
, error
);
166 using in_slice_t
= CryptoKeyHandler::in_slice_t
;
167 using out_slice_t
= CryptoKeyHandler::out_slice_t
;
169 std::size_t encrypt(CephContext
*, const in_slice_t
& in
,
170 const out_slice_t
& out
) {
172 return ckh
->encrypt(in
, out
);
174 std::size_t decrypt(CephContext
*, const in_slice_t
& in
,
175 const out_slice_t
& out
) {
177 return ckh
->encrypt(in
, out
);
180 sha256_digest_t
hmac_sha256(CephContext
*, const ceph::buffer::list
& in
) {
182 return ckh
->hmac_sha256(in
);
185 static constexpr std::size_t get_max_outbuf_size(std::size_t want_size
) {
186 return want_size
+ CryptoKeyHandler::MAX_BLOCK_SIZE
;
189 void to_str(std::string
& s
) const;
191 WRITE_CLASS_ENCODER(CryptoKey
)
193 inline std::ostream
& operator<<(std::ostream
& out
, const CryptoKey
& k
)
201 * Driver for a particular algorithm
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.
206 class CryptoHandler
{
208 virtual ~CryptoHandler() {}
209 virtual int get_type() const = 0;
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;
215 static CryptoHandler
*create(int type
);