]> git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/include/rocksdb/env_encryption.h
import 14.2.4 nautilus point release
[ceph.git] / ceph / src / rocksdb / include / rocksdb / env_encryption.h
1 // Copyright (c) 2016-present, Facebook, Inc. All rights reserved.
2 // This source code is licensed under both the GPLv2 (found in the
3 // COPYING file in the root directory) and Apache 2.0 License
4 // (found in the LICENSE.Apache file in the root directory).
5
6 #pragma once
7
8 #if !defined(ROCKSDB_LITE)
9
10 #include <string>
11
12 #include "env.h"
13
14 namespace rocksdb {
15
16 class EncryptionProvider;
17
18 // Returns an Env that encrypts data when stored on disk and decrypts data when
19 // read from disk.
20 Env* NewEncryptedEnv(Env* base_env, EncryptionProvider* provider);
21
22 // BlockAccessCipherStream is the base class for any cipher stream that
23 // supports random access at block level (without requiring data from other
24 // blocks). E.g. CTR (Counter operation mode) supports this requirement.
25 class BlockAccessCipherStream {
26 public:
27 virtual ~BlockAccessCipherStream(){};
28
29 // BlockSize returns the size of each block supported by this cipher stream.
30 virtual size_t BlockSize() = 0;
31
32 // Encrypt one or more (partial) blocks of data at the file offset.
33 // Length of data is given in dataSize.
34 virtual Status Encrypt(uint64_t fileOffset, char* data, size_t dataSize);
35
36 // Decrypt one or more (partial) blocks of data at the file offset.
37 // Length of data is given in dataSize.
38 virtual Status Decrypt(uint64_t fileOffset, char* data, size_t dataSize);
39
40 protected:
41 // Allocate scratch space which is passed to EncryptBlock/DecryptBlock.
42 virtual void AllocateScratch(std::string&) = 0;
43
44 // Encrypt a block of data at the given block index.
45 // Length of data is equal to BlockSize();
46 virtual Status EncryptBlock(uint64_t blockIndex, char* data,
47 char* scratch) = 0;
48
49 // Decrypt a block of data at the given block index.
50 // Length of data is equal to BlockSize();
51 virtual Status DecryptBlock(uint64_t blockIndex, char* data,
52 char* scratch) = 0;
53 };
54
55 // BlockCipher
56 class BlockCipher {
57 public:
58 virtual ~BlockCipher(){};
59
60 // BlockSize returns the size of each block supported by this cipher stream.
61 virtual size_t BlockSize() = 0;
62
63 // Encrypt a block of data.
64 // Length of data is equal to BlockSize().
65 virtual Status Encrypt(char* data) = 0;
66
67 // Decrypt a block of data.
68 // Length of data is equal to BlockSize().
69 virtual Status Decrypt(char* data) = 0;
70 };
71
72 // Implements a BlockCipher using ROT13.
73 //
74 // Note: This is a sample implementation of BlockCipher,
75 // it is NOT considered safe and should NOT be used in production.
76 class ROT13BlockCipher : public BlockCipher {
77 private:
78 size_t blockSize_;
79
80 public:
81 ROT13BlockCipher(size_t blockSize) : blockSize_(blockSize) {}
82 virtual ~ROT13BlockCipher(){};
83
84 // BlockSize returns the size of each block supported by this cipher stream.
85 virtual size_t BlockSize() override { return blockSize_; }
86
87 // Encrypt a block of data.
88 // Length of data is equal to BlockSize().
89 virtual Status Encrypt(char* data) override;
90
91 // Decrypt a block of data.
92 // Length of data is equal to BlockSize().
93 virtual Status Decrypt(char* data) override;
94 };
95
96 // CTRCipherStream implements BlockAccessCipherStream using an
97 // Counter operations mode.
98 // See https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation
99 //
100 // Note: This is a possible implementation of BlockAccessCipherStream,
101 // it is considered suitable for use.
102 class CTRCipherStream final : public BlockAccessCipherStream {
103 private:
104 BlockCipher& cipher_;
105 std::string iv_;
106 uint64_t initialCounter_;
107
108 public:
109 CTRCipherStream(BlockCipher& c, const char* iv, uint64_t initialCounter)
110 : cipher_(c), iv_(iv, c.BlockSize()), initialCounter_(initialCounter){};
111 virtual ~CTRCipherStream(){};
112
113 // BlockSize returns the size of each block supported by this cipher stream.
114 virtual size_t BlockSize() override { return cipher_.BlockSize(); }
115
116 protected:
117 // Allocate scratch space which is passed to EncryptBlock/DecryptBlock.
118 virtual void AllocateScratch(std::string&) override;
119
120 // Encrypt a block of data at the given block index.
121 // Length of data is equal to BlockSize();
122 virtual Status EncryptBlock(uint64_t blockIndex, char* data,
123 char* scratch) override;
124
125 // Decrypt a block of data at the given block index.
126 // Length of data is equal to BlockSize();
127 virtual Status DecryptBlock(uint64_t blockIndex, char* data,
128 char* scratch) override;
129 };
130
131 // The encryption provider is used to create a cipher stream for a specific
132 // file. The returned cipher stream will be used for actual
133 // encryption/decryption actions.
134 class EncryptionProvider {
135 public:
136 virtual ~EncryptionProvider(){};
137
138 // GetPrefixLength returns the length of the prefix that is added to every
139 // file and used for storing encryption options. For optimal performance, the
140 // prefix length should be a multiple of the page size.
141 virtual size_t GetPrefixLength() = 0;
142
143 // CreateNewPrefix initialized an allocated block of prefix memory
144 // for a new file.
145 virtual Status CreateNewPrefix(const std::string& fname, char* prefix,
146 size_t prefixLength) = 0;
147
148 // CreateCipherStream creates a block access cipher stream for a file given
149 // given name and options.
150 virtual Status CreateCipherStream(
151 const std::string& fname, const EnvOptions& options, Slice& prefix,
152 std::unique_ptr<BlockAccessCipherStream>* result) = 0;
153 };
154
155 // This encryption provider uses a CTR cipher stream, with a given block cipher
156 // and IV.
157 //
158 // Note: This is a possible implementation of EncryptionProvider,
159 // it is considered suitable for use, provided a safe BlockCipher is used.
160 class CTREncryptionProvider : public EncryptionProvider {
161 private:
162 BlockCipher& cipher_;
163
164 protected:
165 const static size_t defaultPrefixLength = 4096;
166
167 public:
168 CTREncryptionProvider(BlockCipher& c) : cipher_(c){};
169 virtual ~CTREncryptionProvider() {}
170
171 // GetPrefixLength returns the length of the prefix that is added to every
172 // file and used for storing encryption options. For optimal performance, the
173 // prefix length should be a multiple of the page size.
174 virtual size_t GetPrefixLength() override;
175
176 // CreateNewPrefix initialized an allocated block of prefix memory
177 // for a new file.
178 virtual Status CreateNewPrefix(const std::string& fname, char* prefix,
179 size_t prefixLength) override;
180
181 // CreateCipherStream creates a block access cipher stream for a file given
182 // given name and options.
183 virtual Status CreateCipherStream(
184 const std::string& fname, const EnvOptions& options, Slice& prefix,
185 std::unique_ptr<BlockAccessCipherStream>* result) override;
186
187 protected:
188 // PopulateSecretPrefixPart initializes the data into a new prefix block
189 // that will be encrypted. This function will store the data in plain text.
190 // It will be encrypted later (before written to disk).
191 // Returns the amount of space (starting from the start of the prefix)
192 // that has been initialized.
193 virtual size_t PopulateSecretPrefixPart(char* prefix, size_t prefixLength,
194 size_t blockSize);
195
196 // CreateCipherStreamFromPrefix creates a block access cipher stream for a
197 // file given given name and options. The given prefix is already decrypted.
198 virtual Status CreateCipherStreamFromPrefix(
199 const std::string& fname, const EnvOptions& options,
200 uint64_t initialCounter, const Slice& iv, const Slice& prefix,
201 std::unique_ptr<BlockAccessCipherStream>* result);
202 };
203
204 } // namespace rocksdb
205
206 #endif // !defined(ROCKSDB_LITE)