Botan  1.11.30
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 
12 CTR_BE* CTR_BE::make(const Spec& spec)
13  {
14  if(spec.algo_name() == "CTR-BE" && spec.arg_count() == 1)
15  {
16  if(auto c = BlockCipher::create(spec.arg(0)))
17  return new CTR_BE(c.release());
18  }
19  return nullptr;
20  }
21 
23  m_cipher(ciph),
24  m_counter(m_cipher->parallel_bytes()),
25  m_pad(m_counter.size()),
26  m_ctr_size(m_cipher->block_size()),
27  m_pad_pos(0)
28  {
29  }
30 
31 CTR_BE::CTR_BE(BlockCipher* cipher, size_t ctr_size) :
32  m_cipher(cipher),
33  m_counter(m_cipher->parallel_bytes()),
34  m_pad(m_counter.size()),
35  m_ctr_size(ctr_size),
36  m_pad_pos(0)
37  {
38  //BOTAN_CHECK_ARG(m_ctr_size > 0 && m_ctr_size <= cipher->block_size(), "Invalid CTR size");
39  if(m_ctr_size == 0 || m_ctr_size > m_cipher->block_size())
40  throw Invalid_Argument("Invalid CTR-BE counter size");
41  }
42 
44  {
45  m_cipher->clear();
46  zeroise(m_pad);
47  zeroise(m_counter);
48  m_pad_pos = 0;
49  }
50 
51 void CTR_BE::key_schedule(const byte key[], size_t key_len)
52  {
53  m_cipher->set_key(key, key_len);
54 
55  // Set a default all-zeros IV
56  set_iv(nullptr, 0);
57  }
58 
59 std::string CTR_BE::name() const
60  {
61  return ("CTR-BE(" + m_cipher->name() + ")");
62  }
63 
64 void CTR_BE::cipher(const byte in[], byte out[], size_t length)
65  {
66  while(length >= m_pad.size() - m_pad_pos)
67  {
68  xor_buf(out, in, &m_pad[m_pad_pos], m_pad.size() - m_pad_pos);
69  length -= (m_pad.size() - m_pad_pos);
70  in += (m_pad.size() - m_pad_pos);
71  out += (m_pad.size() - m_pad_pos);
72  increment_counter();
73  }
74  xor_buf(out, in, &m_pad[m_pad_pos], length);
75  m_pad_pos += length;
76  }
77 
78 void CTR_BE::set_iv(const byte iv[], size_t iv_len)
79  {
80  if(!valid_iv_length(iv_len))
81  throw Invalid_IV_Length(name(), iv_len);
82 
83  const size_t bs = m_cipher->block_size();
84 
85  zeroise(m_counter);
86 
87  const size_t n_wide = m_counter.size() / m_cipher->block_size();
88  buffer_insert(m_counter, 0, iv, iv_len);
89 
90  // Set m_counter blocks to IV, IV + 1, ... IV + n
91  for(size_t i = 1; i != n_wide; ++i)
92  {
93  buffer_insert(m_counter, i*bs, &m_counter[(i-1)*bs], bs);
94 
95  for(size_t j = 0; j != m_ctr_size; ++j)
96  if(++m_counter[i*bs + (bs - 1 - j)])
97  break;
98  }
99 
100  m_cipher->encrypt_n(m_counter.data(), m_pad.data(), n_wide);
101  m_pad_pos = 0;
102  }
103 
104 /*
105 * Increment the counter and update the buffer
106 */
107 void CTR_BE::increment_counter()
108  {
109  const size_t bs = m_cipher->block_size();
110  const size_t n_wide = m_counter.size() / bs;
111 
112  for(size_t i = 0; i != n_wide; ++i)
113  {
114  uint16_t carry = static_cast<uint16_t>(n_wide);
115  for(size_t j = 0; carry && j != m_ctr_size; ++j)
116  {
117  const size_t off = i*bs + (bs-1-j);
118  const uint16_t cnt = static_cast<uint16_t>(m_counter[off]) + carry;
119  m_counter[off] = static_cast<byte>(cnt);
120  carry = (cnt >> 8);
121  }
122  }
123 
124  m_cipher->encrypt_n(m_counter.data(), m_pad.data(), n_wide);
125  m_pad_pos = 0;
126  }
127 
129  {
130  throw Not_Implemented("CTR_BE::seek");
131  }
132 }
void xor_buf(T out[], const T in[], size_t length)
Definition: mem_ops.h:90
std::string arg(size_t i) const
Definition: scan_name.cpp:153
void set_iv(const byte iv[], size_t iv_len) override
Definition: ctr.cpp:78
void seek(u64bit offset) override
Definition: ctr.cpp:128
std::string name() const override
Definition: ctr.cpp:59
size_t arg_count() const
Definition: scan_name.h:64
void cipher(const byte in[], byte out[], size_t length) override
Definition: ctr.cpp:64
std::uint64_t u64bit
Definition: types.h:34
void clear() override
Definition: ctr.cpp:43
Definition: alg_id.cpp:13
static std::unique_ptr< BlockCipher > create(const std::string &algo_spec, const std::string &provider="")
CTR_BE(BlockCipher *cipher)
Definition: ctr.cpp:22
static CTR_BE * make(const Spec &spec)
Definition: ctr.cpp:12
const std::string & algo_name() const
Definition: scan_name.h:49
size_t buffer_insert(std::vector< T, Alloc > &buf, size_t buf_offset, const T input[], size_t input_length)
Definition: secmem.h:108
bool valid_iv_length(size_t iv_len) const override
Definition: ctr.h:26
void zeroise(std::vector< T, Alloc > &vec)
Definition: secmem.h:186
std::uint8_t byte
Definition: types.h:31