summaryrefslogtreecommitdiffstats
path: root/src/rgw/rgw_crypt.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:54:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:54:28 +0000
commite6918187568dbd01842d8d1d2c808ce16a894239 (patch)
tree64f88b554b444a49f656b6c656111a145cbbaa28 /src/rgw/rgw_crypt.h
parentInitial commit. (diff)
downloadceph-e6918187568dbd01842d8d1d2c808ce16a894239.tar.xz
ceph-e6918187568dbd01842d8d1d2c808ce16a894239.zip
Adding upstream version 18.2.2.upstream/18.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--src/rgw/rgw_crypt.h174
1 files changed, 174 insertions, 0 deletions
diff --git a/src/rgw/rgw_crypt.h b/src/rgw/rgw_crypt.h
new file mode 100644
index 000000000..d8f561eca
--- /dev/null
+++ b/src/rgw/rgw_crypt.h
@@ -0,0 +1,174 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab ft=cpp
+
+/**
+ * Crypto filters for Put/Post/Get operations.
+ */
+
+#pragma once
+
+#include <string_view>
+
+#include <rgw/rgw_op.h>
+#include <rgw/rgw_rest.h>
+#include <rgw/rgw_rest_s3.h>
+#include "rgw_putobj.h"
+
+/**
+ * \brief Interface for block encryption methods
+ *
+ * Encrypts and decrypts data.
+ * Operations are performed in context of larger stream being divided into blocks.
+ * Each block can be processed independently, but only as a whole.
+ * Part block cannot be properly processed.
+ * Each request must start on block-aligned offset.
+ * Each request should have length that is multiply of block size.
+ * Request with unaligned length is only acceptable for last part of stream.
+ */
+class BlockCrypt {
+public:
+ BlockCrypt(){};
+ virtual ~BlockCrypt(){};
+
+ /**
+ * Determines size of encryption block.
+ * This is usually multiply of key size.
+ * It determines size of chunks that should be passed to \ref encrypt and \ref decrypt.
+ */
+ virtual size_t get_block_size() = 0;
+
+ /**
+ * Encrypts data.
+ * Argument \ref stream_offset shows where in generalized stream chunk is located.
+ * Input for encryption is \ref input buffer, with relevant data in range <in_ofs, in_ofs+size).
+ * \ref input and \output may not be the same buffer.
+ *
+ * \params
+ * input - source buffer of data
+ * in_ofs - offset of chunk inside input
+ * size - size of chunk, must be chunk-aligned unless last part is processed
+ * output - destination buffer to encrypt to
+ * stream_offset - location of <in_ofs,in_ofs+size) chunk in data stream, must be chunk-aligned
+ * \return true iff successfully encrypted
+ */
+ virtual bool encrypt(bufferlist& input,
+ off_t in_ofs,
+ size_t size,
+ bufferlist& output,
+ off_t stream_offset) = 0;
+
+ /**
+ * Decrypts data.
+ * Argument \ref stream_offset shows where in generalized stream chunk is located.
+ * Input for decryption is \ref input buffer, with relevant data in range <in_ofs, in_ofs+size).
+ * \ref input and \output may not be the same buffer.
+ *
+ * \params
+ * input - source buffer of data
+ * in_ofs - offset of chunk inside input
+ * size - size of chunk, must be chunk-aligned unless last part is processed
+ * output - destination buffer to encrypt to
+ * stream_offset - location of <in_ofs,in_ofs+size) chunk in data stream, must be chunk-aligned
+ * \return true iff successfully encrypted
+ */
+ virtual bool decrypt(bufferlist& input,
+ off_t in_ofs,
+ size_t size,
+ bufferlist& output,
+ off_t stream_offset) = 0;
+};
+
+static const size_t AES_256_KEYSIZE = 256 / 8;
+bool AES_256_ECB_encrypt(const DoutPrefixProvider* dpp,
+ CephContext* cct,
+ const uint8_t* key,
+ size_t key_size,
+ const uint8_t* data_in,
+ uint8_t* data_out,
+ size_t data_size);
+
+class RGWGetObj_BlockDecrypt : public RGWGetObj_Filter {
+ const DoutPrefixProvider *dpp;
+ CephContext* cct;
+ std::unique_ptr<BlockCrypt> crypt; /**< already configured stateless BlockCrypt
+ for operations when enough data is accumulated */
+ off_t enc_begin_skip; /**< amount of data to skip from beginning of received data */
+ off_t ofs; /**< stream offset of data we expect to show up next through \ref handle_data */
+ off_t end; /**< stream offset of last byte that is requested */
+ bufferlist cache; /**< stores extra data that could not (yet) be processed by BlockCrypt */
+ size_t block_size; /**< snapshot of \ref BlockCrypt.get_block_size() */
+ std::vector<size_t> parts_len; /**< size of parts of multipart object, parsed from manifest */
+
+ int process(bufferlist& cipher, size_t part_ofs, size_t size);
+
+public:
+ RGWGetObj_BlockDecrypt(const DoutPrefixProvider *dpp,
+ CephContext* cct,
+ RGWGetObj_Filter* next,
+ std::unique_ptr<BlockCrypt> crypt,
+ std::vector<size_t> parts_len);
+ virtual ~RGWGetObj_BlockDecrypt();
+
+ virtual int fixup_range(off_t& bl_ofs,
+ off_t& bl_end) override;
+ virtual int handle_data(bufferlist& bl,
+ off_t bl_ofs,
+ off_t bl_len) override;
+ virtual int flush() override;
+
+ static int read_manifest_parts(const DoutPrefixProvider *dpp,
+ const bufferlist& manifest_bl,
+ std::vector<size_t>& parts_len);
+}; /* RGWGetObj_BlockDecrypt */
+
+
+class RGWPutObj_BlockEncrypt : public rgw::putobj::Pipe
+{
+ const DoutPrefixProvider *dpp;
+ CephContext* cct;
+ std::unique_ptr<BlockCrypt> crypt; /**< already configured stateless BlockCrypt
+ for operations when enough data is accumulated */
+ bufferlist cache; /**< stores extra data that could not (yet) be processed by BlockCrypt */
+ const size_t block_size; /**< snapshot of \ref BlockCrypt.get_block_size() */
+public:
+ RGWPutObj_BlockEncrypt(const DoutPrefixProvider *dpp,
+ CephContext* cct,
+ rgw::sal::DataProcessor *next,
+ std::unique_ptr<BlockCrypt> crypt);
+
+ int process(bufferlist&& data, uint64_t logical_offset) override;
+}; /* RGWPutObj_BlockEncrypt */
+
+
+int rgw_s3_prepare_encrypt(req_state* s,
+ std::map<std::string, ceph::bufferlist>& attrs,
+ std::unique_ptr<BlockCrypt>* block_crypt,
+ std::map<std::string,
+ std::string>& crypt_http_responses);
+
+int rgw_s3_prepare_decrypt(req_state* s,
+ std::map<std::string, ceph::bufferlist>& attrs,
+ std::unique_ptr<BlockCrypt>* block_crypt,
+ std::map<std::string,
+ std::string>& crypt_http_responses);
+
+static inline void set_attr(std::map<std::string, bufferlist>& attrs,
+ const char* key,
+ std::string_view value)
+{
+ bufferlist bl;
+ bl.append(value.data(), value.size());
+ attrs[key] = std::move(bl);
+}
+
+static inline std::string get_str_attribute(std::map<std::string, bufferlist>& attrs,
+ const char *name)
+{
+ auto iter = attrs.find(name);
+ if (iter == attrs.end()) {
+ return {};
+ }
+ return iter->second.to_str();
+}
+
+int rgw_remove_sse_s3_bucket_key(req_state *s);