/src/rocksdb/env/env_encryption_ctr.h
Line | Count | Source (jump to first uncovered line) |
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 | | |
9 | | #include "rocksdb/env_encryption.h" |
10 | | |
11 | | namespace ROCKSDB_NAMESPACE { |
12 | | // CTRCipherStream implements BlockAccessCipherStream using an |
13 | | // Counter operations mode. |
14 | | // See https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation |
15 | | // |
16 | | // Note: This is a possible implementation of BlockAccessCipherStream, |
17 | | // it is considered suitable for use. |
18 | | class CTRCipherStream final : public BlockAccessCipherStream { |
19 | | private: |
20 | | std::shared_ptr<BlockCipher> cipher_; |
21 | | std::string iv_; |
22 | | uint64_t initialCounter_; |
23 | | |
24 | | public: |
25 | | CTRCipherStream(const std::shared_ptr<BlockCipher>& c, const char* iv, |
26 | | uint64_t initialCounter) |
27 | 0 | : cipher_(c), iv_(iv, c->BlockSize()), initialCounter_(initialCounter){} |
28 | 0 | virtual ~CTRCipherStream(){} |
29 | | |
30 | 0 | size_t BlockSize() override { return cipher_->BlockSize(); } |
31 | | |
32 | | protected: |
33 | | void AllocateScratch(std::string&) override; |
34 | | |
35 | | Status EncryptBlock(uint64_t blockIndex, char* data, char* scratch) override; |
36 | | |
37 | | Status DecryptBlock(uint64_t blockIndex, char* data, char* scratch) override; |
38 | | }; |
39 | | |
40 | | // This encryption provider uses a CTR cipher stream, with a given block cipher |
41 | | // and IV. |
42 | | // |
43 | | // Note: This is a possible implementation of EncryptionProvider, |
44 | | // it is considered suitable for use, provided a safe BlockCipher is used. |
45 | | class CTREncryptionProvider : public EncryptionProvider { |
46 | | private: |
47 | | std::shared_ptr<BlockCipher> cipher_; |
48 | | |
49 | | protected: |
50 | | // For optimal performance when using direct IO, the prefix length should be a |
51 | | // multiple of the page size. This size is to ensure the first real data byte |
52 | | // is placed at largest known alignment point for direct io. |
53 | | const static size_t defaultPrefixLength = 4096; |
54 | | |
55 | | public: |
56 | | explicit CTREncryptionProvider( |
57 | | const std::shared_ptr<BlockCipher>& c = nullptr); |
58 | 0 | virtual ~CTREncryptionProvider() {} |
59 | | |
60 | 0 | static const char* kClassName() { return "CTR"; } |
61 | 0 | const char* Name() const override { return kClassName(); } |
62 | | bool IsInstanceOf(const std::string& name) const override; |
63 | | size_t GetPrefixLength() const override; |
64 | | Status CreateNewPrefix(const std::string& fname, char* prefix, |
65 | | size_t prefixLength) const override; |
66 | | Status CreateCipherStream( |
67 | | const std::string& fname, const EnvOptions& options, Slice& prefix, |
68 | | std::unique_ptr<BlockAccessCipherStream>* result) override; |
69 | | |
70 | | Status AddCipher(const std::string& descriptor, const char* /*cipher*/, |
71 | | size_t /*len*/, bool /*for_write*/) override; |
72 | | |
73 | | protected: |
74 | | // PopulateSecretPrefixPart initializes the data into a new prefix block |
75 | | // that will be encrypted. This function will store the data in plain text. |
76 | | // It will be encrypted later (before written to disk). |
77 | | // Returns the amount of space (starting from the start of the prefix) |
78 | | // that has been initialized. |
79 | | virtual size_t PopulateSecretPrefixPart(char* prefix, size_t prefixLength, |
80 | | size_t blockSize) const; |
81 | | |
82 | | // CreateCipherStreamFromPrefix creates a block access cipher stream for a |
83 | | // file given |
84 | | // given name and options. The given prefix is already decrypted. |
85 | | virtual Status CreateCipherStreamFromPrefix( |
86 | | const std::string& fname, const EnvOptions& options, |
87 | | uint64_t initialCounter, const Slice& iv, const Slice& prefix, |
88 | | std::unique_ptr<BlockAccessCipherStream>* result); |
89 | | }; |
90 | | |
91 | | Status NewEncryptedFileSystemImpl( |
92 | | const std::shared_ptr<FileSystem>& base_fs, |
93 | | const std::shared_ptr<EncryptionProvider>& provider, |
94 | | std::unique_ptr<FileSystem>* fs); |
95 | | |
96 | | } // namespace ROCKSDB_NAMESPACE |
97 | | |