28 #ifndef CRYPTOPP_STRCIPHR_H
29 #define CRYPTOPP_STRCIPHR_H
35 NAMESPACE_BEGIN(CryptoPP)
37 template <class POLICY_INTERFACE, class BASE =
Empty>
41 typedef POLICY_INTERFACE PolicyInterface;
45 virtual const POLICY_INTERFACE & GetPolicy()
const =0;
46 virtual POLICY_INTERFACE & AccessPolicy() =0;
49 template <
class POLICY,
class BASE,
class POLICY_INTERFACE = CPP_TYPENAME BASE::PolicyInterface>
53 const POLICY_INTERFACE & GetPolicy()
const {
return *
this;}
54 POLICY_INTERFACE & AccessPolicy() {
return *
this;}
57 enum KeystreamOperationFlags {OUTPUT_ALIGNED=1, INPUT_ALIGNED=2, INPUT_NULL = 4};
58 enum KeystreamOperation {
59 WRITE_KEYSTREAM = INPUT_NULL,
60 WRITE_KEYSTREAM_ALIGNED = INPUT_NULL | OUTPUT_ALIGNED,
62 XOR_KEYSTREAM_INPUT_ALIGNED = INPUT_ALIGNED,
63 XOR_KEYSTREAM_OUTPUT_ALIGNED= OUTPUT_ALIGNED,
64 XOR_KEYSTREAM_BOTH_ALIGNED = OUTPUT_ALIGNED | INPUT_ALIGNED};
69 virtual unsigned int GetAlignment()
const {
return 1;}
70 virtual unsigned int GetBytesPerIteration()
const =0;
71 virtual unsigned int GetOptimalBlockSize()
const {
return GetBytesPerIteration();}
72 virtual unsigned int GetIterationsToBuffer()
const =0;
73 virtual void WriteKeystream(byte *keystream,
size_t iterationCount)
74 {OperateKeystream(KeystreamOperation(INPUT_NULL | (KeystreamOperationFlags)IsAlignedOn(keystream, GetAlignment())), keystream, NULL, iterationCount);}
75 virtual bool CanOperateKeystream()
const {
return false;}
76 virtual void OperateKeystream(KeystreamOperation operation, byte *output,
const byte *input,
size_t iterationCount) {assert(
false);}
77 virtual void CipherSetKey(
const NameValuePairs ¶ms,
const byte *key,
size_t length) =0;
78 virtual void CipherResynchronize(byte *keystreamBuffer,
const byte *iv,
size_t length) {
throw NotImplemented(
"SimpleKeyingInterface: this object doesn't support resynchronization");}
79 virtual bool CipherIsRandomAccess()
const =0;
80 virtual void SeekToIteration(lword iterationCount) {assert(!CipherIsRandomAccess());
throw NotImplemented(
"StreamTransformation: this object doesn't support random access");}
83 template <
typename WT,
unsigned int W,
unsigned int X = 1,
class BASE = AdditiveCipherAbstractPolicy>
87 CRYPTOPP_CONSTANT(BYTES_PER_ITERATION =
sizeof(WordType) * W)
89 #if !(CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X64)
90 unsigned int GetAlignment()
const {
return GetAlignmentOf<WordType>();}
92 unsigned int GetBytesPerIteration()
const {
return BYTES_PER_ITERATION;}
93 unsigned int GetIterationsToBuffer()
const {
return X;}
94 bool CanOperateKeystream()
const {
return true;}
95 virtual void OperateKeystream(KeystreamOperation operation, byte *output,
const byte *input,
size_t iterationCount) =0;
99 #define CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, b, i, a) \
100 PutWord(bool(x & OUTPUT_ALIGNED), b, output+i*sizeof(WordType), (x & INPUT_NULL) ? a : a ^ GetWord<WordType>(bool(x & INPUT_ALIGNED), b, input+i*sizeof(WordType)));
101 #define CRYPTOPP_KEYSTREAM_OUTPUT_XMM(x, i, a) {\
102 __m128i t = (x & INPUT_NULL) ? a : _mm_xor_si128(a, (x & INPUT_ALIGNED) ? _mm_load_si128((__m128i *)input+i) : _mm_loadu_si128((__m128i *)input+i));\
103 if (x & OUTPUT_ALIGNED) _mm_store_si128((__m128i *)output+i, t);\
104 else _mm_storeu_si128((__m128i *)output+i, t);}
105 #define CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(x, y) \
108 case WRITE_KEYSTREAM: \
111 case XOR_KEYSTREAM: \
115 case XOR_KEYSTREAM_INPUT_ALIGNED: \
116 x(XOR_KEYSTREAM_INPUT_ALIGNED) \
119 case XOR_KEYSTREAM_OUTPUT_ALIGNED: \
120 x(XOR_KEYSTREAM_OUTPUT_ALIGNED) \
123 case WRITE_KEYSTREAM_ALIGNED: \
124 x(WRITE_KEYSTREAM_ALIGNED) \
126 case XOR_KEYSTREAM_BOTH_ALIGNED: \
127 x(XOR_KEYSTREAM_BOTH_ALIGNED) \
133 template <
class BASE = AbstractPolicyHolder<AdditiveCipherAbstractPolicy, SymmetricCipher> >
138 void ProcessData(byte *outString,
const byte *inString,
size_t length);
139 void Resynchronize(
const byte *iv,
int length=-1);
140 unsigned int OptimalBlockSize()
const {
return this->GetPolicy().GetOptimalBlockSize();}
141 unsigned int GetOptimalNextBlockSize()
const {
return (
unsigned int)this->m_leftOver;}
142 unsigned int OptimalDataAlignment()
const {
return this->GetPolicy().GetAlignment();}
143 bool IsSelfInverting()
const {
return true;}
144 bool IsForwardTransformation()
const {
return true;}
145 bool IsRandomAccess()
const {
return this->GetPolicy().CipherIsRandomAccess();}
146 void Seek(lword position);
148 typedef typename BASE::PolicyInterface PolicyInterface;
151 void UncheckedSetKey(
const byte *key,
unsigned int length,
const NameValuePairs ¶ms);
153 unsigned int GetBufferByteSize(
const PolicyInterface &policy)
const {
return policy.GetBytesPerIteration() * policy.GetIterationsToBuffer();}
155 inline byte * KeystreamBufferBegin() {
return this->m_buffer.data();}
156 inline byte * KeystreamBufferEnd() {
return (this->m_buffer.data() + this->m_buffer.size());}
166 virtual unsigned int GetAlignment()
const =0;
167 virtual unsigned int GetBytesPerIteration()
const =0;
168 virtual byte * GetRegisterBegin() =0;
169 virtual void TransformRegister() =0;
170 virtual bool CanIterate()
const {
return false;}
171 virtual void Iterate(byte *output,
const byte *input,
CipherDir dir,
size_t iterationCount) {assert(
false);
throw 0;}
172 virtual void CipherSetKey(
const NameValuePairs ¶ms,
const byte *key,
size_t length) =0;
173 virtual void CipherResynchronize(
const byte *iv,
size_t length) {
throw NotImplemented(
"SimpleKeyingInterface: this object doesn't support resynchronization");}
176 template <
typename WT,
unsigned int W,
class BASE = CFB_CipherAbstractPolicy>
181 unsigned int GetAlignment()
const {
return sizeof(WordType);}
182 unsigned int GetBytesPerIteration()
const {
return sizeof(WordType) * W;}
183 bool CanIterate()
const {
return true;}
184 void TransformRegister() {this->Iterate(NULL, NULL, ENCRYPTION, 1);}
190 : m_output(output), m_input(input), m_dir(dir) {}
194 assert(IsAligned<WordType>(m_output));
195 assert(IsAligned<WordType>(m_input));
197 if (!NativeByteOrderIs(B::ToEnum()))
198 registerWord = ByteReverse(registerWord);
200 if (m_dir == ENCRYPTION)
203 assert(m_output == NULL);
206 WordType ct = *(
const WordType *)m_input ^ registerWord;
208 *(WordType*)m_output = ct;
209 m_input +=
sizeof(WordType);
210 m_output +=
sizeof(WordType);
215 WordType ct = *(
const WordType *)m_input;
216 *(WordType*)m_output = registerWord ^ ct;
218 m_input +=
sizeof(WordType);
219 m_output +=
sizeof(WordType);
233 template <
class BASE>
237 void ProcessData(byte *outString,
const byte *inString,
size_t length);
238 void Resynchronize(
const byte *iv,
int length=-1);
239 unsigned int OptimalBlockSize()
const {
return this->GetPolicy().GetBytesPerIteration();}
240 unsigned int GetOptimalNextBlockSize()
const {
return (
unsigned int)m_leftOver;}
241 unsigned int OptimalDataAlignment()
const {
return this->GetPolicy().GetAlignment();}
242 bool IsRandomAccess()
const {
return false;}
243 bool IsSelfInverting()
const {
return false;}
245 typedef typename BASE::PolicyInterface PolicyInterface;
248 virtual void CombineMessageAndShiftRegister(byte *output, byte *reg,
const byte *message,
size_t length) =0;
250 void UncheckedSetKey(
const byte *key,
unsigned int length,
const NameValuePairs ¶ms);
255 template <
class BASE = AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >
258 bool IsForwardTransformation()
const {
return true;}
259 void CombineMessageAndShiftRegister(byte *output, byte *reg,
const byte *message,
size_t length);
262 template <
class BASE = AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >
265 bool IsForwardTransformation()
const {
return false;}
266 void CombineMessageAndShiftRegister(byte *output, byte *reg,
const byte *message,
size_t length);
269 template <
class BASE>
273 unsigned int MandatoryBlockSize()
const {
return this->OptimalBlockSize();}
277 template <
class BASE,
class INFO = BASE>
283 {this->SetKey(key, this->DEFAULT_KEYLENGTH);}
285 {this->SetKey(key, length);}
287 {this->SetKeyWithIV(key, length, iv);}
294 #ifdef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES
295 #include "strciphr.cpp"
298 NAMESPACE_BEGIN(CryptoPP)
CipherDir
used to specify a direction for a cipher to operate in (encrypt or decrypt)
interface for random number generators
interface for cloning objects, this is not implemented by most classes yet
exception thrown by a class if a non-implemented method is called
interface for one direction (encryption or decryption) of a stream cipher or cipher mode ...
virtual void GenerateBlock(byte *output, size_t size)
generate random array of bytes
interface for retrieving values given their names