- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# modes.h

Go to the documentation of this file.

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