|
|
@ -33,14 +33,14 @@ std::shared_ptr<EncryptionProvider> EncryptionProvider::NewCTRProvider( |
|
|
|
return std::make_shared<CTREncryptionProvider>(cipher); |
|
|
|
return std::make_shared<CTREncryptionProvider>(cipher); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Read up to "n" bytes from the file. "scratch[0..n-1]" may be
|
|
|
|
// Read up to "n" bytes from the file. "scratch[0..n-1]" may be
|
|
|
|
// written by this routine. Sets "*result" to the data that was
|
|
|
|
// written by this routine. Sets "*result" to the data that was
|
|
|
|
// read (including if fewer than "n" bytes were successfully read).
|
|
|
|
// read (including if fewer than "n" bytes were successfully read).
|
|
|
|
// May set "*result" to point at data in "scratch[0..n-1]", so
|
|
|
|
// May set "*result" to point at data in "scratch[0..n-1]", so
|
|
|
|
// "scratch[0..n-1]" must be live when "*result" is used.
|
|
|
|
// "scratch[0..n-1]" must be live when "*result" is used.
|
|
|
|
// If an error was encountered, returns a non-OK status.
|
|
|
|
// If an error was encountered, returns a non-OK status.
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// REQUIRES: External synchronization
|
|
|
|
// REQUIRES: External synchronization
|
|
|
|
IOStatus EncryptedSequentialFile::Read(size_t n, const IOOptions& options, |
|
|
|
IOStatus EncryptedSequentialFile::Read(size_t n, const IOOptions& options, |
|
|
|
Slice* result, char* scratch, |
|
|
|
Slice* result, char* scratch, |
|
|
|
IODebugContext* dbg) { |
|
|
|
IODebugContext* dbg) { |
|
|
@ -89,16 +89,16 @@ size_t EncryptedSequentialFile::GetRequiredBufferAlignment() const { |
|
|
|
return file_->GetRequiredBufferAlignment(); |
|
|
|
return file_->GetRequiredBufferAlignment(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Remove any kind of caching of data from the offset to offset+length
|
|
|
|
// Remove any kind of caching of data from the offset to offset+length
|
|
|
|
// of this file. If the length is 0, then it refers to the end of file.
|
|
|
|
// of this file. If the length is 0, then it refers to the end of file.
|
|
|
|
// If the system is not caching the file contents, then this is a noop.
|
|
|
|
// If the system is not caching the file contents, then this is a noop.
|
|
|
|
IOStatus EncryptedSequentialFile::InvalidateCache(size_t offset, |
|
|
|
IOStatus EncryptedSequentialFile::InvalidateCache(size_t offset, |
|
|
|
size_t length) { |
|
|
|
size_t length) { |
|
|
|
return file_->InvalidateCache(offset + prefixLength_, length); |
|
|
|
return file_->InvalidateCache(offset + prefixLength_, length); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Positioned Read for direct I/O
|
|
|
|
// Positioned Read for direct I/O
|
|
|
|
// If Direct I/O enabled, offset, n, and scratch should be properly aligned
|
|
|
|
// If Direct I/O enabled, offset, n, and scratch should be properly aligned
|
|
|
|
IOStatus EncryptedSequentialFile::PositionedRead(uint64_t offset, size_t n, |
|
|
|
IOStatus EncryptedSequentialFile::PositionedRead(uint64_t offset, size_t n, |
|
|
|
const IOOptions& options, |
|
|
|
const IOOptions& options, |
|
|
|
Slice* result, char* scratch, |
|
|
|
Slice* result, char* scratch, |
|
|
@ -118,16 +118,16 @@ IOStatus EncryptedSequentialFile::PositionedRead(uint64_t offset, size_t n, |
|
|
|
return io_s; |
|
|
|
return io_s; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Read up to "n" bytes from the file starting at "offset".
|
|
|
|
// Read up to "n" bytes from the file starting at "offset".
|
|
|
|
// "scratch[0..n-1]" may be written by this routine. Sets "*result"
|
|
|
|
// "scratch[0..n-1]" may be written by this routine. Sets "*result"
|
|
|
|
// to the data that was read (including if fewer than "n" bytes were
|
|
|
|
// to the data that was read (including if fewer than "n" bytes were
|
|
|
|
// successfully read). May set "*result" to point at data in
|
|
|
|
// successfully read). May set "*result" to point at data in
|
|
|
|
// "scratch[0..n-1]", so "scratch[0..n-1]" must be live when
|
|
|
|
// "scratch[0..n-1]", so "scratch[0..n-1]" must be live when
|
|
|
|
// "*result" is used. If an error was encountered, returns a non-OK
|
|
|
|
// "*result" is used. If an error was encountered, returns a non-OK
|
|
|
|
// status.
|
|
|
|
// status.
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// Safe for concurrent use by multiple threads.
|
|
|
|
// Safe for concurrent use by multiple threads.
|
|
|
|
// If Direct I/O enabled, offset, n, and scratch should be aligned properly.
|
|
|
|
// If Direct I/O enabled, offset, n, and scratch should be aligned properly.
|
|
|
|
IOStatus EncryptedRandomAccessFile::Read(uint64_t offset, size_t n, |
|
|
|
IOStatus EncryptedRandomAccessFile::Read(uint64_t offset, size_t n, |
|
|
|
const IOOptions& options, |
|
|
|
const IOOptions& options, |
|
|
|
Slice* result, char* scratch, |
|
|
|
Slice* result, char* scratch, |
|
|
@ -146,7 +146,7 @@ IOStatus EncryptedRandomAccessFile::Read(uint64_t offset, size_t n, |
|
|
|
return io_s; |
|
|
|
return io_s; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Readahead the file starting from offset by n bytes for caching.
|
|
|
|
// Readahead the file starting from offset by n bytes for caching.
|
|
|
|
IOStatus EncryptedRandomAccessFile::Prefetch(uint64_t offset, size_t n, |
|
|
|
IOStatus EncryptedRandomAccessFile::Prefetch(uint64_t offset, size_t n, |
|
|
|
const IOOptions& options, |
|
|
|
const IOOptions& options, |
|
|
|
IODebugContext* dbg) { |
|
|
|
IODebugContext* dbg) { |
|
|
@ -154,21 +154,21 @@ IOStatus EncryptedRandomAccessFile::Prefetch(uint64_t offset, size_t n, |
|
|
|
return file_->Prefetch(offset + prefixLength_, n, options, dbg); |
|
|
|
return file_->Prefetch(offset + prefixLength_, n, options, dbg); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Tries to get an unique ID for this file that will be the same each time
|
|
|
|
// Tries to get an unique ID for this file that will be the same each time
|
|
|
|
// the file is opened (and will stay the same while the file is open).
|
|
|
|
// the file is opened (and will stay the same while the file is open).
|
|
|
|
// Furthermore, it tries to make this ID at most "max_size" bytes. If such an
|
|
|
|
// Furthermore, it tries to make this ID at most "max_size" bytes. If such an
|
|
|
|
// ID can be created this function returns the length of the ID and places it
|
|
|
|
// ID can be created this function returns the length of the ID and places it
|
|
|
|
// in "id"; otherwise, this function returns 0, in which case "id"
|
|
|
|
// in "id"; otherwise, this function returns 0, in which case "id"
|
|
|
|
// may not have been modified.
|
|
|
|
// may not have been modified.
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// This function guarantees, for IDs from a given environment, two unique ids
|
|
|
|
// This function guarantees, for IDs from a given environment, two unique ids
|
|
|
|
// cannot be made equal to each other by adding arbitrary bytes to one of
|
|
|
|
// cannot be made equal to each other by adding arbitrary bytes to one of
|
|
|
|
// them. That is, no unique ID is the prefix of another.
|
|
|
|
// them. That is, no unique ID is the prefix of another.
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// This function guarantees that the returned ID will not be interpretable as
|
|
|
|
// This function guarantees that the returned ID will not be interpretable as
|
|
|
|
// a single varint.
|
|
|
|
// a single varint.
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// Note: these IDs are only valid for the duration of the process.
|
|
|
|
// Note: these IDs are only valid for the duration of the process.
|
|
|
|
size_t EncryptedRandomAccessFile::GetUniqueId(char* id, size_t max_size) const { |
|
|
|
size_t EncryptedRandomAccessFile::GetUniqueId(char* id, size_t max_size) const { |
|
|
|
return file_->GetUniqueId(id, max_size); |
|
|
|
return file_->GetUniqueId(id, max_size); |
|
|
|
}; |
|
|
|
}; |
|
|
@ -177,21 +177,21 @@ void EncryptedRandomAccessFile::Hint(AccessPattern pattern) { |
|
|
|
file_->Hint(pattern); |
|
|
|
file_->Hint(pattern); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Indicates the upper layers if the current RandomAccessFile implementation
|
|
|
|
// Indicates the upper layers if the current RandomAccessFile implementation
|
|
|
|
// uses direct IO.
|
|
|
|
// uses direct IO.
|
|
|
|
bool EncryptedRandomAccessFile::use_direct_io() const { |
|
|
|
bool EncryptedRandomAccessFile::use_direct_io() const { |
|
|
|
return file_->use_direct_io(); |
|
|
|
return file_->use_direct_io(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Use the returned alignment value to allocate
|
|
|
|
// Use the returned alignment value to allocate
|
|
|
|
// aligned buffer for Direct I/O
|
|
|
|
// aligned buffer for Direct I/O
|
|
|
|
size_t EncryptedRandomAccessFile::GetRequiredBufferAlignment() const { |
|
|
|
size_t EncryptedRandomAccessFile::GetRequiredBufferAlignment() const { |
|
|
|
return file_->GetRequiredBufferAlignment(); |
|
|
|
return file_->GetRequiredBufferAlignment(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Remove any kind of caching of data from the offset to offset+length
|
|
|
|
// Remove any kind of caching of data from the offset to offset+length
|
|
|
|
// of this file. If the length is 0, then it refers to the end of file.
|
|
|
|
// of this file. If the length is 0, then it refers to the end of file.
|
|
|
|
// If the system is not caching the file contents, then this is a noop.
|
|
|
|
// If the system is not caching the file contents, then this is a noop.
|
|
|
|
IOStatus EncryptedRandomAccessFile::InvalidateCache(size_t offset, |
|
|
|
IOStatus EncryptedRandomAccessFile::InvalidateCache(size_t offset, |
|
|
|
size_t length) { |
|
|
|
size_t length) { |
|
|
|
return file_->InvalidateCache(offset + prefixLength_, length); |
|
|
|
return file_->InvalidateCache(offset + prefixLength_, length); |
|
|
@ -267,8 +267,8 @@ bool EncryptedWritableFile::IsSyncThreadSafe() const { |
|
|
|
return file_->IsSyncThreadSafe(); |
|
|
|
return file_->IsSyncThreadSafe(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Use the returned alignment value to allocate
|
|
|
|
// Use the returned alignment value to allocate
|
|
|
|
// aligned buffer for Direct I/O
|
|
|
|
// aligned buffer for Direct I/O
|
|
|
|
size_t EncryptedWritableFile::GetRequiredBufferAlignment() const { |
|
|
|
size_t EncryptedWritableFile::GetRequiredBufferAlignment() const { |
|
|
|
return file_->GetRequiredBufferAlignment(); |
|
|
|
return file_->GetRequiredBufferAlignment(); |
|
|
|
} |
|
|
|
} |
|
|
@ -363,14 +363,14 @@ bool EncryptedRandomRWFile::use_direct_io() const { |
|
|
|
return file_->use_direct_io(); |
|
|
|
return file_->use_direct_io(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Use the returned alignment value to allocate
|
|
|
|
// Use the returned alignment value to allocate
|
|
|
|
// aligned buffer for Direct I/O
|
|
|
|
// aligned buffer for Direct I/O
|
|
|
|
size_t EncryptedRandomRWFile::GetRequiredBufferAlignment() const { |
|
|
|
size_t EncryptedRandomRWFile::GetRequiredBufferAlignment() const { |
|
|
|
return file_->GetRequiredBufferAlignment(); |
|
|
|
return file_->GetRequiredBufferAlignment(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Write bytes in `data` at offset `offset`, Returns Status::OK() on success.
|
|
|
|
// Write bytes in `data` at offset `offset`, Returns Status::OK() on success.
|
|
|
|
// Pass aligned buffer when use_direct_io() returns true.
|
|
|
|
// Pass aligned buffer when use_direct_io() returns true.
|
|
|
|
IOStatus EncryptedRandomRWFile::Write(uint64_t offset, const Slice& data, |
|
|
|
IOStatus EncryptedRandomRWFile::Write(uint64_t offset, const Slice& data, |
|
|
|
const IOOptions& options, |
|
|
|
const IOOptions& options, |
|
|
|
IODebugContext* dbg) { |
|
|
|
IODebugContext* dbg) { |
|
|
@ -397,9 +397,9 @@ IOStatus EncryptedRandomRWFile::Write(uint64_t offset, const Slice& data, |
|
|
|
return file_->Write(offset, dataToWrite, options, dbg); |
|
|
|
return file_->Write(offset, dataToWrite, options, dbg); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Read up to `n` bytes starting from offset `offset` and store them in
|
|
|
|
// Read up to `n` bytes starting from offset `offset` and store them in
|
|
|
|
// result, provided `scratch` size should be at least `n`.
|
|
|
|
// result, provided `scratch` size should be at least `n`.
|
|
|
|
// Returns Status::OK() on success.
|
|
|
|
// Returns Status::OK() on success.
|
|
|
|
IOStatus EncryptedRandomRWFile::Read(uint64_t offset, size_t n, |
|
|
|
IOStatus EncryptedRandomRWFile::Read(uint64_t offset, size_t n, |
|
|
|
const IOOptions& options, Slice* result, |
|
|
|
const IOOptions& options, Slice* result, |
|
|
|
char* scratch, IODebugContext* dbg) const { |
|
|
|
char* scratch, IODebugContext* dbg) const { |
|
|
@ -953,7 +953,8 @@ Env* NewEncryptedEnv(Env* base_env, |
|
|
|
|
|
|
|
|
|
|
|
// Encrypt one or more (partial) blocks of data at the file offset.
|
|
|
|
// Encrypt one or more (partial) blocks of data at the file offset.
|
|
|
|
// Length of data is given in dataSize.
|
|
|
|
// Length of data is given in dataSize.
|
|
|
|
Status BlockAccessCipherStream::Encrypt(uint64_t fileOffset, char *data, size_t dataSize) { |
|
|
|
Status BlockAccessCipherStream::Encrypt(uint64_t fileOffset, char* data, |
|
|
|
|
|
|
|
size_t dataSize) { |
|
|
|
// Calculate block index
|
|
|
|
// Calculate block index
|
|
|
|
auto blockSize = BlockSize(); |
|
|
|
auto blockSize = BlockSize(); |
|
|
|
uint64_t blockIndex = fileOffset / blockSize; |
|
|
|
uint64_t blockIndex = fileOffset / blockSize; |
|
|
@ -965,7 +966,7 @@ Status BlockAccessCipherStream::Encrypt(uint64_t fileOffset, char *data, size_t |
|
|
|
|
|
|
|
|
|
|
|
// Encrypt individual blocks.
|
|
|
|
// Encrypt individual blocks.
|
|
|
|
while (1) { |
|
|
|
while (1) { |
|
|
|
char *block = data; |
|
|
|
char* block = data; |
|
|
|
size_t n = std::min(dataSize, blockSize - blockOffset); |
|
|
|
size_t n = std::min(dataSize, blockSize - blockOffset); |
|
|
|
if (n != blockSize) { |
|
|
|
if (n != blockSize) { |
|
|
|
// We're not encrypting a full block.
|
|
|
|
// We're not encrypting a full block.
|
|
|
@ -998,7 +999,8 @@ Status BlockAccessCipherStream::Encrypt(uint64_t fileOffset, char *data, size_t |
|
|
|
|
|
|
|
|
|
|
|
// Decrypt one or more (partial) blocks of data at the file offset.
|
|
|
|
// Decrypt one or more (partial) blocks of data at the file offset.
|
|
|
|
// Length of data is given in dataSize.
|
|
|
|
// Length of data is given in dataSize.
|
|
|
|
Status BlockAccessCipherStream::Decrypt(uint64_t fileOffset, char *data, size_t dataSize) { |
|
|
|
Status BlockAccessCipherStream::Decrypt(uint64_t fileOffset, char* data, |
|
|
|
|
|
|
|
size_t dataSize) { |
|
|
|
// Calculate block index
|
|
|
|
// Calculate block index
|
|
|
|
auto blockSize = BlockSize(); |
|
|
|
auto blockSize = BlockSize(); |
|
|
|
uint64_t blockIndex = fileOffset / blockSize; |
|
|
|
uint64_t blockIndex = fileOffset / blockSize; |
|
|
@ -1010,7 +1012,7 @@ Status BlockAccessCipherStream::Decrypt(uint64_t fileOffset, char *data, size_t |
|
|
|
|
|
|
|
|
|
|
|
// Decrypt individual blocks.
|
|
|
|
// Decrypt individual blocks.
|
|
|
|
while (1) { |
|
|
|
while (1) { |
|
|
|
char *block = data; |
|
|
|
char* block = data; |
|
|
|
size_t n = std::min(dataSize, blockSize - blockOffset); |
|
|
|
size_t n = std::min(dataSize, blockSize - blockOffset); |
|
|
|
if (n != blockSize) { |
|
|
|
if (n != blockSize) { |
|
|
|
// We're not decrypting a full block.
|
|
|
|
// We're not decrypting a full block.
|
|
|
|