Botan  1.11.17
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/internal/stream_utils.h>
9 #include <botan/ctr.h>
10 
11 namespace Botan {
12 
13 BOTAN_REGISTER_NAMED_T(StreamCipher, "CTR-BE", CTR_BE, CTR_BE::make);
14 
15 CTR_BE* CTR_BE::make(const Spec& spec)
16  {
17  if(spec.algo_name() == "CTR-BE" && spec.arg_count() == 1)
18  {
19  if(BlockCipher* c = get_block_cipher(spec.arg(0)))
20  return new CTR_BE(c);
21  }
22  return nullptr;
23  }
24 
26  m_cipher(ciph),
27  m_counter(m_cipher->parallel_bytes()),
28  m_pad(m_counter.size()),
29  m_pad_pos(0)
30  {
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 != bs; ++j)
86  if(++m_counter[i*bs + (bs - 1 - j)])
87  break;
88  }
89 
90  m_cipher->encrypt_n(&m_counter[0], &m_pad[0], 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 = n_wide;
105  for(size_t j = 0; carry && j != bs; ++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[0], &m_pad[0], n_wide);
115  m_pad_pos = 0;
116  }
117 
118 }
void xor_buf(T out[], const T in[], size_t length)
Definition: xor_buf.h:23
std::string arg(size_t i) const
Definition: scan_name.cpp:156
BlockCipher * get_block_cipher(const std::string &algo_spec, const std::string &provider)
Definition: lookup.cpp:27
void cipher(const byte in[], byte out[], size_t length)
Definition: ctr.cpp:54
size_t arg_count() const
Definition: scan_name.h:64
std::string name() const
Definition: ctr.cpp:49
bool valid_iv_length(size_t iv_len) const
Definition: ctr.h:26
const BigInt & c
Definition: rsa.cpp:109
void clear()
Definition: ctr.cpp:33
uint8_t byte
Definition: types.h:31
BOTAN_REGISTER_NAMED_T(BlockCipher,"Cascade", Cascade_Cipher, Cascade_Cipher::make)
CTR_BE(BlockCipher *cipher)
Definition: ctr.cpp:25
static CTR_BE * make(const Spec &spec)
Definition: ctr.cpp:15
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:105
void set_iv(const byte iv[], size_t iv_len)
Definition: ctr.cpp:68
void zeroise(std::vector< T, Alloc > &vec)
Definition: secmem.h:168