Botan  1.11.26
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_pad_pos(0)
27  {
28  }
29 
31  {
32  m_cipher->clear();
33  zeroise(m_pad);
34  zeroise(m_counter);
35  m_pad_pos = 0;
36  }
37 
38 void CTR_BE::key_schedule(const byte key[], size_t key_len)
39  {
40  m_cipher->set_key(key, key_len);
41 
42  // Set a default all-zeros IV
43  set_iv(nullptr, 0);
44  }
45 
46 std::string CTR_BE::name() const
47  {
48  return ("CTR-BE(" + m_cipher->name() + ")");
49  }
50 
51 void CTR_BE::cipher(const byte in[], byte out[], size_t length)
52  {
53  while(length >= m_pad.size() - m_pad_pos)
54  {
55  xor_buf(out, in, &m_pad[m_pad_pos], m_pad.size() - m_pad_pos);
56  length -= (m_pad.size() - m_pad_pos);
57  in += (m_pad.size() - m_pad_pos);
58  out += (m_pad.size() - m_pad_pos);
59  increment_counter();
60  }
61  xor_buf(out, in, &m_pad[m_pad_pos], length);
62  m_pad_pos += length;
63  }
64 
65 void CTR_BE::set_iv(const byte iv[], size_t iv_len)
66  {
67  if(!valid_iv_length(iv_len))
68  throw Invalid_IV_Length(name(), iv_len);
69 
70  const size_t bs = m_cipher->block_size();
71 
72  zeroise(m_counter);
73 
74  const size_t n_wide = m_counter.size() / m_cipher->block_size();
75  buffer_insert(m_counter, 0, iv, iv_len);
76 
77  // Set m_counter blocks to IV, IV + 1, ... IV + n
78  for(size_t i = 1; i != n_wide; ++i)
79  {
80  buffer_insert(m_counter, i*bs, &m_counter[(i-1)*bs], bs);
81 
82  for(size_t j = 0; j != bs; ++j)
83  if(++m_counter[i*bs + (bs - 1 - j)])
84  break;
85  }
86 
87  m_cipher->encrypt_n(m_counter.data(), m_pad.data(), n_wide);
88  m_pad_pos = 0;
89  }
90 
91 /*
92 * Increment the counter and update the buffer
93 */
94 void CTR_BE::increment_counter()
95  {
96  const size_t bs = m_cipher->block_size();
97  const size_t n_wide = m_counter.size() / bs;
98 
99  for(size_t i = 0; i != n_wide; ++i)
100  {
101  uint16_t carry = n_wide;
102  for(size_t j = 0; carry && j != bs; ++j)
103  {
104  const size_t off = i*bs + (bs-1-j);
105  const uint16_t cnt = static_cast<uint16_t>(m_counter[off]) + carry;
106  m_counter[off] = static_cast<byte>(cnt);
107  carry = (cnt >> 8);
108  }
109  }
110 
111  m_cipher->encrypt_n(m_counter.data(), m_pad.data(), n_wide);
112  m_pad_pos = 0;
113  }
114 
115 }
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:155
void set_iv(const byte iv[], size_t iv_len) override
Definition: ctr.cpp:65
std::string name() const override
Definition: ctr.cpp:46
size_t arg_count() const
Definition: scan_name.h:64
void cipher(const byte in[], byte out[], size_t length) override
Definition: ctr.cpp:51
void clear() override
Definition: ctr.cpp:30
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