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