EncryptedBlock stores an IV
This commit is contained in:
parent
711283a89b
commit
e210b5b601
@ -1,26 +1,72 @@
|
||||
#include "EncryptedBlock.h"
|
||||
#include <cryptopp/cryptopp/modes.h>
|
||||
|
||||
#include "../../utils/BlockStoreUtils.h"
|
||||
|
||||
using CryptoPP::CBC_Mode;
|
||||
using CryptoPP::AES;
|
||||
|
||||
using std::make_unique;
|
||||
|
||||
namespace blockstore {
|
||||
namespace encrypted {
|
||||
|
||||
constexpr unsigned int EncryptedBlock::IV_SIZE;
|
||||
|
||||
std::unique_ptr<EncryptedBlock> EncryptedBlock::CreateNew(std::unique_ptr<Block> baseBlock, const EncryptionKey &encKey) {
|
||||
auto block = make_unique<EncryptedBlock>(std::move(baseBlock), encKey);
|
||||
//We have to explicitly fill the block with zeroes, because otherwise the encrypted version is filled with zeroes and not the plaintext version
|
||||
utils::fillWithZeroes(block.get());
|
||||
return block;
|
||||
}
|
||||
|
||||
EncryptedBlock::EncryptedBlock(std::unique_ptr<Block> baseBlock, const EncryptionKey &encKey)
|
||||
:Block(baseBlock->key()), _baseBlock(std::move(baseBlock)), _encKey(encKey) {
|
||||
:Block(baseBlock->key()),
|
||||
_baseBlock(std::move(baseBlock)),
|
||||
_plaintextData(USEABLE_BLOCK_SIZE(_baseBlock->size())),
|
||||
_encKey(encKey),
|
||||
_dataChanged(false) {
|
||||
_decryptFromBaseBlock();
|
||||
}
|
||||
|
||||
EncryptedBlock::~EncryptedBlock() {
|
||||
flush();
|
||||
}
|
||||
|
||||
const void *EncryptedBlock::data() const {
|
||||
return _baseBlock->data();
|
||||
return _plaintextData.data();
|
||||
}
|
||||
|
||||
void EncryptedBlock::write(const void *source, uint64_t offset, uint64_t size) {
|
||||
return _baseBlock->write(source, offset, size);
|
||||
assert(offset <= _plaintextData.size() && offset + size <= _plaintextData.size()); //Also check offset < _data->size() because of possible overflow in the addition
|
||||
std::memcpy((uint8_t*)_plaintextData.data()+offset, source, size);
|
||||
_dataChanged = true;
|
||||
}
|
||||
|
||||
void EncryptedBlock::flush() {
|
||||
_encryptToBaseBlock();
|
||||
return _baseBlock->flush();
|
||||
}
|
||||
|
||||
size_t EncryptedBlock::size() const {
|
||||
return _baseBlock->size();
|
||||
return _plaintextData.size();
|
||||
}
|
||||
|
||||
void EncryptedBlock::_decryptFromBaseBlock() {
|
||||
const byte *iv = (byte*)_baseBlock->data();
|
||||
const byte *data = (byte*)_baseBlock->data() + IV_SIZE;
|
||||
auto dec = CBC_Mode<AES>::Decryption((byte*)_encKey.data(), EncryptionKey::BINARY_LENGTH, iv);
|
||||
std::memcpy(_plaintextData.data(), (byte*)_baseBlock->data()+IV_SIZE, _plaintextData.size());
|
||||
}
|
||||
|
||||
void EncryptedBlock::_encryptToBaseBlock() {
|
||||
if (_dataChanged) {
|
||||
FixedSizeData<IV_SIZE> iv = FixedSizeData<IV_SIZE>::CreateRandom();
|
||||
auto enc = CBC_Mode<AES>::Decryption(_encKey.data(), EncryptionKey::BINARY_LENGTH, iv.data());
|
||||
_baseBlock->write(iv.data(), 0, IV_SIZE);
|
||||
_baseBlock->write(_plaintextData.data(), IV_SIZE, _plaintextData.size());
|
||||
_dataChanged = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "../../interface/Block.h"
|
||||
#include "EncryptionKey.h"
|
||||
#include "../../utils/Data.h"
|
||||
|
||||
#include "messmer/cpp-utils/macros.h"
|
||||
#include <memory>
|
||||
@ -16,6 +17,9 @@ class EncryptedBlock: public Block {
|
||||
public:
|
||||
//TODO Storing key twice (in parent class and in object pointed to). Once would be enough.
|
||||
EncryptedBlock(std::unique_ptr<Block> baseBlock, const EncryptionKey &encKey);
|
||||
virtual ~EncryptedBlock();
|
||||
|
||||
static std::unique_ptr<EncryptedBlock> CreateNew(std::unique_ptr<Block>, const EncryptionKey &encKey);
|
||||
|
||||
const void *data() const override;
|
||||
void write(const void *source, uint64_t offset, uint64_t size) override;
|
||||
@ -23,9 +27,27 @@ public:
|
||||
|
||||
size_t size() const override;
|
||||
|
||||
static constexpr unsigned int BASE_BLOCK_SIZE(unsigned int useableBlockSize) {
|
||||
return useableBlockSize + IV_SIZE;
|
||||
}
|
||||
|
||||
static constexpr unsigned int USEABLE_BLOCK_SIZE(unsigned int baseBlockSize) {
|
||||
return baseBlockSize - IV_SIZE;
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<Block> _baseBlock;
|
||||
Data _plaintextData;
|
||||
EncryptionKey _encKey;
|
||||
bool _dataChanged;
|
||||
|
||||
static constexpr unsigned int IV_SIZE = CryptoPP::AES::BLOCKSIZE;
|
||||
|
||||
byte *baseBlockIV();
|
||||
byte *baseBlockData();
|
||||
|
||||
void _encryptToBaseBlock();
|
||||
void _decryptFromBaseBlock();
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(EncryptedBlock);
|
||||
};
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "EncryptedBlockStore.h"
|
||||
#include "EncryptedBlock.h"
|
||||
#include <messmer/cpp-utils/pointer.h>
|
||||
#include "../../utils/BlockStoreUtils.h"
|
||||
|
||||
using std::unique_ptr;
|
||||
using std::make_unique;
|
||||
@ -13,7 +14,7 @@ EncryptedBlockStore::EncryptedBlockStore(unique_ptr<BlockStore> baseBlockStore,
|
||||
}
|
||||
|
||||
unique_ptr<Block> EncryptedBlockStore::create(size_t size) {
|
||||
return make_unique<EncryptedBlock>(_baseBlockStore->create(size), _encKey);
|
||||
return EncryptedBlock::CreateNew(_baseBlockStore->create(EncryptedBlock::BASE_BLOCK_SIZE(size)), _encKey);
|
||||
}
|
||||
|
||||
unique_ptr<Block> EncryptedBlockStore::load(const Key &key) {
|
||||
|
@ -7,7 +7,7 @@
|
||||
namespace blockstore {
|
||||
namespace encrypted {
|
||||
|
||||
using EncryptionKey = FixedSizeData<32>;
|
||||
using EncryptionKey = FixedSizeData<CryptoPP::AES::MAX_KEYLENGTH>;
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user