aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRenĂ© Meusel <[email protected]>2017-04-12 21:25:12 +0200
committerRenĂ© Meusel <[email protected]>2017-04-13 09:41:31 +0200
commited14a2f83d27125026d1fec20938dec28f1404ab (patch)
tree9072b3dfe69f2e150999d15c650c4b5d2d5226e5
parentb8b50eaf392a5da53d59f28919af0dcfd16b6f4d (diff)
Add implementation of CTR_BE::seek()
-rw-r--r--src/lib/stream/ctr/ctr.cpp32
-rw-r--r--src/lib/stream/ctr/ctr.h1
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;
};