51778612c9
Summary: This PR adds support for encrypting data stored by RocksDB when written to disk. It adds an `EncryptedEnv` override of the `Env` class with matching overrides for sequential&random access files. The encryption itself is done through a configurable `EncryptionProvider`. This class creates is asked to create `BlockAccessCipherStream` for a file. This is where the actual encryption/decryption is being done. Currently there is a Counter mode implementation of `BlockAccessCipherStream` with a `ROT13` block cipher (NOTE the `ROT13` is for demo purposes only!!). The Counter operation mode uses an initial counter & random initialization vector (IV). Both are created randomly for each file and stored in a 4K (default size) block that is prefixed to that file. The `EncryptedEnv` implementation is such that clients of the `Env` class do not see this prefix (nor data, nor in filesize). The largest part of the prefix block is also encrypted, and there is room left for implementation specific settings/values/keys in there. To test the encryption, the `DBTestBase` class has been extended to consider a new environment variable called `ENCRYPTED_ENV`. If set, the test will setup a encrypted instance of the `Env` class to use for all tests. Typically you would run it like this: ``` ENCRYPTED_ENV=1 make check_some ``` There is also an added test that checks that some data inserted into the database is or is not "visible" on disk. With `ENCRYPTED_ENV` active it must not find plain text strings, with `ENCRYPTED_ENV` unset, it must find the plain text strings. Closes https://github.com/facebook/rocksdb/pull/2424 Differential Revision: D5322178 Pulled By: sdwilsh fbshipit-source-id: 253b0a9c2c498cc98f580df7f2623cbf7678a27f
97 lines
2.8 KiB
C++
97 lines
2.8 KiB
C++
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
|
|
// This source code is licensed under the BSD-style license found in the
|
|
// LICENSE file in the root directory of this source tree. An additional grant
|
|
// of patent rights can be found in the PATENTS file in the same directory.
|
|
// This source code is also licensed under the GPLv2 license found in the
|
|
// COPYING file in the root directory of this source tree.
|
|
//
|
|
#include "db/db_test_util.h"
|
|
#include "port/stack_trace.h"
|
|
#include "rocksdb/perf_context.h"
|
|
#if !defined(ROCKSDB_LITE)
|
|
#include "util/sync_point.h"
|
|
#endif
|
|
#include <iostream>
|
|
#include <string>
|
|
|
|
namespace rocksdb {
|
|
|
|
class DBEncryptionTest : public DBTestBase {
|
|
public:
|
|
DBEncryptionTest() : DBTestBase("/db_encryption_test") {}
|
|
};
|
|
|
|
#ifndef ROCKSDB_LITE
|
|
|
|
TEST_F(DBEncryptionTest, CheckEncrypted) {
|
|
ASSERT_OK(Put("foo567", "v1.fetdq"));
|
|
ASSERT_OK(Put("bar123", "v2.dfgkjdfghsd"));
|
|
Close();
|
|
|
|
// Open all files and look for the values we've put in there.
|
|
// They should not be found if encrypted, otherwise
|
|
// they should be found.
|
|
std::vector<std::string> fileNames;
|
|
auto status = env_->GetChildren(dbname_, &fileNames);
|
|
ASSERT_OK(status);
|
|
|
|
auto defaultEnv = Env::Default();
|
|
int hits = 0;
|
|
for (auto it = fileNames.begin() ; it != fileNames.end(); ++it) {
|
|
if ((*it == "..") || (*it == ".")) {
|
|
continue;
|
|
}
|
|
auto filePath = dbname_ + "/" + *it;
|
|
unique_ptr<SequentialFile> seqFile;
|
|
auto envOptions = EnvOptions(CurrentOptions());
|
|
status = defaultEnv->NewSequentialFile(filePath, &seqFile, envOptions);
|
|
ASSERT_OK(status);
|
|
|
|
uint64_t fileSize;
|
|
status = defaultEnv->GetFileSize(filePath, &fileSize);
|
|
ASSERT_OK(status);
|
|
|
|
std::string scratch;
|
|
scratch.reserve(fileSize);
|
|
Slice data;
|
|
status = seqFile->Read(fileSize, &data, (char*)scratch.data());
|
|
ASSERT_OK(status);
|
|
|
|
if (data.ToString().find("foo567") != std::string::npos) {
|
|
hits++;
|
|
//std::cout << "Hit in " << filePath << "\n";
|
|
}
|
|
if (data.ToString().find("v1.fetdq") != std::string::npos) {
|
|
hits++;
|
|
//std::cout << "Hit in " << filePath << "\n";
|
|
}
|
|
if (data.ToString().find("bar123") != std::string::npos) {
|
|
hits++;
|
|
//std::cout << "Hit in " << filePath << "\n";
|
|
}
|
|
if (data.ToString().find("v2.dfgkjdfghsd") != std::string::npos) {
|
|
hits++;
|
|
//std::cout << "Hit in " << filePath << "\n";
|
|
}
|
|
if (data.ToString().find("dfgk") != std::string::npos) {
|
|
hits++;
|
|
//std::cout << "Hit in " << filePath << "\n";
|
|
}
|
|
}
|
|
if (encrypted_env_) {
|
|
ASSERT_EQ(hits, 0);
|
|
} else {
|
|
ASSERT_GE(hits, 4);
|
|
}
|
|
}
|
|
|
|
#endif // ROCKSDB_LITE
|
|
|
|
} // namespace rocksdb
|
|
|
|
int main(int argc, char** argv) {
|
|
rocksdb::port::InstallStackTraceHandler();
|
|
::testing::InitGoogleTest(&argc, argv);
|
|
return RUN_ALL_TESTS();
|
|
}
|