diff options
author | René Meusel <[email protected]> | 2017-04-12 21:25:12 +0200 |
---|---|---|
committer | René Meusel <[email protected]> | 2017-04-13 09:41:31 +0200 |
commit | ed14a2f83d27125026d1fec20938dec28f1404ab (patch) | |
tree | 9072b3dfe69f2e150999d15c650c4b5d2d5226e5 /src | |
parent | b8b50eaf392a5da53d59f28919af0dcfd16b6f4d (diff) |
Add implementation of CTR_BE::seek()
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/stream/ctr/ctr.cpp | 32 | ||||
-rw-r--r-- | src/lib/stream/ctr/ctr.h | 1 |
2 files changed, 31 insertions, 2 deletions
diff --git a/src/lib/stream/ctr/ctr.cpp b/src/lib/stream/ctr/ctr.cpp index 728da3567..4bcf46c06 100644 --- a/src/lib/stream/ctr/ctr.cpp +++ b/src/lib/stream/ctr/ctr.cpp @@ -13,6 +13,7 @@ CTR_BE::CTR_BE(BlockCipher* ciph) : m_cipher(ciph), m_counter(m_cipher->parallel_bytes()), m_pad(m_counter.size()), + m_iv(m_cipher->block_size()), m_ctr_size(m_cipher->block_size()), m_pad_pos(0) { @@ -22,6 +23,7 @@ CTR_BE::CTR_BE(BlockCipher* cipher, size_t ctr_size) : m_cipher(cipher), m_counter(m_cipher->parallel_bytes()), m_pad(m_counter.size()), + m_iv(m_cipher->block_size()), m_ctr_size(ctr_size), m_pad_pos(0) { @@ -35,6 +37,7 @@ void CTR_BE::clear() m_cipher->clear(); zeroise(m_pad); zeroise(m_counter); + zeroise(m_iv); m_pad_pos = 0; } @@ -73,6 +76,8 @@ void CTR_BE::set_iv(const uint8_t iv[], size_t iv_len) const size_t bs = m_cipher->block_size(); zeroise(m_counter); + zeroise(m_iv); + buffer_insert(m_iv, 0, iv, iv_len); const size_t n_wide = m_counter.size() / m_cipher->block_size(); buffer_insert(m_counter, 0, iv, iv_len); @@ -115,8 +120,31 @@ void CTR_BE::increment_counter() m_pad_pos = 0; } -void CTR_BE::seek(uint64_t) +void CTR_BE::seek(uint64_t offset) { - throw Not_Implemented("CTR_BE::seek"); + const size_t bs = m_cipher->block_size(); + const size_t n_wide = m_counter.size() / bs; + const uint64_t base_counter = n_wide * (offset / m_counter.size()); + + zeroise(m_counter); + + for (size_t i = 0; i != n_wide; ++i) + { + buffer_insert(m_counter, bs * i, m_iv); + + uint64_t counter = base_counter + i; + uint16_t carry = static_cast<uint8_t>(counter); + for (size_t j = 0; (carry || counter) && j != m_ctr_size; ++j) + { + const size_t off = i*bs + (bs-1-j); + const uint16_t cnt = static_cast<uint16_t>(m_counter[off]) + carry; + m_counter[off] = static_cast<uint8_t>(cnt); + counter = (counter >> 8); + carry = (cnt >> 8) + static_cast<uint8_t>(counter); + } + } + + m_cipher->encrypt_n(m_counter.data(), m_pad.data(), n_wide); + m_pad_pos = offset % m_counter.size(); } } diff --git a/src/lib/stream/ctr/ctr.h b/src/lib/stream/ctr/ctr.h index 345c4f6e8..39deb0eec 100644 --- a/src/lib/stream/ctr/ctr.h +++ b/src/lib/stream/ctr/ctr.h @@ -52,6 +52,7 @@ class BOTAN_DLL CTR_BE final : public StreamCipher std::unique_ptr<BlockCipher> m_cipher; secure_vector<uint8_t> m_counter, m_pad; + std::vector<uint8_t> m_iv; size_t m_ctr_size; size_t m_pad_pos; }; |