File indexing completed on 2025-01-18 09:55:05
0001
0002
0003
0004
0005
0006 #ifndef CRYPTOPP_MODES_H
0007 #define CRYPTOPP_MODES_H
0008
0009 #include "cryptlib.h"
0010 #include "secblock.h"
0011 #include "misc.h"
0012 #include "strciphr.h"
0013 #include "argnames.h"
0014 #include "algparam.h"
0015
0016
0017 #if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
0018 # pragma GCC diagnostic push
0019 # pragma GCC diagnostic ignored "-Wconversion"
0020 # pragma GCC diagnostic ignored "-Wsign-conversion"
0021 #endif
0022
0023 #if CRYPTOPP_MSC_VERSION
0024 # pragma warning(push)
0025 # pragma warning(disable: 4231 4275)
0026 # if (CRYPTOPP_MSC_VERSION >= 1400)
0027 # pragma warning(disable: 6011 6386 28193)
0028 # endif
0029 #endif
0030
0031 NAMESPACE_BEGIN(CryptoPP)
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044 struct CipherModeDocumentation : public SymmetricCipherDocumentation
0045 {
0046 };
0047
0048
0049 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CipherModeBase : public SymmetricCipher
0050 {
0051 public:
0052 virtual ~CipherModeBase() {}
0053
0054
0055 std::string AlgorithmProvider() const {
0056 return m_cipher != NULLPTR ? m_cipher->AlgorithmProvider() : "C++";
0057 }
0058
0059
0060
0061 size_t MinKeyLength() const {return m_cipher->MinKeyLength();}
0062
0063
0064
0065 size_t MaxKeyLength() const {return m_cipher->MaxKeyLength();}
0066
0067
0068
0069 size_t DefaultKeyLength() const {return m_cipher->DefaultKeyLength();}
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079 size_t GetValidKeyLength(size_t keylength) const {return m_cipher->GetValidKeyLength(keylength);}
0080
0081
0082
0083
0084
0085 bool IsValidKeyLength(size_t keylength) const {return m_cipher->IsValidKeyLength(keylength);}
0086
0087
0088
0089
0090 unsigned int OptimalDataAlignment() const {return m_cipher->OptimalDataAlignment();}
0091
0092
0093
0094
0095
0096 unsigned int IVSize() const {return BlockSize();}
0097
0098
0099
0100 virtual IV_Requirement IVRequirement() const =0;
0101
0102
0103
0104
0105 void SetCipher(BlockCipher &cipher)
0106 {
0107 this->ThrowIfResynchronizable();
0108 this->m_cipher = &cipher;
0109 this->ResizeBuffers();
0110 }
0111
0112
0113
0114
0115
0116
0117 void SetCipherWithIV(BlockCipher &cipher, const byte *iv, int feedbackSize = 0)
0118 {
0119 this->ThrowIfInvalidIV(iv);
0120 this->m_cipher = &cipher;
0121 this->ResizeBuffers();
0122 this->SetFeedbackSize(feedbackSize);
0123 if (this->IsResynchronizable())
0124 this->Resynchronize(iv);
0125 }
0126
0127 protected:
0128 CipherModeBase() : m_cipher(NULLPTR) {}
0129 inline unsigned int BlockSize() const
0130 {
0131 CRYPTOPP_ASSERT(m_register.size() > 0);
0132 return static_cast<unsigned int>(m_register.size());
0133 }
0134 virtual void SetFeedbackSize(unsigned int feedbackSize)
0135 {
0136 if (!(feedbackSize == 0 || feedbackSize == BlockSize()))
0137 throw InvalidArgument("CipherModeBase: feedback size cannot be specified for this cipher mode");
0138 }
0139
0140 virtual void ResizeBuffers();
0141
0142 BlockCipher *m_cipher;
0143 SecByteBlock m_register;
0144 };
0145
0146
0147
0148 template <class POLICY_INTERFACE>
0149 class CRYPTOPP_NO_VTABLE ModePolicyCommonTemplate : public CipherModeBase, public POLICY_INTERFACE
0150 {
0151 unsigned int GetAlignment() const {return m_cipher->OptimalDataAlignment();}
0152 void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length);
0153 };
0154
0155 template <class POLICY_INTERFACE>
0156 void ModePolicyCommonTemplate<POLICY_INTERFACE>::CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length)
0157 {
0158 m_cipher->SetKey(key, length, params);
0159 ResizeBuffers();
0160 int feedbackSize = params.GetIntValueWithDefault(Name::FeedbackSize(), 0);
0161 SetFeedbackSize(feedbackSize);
0162 }
0163
0164
0165 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CFB_ModePolicy : public ModePolicyCommonTemplate<CFB_CipherAbstractPolicy>
0166 {
0167 public:
0168 CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "CFB";}
0169
0170 virtual ~CFB_ModePolicy() {}
0171 CFB_ModePolicy() : m_feedbackSize(0) {}
0172 IV_Requirement IVRequirement() const {return RANDOM_IV;}
0173
0174 protected:
0175 unsigned int GetBytesPerIteration() const {return m_feedbackSize;}
0176 bool CanIterate() const {return m_feedbackSize == BlockSize();}
0177 void Iterate(byte *output, const byte *input, CipherDir dir, size_t iterationCount);
0178 void TransformRegister();
0179 void CipherResynchronize(const byte *iv, size_t length);
0180 void SetFeedbackSize(unsigned int feedbackSize);
0181 void ResizeBuffers();
0182 byte * GetRegisterBegin();
0183
0184 SecByteBlock m_temp;
0185 unsigned int m_feedbackSize;
0186 };
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196 inline void CopyOrZero(void *dest, size_t dsize, const void *src, size_t ssize)
0197 {
0198 CRYPTOPP_ASSERT(dest);
0199 CRYPTOPP_ASSERT(dsize >= ssize);
0200
0201 if (src != NULLPTR)
0202 memcpy_s(dest, dsize, src, ssize);
0203 else
0204 std::memset(dest, 0, dsize);
0205 }
0206
0207
0208 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE OFB_ModePolicy : public ModePolicyCommonTemplate<AdditiveCipherAbstractPolicy>
0209 {
0210 public:
0211 CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "OFB";}
0212
0213 bool CipherIsRandomAccess() const {return false;}
0214 IV_Requirement IVRequirement() const {return UNIQUE_IV;}
0215
0216 protected:
0217 unsigned int GetBytesPerIteration() const {return BlockSize();}
0218 unsigned int GetIterationsToBuffer() const {return m_cipher->OptimalNumberOfParallelBlocks();}
0219 void WriteKeystream(byte *keystreamBuffer, size_t iterationCount);
0220 void CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length);
0221 };
0222
0223
0224 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CTR_ModePolicy : public ModePolicyCommonTemplate<AdditiveCipherAbstractPolicy>
0225 {
0226 public:
0227 CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "CTR";}
0228
0229 virtual ~CTR_ModePolicy() {}
0230 bool CipherIsRandomAccess() const {return true;}
0231 IV_Requirement IVRequirement() const {return RANDOM_IV;}
0232
0233 protected:
0234 virtual void IncrementCounterBy256();
0235 unsigned int GetAlignment() const {return m_cipher->OptimalDataAlignment();}
0236 unsigned int GetBytesPerIteration() const {return BlockSize();}
0237 unsigned int GetIterationsToBuffer() const {return m_cipher->OptimalNumberOfParallelBlocks();}
0238 void WriteKeystream(byte *buffer, size_t iterationCount)
0239 {OperateKeystream(WRITE_KEYSTREAM, buffer, NULLPTR, iterationCount);}
0240 bool CanOperateKeystream() const {return true;}
0241 void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount);
0242 void CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length);
0243 void SeekToIteration(lword iterationCount);
0244
0245
0246 mutable SecByteBlock m_counterArray;
0247 };
0248
0249
0250 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE BlockOrientedCipherModeBase : public CipherModeBase
0251 {
0252 public:
0253 virtual ~BlockOrientedCipherModeBase() {}
0254 void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms);
0255 unsigned int MandatoryBlockSize() const {return BlockSize();}
0256 bool IsRandomAccess() const {return false;}
0257 bool IsSelfInverting() const {return false;}
0258 bool IsForwardTransformation() const
0259 {return m_cipher->IsForwardTransformation();}
0260 void Resynchronize(const byte *iv, int length=-1)
0261 {memcpy_s(m_register, m_register.size(), iv, ThrowIfInvalidIVLength(length));}
0262
0263 protected:
0264 bool RequireAlignedInput() const {return true;}
0265 virtual void ResizeBuffers();
0266
0267 SecByteBlock m_buffer;
0268 };
0269
0270
0271 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE ECB_OneWay : public BlockOrientedCipherModeBase
0272 {
0273 public:
0274 CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "ECB";}
0275
0276 void SetKey(const byte *key, size_t length, const NameValuePairs ¶ms = g_nullNameValuePairs)
0277 {m_cipher->SetKey(key, length, params); BlockOrientedCipherModeBase::ResizeBuffers();}
0278 IV_Requirement IVRequirement() const {return NOT_RESYNCHRONIZABLE;}
0279 unsigned int OptimalBlockSize() const {return static_cast<unsigned int>(BlockSize() * m_cipher->OptimalNumberOfParallelBlocks());}
0280 void ProcessData(byte *outString, const byte *inString, size_t length);
0281 };
0282
0283
0284 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_ModeBase : public BlockOrientedCipherModeBase
0285 {
0286 public:
0287 CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "CBC";}
0288
0289 IV_Requirement IVRequirement() const {return UNPREDICTABLE_RANDOM_IV;}
0290 bool RequireAlignedInput() const {return false;}
0291 unsigned int MinLastBlockSize() const {return 0;}
0292 };
0293
0294
0295 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_Encryption : public CBC_ModeBase
0296 {
0297 public:
0298 void ProcessData(byte *outString, const byte *inString, size_t length);
0299 };
0300
0301
0302
0303 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_CTS_Encryption : public CBC_Encryption
0304 {
0305 public:
0306 CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "CBC/CTS";}
0307
0308 void SetStolenIV(byte *iv) {m_stolenIV = iv;}
0309 unsigned int MinLastBlockSize() const {return BlockSize()+1;}
0310 size_t ProcessLastBlock(byte *outString, size_t outLength, const byte *inString, size_t inLength);
0311
0312 protected:
0313 void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms)
0314 {
0315 CBC_Encryption::UncheckedSetKey(key, length, params);
0316 m_stolenIV = params.GetValueWithDefault(Name::StolenIV(), static_cast<byte *>(NULLPTR));
0317 }
0318
0319 byte *m_stolenIV;
0320 };
0321
0322
0323 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_Decryption : public CBC_ModeBase
0324 {
0325 public:
0326 virtual ~CBC_Decryption() {}
0327 void ProcessData(byte *outString, const byte *inString, size_t length);
0328
0329 protected:
0330 virtual void ResizeBuffers();
0331
0332 SecByteBlock m_temp;
0333 };
0334
0335
0336
0337 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_CTS_Decryption : public CBC_Decryption
0338 {
0339 public:
0340 unsigned int MinLastBlockSize() const {return BlockSize()+1;}
0341 size_t ProcessLastBlock(byte *outString, size_t outLength, const byte *inString, size_t inLength);
0342 };
0343
0344
0345 template <class CIPHER, class BASE>
0346 class CipherModeFinalTemplate_CipherHolder : protected ObjectHolder<CIPHER>, public AlgorithmImpl<BASE, CipherModeFinalTemplate_CipherHolder<CIPHER, BASE> >
0347 {
0348 public:
0349
0350
0351
0352
0353
0354 static std::string CRYPTOPP_API StaticAlgorithmName()
0355 {return CIPHER::StaticAlgorithmName() + "/" + BASE::StaticAlgorithmName();}
0356
0357
0358 CipherModeFinalTemplate_CipherHolder()
0359 {
0360 this->m_cipher = &this->m_object;
0361 this->ResizeBuffers();
0362 }
0363
0364
0365
0366
0367
0368
0369 CipherModeFinalTemplate_CipherHolder(const byte *key, size_t length)
0370 {
0371 this->m_cipher = &this->m_object;
0372 this->SetKey(key, length);
0373 }
0374
0375
0376
0377
0378
0379
0380
0381 CipherModeFinalTemplate_CipherHolder(const byte *key, size_t length, const byte *iv)
0382 {
0383 this->m_cipher = &this->m_object;
0384 this->SetKey(key, length, MakeParameters(Name::IV(), ConstByteArrayParameter(iv, this->m_cipher->BlockSize())));
0385 }
0386
0387
0388
0389
0390
0391
0392
0393
0394 CipherModeFinalTemplate_CipherHolder(const byte *key, size_t length, const byte *iv, int feedbackSize)
0395 {
0396 this->m_cipher = &this->m_object;
0397 this->SetKey(key, length, MakeParameters(Name::IV(), ConstByteArrayParameter(iv, this->m_cipher->BlockSize()))(Name::FeedbackSize(), feedbackSize));
0398 }
0399
0400
0401 std::string AlgorithmProvider() const {
0402 return this->m_cipher->AlgorithmProvider();
0403 }
0404 };
0405
0406
0407
0408 template <class BASE>
0409 class CipherModeFinalTemplate_ExternalCipher : public BASE
0410 {
0411 public:
0412
0413
0414 CipherModeFinalTemplate_ExternalCipher() {}
0415
0416
0417
0418
0419 CipherModeFinalTemplate_ExternalCipher(BlockCipher &cipher)
0420 {this->SetCipher(cipher);}
0421
0422
0423
0424
0425
0426
0427 CipherModeFinalTemplate_ExternalCipher(BlockCipher &cipher, const byte *iv, int feedbackSize = 0)
0428 {this->SetCipherWithIV(cipher, iv, feedbackSize);}
0429
0430
0431
0432
0433
0434
0435
0436 std::string AlgorithmName() const
0437 {return (this->m_cipher ? this->m_cipher->AlgorithmName() + "/" : std::string("")) + BASE::StaticAlgorithmName();}
0438
0439
0440 std::string AlgorithmProvider() const
0441 {return this->m_cipher->AlgorithmProvider();}
0442 };
0443
0444 CRYPTOPP_DLL_TEMPLATE_CLASS CFB_CipherTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> >;
0445 CRYPTOPP_DLL_TEMPLATE_CLASS CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> >;
0446 CRYPTOPP_DLL_TEMPLATE_CLASS CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> >;
0447
0448
0449
0450
0451 template <class CIPHER>
0452 struct CFB_Mode : public CipherModeDocumentation
0453 {
0454 typedef CipherModeFinalTemplate_CipherHolder<typename CIPHER::Encryption, ConcretePolicyHolder<Empty, CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Encryption;
0455 typedef CipherModeFinalTemplate_CipherHolder<typename CIPHER::Encryption, ConcretePolicyHolder<Empty, CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Decryption;
0456 };
0457
0458
0459
0460
0461 struct CFB_Mode_ExternalCipher : public CipherModeDocumentation
0462 {
0463 typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Encryption;
0464 typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Decryption;
0465 };
0466
0467
0468
0469
0470
0471 template <class CIPHER>
0472 struct CFB_FIPS_Mode : public CipherModeDocumentation
0473 {
0474 typedef CipherModeFinalTemplate_CipherHolder<typename CIPHER::Encryption, ConcretePolicyHolder<Empty, CFB_RequireFullDataBlocks<CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > > Encryption;
0475 typedef CipherModeFinalTemplate_CipherHolder<typename CIPHER::Encryption, ConcretePolicyHolder<Empty, CFB_RequireFullDataBlocks<CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > > Decryption;
0476 };
0477
0478
0479
0480
0481
0482 struct CFB_FIPS_Mode_ExternalCipher : public CipherModeDocumentation
0483 {
0484 typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, CFB_RequireFullDataBlocks<CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > > Encryption;
0485 typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, CFB_RequireFullDataBlocks<CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > > Decryption;
0486 };
0487
0488 CRYPTOPP_DLL_TEMPLATE_CLASS AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, OFB_ModePolicy> >;
0489
0490
0491
0492
0493 template <class CIPHER>
0494 struct OFB_Mode : public CipherModeDocumentation
0495 {
0496 typedef CipherModeFinalTemplate_CipherHolder<typename CIPHER::Encryption, ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, OFB_ModePolicy> > > > Encryption;
0497 typedef Encryption Decryption;
0498 };
0499
0500
0501
0502
0503 struct OFB_Mode_ExternalCipher : public CipherModeDocumentation
0504 {
0505 typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, OFB_ModePolicy> > > > Encryption;
0506 typedef Encryption Decryption;
0507 };
0508
0509 CRYPTOPP_DLL_TEMPLATE_CLASS AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, CTR_ModePolicy> >;
0510 CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, CTR_ModePolicy> > > >;
0511
0512
0513
0514
0515 template <class CIPHER>
0516 struct CTR_Mode : public CipherModeDocumentation
0517 {
0518 typedef CipherModeFinalTemplate_CipherHolder<typename CIPHER::Encryption, ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, CTR_ModePolicy> > > > Encryption;
0519 typedef Encryption Decryption;
0520 };
0521
0522
0523
0524
0525 struct CTR_Mode_ExternalCipher : public CipherModeDocumentation
0526 {
0527 typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, CTR_ModePolicy> > > > Encryption;
0528 typedef Encryption Decryption;
0529 };
0530
0531
0532
0533
0534 template <class CIPHER>
0535 struct ECB_Mode : public CipherModeDocumentation
0536 {
0537 typedef CipherModeFinalTemplate_CipherHolder<typename CIPHER::Encryption, ECB_OneWay> Encryption;
0538 typedef CipherModeFinalTemplate_CipherHolder<typename CIPHER::Decryption, ECB_OneWay> Decryption;
0539 };
0540
0541 CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<ECB_OneWay>;
0542
0543
0544
0545
0546 struct ECB_Mode_ExternalCipher : public CipherModeDocumentation
0547 {
0548 typedef CipherModeFinalTemplate_ExternalCipher<ECB_OneWay> Encryption;
0549 typedef Encryption Decryption;
0550 };
0551
0552
0553
0554
0555 template <class CIPHER>
0556 struct CBC_Mode : public CipherModeDocumentation
0557 {
0558 typedef CipherModeFinalTemplate_CipherHolder<typename CIPHER::Encryption, CBC_Encryption> Encryption;
0559 typedef CipherModeFinalTemplate_CipherHolder<typename CIPHER::Decryption, CBC_Decryption> Decryption;
0560 };
0561
0562 CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<CBC_Encryption>;
0563 CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<CBC_Decryption>;
0564
0565
0566
0567
0568 struct CBC_Mode_ExternalCipher : public CipherModeDocumentation
0569 {
0570 typedef CipherModeFinalTemplate_ExternalCipher<CBC_Encryption> Encryption;
0571 typedef CipherModeFinalTemplate_ExternalCipher<CBC_Decryption> Decryption;
0572 };
0573
0574
0575
0576
0577
0578 template <class CIPHER>
0579 struct CBC_CTS_Mode : public CipherModeDocumentation
0580 {
0581 typedef CipherModeFinalTemplate_CipherHolder<typename CIPHER::Encryption, CBC_CTS_Encryption> Encryption;
0582 typedef CipherModeFinalTemplate_CipherHolder<typename CIPHER::Decryption, CBC_CTS_Decryption> Decryption;
0583 };
0584
0585 CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Encryption>;
0586 CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Decryption>;
0587
0588
0589
0590
0591
0592 struct CBC_CTS_Mode_ExternalCipher : public CipherModeDocumentation
0593 {
0594 typedef CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Encryption> Encryption;
0595 typedef CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Decryption> Decryption;
0596 };
0597
0598 NAMESPACE_END
0599
0600
0601 #if CRYPTOPP_MSC_VERSION
0602 # pragma warning(pop)
0603 #endif
0604
0605 #if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
0606 # pragma GCC diagnostic pop
0607 #endif
0608
0609 #endif