Crypto++  5.6.5
Free C++ class library of cryptographic schemes
strciphr.cpp
1 // strciphr.cpp - written and placed in the public domain by Wei Dai
2 
3 #include "pch.h"
4 
5 #ifndef CRYPTOPP_IMPORTS
6 
7 #include "strciphr.h"
8 
9 NAMESPACE_BEGIN(CryptoPP)
10 
11 template <class S>
12 void AdditiveCipherTemplate<S>::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params)
13 {
14  PolicyInterface &policy = this->AccessPolicy();
15  policy.CipherSetKey(params, key, length);
16  m_leftOver = 0;
17  unsigned int bufferByteSize = policy.CanOperateKeystream() ? GetBufferByteSize(policy) : RoundUpToMultipleOf(1024U, GetBufferByteSize(policy));
18  m_buffer.New(bufferByteSize);
19 
20  if (this->IsResynchronizable())
21  {
22  size_t ivLength;
23  const byte *iv = this->GetIVAndThrowIfInvalid(params, ivLength);
24  policy.CipherResynchronize(m_buffer, iv, ivLength);
25  }
26 }
27 
28 template <class S>
29 void AdditiveCipherTemplate<S>::GenerateBlock(byte *outString, size_t length)
30 {
31  if (m_leftOver > 0)
32  {
33  size_t len = STDMIN(m_leftOver, length);
34  memcpy(outString, KeystreamBufferEnd()-m_leftOver, len);
35  length -= len;
36  m_leftOver -= len;
37  outString += len;
38 
39  if (!length)
40  return;
41  }
42  CRYPTOPP_ASSERT(m_leftOver == 0);
43 
44  PolicyInterface &policy = this->AccessPolicy();
45  unsigned int bytesPerIteration = policy.GetBytesPerIteration();
46 
47  if (length >= bytesPerIteration)
48  {
49  size_t iterations = length / bytesPerIteration;
50  policy.WriteKeystream(outString, iterations);
51  outString += iterations * bytesPerIteration;
52  length -= iterations * bytesPerIteration;
53  }
54 
55  if (length > 0)
56  {
57  size_t bufferByteSize = RoundUpToMultipleOf(length, bytesPerIteration);
58  size_t bufferIterations = bufferByteSize / bytesPerIteration;
59 
60  policy.WriteKeystream(KeystreamBufferEnd()-bufferByteSize, bufferIterations);
61  memcpy(outString, KeystreamBufferEnd()-bufferByteSize, length);
62  m_leftOver = bufferByteSize - length;
63  }
64 }
65 
66 template <class S>
67 void AdditiveCipherTemplate<S>::ProcessData(byte *outString, const byte *inString, size_t length)
68 {
69  if (m_leftOver > 0)
70  {
71  size_t len = STDMIN(m_leftOver, length);
72  xorbuf(outString, inString, KeystreamBufferEnd()-m_leftOver, len);
73  length -= len;
74  m_leftOver -= len;
75  inString += len;
76  outString += len;
77 
78  if (!length)
79  return;
80  }
81  CRYPTOPP_ASSERT(m_leftOver == 0);
82 
83  PolicyInterface &policy = this->AccessPolicy();
84  unsigned int bytesPerIteration = policy.GetBytesPerIteration();
85 
86  if (policy.CanOperateKeystream() && length >= bytesPerIteration)
87  {
88  size_t iterations = length / bytesPerIteration;
89  unsigned int alignment = policy.GetAlignment();
90  KeystreamOperation operation = KeystreamOperation((IsAlignedOn(inString, alignment) * 2) | (int)IsAlignedOn(outString, alignment));
91 
92  policy.OperateKeystream(operation, outString, inString, iterations);
93 
94  inString += iterations * bytesPerIteration;
95  outString += iterations * bytesPerIteration;
96  length -= iterations * bytesPerIteration;
97 
98  if (!length)
99  return;
100  }
101 
102  size_t bufferByteSize = m_buffer.size();
103  size_t bufferIterations = bufferByteSize / bytesPerIteration;
104 
105  while (length >= bufferByteSize)
106  {
107  policy.WriteKeystream(m_buffer, bufferIterations);
108  xorbuf(outString, inString, KeystreamBufferBegin(), bufferByteSize);
109  length -= bufferByteSize;
110  inString += bufferByteSize;
111  outString += bufferByteSize;
112  }
113 
114  if (length > 0)
115  {
116  bufferByteSize = RoundUpToMultipleOf(length, bytesPerIteration);
117  bufferIterations = bufferByteSize / bytesPerIteration;
118 
119  policy.WriteKeystream(KeystreamBufferEnd()-bufferByteSize, bufferIterations);
120  xorbuf(outString, inString, KeystreamBufferEnd()-bufferByteSize, length);
121  m_leftOver = bufferByteSize - length;
122  }
123 }
124 
125 template <class S>
126 void AdditiveCipherTemplate<S>::Resynchronize(const byte *iv, int length)
127 {
128  PolicyInterface &policy = this->AccessPolicy();
129  m_leftOver = 0;
130  m_buffer.New(GetBufferByteSize(policy));
131  policy.CipherResynchronize(m_buffer, iv, this->ThrowIfInvalidIVLength(length));
132 }
133 
134 template <class BASE>
136 {
137  PolicyInterface &policy = this->AccessPolicy();
138  unsigned int bytesPerIteration = policy.GetBytesPerIteration();
139 
140  policy.SeekToIteration(position / bytesPerIteration);
141  position %= bytesPerIteration;
142 
143  if (position > 0)
144  {
145  policy.WriteKeystream(KeystreamBufferEnd()-bytesPerIteration, 1);
146  m_leftOver = bytesPerIteration - (unsigned int)position;
147  }
148  else
149  m_leftOver = 0;
150 }
151 
152 template <class BASE>
153 void CFB_CipherTemplate<BASE>::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params)
154 {
155  PolicyInterface &policy = this->AccessPolicy();
156  policy.CipherSetKey(params, key, length);
157 
158  if (this->IsResynchronizable())
159  {
160  size_t ivLength;
161  const byte *iv = this->GetIVAndThrowIfInvalid(params, ivLength);
162  policy.CipherResynchronize(iv, ivLength);
163  }
164 
165  m_leftOver = policy.GetBytesPerIteration();
166 }
167 
168 template <class BASE>
169 void CFB_CipherTemplate<BASE>::Resynchronize(const byte *iv, int length)
170 {
171  PolicyInterface &policy = this->AccessPolicy();
172  policy.CipherResynchronize(iv, this->ThrowIfInvalidIVLength(length));
173  m_leftOver = policy.GetBytesPerIteration();
174 }
175 
176 template <class BASE>
177 void CFB_CipherTemplate<BASE>::ProcessData(byte *outString, const byte *inString, size_t length)
178 {
179  CRYPTOPP_ASSERT(length % this->MandatoryBlockSize() == 0);
180 
181  PolicyInterface &policy = this->AccessPolicy();
182  unsigned int bytesPerIteration = policy.GetBytesPerIteration();
183  unsigned int alignment = policy.GetAlignment();
184  byte *reg = policy.GetRegisterBegin();
185 
186  if (m_leftOver)
187  {
188  size_t len = STDMIN(m_leftOver, length);
189  CombineMessageAndShiftRegister(outString, reg + bytesPerIteration - m_leftOver, inString, len);
190  m_leftOver -= len;
191  length -= len;
192  inString += len;
193  outString += len;
194  }
195 
196  if (!length)
197  return;
198 
199  CRYPTOPP_ASSERT(m_leftOver == 0);
200 
201  if (policy.CanIterate() && length >= bytesPerIteration && IsAlignedOn(outString, alignment))
202  {
203  if (IsAlignedOn(inString, alignment))
204  policy.Iterate(outString, inString, GetCipherDir(*this), length / bytesPerIteration);
205  else
206  {
207  memcpy(outString, inString, length);
208  policy.Iterate(outString, outString, GetCipherDir(*this), length / bytesPerIteration);
209  }
210  inString += length - length % bytesPerIteration;
211  outString += length - length % bytesPerIteration;
212  length %= bytesPerIteration;
213  }
214 
215  while (length >= bytesPerIteration)
216  {
217  policy.TransformRegister();
218  CombineMessageAndShiftRegister(outString, reg, inString, bytesPerIteration);
219  length -= bytesPerIteration;
220  inString += bytesPerIteration;
221  outString += bytesPerIteration;
222  }
223 
224  if (length > 0)
225  {
226  policy.TransformRegister();
227  CombineMessageAndShiftRegister(outString, reg, inString, length);
228  m_leftOver = bytesPerIteration - length;
229  }
230 }
231 
232 template <class BASE>
233 void CFB_EncryptionTemplate<BASE>::CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length)
234 {
235  xorbuf(reg, message, length);
236  memcpy(output, reg, length);
237 }
238 
239 template <class BASE>
240 void CFB_DecryptionTemplate<BASE>::CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length)
241 {
242  for (unsigned int i=0; i<length; i++)
243  {
244  byte b = message[i];
245  output[i] = reg[i] ^ b;
246  reg[i] = b;
247  }
248 }
249 
250 NAMESPACE_END
251 
252 #endif
void Resynchronize(const byte *iv, int length=-1)
Resynchronize the cipher.
Definition: strciphr.cpp:126
Base class for feedback based stream ciphers with SymmetricCipher interface.
Definition: strciphr.h:489
void Seek(lword position)
Seeks to a random position in the stream.
Definition: strciphr.cpp:135
bool IsAlignedOn(const void *ptr, unsigned int alignment)
Determines whether ptr is aligned to a minimum value.
Definition: misc.h:949
void ProcessData(byte *outString, const byte *inString, size_t length)
Apply keystream to data.
Definition: strciphr.cpp:67
Base class for feedback based stream ciphers in the reverse direction with SymmetricCipher interface...
Definition: strciphr.h:562
void ProcessData(byte *outString, const byte *inString, size_t length)
Apply keystream to data.
Definition: strciphr.cpp:177
CipherDir GetCipherDir(const T &obj)
Returns the direction the cipher is being operated.
Definition: misc.h:1005
Base class for feedback based stream ciphers in the forward direction with SymmetricCipher interface...
Definition: strciphr.h:552
void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
Definition: strciphr.cpp:29
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition: misc.h:470
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:62
Classes for implementing stream ciphers.
void xorbuf(byte *buf, const byte *mask, size_t count)
Performs an XOR of a buffer with a mask.
Definition: misc.cpp:28
T1 RoundUpToMultipleOf(const T1 &n, const T2 &m)
Rounds a value up to a multiple of a second value.
Definition: misc.h:899
KeystreamOperation
Keystream operation flags.
Definition: strciphr.h:92
Crypto++ library namespace.
void Resynchronize(const byte *iv, int length=-1)
Resynchronize the cipher.
Definition: strciphr.cpp:169
Base class for additive stream ciphers with SymmetricCipher interface.
Definition: strciphr.h:269
Interface for retrieving values given their names.
Definition: cryptlib.h:278