// -*- mode:C; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- // vim: ts=8 sw=2 smarttab /** * Crypto filters for Put/Post/Get operations. */ #ifndef CEPH_RGW_CRYPT_H #define CEPH_RGW_CRYPT_H #include #include #include #include /** * \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 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 parts_len; /**< size of parts of multipart object, parsed from manifest */ public: RGWGetObj_BlockDecrypt(CephContext* cct, RGWGetDataCB* next, std::unique_ptr crypt); 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; int read_manifest(bufferlist& manifest_bl); }; /* RGWGetObj_BlockDecrypt */ class RGWPutObj_BlockEncrypt : public RGWPutObj_Filter { CephContext* cct; std::unique_ptr crypt; /**< already configured stateless BlockCrypt for operations when enough data is accumulated */ off_t ofs; /**< stream offset of data we expect to show up next through \ref handle_data */ bufferlist cache; /**< stores extra data that could not (yet) be processed by BlockCrypt */ size_t block_size; /**< snapshot of \ref BlockCrypt.get_block_size() */ public: RGWPutObj_BlockEncrypt(CephContext* cct, RGWPutObjDataProcessor* next, std::unique_ptr crypt); virtual ~RGWPutObj_BlockEncrypt(); virtual int handle_data(bufferlist& bl, off_t ofs, void **phandle, rgw_raw_obj *pobj, bool *again) override; virtual int throttle_data(void *handle, const rgw_raw_obj& obj, uint64_t size, bool need_to_wait) override; }; /* RGWPutObj_BlockEncrypt */ int rgw_s3_prepare_encrypt(struct req_state* s, std::map& attrs, std::map* parts, std::unique_ptr* block_crypt, std::map& crypt_http_responses); int rgw_s3_prepare_decrypt(struct req_state* s, std::map& attrs, std::unique_ptr* block_crypt, std::map& crypt_http_responses); #endif