| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- // This file is part of Desktop App Toolkit,
- // a set of libraries for developing nice desktop applications.
- //
- // For license and copyright information please follow this link:
- // https://github.com/desktop-app/legal/blob/master/LEGAL
- //
- #include "storage/storage_encryption.h"
- #include "base/openssl_help.h"
- namespace Storage {
- CtrState::CtrState(bytes::const_span key, bytes::const_span iv) {
- Expects(key.size() == _key.size());
- Expects(iv.size() == _iv.size());
- bytes::copy(_key, key);
- bytes::copy(_iv, iv);
- }
- template <typename Method>
- void CtrState::process(bytes::span data, int64 offset, Method method) {
- Expects((data.size() % kBlockSize) == 0);
- Expects((offset % kBlockSize) == 0);
- AES_KEY aes;
- AES_set_encrypt_key(
- reinterpret_cast<const uchar*>(_key.data()),
- _key.size() * CHAR_BIT,
- &aes);
- unsigned char ecountBuf[kBlockSize] = { 0 };
- unsigned int offsetInBlock = 0;
- const auto blockIndex = offset / kBlockSize;
- auto iv = incrementedIv(blockIndex);
- CRYPTO_ctr128_encrypt(
- reinterpret_cast<const uchar*>(data.data()),
- reinterpret_cast<uchar*>(data.data()),
- data.size(),
- &aes,
- reinterpret_cast<unsigned char*>(iv.data()),
- ecountBuf,
- &offsetInBlock,
- (block128_f)method);
- }
- auto CtrState::incrementedIv(int64 blockIndex)
- -> bytes::array<kIvSize> {
- Expects(blockIndex >= 0);
- if (!blockIndex) {
- return _iv;
- }
- auto result = _iv;
- auto digits = kIvSize;
- auto increment = uint64(blockIndex);
- do {
- --digits;
- increment += static_cast<uint64>(result[digits]);
- result[digits] = static_cast<bytes::type>(increment & 0xFFULL);
- increment >>= 8;
- } while (digits != 0 && increment != 0);
- return result;
- }
- void CtrState::encrypt(bytes::span data, int64 offset) {
- return process(data, offset, AES_encrypt);
- }
- void CtrState::decrypt(bytes::span data, int64 offset) {
- return process(data, offset, AES_encrypt);
- }
- EncryptionKey::EncryptionKey(bytes::vector &&data)
- : _data(std::move(data)) {
- Expects(_data.size() == kSize || _data.size() == kSize_v2);
- }
- bool EncryptionKey::empty() const {
- return _data.empty();
- }
- EncryptionKey::operator bool() const {
- return !empty();
- }
- const bytes::vector &EncryptionKey::data() const {
- return _data;
- }
- CtrState EncryptionKey::prepareCtrState(bytes::const_span salt) const {
- Expects(salt.size() == kSaltSize);
- Expects(!empty());
- const auto data = bytes::make_span(_data);
- const auto key = openssl::Sha256(
- data.subspan(0, data.size() / 2),
- salt.subspan(0, kSaltSize / 2));
- const auto iv = openssl::Sha256(
- data.subspan(data.size() / 2),
- salt.subspan(kSaltSize / 2));
- return CtrState(
- key,
- bytes::make_span(iv).subspan(0, CtrState::kIvSize));
- }
- } // namespace Storage
|