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