Botan  1.11.34
Crypto and TLS for C++11
ctr.cpp
Go to the documentation of this file.
1 /*
2 * Counter mode
3 * (C) 1999-2011,2014 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #include <botan/ctr.h>
9 
10 namespace Botan {
11 
13  m_cipher(ciph),
14  m_counter(m_cipher->parallel_bytes()),
15  m_pad(m_counter.size()),
16  m_ctr_size(m_cipher->block_size()),
17  m_pad_pos(0)
18  {
19  }
20 
21 CTR_BE::CTR_BE(BlockCipher* cipher, size_t ctr_size) :
22  m_cipher(cipher),
23  m_counter(m_cipher->parallel_bytes()),
24  m_pad(m_counter.size()),
25  m_ctr_size(ctr_size),
26  m_pad_pos(0)
27  {
28  //BOTAN_CHECK_ARG(m_ctr_size > 0 && m_ctr_size <= cipher->block_size(), "Invalid CTR size");
29  if(m_ctr_size == 0 || m_ctr_size > m_cipher->block_size())
30  throw Invalid_Argument("Invalid CTR-BE counter size");
31  }
32 
34  {
35  m_cipher->clear();
36  zeroise(m_pad);
37  zeroise(m_counter);
38  m_pad_pos = 0;
39  }
40 
41 void CTR_BE::key_schedule(const byte key[], size_t key_len)
42  {
43  m_cipher->set_key(key, key_len);
44 
45  // Set a default all-zeros IV
46  set_iv(nullptr, 0);
47  }
48 
49 std::string CTR_BE::name() const
50  {
51  return ("CTR-BE(" + m_cipher->name() + ")");
52  }
53 
54 void CTR_BE::cipher(const byte in[], byte out[], size_t length)
55  {
56  while(length >= m_pad.size() - m_pad_pos)
57  {
58  xor_buf(out, in, &m_pad[m_pad_pos], m_pad.size() - m_pad_pos);
59  length -= (m_pad.size() - m_pad_pos);
60  in += (m_pad.size() - m_pad_pos);
61  out += (m_pad.size() - m_pad_pos);
62  increment_counter();
63  }
64  xor_buf(out, in, &m_pad[m_pad_pos], length);
65  m_pad_pos += length;
66  }
67 
68 void CTR_BE::set_iv(const byte iv[], size_t iv_len)
69  {
70  if(!valid_iv_length(iv_len))
71  throw Invalid_IV_Length(name(), iv_len);
72 
73  const size_t bs = m_cipher->block_size();
74 
75  zeroise(m_counter);
76 
77  const size_t n_wide = m_counter.size() / m_cipher->block_size();
78  buffer_insert(m_counter, 0, iv, iv_len);
79 
80  // Set m_counter blocks to IV, IV + 1, ... IV + n
81  for(size_t i = 1; i != n_wide; ++i)
82  {
83  buffer_insert(m_counter, i*bs, &m_counter[(i-1)*bs], bs);
84 
85  for(size_t j = 0; j != m_ctr_size; ++j)
86  if(++m_counter[i*bs + (bs - 1 - j)])
87  break;
88  }
89 
90  m_cipher->encrypt_n(m_counter.data(), m_pad.data(), n_wide);
91  m_pad_pos = 0;
92  }
93 
94 /*
95 * Increment the counter and update the buffer
96 */
97 void CTR_BE::increment_counter()
98  {
99  const size_t bs = m_cipher->block_size();
100  const size_t n_wide = m_counter.size() / bs;
101 
102  for(size_t i = 0; i != n_wide; ++i)
103  {
104  uint16_t carry = static_cast<uint16_t>(n_wide);
105  for(size_t j = 0; carry && j != m_ctr_size; ++j)
106  {
107  const size_t off = i*bs + (bs-1-j);
108  const uint16_t cnt = static_cast<uint16_t>(m_counter[off]) + carry;
109  m_counter[off] = static_cast<byte>(cnt);
110  carry = (cnt >> 8);
111  }
112  }
113 
114  m_cipher->encrypt_n(m_counter.data(), m_pad.data(), n_wide);
115  m_pad_pos = 0;
116  }
117 
119  {
120  throw Not_Implemented("CTR_BE::seek");
121  }
122 }
void xor_buf(T out[], const T in[], size_t length)
Definition: mem_ops.h:115
void set_iv(const byte iv[], size_t iv_len) override
Definition: ctr.cpp:68
void seek(u64bit offset) override
Definition: ctr.cpp:118
std::string name() const override
Definition: ctr.cpp:49
void cipher(const byte in[], byte out[], size_t length) override
Definition: ctr.cpp:54
std::uint64_t u64bit
Definition: types.h:34
void clear() override
Definition: ctr.cpp:33
Definition: alg_id.cpp:13
CTR_BE(BlockCipher *cipher)
Definition: ctr.cpp:12
size_t buffer_insert(std::vector< T, Alloc > &buf, size_t buf_offset, const T input[], size_t input_length)
Definition: secmem.h:125
bool valid_iv_length(size_t iv_len) const override
Definition: ctr.h:26
void zeroise(std::vector< T, Alloc > &vec)
Definition: secmem.h:203
std::uint8_t byte
Definition: types.h:31