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