Crypto++ 8.9 Free C++ class library of cryptographic schemes

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