mirror of
https://github.com/apple/foundationdb.git
synced 2025-05-31 18:19:35 +08:00
Move global key into StreamCipher
This commit is contained in:
parent
24c3827317
commit
5be4df6f84
@ -42,7 +42,7 @@ public:
|
||||
state unsigned char* encrypted = new (arena) unsigned char[FLOW_KNOBS->ENCRYPTION_BLOCK_SIZE];
|
||||
int bytes = wait(
|
||||
self->file->read(encrypted, FLOW_KNOBS->ENCRYPTION_BLOCK_SIZE, FLOW_KNOBS->ENCRYPTION_BLOCK_SIZE * block));
|
||||
DecryptionStreamCipher decryptor(AsyncFileEncrypted::getKey(), self->getIV(block));
|
||||
DecryptionStreamCipher decryptor(StreamCipher::getKey(), self->getIV(block));
|
||||
auto decrypted = decryptor.decrypt(encrypted, bytes, arena);
|
||||
return Standalone<StringRef>(decrypted, arena);
|
||||
}
|
||||
@ -98,7 +98,8 @@ public:
|
||||
self->offsetInBlock = 0;
|
||||
ASSERT(self->currentBlock < std::numeric_limits<uint16_t>::max());
|
||||
++self->currentBlock;
|
||||
self->encryptor = std::make_unique<EncryptionStreamCipher>(AsyncFileEncrypted::getKey(), self->getIV(self->currentBlock));
|
||||
self->encryptor =
|
||||
std::make_unique<EncryptionStreamCipher>(StreamCipher::getKey(), self->getIV(self->currentBlock));
|
||||
}
|
||||
}
|
||||
return Void();
|
||||
@ -111,20 +112,6 @@ public:
|
||||
return Void();
|
||||
}
|
||||
|
||||
ACTOR static Future<Void> initializeKey(Reference<IAsyncFile> keyFile, int64_t offset) {
|
||||
ASSERT(!AsyncFileEncrypted::key.present());
|
||||
AsyncFileEncrypted::key = StreamCipher::Key{};
|
||||
state int keySize = AsyncFileEncrypted::key.get().size();
|
||||
if (g_network->isSimulated()) {
|
||||
generateRandomData(AsyncFileEncrypted::key.get().data(), keySize);
|
||||
return Void();
|
||||
} else {
|
||||
int bytesRead = wait(keyFile->read(AsyncFileEncrypted::key.get().data(), keySize, offset));
|
||||
ASSERT(bytesRead == keySize);
|
||||
return Void();
|
||||
}
|
||||
}
|
||||
|
||||
ACTOR static Future<Void> zeroRange(AsyncFileEncrypted* self, int64_t offset, int64_t length) {
|
||||
// TODO: Could optimize this
|
||||
Arena arena;
|
||||
@ -139,7 +126,7 @@ AsyncFileEncrypted::AsyncFileEncrypted(Reference<IAsyncFile> file, bool canWrite
|
||||
: file(file), canWrite(canWrite), currentBlock(0), readBuffers(FLOW_KNOBS->MAX_DECRYPTED_BLOCKS) {
|
||||
firstBlockIV = AsyncFileEncryptedImpl::getFirstBlockIV(file->getFilename());
|
||||
if (canWrite) {
|
||||
encryptor = std::make_unique<EncryptionStreamCipher>(AsyncFileEncrypted::getKey(), getIV(currentBlock));
|
||||
encryptor = std::make_unique<EncryptionStreamCipher>(StreamCipher::getKey(), getIV(currentBlock));
|
||||
writeBuffer = std::vector<unsigned char>(FLOW_KNOBS->ENCRYPTION_BLOCK_SIZE, 0);
|
||||
}
|
||||
}
|
||||
@ -209,16 +196,6 @@ Future<Void> AsyncFileEncrypted::writeLastBlockToFile() {
|
||||
return file->write(&writeBuffer[0], offsetInBlock, currentBlock * FLOW_KNOBS->ENCRYPTION_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
Optional<StreamCipher::Key> AsyncFileEncrypted::key;
|
||||
|
||||
StreamCipher::Key AsyncFileEncrypted::getKey() {
|
||||
return key.get();
|
||||
}
|
||||
|
||||
Future<Void> AsyncFileEncrypted::initializeKey(const Reference<IAsyncFile>& keyFile, int64_t offset) {
|
||||
return AsyncFileEncryptedImpl::initializeKey(keyFile, offset);
|
||||
}
|
||||
|
||||
size_t AsyncFileEncrypted::RandomCache::evict() {
|
||||
ASSERT(vec.size() == maxSize);
|
||||
auto index = deterministicRandom()->randomInt(0, maxSize);
|
||||
@ -257,7 +234,7 @@ TEST_CASE("fdbrpc/AsyncFileEncrypted") {
|
||||
generateRandomData(&writeBuffer.front(), bytes);
|
||||
state std::vector<unsigned char> readBuffer(bytes, 0);
|
||||
ASSERT(g_network->isSimulated());
|
||||
wait(AsyncFileEncrypted::initializeKey(Reference<IAsyncFile>{}));
|
||||
StreamCipher::initializeRandomKey();
|
||||
int flags = IAsyncFile::OPEN_READWRITE | IAsyncFile::OPEN_CREATE | IAsyncFile::OPEN_ATOMIC_WRITE_AND_CREATE |
|
||||
IAsyncFile::OPEN_UNBUFFERED | IAsyncFile::OPEN_ENCRYPTED | IAsyncFile::OPEN_UNCACHED |
|
||||
IAsyncFile::OPEN_NO_AIO;
|
||||
|
@ -39,8 +39,6 @@ class AsyncFileEncrypted : public IAsyncFile, public ReferenceCounted<AsyncFileE
|
||||
bool canWrite;
|
||||
Future<Void> writeLastBlockToFile();
|
||||
friend class AsyncFileEncryptedImpl;
|
||||
static Optional<StreamCipher::Key> key;
|
||||
static StreamCipher::Key getKey();
|
||||
|
||||
// Reading:
|
||||
class RandomCache {
|
||||
@ -76,7 +74,6 @@ public:
|
||||
Future<Void> readZeroCopy(void** data, int* length, int64_t offset) override;
|
||||
void releaseZeroCopy(void* data, int length, int64_t offset) override;
|
||||
int64_t debugFD() const override;
|
||||
static Future<Void> initializeKey(const Reference<IAsyncFile>& keyFile, int64_t offset = 0);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include "flow/StreamCipher.h"
|
||||
#include "flow/UnitTest.h"
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
EncryptionStreamCipher::EncryptionStreamCipher(const StreamCipher::Key& key, const StreamCipher::IV& iv)
|
||||
: ctx(EVP_CIPHER_CTX_new()) {
|
||||
EVP_EncryptInit_ex(ctx, EVP_aes_128_gcm(), nullptr, nullptr, nullptr);
|
||||
@ -74,6 +76,20 @@ StringRef DecryptionStreamCipher::finish(Arena& arena) {
|
||||
return StringRef(plaintext, finalBlockBytes);
|
||||
}
|
||||
|
||||
static std::unordered_set<EVP_CIPHER_CTX*> ciphers;
|
||||
static Optional<StreamCipher::Key> globalKey;
|
||||
|
||||
void StreamCipher::initializeRandomKey() {
|
||||
ASSERT(g_network->isSimulated());
|
||||
ASSERT(!globalKey.present());
|
||||
globalKey = StreamCipher::Key{};
|
||||
generateRandomData(globalKey.get().data(), globalKey.get().size());
|
||||
}
|
||||
|
||||
StreamCipher::Key StreamCipher::getKey() {
|
||||
return globalKey.get();
|
||||
}
|
||||
|
||||
void forceLinkStreamCipherTests() {}
|
||||
|
||||
TEST_CASE("flow/StreamCipher") {
|
||||
|
@ -33,6 +33,10 @@
|
||||
namespace StreamCipher {
|
||||
using Key = std::array<unsigned char, 16>;
|
||||
using IV = std::array<unsigned char, 16>;
|
||||
void initializeRandomKey();
|
||||
Key getKey();
|
||||
void registerCipherForCleanup(EVP_CIPHER_CTX*) noexcept;
|
||||
void deregisterCipherForCleanup(EVP_CIPHER_CTX*) noexcept;
|
||||
}; // namespace StreamCipher
|
||||
|
||||
class EncryptionStreamCipher final : NonCopyable, public ReferenceCounted<EncryptionStreamCipher> {
|
||||
|
Loading…
x
Reference in New Issue
Block a user