Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

459 lines
18 KiB

  1. // modes.h - written and placed in the public domain by Wei Dai
  2. //! \file modes.h
  3. //! \brief Class file for modes of operation.
  4. #ifndef CRYPTOPP_MODES_H
  5. #define CRYPTOPP_MODES_H
  6. #include "cryptlib.h"
  7. #include "secblock.h"
  8. #include "misc.h"
  9. #include "strciphr.h"
  10. #include "argnames.h"
  11. #include "algparam.h"
  12. NAMESPACE_BEGIN(CryptoPP)
  13. //! \class CipherModeDocumentation
  14. //! \brief Classes for operating block cipher modes of operation
  15. //! \details Each class derived from this one defines two types, Encryption and Decryption,
  16. //! both of which implement the SymmetricCipher interface.
  17. //! For each mode there are two classes, one of which is a template class,
  18. //! and the other one has a name that ends in "_ExternalCipher".
  19. //! The "external cipher" mode objects hold a reference to the underlying block cipher,
  20. //! instead of holding an instance of it. The reference must be passed in to the constructor.
  21. //! For the "cipher holder" classes, the CIPHER template parameter should be a class
  22. //! derived from BlockCipherDocumentation, for example DES or AES.
  23. //! \details See NIST SP 800-38A for definitions of these modes. See
  24. //! AuthenticatedSymmetricCipherDocumentation for authenticated encryption modes.
  25. struct CipherModeDocumentation : public SymmetricCipherDocumentation
  26. {
  27. };
  28. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CipherModeBase : public SymmetricCipher
  29. {
  30. public:
  31. size_t MinKeyLength() const {return m_cipher->MinKeyLength();}
  32. size_t MaxKeyLength() const {return m_cipher->MaxKeyLength();}
  33. size_t DefaultKeyLength() const {return m_cipher->DefaultKeyLength();}
  34. size_t GetValidKeyLength(size_t n) const {return m_cipher->GetValidKeyLength(n);}
  35. bool IsValidKeyLength(size_t n) const {return m_cipher->IsValidKeyLength(n);}
  36. unsigned int OptimalDataAlignment() const {return m_cipher->OptimalDataAlignment();}
  37. unsigned int IVSize() const {return BlockSize();}
  38. virtual IV_Requirement IVRequirement() const =0;
  39. void SetCipher(BlockCipher &cipher)
  40. {
  41. this->ThrowIfResynchronizable();
  42. this->m_cipher = &cipher;
  43. this->ResizeBuffers();
  44. }
  45. void SetCipherWithIV(BlockCipher &cipher, const byte *iv, int feedbackSize = 0)
  46. {
  47. this->ThrowIfInvalidIV(iv);
  48. this->m_cipher = &cipher;
  49. this->ResizeBuffers();
  50. this->SetFeedbackSize(feedbackSize);
  51. if (this->IsResynchronizable())
  52. this->Resynchronize(iv);
  53. }
  54. protected:
  55. CipherModeBase() : m_cipher(NULL) {}
  56. inline unsigned int BlockSize() const {assert(m_register.size() > 0); return (unsigned int)m_register.size();}
  57. virtual void SetFeedbackSize(unsigned int feedbackSize)
  58. {
  59. if (!(feedbackSize == 0 || feedbackSize == BlockSize()))
  60. throw InvalidArgument("CipherModeBase: feedback size cannot be specified for this cipher mode");
  61. }
  62. // Thanks to Zireael, http://github.com/weidai11/cryptopp/pull/46
  63. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  64. virtual void ResizeBuffers();
  65. #else
  66. virtual void ResizeBuffers()
  67. {
  68. m_register.New(m_cipher->BlockSize());
  69. }
  70. #endif
  71. BlockCipher *m_cipher;
  72. AlignedSecByteBlock m_register;
  73. };
  74. template <class POLICY_INTERFACE>
  75. class CRYPTOPP_NO_VTABLE ModePolicyCommonTemplate : public CipherModeBase, public POLICY_INTERFACE
  76. {
  77. unsigned int GetAlignment() const {return m_cipher->OptimalDataAlignment();}
  78. void CipherSetKey(const NameValuePairs &params, const byte *key, size_t length);
  79. };
  80. template <class POLICY_INTERFACE>
  81. void ModePolicyCommonTemplate<POLICY_INTERFACE>::CipherSetKey(const NameValuePairs &params, const byte *key, size_t length)
  82. {
  83. m_cipher->SetKey(key, length, params);
  84. ResizeBuffers();
  85. int feedbackSize = params.GetIntValueWithDefault(Name::FeedbackSize(), 0);
  86. SetFeedbackSize(feedbackSize);
  87. }
  88. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CFB_ModePolicy : public ModePolicyCommonTemplate<CFB_CipherAbstractPolicy>
  89. {
  90. public:
  91. IV_Requirement IVRequirement() const {return RANDOM_IV;}
  92. static const char * CRYPTOPP_API StaticAlgorithmName() {return "CFB";}
  93. protected:
  94. unsigned int GetBytesPerIteration() const {return m_feedbackSize;}
  95. byte * GetRegisterBegin() {return m_register + BlockSize() - m_feedbackSize;}
  96. bool CanIterate() const {return m_feedbackSize == BlockSize();}
  97. void Iterate(byte *output, const byte *input, CipherDir dir, size_t iterationCount);
  98. void TransformRegister();
  99. void CipherResynchronize(const byte *iv, size_t length);
  100. void SetFeedbackSize(unsigned int feedbackSize);
  101. void ResizeBuffers();
  102. SecByteBlock m_temp;
  103. unsigned int m_feedbackSize;
  104. };
  105. inline void CopyOrZero(void *dest, const void *src, size_t s)
  106. {
  107. if (src)
  108. memcpy_s(dest, s, src, s);
  109. else
  110. memset(dest, 0, s);
  111. }
  112. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE OFB_ModePolicy : public ModePolicyCommonTemplate<AdditiveCipherAbstractPolicy>
  113. {
  114. public:
  115. bool CipherIsRandomAccess() const {return false;}
  116. IV_Requirement IVRequirement() const {return UNIQUE_IV;}
  117. static const char * CRYPTOPP_API StaticAlgorithmName() {return "OFB";}
  118. private:
  119. unsigned int GetBytesPerIteration() const {return BlockSize();}
  120. unsigned int GetIterationsToBuffer() const {return m_cipher->OptimalNumberOfParallelBlocks();}
  121. void WriteKeystream(byte *keystreamBuffer, size_t iterationCount);
  122. void CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length);
  123. };
  124. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CTR_ModePolicy : public ModePolicyCommonTemplate<AdditiveCipherAbstractPolicy>
  125. {
  126. public:
  127. bool CipherIsRandomAccess() const {return true;}
  128. IV_Requirement IVRequirement() const {return RANDOM_IV;}
  129. static const char * CRYPTOPP_API StaticAlgorithmName() {return "CTR";}
  130. protected:
  131. virtual void IncrementCounterBy256();
  132. unsigned int GetAlignment() const {return m_cipher->OptimalDataAlignment();}
  133. unsigned int GetBytesPerIteration() const {return BlockSize();}
  134. unsigned int GetIterationsToBuffer() const {return m_cipher->OptimalNumberOfParallelBlocks();}
  135. void WriteKeystream(byte *buffer, size_t iterationCount)
  136. {OperateKeystream(WRITE_KEYSTREAM, buffer, NULL, iterationCount);}
  137. bool CanOperateKeystream() const {return true;}
  138. void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount);
  139. void CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length);
  140. void SeekToIteration(lword iterationCount);
  141. AlignedSecByteBlock m_counterArray;
  142. };
  143. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE BlockOrientedCipherModeBase : public CipherModeBase
  144. {
  145. public:
  146. void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params);
  147. unsigned int MandatoryBlockSize() const {return BlockSize();}
  148. bool IsRandomAccess() const {return false;}
  149. bool IsSelfInverting() const {return false;}
  150. bool IsForwardTransformation() const {return m_cipher->IsForwardTransformation();}
  151. void Resynchronize(const byte *iv, int length=-1) {memcpy_s(m_register, m_register.size(), iv, ThrowIfInvalidIVLength(length));}
  152. protected:
  153. bool RequireAlignedInput() const {return true;}
  154. // Thanks to Zireael, http://github.com/weidai11/cryptopp/pull/46
  155. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  156. void ResizeBuffers();
  157. #else
  158. void ResizeBuffers()
  159. {
  160. CipherModeBase::ResizeBuffers();
  161. m_buffer.New(BlockSize());
  162. }
  163. #endif
  164. SecByteBlock m_buffer;
  165. };
  166. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE ECB_OneWay : public BlockOrientedCipherModeBase
  167. {
  168. public:
  169. void SetKey(const byte *key, size_t length, const NameValuePairs &params = g_nullNameValuePairs)
  170. {m_cipher->SetKey(key, length, params); BlockOrientedCipherModeBase::ResizeBuffers();}
  171. IV_Requirement IVRequirement() const {return NOT_RESYNCHRONIZABLE;}
  172. unsigned int OptimalBlockSize() const {return BlockSize() * m_cipher->OptimalNumberOfParallelBlocks();}
  173. void ProcessData(byte *outString, const byte *inString, size_t length);
  174. static const char * CRYPTOPP_API StaticAlgorithmName() {return "ECB";}
  175. };
  176. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_ModeBase : public BlockOrientedCipherModeBase
  177. {
  178. public:
  179. IV_Requirement IVRequirement() const {return UNPREDICTABLE_RANDOM_IV;}
  180. bool RequireAlignedInput() const {return false;}
  181. unsigned int MinLastBlockSize() const {return 0;}
  182. static const char * CRYPTOPP_API StaticAlgorithmName() {return "CBC";}
  183. };
  184. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_Encryption : public CBC_ModeBase
  185. {
  186. public:
  187. void ProcessData(byte *outString, const byte *inString, size_t length);
  188. };
  189. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_CTS_Encryption : public CBC_Encryption
  190. {
  191. public:
  192. void SetStolenIV(byte *iv) {m_stolenIV = iv;}
  193. unsigned int MinLastBlockSize() const {return BlockSize()+1;}
  194. void ProcessLastBlock(byte *outString, const byte *inString, size_t length);
  195. static const char * CRYPTOPP_API StaticAlgorithmName() {return "CBC/CTS";}
  196. protected:
  197. void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params)
  198. {
  199. CBC_Encryption::UncheckedSetKey(key, length, params);
  200. m_stolenIV = params.GetValueWithDefault(Name::StolenIV(), (byte *)NULL);
  201. }
  202. byte *m_stolenIV;
  203. };
  204. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_Decryption : public CBC_ModeBase
  205. {
  206. public:
  207. void ProcessData(byte *outString, const byte *inString, size_t length);
  208. protected:
  209. // Thanks to Zireael, http://github.com/weidai11/cryptopp/pull/46
  210. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  211. void ResizeBuffers();
  212. #else
  213. void ResizeBuffers()
  214. {
  215. BlockOrientedCipherModeBase::ResizeBuffers();
  216. m_temp.New(BlockSize());
  217. }
  218. #endif
  219. AlignedSecByteBlock m_temp;
  220. };
  221. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_CTS_Decryption : public CBC_Decryption
  222. {
  223. public:
  224. unsigned int MinLastBlockSize() const {return BlockSize()+1;}
  225. void ProcessLastBlock(byte *outString, const byte *inString, size_t length);
  226. };
  227. //! _
  228. template <class CIPHER, class BASE>
  229. class CipherModeFinalTemplate_CipherHolder : protected ObjectHolder<CIPHER>, public AlgorithmImpl<BASE, CipherModeFinalTemplate_CipherHolder<CIPHER, BASE> >
  230. {
  231. public:
  232. CipherModeFinalTemplate_CipherHolder()
  233. {
  234. this->m_cipher = &this->m_object;
  235. this->ResizeBuffers();
  236. }
  237. CipherModeFinalTemplate_CipherHolder(const byte *key, size_t length)
  238. {
  239. this->m_cipher = &this->m_object;
  240. this->SetKey(key, length);
  241. }
  242. CipherModeFinalTemplate_CipherHolder(const byte *key, size_t length, const byte *iv)
  243. {
  244. this->m_cipher = &this->m_object;
  245. this->SetKey(key, length, MakeParameters(Name::IV(), ConstByteArrayParameter(iv, this->m_cipher->BlockSize())));
  246. }
  247. CipherModeFinalTemplate_CipherHolder(const byte *key, size_t length, const byte *iv, int feedbackSize)
  248. {
  249. this->m_cipher = &this->m_object;
  250. this->SetKey(key, length, MakeParameters(Name::IV(), ConstByteArrayParameter(iv, this->m_cipher->BlockSize()))(Name::FeedbackSize(), feedbackSize));
  251. }
  252. static std::string CRYPTOPP_API StaticAlgorithmName()
  253. {return CIPHER::StaticAlgorithmName() + "/" + BASE::StaticAlgorithmName();}
  254. };
  255. //! \class CipherModeFinalTemplate_ExternalCipher
  256. //! \tparam BASE CipherModeFinalTemplate_CipherHolder class
  257. //! \brief OFB block cipher mode of operation.
  258. template <class BASE>
  259. class CipherModeFinalTemplate_ExternalCipher : public BASE
  260. {
  261. public:
  262. CipherModeFinalTemplate_ExternalCipher() {}
  263. CipherModeFinalTemplate_ExternalCipher(BlockCipher &cipher)
  264. {this->SetCipher(cipher);}
  265. CipherModeFinalTemplate_ExternalCipher(BlockCipher &cipher, const byte *iv, int feedbackSize = 0)
  266. {this->SetCipherWithIV(cipher, iv, feedbackSize);}
  267. std::string AlgorithmName() const
  268. {return (this->m_cipher ? this->m_cipher->AlgorithmName() + "/" : std::string("")) + BASE::StaticAlgorithmName();}
  269. };
  270. CRYPTOPP_DLL_TEMPLATE_CLASS CFB_CipherTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> >;
  271. CRYPTOPP_DLL_TEMPLATE_CLASS CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> >;
  272. CRYPTOPP_DLL_TEMPLATE_CLASS CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> >;
  273. //! \class CFB_Mode
  274. //! \brief CFB block cipher mode of operation.
  275. template <class CIPHER>
  276. struct CFB_Mode : public CipherModeDocumentation
  277. {
  278. typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Encryption;
  279. typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Decryption;
  280. };
  281. //! \class CFB_Mode_ExternalCipher
  282. //! \brief CFB mode, external cipher.
  283. struct CFB_Mode_ExternalCipher : public CipherModeDocumentation
  284. {
  285. typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Encryption;
  286. typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Decryption;
  287. };
  288. //! \class CFB_FIPS_Mode
  289. //! \brief CFB block cipher mode of operation providing FIPS validated cryptography.
  290. //! \details Requires full block plaintext according to FIPS 800-38A
  291. template <class CIPHER>
  292. struct CFB_FIPS_Mode : public CipherModeDocumentation
  293. {
  294. typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, CFB_RequireFullDataBlocks<CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > > Encryption;
  295. typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, CFB_RequireFullDataBlocks<CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > > Decryption;
  296. };
  297. //! \class CFB_FIPS_Mode_ExternalCipher
  298. //! \brief CFB mode, external cipher, providing FIPS validated cryptography.
  299. //! \details Requires full block plaintext according to FIPS 800-38A
  300. struct CFB_FIPS_Mode_ExternalCipher : public CipherModeDocumentation
  301. {
  302. typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, CFB_RequireFullDataBlocks<CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > > Encryption;
  303. typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, CFB_RequireFullDataBlocks<CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > > Decryption;
  304. };
  305. CRYPTOPP_DLL_TEMPLATE_CLASS AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, OFB_ModePolicy> >;
  306. //! \class OFB_Mode
  307. //! \brief OFB block cipher mode of operation.
  308. template <class CIPHER>
  309. struct OFB_Mode : public CipherModeDocumentation
  310. {
  311. typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, OFB_ModePolicy> > > > Encryption;
  312. typedef Encryption Decryption;
  313. };
  314. //! \class OFB_Mode_ExternalCipher
  315. //! \brief OFB mode, external cipher.
  316. struct OFB_Mode_ExternalCipher : public CipherModeDocumentation
  317. {
  318. typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, OFB_ModePolicy> > > > Encryption;
  319. typedef Encryption Decryption;
  320. };
  321. CRYPTOPP_DLL_TEMPLATE_CLASS AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, CTR_ModePolicy> >;
  322. CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, CTR_ModePolicy> > > >;
  323. //! \class CTR_Mode
  324. //! \brief CTR block cipher mode of operation.
  325. template <class CIPHER>
  326. struct CTR_Mode : public CipherModeDocumentation
  327. {
  328. typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, CTR_ModePolicy> > > > Encryption;
  329. typedef Encryption Decryption;
  330. };
  331. //! \class CTR_Mode_ExternalCipher
  332. //! \brief CTR mode, external cipher.
  333. struct CTR_Mode_ExternalCipher : public CipherModeDocumentation
  334. {
  335. typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, CTR_ModePolicy> > > > Encryption;
  336. typedef Encryption Decryption;
  337. };
  338. //! \class ECB_Mode
  339. //! \brief ECB block cipher mode of operation.
  340. template <class CIPHER>
  341. struct ECB_Mode : public CipherModeDocumentation
  342. {
  343. typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ECB_OneWay> Encryption;
  344. typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Decryption, ECB_OneWay> Decryption;
  345. };
  346. CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<ECB_OneWay>;
  347. //! \class ECB_Mode_ExternalCipher
  348. //! \brief ECB mode, external cipher.
  349. struct ECB_Mode_ExternalCipher : public CipherModeDocumentation
  350. {
  351. typedef CipherModeFinalTemplate_ExternalCipher<ECB_OneWay> Encryption;
  352. typedef Encryption Decryption;
  353. };
  354. //! CBC mode
  355. template <class CIPHER>
  356. struct CBC_Mode : public CipherModeDocumentation
  357. {
  358. typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, CBC_Encryption> Encryption;
  359. typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Decryption, CBC_Decryption> Decryption;
  360. };
  361. CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<CBC_Encryption>;
  362. CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<CBC_Decryption>;
  363. //! CBC mode, external cipher
  364. struct CBC_Mode_ExternalCipher : public CipherModeDocumentation
  365. {
  366. typedef CipherModeFinalTemplate_ExternalCipher<CBC_Encryption> Encryption;
  367. typedef CipherModeFinalTemplate_ExternalCipher<CBC_Decryption> Decryption;
  368. };
  369. //! CBC mode with ciphertext stealing
  370. template <class CIPHER>
  371. struct CBC_CTS_Mode : public CipherModeDocumentation
  372. {
  373. typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, CBC_CTS_Encryption> Encryption;
  374. typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Decryption, CBC_CTS_Decryption> Decryption;
  375. };
  376. CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Encryption>;
  377. CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Decryption>;
  378. //! \class CBC_CTS_Mode_ExternalCipher
  379. //! \brief CBC mode with ciphertext stealing, external cipher
  380. struct CBC_CTS_Mode_ExternalCipher : public CipherModeDocumentation
  381. {
  382. typedef CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Encryption> Encryption;
  383. typedef CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Decryption> Decryption;
  384. };
  385. #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
  386. typedef CFB_Mode_ExternalCipher::Encryption CFBEncryption;
  387. typedef CFB_Mode_ExternalCipher::Decryption CFBDecryption;
  388. typedef OFB_Mode_ExternalCipher::Encryption OFB;
  389. typedef CTR_Mode_ExternalCipher::Encryption CounterMode;
  390. #endif
  391. NAMESPACE_END
  392. #endif