- 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         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 &params, 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 &params, 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 &params);
    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 &params)
    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 //! CFB mode
    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 //! CFB mode, external cipher
    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 //! CFB mode FIPS variant, requiring full block plaintext according to FIPS 800-38A
    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 //! CFB mode FIPS variant, requiring full block plaintext according to FIPS 800-38A, external cipher
    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 //! OFB mode
    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 //! OFB mode, external cipher
    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 //! CTR mode
    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 //! CTR mode, external cipher
    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 //! ECB mode
    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 //! ECB mode, external cipher
    00399 struct ECB_Mode_ExternalCipher : public CipherModeDocumentation
    00400 {
    00401         typedef CipherModeFinalTemplate_ExternalCipher<ECB_OneWay> Encryption;
    00402         typedef Encryption Decryption;
    00403 };
    00404
    00405 //! CBC mode
    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 //! CBC mode, external cipher
    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 //! CBC mode with ciphertext stealing
    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 //! CBC mode with ciphertext stealing, external cipher
    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