1 #ifndef CRYPTOPP_MODES_H
2 #define CRYPTOPP_MODES_H
14 NAMESPACE_BEGIN(CryptoPP)
42 unsigned int IVSize()
const {
return BlockSize();}
47 this->ThrowIfResynchronizable();
48 this->m_cipher = &cipher;
49 this->ResizeBuffers();
52 void SetCipherWithIV(
BlockCipher &cipher,
const byte *iv,
int feedbackSize = 0)
54 this->ThrowIfInvalidIV(iv);
55 this->m_cipher = &cipher;
56 this->ResizeBuffers();
57 this->SetFeedbackSize(feedbackSize);
64 inline unsigned int BlockSize()
const {assert(m_register.size() > 0);
return (
unsigned int)m_register.size();}
65 virtual void SetFeedbackSize(
unsigned int feedbackSize)
67 if (!(feedbackSize == 0 || feedbackSize ==
BlockSize()))
68 throw InvalidArgument(
"CipherModeBase: feedback size cannot be specified for this cipher mode");
70 virtual void ResizeBuffers()
72 m_register.New(m_cipher->BlockSize());
79 template <
class POLICY_INTERFACE>
83 void CipherSetKey(
const NameValuePairs ¶ms,
const byte *key,
size_t length);
86 template <
class POLICY_INTERFACE>
89 m_cipher->
SetKey(key, length, params);
92 SetFeedbackSize(feedbackSize);
99 static const char * CRYPTOPP_API StaticAlgorithmName() {
return "CFB";}
102 unsigned int GetBytesPerIteration()
const {
return m_feedbackSize;}
103 byte * GetRegisterBegin() {
return m_register +
BlockSize() - m_feedbackSize;}
104 bool CanIterate()
const {
return m_feedbackSize ==
BlockSize();}
105 void Iterate(byte *output,
const byte *input,
CipherDir dir,
size_t iterationCount);
106 void TransformRegister();
107 void CipherResynchronize(
const byte *iv,
size_t length);
108 void SetFeedbackSize(
unsigned int feedbackSize);
109 void ResizeBuffers();
112 unsigned int m_feedbackSize;
115 inline void CopyOrZero(
void *dest,
const void *src,
size_t s)
118 memcpy_s(dest, s, src, s);
126 bool CipherIsRandomAccess()
const {
return false;}
128 static const char * CRYPTOPP_API StaticAlgorithmName() {
return "OFB";}
131 unsigned int GetBytesPerIteration()
const {
return BlockSize();}
132 unsigned int GetIterationsToBuffer()
const {
return m_cipher->OptimalNumberOfParallelBlocks();}
133 void WriteKeystream(byte *keystreamBuffer,
size_t iterationCount);
134 void CipherResynchronize(byte *keystreamBuffer,
const byte *iv,
size_t length);
140 bool CipherIsRandomAccess()
const {
return true;}
142 static const char * CRYPTOPP_API StaticAlgorithmName() {
return "CTR";}
145 virtual void IncrementCounterBy256();
147 unsigned int GetAlignment()
const {
return m_cipher->OptimalDataAlignment();}
148 unsigned int GetBytesPerIteration()
const {
return BlockSize();}
149 unsigned int GetIterationsToBuffer()
const {
return m_cipher->OptimalNumberOfParallelBlocks();}
150 void WriteKeystream(byte *buffer,
size_t iterationCount)
151 {OperateKeystream(WRITE_KEYSTREAM, buffer, NULL, iterationCount);}
152 bool CanOperateKeystream()
const {
return true;}
153 void OperateKeystream(KeystreamOperation operation, byte *output,
const byte *input,
size_t iterationCount);
154 void CipherResynchronize(byte *keystreamBuffer,
const byte *iv,
size_t length);
155 void SeekToIteration(lword iterationCount);
163 void UncheckedSetKey(
const byte *key,
unsigned int length,
const NameValuePairs ¶ms);
168 void Resynchronize(
const byte *iv,
int length=-1) {memcpy_s(m_register, m_register.size(), iv, ThrowIfInvalidIVLength(length));}
171 bool RequireAlignedInput()
const {
return true;}
174 CipherModeBase::ResizeBuffers();
185 {m_cipher->SetKey(key, length, params); BlockOrientedCipherModeBase::ResizeBuffers();}
187 unsigned int OptimalBlockSize()
const {
return BlockSize() * m_cipher->OptimalNumberOfParallelBlocks();}
188 void ProcessData(byte *outString,
const byte *inString,
size_t length);
189 static const char * CRYPTOPP_API StaticAlgorithmName() {
return "ECB";}
196 bool RequireAlignedInput()
const {
return false;}
198 static const char * CRYPTOPP_API StaticAlgorithmName() {
return "CBC";}
204 void ProcessData(byte *outString,
const byte *inString,
size_t length);
210 void SetStolenIV(byte *iv) {m_stolenIV = iv;}
212 void ProcessLastBlock(byte *outString,
const byte *inString,
size_t length);
213 static const char * CRYPTOPP_API StaticAlgorithmName() {
return "CBC/CTS";}
216 void UncheckedSetKey(
const byte *key,
unsigned int length,
const NameValuePairs ¶ms)
218 CBC_Encryption::UncheckedSetKey(key, length, params);
228 void ProcessData(byte *outString,
const byte *inString,
size_t length);
233 BlockOrientedCipherModeBase::ResizeBuffers();
234 m_temp.New(BlockSize());
243 void ProcessLastBlock(byte *outString,
const byte *inString,
size_t length);
247 template <
class CIPHER,
class BASE>
253 this->m_cipher = &this->m_object;
254 this->ResizeBuffers();
258 this->m_cipher = &this->m_object;
259 this->SetKey(key, length);
263 this->m_cipher = &this->m_object;
268 this->m_cipher = &this->m_object;
272 static std::string CRYPTOPP_API StaticAlgorithmName()
273 {
return CIPHER::StaticAlgorithmName() +
"/" + BASE::StaticAlgorithmName();}
277 template <
class BASE>
283 {this->SetCipher(cipher);}
285 {this->SetCipherWithIV(cipher, iv, feedbackSize);}
287 std::string AlgorithmName()
const
288 {
return (this->m_cipher ? this->m_cipher->AlgorithmName() +
"/" : std::string(
"")) + BASE::StaticAlgorithmName();}
296 template <
class CIPHER>
311 template <
class CIPHER>
328 template <
class CIPHER>
346 template <
class CIPHER>
356 typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, CTR_ModePolicy> > > >
Encryption;
361 template <
class CIPHER>
373 typedef CipherModeFinalTemplate_ExternalCipher<ECB_OneWay>
Encryption;
378 template <
class CIPHER>
391 typedef CipherModeFinalTemplate_ExternalCipher<CBC_Encryption>
Encryption;
392 typedef CipherModeFinalTemplate_ExternalCipher<CBC_Decryption>
Decryption;
396 template <
class CIPHER>
409 typedef CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Encryption>
Encryption;
410 typedef CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Decryption>
Decryption;
413 #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY