]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_crypt.h
import 15.2.0 Octopus source
[ceph.git] / ceph / src / rgw / rgw_crypt.h
1 // -*- mode:C; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
3
4 /**
5 * Crypto filters for Put/Post/Get operations.
6 */
7
8 #ifndef CEPH_RGW_CRYPT_H
9 #define CEPH_RGW_CRYPT_H
10
11 #include <rgw/rgw_op.h>
12 #include <rgw/rgw_rest.h>
13 #include <rgw/rgw_rest_s3.h>
14 #include "rgw_putobj.h"
15 #include <boost/utility/string_view.hpp>
16
17 /**
18 * \brief Interface for block encryption methods
19 *
20 * Encrypts and decrypts data.
21 * Operations are performed in context of larger stream being divided into blocks.
22 * Each block can be processed independently, but only as a whole.
23 * Part block cannot be properly processed.
24 * Each request must start on block-aligned offset.
25 * Each request should have length that is multiply of block size.
26 * Request with unaligned length is only acceptable for last part of stream.
27 */
28 class BlockCrypt {
29 public:
30 BlockCrypt(){};
31 virtual ~BlockCrypt(){};
32
33 /**
34 * Determines size of encryption block.
35 * This is usually multiply of key size.
36 * It determines size of chunks that should be passed to \ref encrypt and \ref decrypt.
37 */
38 virtual size_t get_block_size() = 0;
39
40 /**
41 * Encrypts data.
42 * Argument \ref stream_offset shows where in generalized stream chunk is located.
43 * Input for encryption is \ref input buffer, with relevant data in range <in_ofs, in_ofs+size).
44 * \ref input and \output may not be the same buffer.
45 *
46 * \params
47 * input - source buffer of data
48 * in_ofs - offset of chunk inside input
49 * size - size of chunk, must be chunk-aligned unless last part is processed
50 * output - destination buffer to encrypt to
51 * stream_offset - location of <in_ofs,in_ofs+size) chunk in data stream, must be chunk-aligned
52 * \return true iff successfully encrypted
53 */
54 virtual bool encrypt(bufferlist& input,
55 off_t in_ofs,
56 size_t size,
57 bufferlist& output,
58 off_t stream_offset) = 0;
59
60 /**
61 * Decrypts data.
62 * Argument \ref stream_offset shows where in generalized stream chunk is located.
63 * Input for decryption is \ref input buffer, with relevant data in range <in_ofs, in_ofs+size).
64 * \ref input and \output may not be the same buffer.
65 *
66 * \params
67 * input - source buffer of data
68 * in_ofs - offset of chunk inside input
69 * size - size of chunk, must be chunk-aligned unless last part is processed
70 * output - destination buffer to encrypt to
71 * stream_offset - location of <in_ofs,in_ofs+size) chunk in data stream, must be chunk-aligned
72 * \return true iff successfully encrypted
73 */
74 virtual bool decrypt(bufferlist& input,
75 off_t in_ofs,
76 size_t size,
77 bufferlist& output,
78 off_t stream_offset) = 0;
79 };
80
81 static const size_t AES_256_KEYSIZE = 256 / 8;
82 bool AES_256_ECB_encrypt(CephContext* cct,
83 const uint8_t* key,
84 size_t key_size,
85 const uint8_t* data_in,
86 uint8_t* data_out,
87 size_t data_size);
88
89 class RGWGetObj_BlockDecrypt : public RGWGetObj_Filter {
90 CephContext* cct;
91
92 std::unique_ptr<BlockCrypt> crypt; /**< already configured stateless BlockCrypt
93 for operations when enough data is accumulated */
94 off_t enc_begin_skip; /**< amount of data to skip from beginning of received data */
95 off_t ofs; /**< stream offset of data we expect to show up next through \ref handle_data */
96 off_t end; /**< stream offset of last byte that is requested */
97 bufferlist cache; /**< stores extra data that could not (yet) be processed by BlockCrypt */
98 size_t block_size; /**< snapshot of \ref BlockCrypt.get_block_size() */
99
100 int process(bufferlist& cipher, size_t part_ofs, size_t size);
101
102 protected:
103 std::vector<size_t> parts_len; /**< size of parts of multipart object, parsed from manifest */
104 public:
105 RGWGetObj_BlockDecrypt(CephContext* cct,
106 RGWGetObj_Filter* next,
107 std::unique_ptr<BlockCrypt> crypt);
108 virtual ~RGWGetObj_BlockDecrypt();
109
110 virtual int fixup_range(off_t& bl_ofs,
111 off_t& bl_end) override;
112 virtual int handle_data(bufferlist& bl,
113 off_t bl_ofs,
114 off_t bl_len) override;
115 virtual int flush() override;
116
117 int read_manifest(bufferlist& manifest_bl);
118 }; /* RGWGetObj_BlockDecrypt */
119
120
121 class RGWPutObj_BlockEncrypt : public rgw::putobj::Pipe
122 {
123 CephContext* cct;
124 std::unique_ptr<BlockCrypt> crypt; /**< already configured stateless BlockCrypt
125 for operations when enough data is accumulated */
126 bufferlist cache; /**< stores extra data that could not (yet) be processed by BlockCrypt */
127 const size_t block_size; /**< snapshot of \ref BlockCrypt.get_block_size() */
128 public:
129 RGWPutObj_BlockEncrypt(CephContext* cct,
130 rgw::putobj::DataProcessor *next,
131 std::unique_ptr<BlockCrypt> crypt);
132
133 int process(bufferlist&& data, uint64_t logical_offset) override;
134 }; /* RGWPutObj_BlockEncrypt */
135
136
137 int rgw_s3_prepare_encrypt(struct req_state* s,
138 std::map<std::string, ceph::bufferlist>& attrs,
139 std::map<std::string,
140 RGWPostObj_ObjStore::post_form_part,
141 const ltstr_nocase>* parts,
142 std::unique_ptr<BlockCrypt>* block_crypt,
143 std::map<std::string,
144 std::string>& crypt_http_responses);
145
146 int rgw_s3_prepare_decrypt(struct req_state* s,
147 std::map<std::string, ceph::bufferlist>& attrs,
148 std::unique_ptr<BlockCrypt>* block_crypt,
149 std::map<std::string,
150 std::string>& crypt_http_responses);
151
152 #endif