aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/stream/ctr/ctr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/stream/ctr/ctr.cpp')
-rw-r--r--src/lib/stream/ctr/ctr.cpp32
1 files changed, 30 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();
}
}