/Users/deen/code/yugabyte-db/src/yb/encryption/encrypted_file_factory.cc
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) YugaByte, Inc. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
4 | | // in compliance with the License. You may obtain a copy of the License at |
5 | | // |
6 | | // http://www.apache.org/licenses/LICENSE-2.0 |
7 | | // |
8 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
9 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
10 | | // or implied. See the License for the specific language governing permissions and limitations |
11 | | // under the License. |
12 | | // |
13 | | |
14 | | #include "yb/encryption/encrypted_file_factory.h" |
15 | | |
16 | | #include "yb/encryption/cipher_stream.h" |
17 | | #include "yb/encryption/encrypted_file.h" |
18 | | #include "yb/encryption/encryption_util.h" |
19 | | #include "yb/encryption/header_manager.h" |
20 | | |
21 | | namespace yb { |
22 | | namespace encryption { |
23 | | |
24 | | // An encrypted file implementation for a writable file. |
25 | | class EncryptedWritableFile : public WritableFileWrapper { |
26 | | public: |
27 | | |
28 | | static Status Create(std::unique_ptr<WritableFile>* result, |
29 | | HeaderManager* header_manager, |
30 | 1.19M | std::unique_ptr<WritableFile> underlying) { |
31 | 1.19M | return CreateWritableFile<EncryptedWritableFile>( |
32 | 1.19M | result, header_manager, std::move(underlying)); |
33 | 1.19M | } |
34 | | |
35 | | // Default constructor. |
36 | | EncryptedWritableFile(std::unique_ptr<WritableFile> file, |
37 | | std::unique_ptr<encryption::BlockAccessCipherStream> stream, |
38 | | uint32_t header_size) |
39 | | : WritableFileWrapper(std::move(file)), stream_(std::move(stream)), header_size_(header_size) |
40 | 1 | {} |
41 | | |
42 | 1 | ~EncryptedWritableFile() {} |
43 | | |
44 | 11 | Status Append(const Slice& data) override { |
45 | 11 | if (data.empty()) { |
46 | 0 | return Status::OK(); |
47 | 0 | } |
48 | | |
49 | 11 | uint8_t* buf = static_cast<uint8_t*>(EncryptionBuffer::Get()->GetBuffer(data.size())); |
50 | 11 | RETURN_NOT_OK(stream_->Encrypt(Size() - header_size_, data, buf)); |
51 | 11 | return WritableFileWrapper::Append(Slice(buf, data.size())); |
52 | 11 | } |
53 | | |
54 | 0 | Status AppendSlices(const Slice* slices, size_t num) override { |
55 | 0 | auto end = slices + num; |
56 | 0 | size_t total_size = 0; |
57 | 0 | for (auto it = slices; it != end; ++it) { |
58 | 0 | total_size += it->size(); |
59 | 0 | } |
60 | 0 | if (total_size == 0) { |
61 | 0 | return Status::OK(); |
62 | 0 | } |
63 | | |
64 | 0 | uint8_t* buf = static_cast<uint8_t*>(EncryptionBuffer::Get()->GetBuffer(total_size)); |
65 | 0 | auto write_pos = buf; |
66 | 0 | auto offset = Size() - header_size_; |
67 | 0 | for (auto it = slices; it != end; ++it) { |
68 | 0 | RETURN_NOT_OK(stream_->Encrypt(offset, *it, write_pos)); |
69 | 0 | write_pos += it->size(); |
70 | 0 | offset += it->size(); |
71 | 0 | } |
72 | | |
73 | 0 | return WritableFileWrapper::Append(Slice(buf, total_size)); |
74 | 0 | } |
75 | | |
76 | | private: |
77 | | std::unique_ptr<BlockAccessCipherStream> stream_; |
78 | | uint32_t header_size_; |
79 | | }; |
80 | | |
81 | | // EncryptedFileFactory creates encrypted files. |
82 | | class EncryptedFileFactory : public FileFactoryWrapper { |
83 | | public: |
84 | | explicit EncryptedFileFactory(FileFactory* file_factory, |
85 | | std::unique_ptr<HeaderManager> header_manager) : |
86 | | FileFactoryWrapper(file_factory), |
87 | 9.27k | header_manager_(std::move(header_manager)) { |
88 | 9.27k | LOG(INFO) << "Created encrypted file factory"; |
89 | 9.27k | } |
90 | | |
91 | 155 | ~EncryptedFileFactory() {} |
92 | | |
93 | | // NewRandomAccessFile opens a file for random read access. |
94 | | Status NewRandomAccessFile(const std::string& fname, |
95 | 536k | std::unique_ptr<yb::RandomAccessFile>* result) override { |
96 | 536k | std::unique_ptr<yb::RandomAccessFile> underlying; |
97 | 536k | RETURN_NOT_OK(FileFactoryWrapper::NewRandomAccessFile(fname, &underlying)); |
98 | 526k | return EncryptedRandomAccessFile::Create(result, header_manager_.get(), std::move(underlying)); |
99 | 536k | } |
100 | | |
101 | | Status NewTempWritableFile(const WritableFileOptions& opts, |
102 | | const std::string& name_template, |
103 | | std::string* created_filename, |
104 | 1.19M | std::unique_ptr<WritableFile>* result) override { |
105 | 1.19M | std::unique_ptr<WritableFile> underlying; |
106 | 1.19M | RETURN_NOT_OK(FileFactoryWrapper::NewTempWritableFile( |
107 | 1.19M | opts, name_template, created_filename, &underlying)); |
108 | 1.19M | return EncryptedWritableFile::Create(result, header_manager_.get(), std::move(underlying)); |
109 | 1.19M | } |
110 | | |
111 | 0 | bool IsEncrypted() const override { |
112 | 0 | return true; |
113 | 0 | } |
114 | | |
115 | | private: |
116 | | std::unique_ptr<HeaderManager> header_manager_; |
117 | | }; |
118 | | |
119 | 9.27k | std::unique_ptr<yb::Env> NewEncryptedEnv(std::unique_ptr<HeaderManager> header_manager) { |
120 | 9.27k | auto file_factory = Env::DefaultFileFactory(); |
121 | 9.27k | auto encrypted_file_factory = std::make_unique<EncryptedFileFactory>(file_factory, |
122 | 9.27k | std::move(header_manager)); |
123 | 9.27k | auto encrypted_env = Env::NewDefaultEnv(std::move(encrypted_file_factory)); |
124 | 9.27k | return encrypted_env; |
125 | 9.27k | } |
126 | | |
127 | | } // namespace encryption |
128 | | } // namespace yb |