]>
Commit | Line | Data |
---|---|---|
7c673cae | 1 | // -*- mode:C; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
9f95a23c | 2 | // vim: ts=8 sw=2 smarttab ft=cpp |
11fdf7f2 | 3 | |
7c673cae FG |
4 | /** |
5 | * Crypto filters for Put/Post/Get operations. | |
6 | */ | |
11fdf7f2 | 7 | |
7c673cae FG |
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> | |
11fdf7f2 | 14 | #include "rgw_putobj.h" |
31f18b77 | 15 | #include <boost/utility/string_view.hpp> |
7c673cae FG |
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() */ | |
a8e16298 TL |
99 | |
100 | int process(bufferlist& cipher, size_t part_ofs, size_t size); | |
101 | ||
102 | protected: | |
7c673cae FG |
103 | std::vector<size_t> parts_len; /**< size of parts of multipart object, parsed from manifest */ |
104 | public: | |
105 | RGWGetObj_BlockDecrypt(CephContext* cct, | |
11fdf7f2 | 106 | RGWGetObj_Filter* next, |
7c673cae FG |
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 | ||
11fdf7f2 | 121 | class RGWPutObj_BlockEncrypt : public rgw::putobj::Pipe |
7c673cae FG |
122 | { |
123 | CephContext* cct; | |
124 | std::unique_ptr<BlockCrypt> crypt; /**< already configured stateless BlockCrypt | |
125 | for operations when enough data is accumulated */ | |
7c673cae | 126 | bufferlist cache; /**< stores extra data that could not (yet) be processed by BlockCrypt */ |
11fdf7f2 | 127 | const size_t block_size; /**< snapshot of \ref BlockCrypt.get_block_size() */ |
7c673cae FG |
128 | public: |
129 | RGWPutObj_BlockEncrypt(CephContext* cct, | |
11fdf7f2 | 130 | rgw::putobj::DataProcessor *next, |
7c673cae | 131 | std::unique_ptr<BlockCrypt> crypt); |
11fdf7f2 TL |
132 | |
133 | int process(bufferlist&& data, uint64_t logical_offset) override; | |
7c673cae FG |
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 |