00001 #ifndef CRYPTOPP_MODES_H
00002 #define CRYPTOPP_MODES_H
00003
00004
00005
00006
00007 #include "cryptlib.h"
00008 #include "secblock.h"
00009 #include "misc.h"
00010 #include "strciphr.h"
00011 #include "argnames.h"
00012 #include "algparam.h"
00013
00014 NAMESPACE_BEGIN(CryptoPP)
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 struct CipherModeDocumentation : public SymmetricCipherDocumentation
00028 {
00029 };
00030
00031 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CipherModeBase : public SymmetricCipher
00032 {
00033 public:
00034 size_t MinKeyLength() const {return m_cipher->MinKeyLength();}
00035 size_t MaxKeyLength() const {return m_cipher->MaxKeyLength();}
00036 size_t DefaultKeyLength() const {return m_cipher->DefaultKeyLength();}
00037 size_t GetValidKeyLength(size_t n) const {return m_cipher->GetValidKeyLength(n);}
00038 bool IsValidKeyLength(size_t n) const {return m_cipher->IsValidKeyLength(n);}
00039
00040 unsigned int OptimalDataAlignment() const {return BlockSize();}
00041
00042 unsigned int IVSize() const {return BlockSize();}
00043 void GetNextIV(byte *IV);
00044 virtual IV_Requirement IVRequirement() const =0;
00045
00046 protected:
00047 inline unsigned int BlockSize() const {assert(m_register.size() > 0); return (unsigned int)m_register.size();}
00048 virtual void SetFeedbackSize(unsigned int feedbackSize)
00049 {
00050 if (!(feedbackSize == 0 || feedbackSize == BlockSize()))
00051 throw InvalidArgument("CipherModeBase: feedback size cannot be specified for this cipher mode");
00052 }
00053 virtual void ResizeBuffers()
00054 {
00055 m_register.New(m_cipher->BlockSize());
00056 }
00057
00058 BlockCipher *m_cipher;
00059 SecByteBlock m_register;
00060 };
00061
00062 template <class POLICY_INTERFACE>
00063 class CRYPTOPP_NO_VTABLE ModePolicyCommonTemplate : public CipherModeBase, public POLICY_INTERFACE
00064 {
00065 unsigned int GetAlignment() const {return m_cipher->BlockAlignment();}
00066 void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length);
00067 void CipherGetNextIV(byte *IV) {CipherModeBase::GetNextIV(IV);}
00068 };
00069
00070 template <class POLICY_INTERFACE>
00071 void ModePolicyCommonTemplate<POLICY_INTERFACE>::CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length)
00072 {
00073 m_cipher->SetKey(key, length, params);
00074 ResizeBuffers();
00075 int feedbackSize = params.GetIntValueWithDefault(Name::FeedbackSize(), 0);
00076 SetFeedbackSize(feedbackSize);
00077 }
00078
00079 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CFB_ModePolicy : public ModePolicyCommonTemplate<CFB_CipherAbstractPolicy>
00080 {
00081 public:
00082 IV_Requirement IVRequirement() const {return RANDOM_IV;}
00083 static const char * CRYPTOPP_API StaticAlgorithmName() {return "CFB";}
00084
00085 protected:
00086 unsigned int GetBytesPerIteration() const {return m_feedbackSize;}
00087 byte * GetRegisterBegin() {return m_register + BlockSize() - m_feedbackSize;}
00088 void TransformRegister()
00089 {
00090 m_cipher->ProcessBlock(m_register, m_temp);
00091 unsigned int updateSize = BlockSize()-m_feedbackSize;
00092 memmove_s(m_register, m_register.size(), m_register+m_feedbackSize, updateSize);
00093 memcpy_s(m_register+updateSize, m_register.size()-updateSize, m_temp, m_feedbackSize);
00094 }
00095 void CipherResynchronize(const byte *iv)
00096 {
00097 memcpy_s(m_register, m_register.size(), iv, BlockSize());
00098 TransformRegister();
00099 }
00100 void SetFeedbackSize(unsigned int feedbackSize)
00101 {
00102 if (feedbackSize > BlockSize())
00103 throw InvalidArgument("CFB_Mode: invalid feedback size");
00104 m_feedbackSize = feedbackSize ? feedbackSize : BlockSize();
00105 }
00106 void ResizeBuffers()
00107 {
00108 CipherModeBase::ResizeBuffers();
00109 m_temp.New(BlockSize());
00110 }
00111
00112 SecByteBlock m_temp;
00113 unsigned int m_feedbackSize;
00114 };
00115
00116 inline void CopyOrZero(void *dest, const void *src, size_t s)
00117 {
00118 if (src)
00119 memcpy_s(dest, s, src, s);
00120 else
00121 memset(dest, 0, s);
00122 }
00123
00124 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE OFB_ModePolicy : public ModePolicyCommonTemplate<AdditiveCipherAbstractPolicy>
00125 {
00126 public:
00127 bool IsRandomAccess() const {return false;}
00128 IV_Requirement IVRequirement() const {return STRUCTURED_IV;}
00129 static const char * CRYPTOPP_API StaticAlgorithmName() {return "OFB";}
00130
00131 private:
00132 unsigned int GetBytesPerIteration() const {return BlockSize();}
00133 unsigned int GetIterationsToBuffer() const {return 1;}
00134 void WriteKeystream(byte *keystreamBuffer, size_t iterationCount)
00135 {
00136 assert(iterationCount == 1);
00137 m_cipher->ProcessBlock(keystreamBuffer);
00138 memcpy_s(m_register, m_register.size(), keystreamBuffer, BlockSize());
00139 }
00140 void CipherResynchronize(byte *keystreamBuffer, const byte *iv)
00141 {
00142 CopyOrZero(keystreamBuffer, iv, BlockSize());
00143 }
00144 };
00145
00146 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CTR_ModePolicy : public ModePolicyCommonTemplate<AdditiveCipherAbstractPolicy>
00147 {
00148 public:
00149 bool IsRandomAccess() const {return true;}
00150 IV_Requirement IVRequirement() const {return STRUCTURED_IV;}
00151 void CipherGetNextIV(byte *IV);
00152 static const char * CRYPTOPP_API StaticAlgorithmName() {return "CTR";}
00153
00154 private:
00155 unsigned int GetBytesPerIteration() const {return BlockSize();}
00156 unsigned int GetIterationsToBuffer() const {return m_cipher->OptimalNumberOfParallelBlocks();}
00157 void WriteKeystream(byte *buffer, size_t iterationCount)
00158 {OperateKeystream(WRITE_KEYSTREAM, buffer, NULL, iterationCount);}
00159 bool CanOperateKeystream() const {return true;}
00160 void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount);
00161 void CipherResynchronize(byte *keystreamBuffer, const byte *iv);
00162 void SeekToIteration(lword iterationCount);
00163
00164 inline void ProcessMultipleBlocks(byte *output, const byte *input, size_t n);
00165
00166 SecByteBlock m_counterArray;
00167 };
00168
00169 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE BlockOrientedCipherModeBase : public CipherModeBase
00170 {
00171 public:
00172 void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms);
00173 unsigned int MandatoryBlockSize() const {return BlockSize();}
00174 bool IsRandomAccess() const {return false;}
00175 bool IsSelfInverting() const {return false;}
00176 bool IsForwardTransformation() const {return m_cipher->IsForwardTransformation();}
00177 void Resynchronize(const byte *iv) {memcpy_s(m_register, m_register.size(), iv, BlockSize());}
00178 void ProcessData(byte *outString, const byte *inString, size_t length);
00179
00180 protected:
00181 bool RequireAlignedInput() const {return true;}
00182 virtual void ProcessBlocks(byte *outString, const byte *inString, size_t numberOfBlocks) =0;
00183 void ResizeBuffers()
00184 {
00185 CipherModeBase::ResizeBuffers();
00186 m_buffer.New(BlockSize());
00187 }
00188
00189 SecByteBlock m_buffer;
00190 };
00191
00192 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE ECB_OneWay : public BlockOrientedCipherModeBase
00193 {
00194 public:
00195 IV_Requirement IVRequirement() const {return NOT_RESYNCHRONIZABLE;}
00196 unsigned int OptimalBlockSize() const {return BlockSize() * m_cipher->OptimalNumberOfParallelBlocks();}
00197 void ProcessBlocks(byte *outString, const byte *inString, size_t numberOfBlocks)
00198 {m_cipher->ProcessAndXorMultipleBlocks(inString, NULL, outString, numberOfBlocks);}
00199 static const char * CRYPTOPP_API StaticAlgorithmName() {return "ECB";}
00200 };
00201
00202 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_ModeBase : public BlockOrientedCipherModeBase
00203 {
00204 public:
00205 IV_Requirement IVRequirement() const {return UNPREDICTABLE_RANDOM_IV;}
00206 bool RequireAlignedInput() const {return false;}
00207 unsigned int MinLastBlockSize() const {return 0;}
00208 static const char * CRYPTOPP_API StaticAlgorithmName() {return "CBC";}
00209 };
00210
00211 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_Encryption : public CBC_ModeBase
00212 {
00213 public:
00214 void ProcessBlocks(byte *outString, const byte *inString, size_t numberOfBlocks);
00215 };
00216
00217 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_CTS_Encryption : public CBC_Encryption
00218 {
00219 public:
00220 void SetStolenIV(byte *iv) {m_stolenIV = iv;}
00221 unsigned int MinLastBlockSize() const {return BlockSize()+1;}
00222 void ProcessLastBlock(byte *outString, const byte *inString, size_t length);
00223 static const char * CRYPTOPP_API StaticAlgorithmName() {return "CBC/CTS";}
00224
00225 protected:
00226 void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms)
00227 {
00228 CBC_Encryption::UncheckedSetKey(key, length, params);
00229 m_stolenIV = params.GetValueWithDefault(Name::StolenIV(), (byte *)NULL);
00230 }
00231
00232 byte *m_stolenIV;
00233 };
00234
00235 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_Decryption : public CBC_ModeBase
00236 {
00237 public:
00238 void ProcessBlocks(byte *outString, const byte *inString, size_t numberOfBlocks);
00239
00240 protected:
00241 void ResizeBuffers()
00242 {
00243 BlockOrientedCipherModeBase::ResizeBuffers();
00244 m_temp.New(BlockSize());
00245 }
00246 SecByteBlock m_temp;
00247 };
00248
00249 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_CTS_Decryption : public CBC_Decryption
00250 {
00251 public:
00252 unsigned int MinLastBlockSize() const {return BlockSize()+1;}
00253 void ProcessLastBlock(byte *outString, const byte *inString, size_t length);
00254 };
00255
00256
00257 template <class CIPHER, class BASE>
00258 class CipherModeFinalTemplate_CipherHolder : protected ObjectHolder<CIPHER>, public AlgorithmImpl<BASE, CipherModeFinalTemplate_CipherHolder<CIPHER, BASE> >
00259 {
00260 public:
00261 CipherModeFinalTemplate_CipherHolder()
00262 {
00263 this->m_cipher = &this->m_object;
00264 this->ResizeBuffers();
00265 }
00266 CipherModeFinalTemplate_CipherHolder(const byte *key, size_t length)
00267 {
00268 this->m_cipher = &this->m_object;
00269 this->SetKey(key, length);
00270 }
00271 CipherModeFinalTemplate_CipherHolder(const byte *key, size_t length, const byte *iv)
00272 {
00273 this->m_cipher = &this->m_object;
00274 this->SetKey(key, length, MakeParameters(Name::IV(), iv));
00275 }
00276 CipherModeFinalTemplate_CipherHolder(const byte *key, size_t length, const byte *iv, int feedbackSize)
00277 {
00278 this->m_cipher = &this->m_object;
00279 this->SetKey(key, length, MakeParameters(Name::IV(), iv)(Name::FeedbackSize(), feedbackSize));
00280 }
00281
00282 static std::string CRYPTOPP_API StaticAlgorithmName()
00283 {return CIPHER::StaticAlgorithmName() + "/" + BASE::StaticAlgorithmName();}
00284 };
00285
00286
00287 template <class BASE>
00288 class CipherModeFinalTemplate_ExternalCipher : public BASE
00289 {
00290 public:
00291 CipherModeFinalTemplate_ExternalCipher() {}
00292 CipherModeFinalTemplate_ExternalCipher(BlockCipher &cipher)
00293 {SetCipher(cipher);}
00294 CipherModeFinalTemplate_ExternalCipher(BlockCipher &cipher, const byte *iv, int feedbackSize = 0)
00295 {SetCipherWithIV(cipher, iv, feedbackSize);}
00296
00297 void SetCipher(BlockCipher &cipher);
00298 void SetCipherWithIV(BlockCipher &cipher, const byte *iv, int feedbackSize = 0);
00299 };
00300
00301 template <class BASE>
00302 void CipherModeFinalTemplate_ExternalCipher<BASE>::SetCipher(BlockCipher &cipher)
00303 {
00304 this->ThrowIfResynchronizable();
00305 this->m_cipher = &cipher;
00306 this->ResizeBuffers();
00307 }
00308
00309 template <class BASE>
00310 void CipherModeFinalTemplate_ExternalCipher<BASE>::SetCipherWithIV(BlockCipher &cipher, const byte *iv, int feedbackSize)
00311 {
00312 this->ThrowIfInvalidIV(iv);
00313 this->m_cipher = &cipher;
00314 this->ResizeBuffers();
00315 this->SetFeedbackSize(feedbackSize);
00316 if (this->IsResynchronizable())
00317 this->Resynchronize(iv);
00318 }
00319
00320 CRYPTOPP_DLL_TEMPLATE_CLASS CFB_CipherTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> >;
00321 CRYPTOPP_DLL_TEMPLATE_CLASS CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> >;
00322 CRYPTOPP_DLL_TEMPLATE_CLASS CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> >;
00323
00324
00325 template <class CIPHER>
00326 struct CFB_Mode : public CipherModeDocumentation
00327 {
00328 typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Encryption;
00329 typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Decryption;
00330 };
00331
00332
00333 struct CFB_Mode_ExternalCipher : public CipherModeDocumentation
00334 {
00335 typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Encryption;
00336 typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Decryption;
00337 };
00338
00339
00340 template <class CIPHER>
00341 struct CFB_FIPS_Mode : public CipherModeDocumentation
00342 {
00343 typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, CFB_RequireFullDataBlocks<CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > > Encryption;
00344 typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, CFB_RequireFullDataBlocks<CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > > Decryption;
00345 };
00346
00347
00348 struct CFB_FIPS_Mode_ExternalCipher : public CipherModeDocumentation
00349 {
00350 typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, CFB_RequireFullDataBlocks<CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > > Encryption;
00351 typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, CFB_RequireFullDataBlocks<CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > > Decryption;
00352 };
00353
00354 CRYPTOPP_DLL_TEMPLATE_CLASS AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, OFB_ModePolicy> >;
00355
00356
00357 template <class CIPHER>
00358 struct OFB_Mode : public CipherModeDocumentation
00359 {
00360 typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, OFB_ModePolicy> > > > Encryption;
00361 typedef Encryption Decryption;
00362 };
00363
00364
00365 struct OFB_Mode_ExternalCipher : public CipherModeDocumentation
00366 {
00367 typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, OFB_ModePolicy> > > > Encryption;
00368 typedef Encryption Decryption;
00369 };
00370
00371 CRYPTOPP_DLL_TEMPLATE_CLASS AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, CTR_ModePolicy> >;
00372
00373
00374 template <class CIPHER>
00375 struct CTR_Mode : public CipherModeDocumentation
00376 {
00377 typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, CTR_ModePolicy> > > > Encryption;
00378 typedef Encryption Decryption;
00379 };
00380
00381
00382 struct CTR_Mode_ExternalCipher : public CipherModeDocumentation
00383 {
00384 typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, CTR_ModePolicy> > > > Encryption;
00385 typedef Encryption Decryption;
00386 };
00387
00388
00389 template <class CIPHER>
00390 struct ECB_Mode : public CipherModeDocumentation
00391 {
00392 typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ECB_OneWay> Encryption;
00393 typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Decryption, ECB_OneWay> Decryption;
00394 };
00395
00396 CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<ECB_OneWay>;
00397
00398
00399 struct ECB_Mode_ExternalCipher : public CipherModeDocumentation
00400 {
00401 typedef CipherModeFinalTemplate_ExternalCipher<ECB_OneWay> Encryption;
00402 typedef Encryption Decryption;
00403 };
00404
00405
00406 template <class CIPHER>
00407 struct CBC_Mode : public CipherModeDocumentation
00408 {
00409 typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, CBC_Encryption> Encryption;
00410 typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Decryption, CBC_Decryption> Decryption;
00411 };
00412
00413 CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<CBC_Encryption>;
00414 CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<CBC_Decryption>;
00415
00416
00417 struct CBC_Mode_ExternalCipher : public CipherModeDocumentation
00418 {
00419 typedef CipherModeFinalTemplate_ExternalCipher<CBC_Encryption> Encryption;
00420 typedef CipherModeFinalTemplate_ExternalCipher<CBC_Decryption> Decryption;
00421 };
00422
00423
00424 template <class CIPHER>
00425 struct CBC_CTS_Mode : public CipherModeDocumentation
00426 {
00427 typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, CBC_CTS_Encryption> Encryption;
00428 typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Decryption, CBC_CTS_Decryption> Decryption;
00429 };
00430
00431 CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Encryption>;
00432 CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Decryption>;
00433
00434
00435 struct CBC_CTS_Mode_ExternalCipher : public CipherModeDocumentation
00436 {
00437 typedef CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Encryption> Encryption;
00438 typedef CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Decryption> Decryption;
00439 };
00440
00441 #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
00442 typedef CFB_Mode_ExternalCipher::Encryption CFBEncryption;
00443 typedef CFB_Mode_ExternalCipher::Decryption CFBDecryption;
00444 typedef OFB_Mode_ExternalCipher::Encryption OFB;
00445 typedef CTR_Mode_ExternalCipher::Encryption CounterMode;
00446 #endif
00447
00448 NAMESPACE_END
00449
00450 #endif