Botan  1.11.4
cfb.cpp
Go to the documentation of this file.
1 /*
2 * CFB Mode
3 * (C) 1999-2007 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
6 */
7 
8 #include <botan/cfb.h>
9 #include <botan/parsing.h>
10 #include <botan/internal/xor_buf.h>
11 #include <algorithm>
12 
13 namespace Botan {
14 
15 /*
16 * CFB Encryption Constructor
17 */
19  {
20  cipher = ciph;
21  feedback = fback_bits ? fback_bits / 8: cipher->block_size();
22 
23  buffer.resize(cipher->block_size());
24  state.resize(cipher->block_size());
25  position = 0;
26 
27  if(feedback == 0 || fback_bits % 8 != 0 || feedback > cipher->block_size())
28  throw Invalid_Argument("CFB_Encryption: Invalid feedback size " +
29  std::to_string(fback_bits));
30  }
31 
32 /*
33 * CFB Encryption Constructor
34 */
36  const SymmetricKey& key,
37  const InitializationVector& iv,
38  size_t fback_bits)
39  {
40  cipher = ciph;
41  feedback = fback_bits ? fback_bits / 8: cipher->block_size();
42 
43  buffer.resize(cipher->block_size());
44  state.resize(cipher->block_size());
45  position = 0;
46 
47  if(feedback == 0 || fback_bits % 8 != 0 || feedback > cipher->block_size())
48  throw Invalid_Argument("CFB_Encryption: Invalid feedback size " +
49  std::to_string(fback_bits));
50 
51  set_key(key);
52  set_iv(iv);
53  }
54 
56  {
57  if(!valid_iv_length(iv.length()))
58  throw Invalid_IV_Length(name(), iv.length());
59 
60  state = iv.bits_of();
61  zeroise(buffer);
62  position = 0;
63 
64  cipher->encrypt(&state[0], &buffer[0]);
65  }
66 
67 /*
68 * Encrypt data in CFB mode
69 */
70 void CFB_Encryption::write(const byte input[], size_t length)
71  {
72  while(length)
73  {
74  size_t xored = std::min(feedback - position, length);
75  xor_buf(&buffer[position], input, xored);
76  send(&buffer[position], xored);
77  input += xored;
78  length -= xored;
79  position += xored;
80 
81  if(position == feedback)
82  {
83  for(size_t j = 0; j != cipher->block_size() - feedback; ++j)
84  state[j] = state[j + feedback];
85 
86  buffer_insert(state, cipher->block_size() - feedback,
87  &buffer[0], feedback);
88 
89  cipher->encrypt(state, buffer);
90  position = 0;
91  }
92  }
93  }
94 
95 /*
96 * CFB Decryption Constructor
97 */
99  {
100  cipher = ciph;
101  feedback = fback_bits ? fback_bits / 8: cipher->block_size();
102 
103  buffer.resize(cipher->block_size());
104  state.resize(cipher->block_size());
105  position = 0;
106 
107  if(feedback == 0 || fback_bits % 8 != 0 || feedback > cipher->block_size())
108  throw Invalid_Argument("CFB_Decryption: Invalid feedback size " +
109  std::to_string(fback_bits));
110  }
111 
112 /*
113 * CFB Decryption Constructor
114 */
116  const SymmetricKey& key,
117  const InitializationVector& iv,
118  size_t fback_bits)
119  {
120  cipher = ciph;
121  feedback = fback_bits ? fback_bits / 8: cipher->block_size();
122 
123  buffer.resize(cipher->block_size());
124  state.resize(cipher->block_size());
125  position = 0;
126 
127  if(feedback == 0 || fback_bits % 8 != 0 || feedback > cipher->block_size())
128  throw Invalid_Argument("CFB_Decryption: Invalid feedback size " +
129  std::to_string(fback_bits));
130 
131  set_key(key);
132  set_iv(iv);
133  }
134 
136  {
137  if(!valid_iv_length(iv.length()))
138  throw Invalid_IV_Length(name(), iv.length());
139 
140  state = iv.bits_of();
141  zeroise(buffer);
142  position = 0;
143 
144  cipher->encrypt(state, buffer);
145  }
146 
147 /*
148 * Decrypt data in CFB mode
149 */
150 void CFB_Decryption::write(const byte input[], size_t length)
151  {
152  while(length)
153  {
154  size_t xored = std::min(feedback - position, length);
155  xor_buf(&buffer[position], input, xored);
156  send(&buffer[position], xored);
157  buffer_insert(buffer, position, input, xored);
158  input += xored;
159  length -= xored;
160  position += xored;
161  if(position == feedback)
162  {
163  for(size_t j = 0; j != cipher->block_size() - feedback; ++j)
164  state[j] = state[j + feedback];
165 
166  buffer_insert(state, cipher->block_size() - feedback,
167  &buffer[0], feedback);
168 
169  cipher->encrypt(state, buffer);
170  position = 0;
171  }
172  }
173  }
174 
175 }