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 CipherModeBase : public SymmetricCipher
00032 {
00033 public:
00034 unsigned int MinKeyLength() const {return m_cipher->MinKeyLength();}
00035 unsigned int MaxKeyLength() const {return m_cipher->MaxKeyLength();}
00036 unsigned int DefaultKeyLength() const {return m_cipher->DefaultKeyLength();}
00037 unsigned int GetValidKeyLength(unsigned int n) const {return m_cipher->GetValidKeyLength(n);}
00038 bool IsValidKeyLength(unsigned int n) const {return m_cipher->IsValidKeyLength(n);}
00039
00040 void SetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms = g_nullNameValuePairs);
00041
00042 unsigned int OptimalDataAlignment() const {return BlockSize();}
00043
00044 unsigned int IVSize() const {return BlockSize();}
00045 void GetNextIV(byte *IV);
00046 virtual IV_Requirement IVRequirement() const =0;
00047
00048 protected:
00049 inline unsigned int BlockSize() const {assert(m_register.size() > 0); return m_register.size();}
00050 void SetIV(const byte *iv);
00051 virtual void SetFeedbackSize(unsigned int feedbackSize)
00052 {
00053 if (!(feedbackSize == 0 || feedbackSize == BlockSize()))
00054 throw InvalidArgument("CipherModeBase: feedback size cannot be specified for this cipher mode");
00055 }
00056 virtual void ResizeBuffers()
00057 {
00058 m_register.New(m_cipher->BlockSize());
00059 }
00060 virtual void UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length) =0;
00061
00062 BlockCipher *m_cipher;
00063 SecByteBlock m_register;
00064 };
00065
00066 template <class POLICY_INTERFACE>
00067 class ModePolicyCommonTemplate : public CipherModeBase, public POLICY_INTERFACE
00068 {
00069 unsigned int GetAlignment() const {return m_cipher->BlockAlignment();}
00070 void CipherSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length)
00071 {
00072 m_cipher->SetKey(key, length, params);
00073 ResizeBuffers();
00074 int feedbackSize = params.GetIntValueWithDefault(Name::FeedbackSize(), 0);
00075 SetFeedbackSize(feedbackSize);
00076 const byte *iv = params.GetValueWithDefault(Name::IV(), (const byte *)NULL);
00077 SetIV(iv);
00078 }
00079 };
00080
00081 class CFB_ModePolicy : public ModePolicyCommonTemplate<CFB_CipherAbstractPolicy>
00082 {
00083 public:
00084 IV_Requirement IVRequirement() const {return RANDOM_IV;}
00085
00086 protected:
00087 unsigned int GetBytesPerIteration() const {return m_feedbackSize;}
00088 byte * GetRegisterBegin() {return m_register + BlockSize() - m_feedbackSize;}
00089 void TransformRegister()
00090 {
00091 m_cipher->ProcessBlock(m_register, m_temp);
00092 memmove(m_register, m_register+m_feedbackSize, BlockSize()-m_feedbackSize);
00093 memcpy(m_register+BlockSize()-m_feedbackSize, m_temp, m_feedbackSize);
00094 }
00095 void CipherResynchronize(const byte *iv)
00096 {
00097 memcpy(m_register, 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 class OFB_ModePolicy : public ModePolicyCommonTemplate<AdditiveCipherAbstractPolicy>
00117 {
00118 unsigned int GetBytesPerIteration() const {return BlockSize();}
00119 unsigned int GetIterationsToBuffer() const {return 1;}
00120 void WriteKeystream(byte *keystreamBuffer, unsigned int iterationCount)
00121 {
00122 assert(iterationCount == 1);
00123 m_cipher->ProcessBlock(keystreamBuffer);
00124 }
00125 void CipherResynchronize(byte *keystreamBuffer, const byte *iv)
00126 {
00127 memcpy(keystreamBuffer, iv, BlockSize());
00128 }
00129 bool IsRandomAccess() const {return false;}
00130 IV_Requirement IVRequirement() const {return STRUCTURED_IV;}
00131 };
00132
00133 class CTR_ModePolicy : public ModePolicyCommonTemplate<AdditiveCipherAbstractPolicy>
00134 {
00135 unsigned int GetBytesPerIteration() const {return BlockSize();}
00136 unsigned int GetIterationsToBuffer() const {return m_cipher->OptimalNumberOfParallelBlocks();}
00137 void WriteKeystream(byte *buffer, unsigned int iterationCount)
00138 {OperateKeystream(WRITE_KEYSTREAM, buffer, NULL, iterationCount);}
00139 bool CanOperateKeystream() const {return true;}
00140 void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, unsigned int iterationCount);
00141 void CipherResynchronize(byte *keystreamBuffer, const byte *iv);
00142 bool IsRandomAccess() const {return true;}
00143 void SeekToIteration(dword iterationCount);
00144 IV_Requirement IVRequirement() const {return STRUCTURED_IV;}
00145
00146 inline void ProcessMultipleBlocks(byte *output, const byte *input, unsigned int n);
00147
00148 SecByteBlock m_counterArray;
00149 };
00150
00151 class BlockOrientedCipherModeBase : public CipherModeBase
00152 {
00153 public:
00154 void UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length);
00155 unsigned int MandatoryBlockSize() const {return BlockSize();}
00156 bool IsRandomAccess() const {return false;}
00157 bool IsSelfInverting() const {return false;}
00158 bool IsForwardTransformation() const {return m_cipher->IsForwardTransformation();}
00159 void Resynchronize(const byte *iv) {memcpy(m_register, iv, BlockSize());}
00160 void ProcessData(byte *outString, const byte *inString, unsigned int length);
00161
00162 protected:
00163 bool RequireAlignedInput() const {return true;}
00164 virtual void ProcessBlocks(byte *outString, const byte *inString, unsigned int numberOfBlocks) =0;
00165 void ResizeBuffers()
00166 {
00167 CipherModeBase::ResizeBuffers();
00168 m_buffer.New(BlockSize());
00169 }
00170
00171 SecByteBlock m_buffer;
00172 };
00173
00174 class ECB_OneWay : public BlockOrientedCipherModeBase
00175 {
00176 public:
00177 IV_Requirement IVRequirement() const {return NOT_RESYNCHRONIZABLE;}
00178 unsigned int OptimalBlockSize() const {return BlockSize() * m_cipher->OptimalNumberOfParallelBlocks();}
00179 void ProcessBlocks(byte *outString, const byte *inString, unsigned int numberOfBlocks)
00180 {m_cipher->ProcessAndXorMultipleBlocks(inString, NULL, outString, numberOfBlocks);}
00181 };
00182
00183 class CBC_ModeBase : public BlockOrientedCipherModeBase
00184 {
00185 public:
00186 IV_Requirement IVRequirement() const {return UNPREDICTABLE_RANDOM_IV;}
00187 bool RequireAlignedInput() const {return false;}
00188 unsigned int MinLastBlockSize() const {return 0;}
00189 };
00190
00191 class CBC_Encryption : public CBC_ModeBase
00192 {
00193 public:
00194 void ProcessBlocks(byte *outString, const byte *inString, unsigned int numberOfBlocks);
00195 };
00196
00197 class CBC_CTS_Encryption : public CBC_Encryption
00198 {
00199 public:
00200 void SetStolenIV(byte *iv) {m_stolenIV = iv;}
00201 unsigned int MinLastBlockSize() const {return BlockSize()+1;}
00202 void ProcessLastBlock(byte *outString, const byte *inString, unsigned int length);
00203
00204 protected:
00205 void UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length)
00206 {
00207 CBC_Encryption::UncheckedSetKey(params, key, length);
00208 m_stolenIV = params.GetValueWithDefault(Name::StolenIV(), (byte *)NULL);
00209 }
00210
00211 byte *m_stolenIV;
00212 };
00213
00214 class CBC_Decryption : public CBC_ModeBase
00215 {
00216 public:
00217 void ProcessBlocks(byte *outString, const byte *inString, unsigned int numberOfBlocks);
00218
00219 protected:
00220 void ResizeBuffers()
00221 {
00222 BlockOrientedCipherModeBase::ResizeBuffers();
00223 m_temp.New(BlockSize());
00224 }
00225 SecByteBlock m_temp;
00226 };
00227
00228 class CBC_CTS_Decryption : public CBC_Decryption
00229 {
00230 public:
00231 unsigned int MinLastBlockSize() const {return BlockSize()+1;}
00232 void ProcessLastBlock(byte *outString, const byte *inString, unsigned int length);
00233 };
00234
00235
00236 template <class CIPHER, class BASE>
00237 class CipherModeFinalTemplate_CipherHolder : public ObjectHolder<CIPHER>, public BASE
00238 {
00239 public:
00240 CipherModeFinalTemplate_CipherHolder()
00241 {
00242 m_cipher = &m_object;
00243 ResizeBuffers();
00244 }
00245 CipherModeFinalTemplate_CipherHolder(const byte *key, unsigned int length)
00246 {
00247 m_cipher = &m_object;
00248 SetKey(key, length);
00249 }
00250 CipherModeFinalTemplate_CipherHolder(const byte *key, unsigned int length, const byte *iv, int feedbackSize = 0)
00251 {
00252 m_cipher = &m_object;
00253 SetKey(key, length, MakeParameters("IV", iv)("FeedbackSize", feedbackSize));
00254 }
00255 };
00256
00257
00258 template <class BASE>
00259 class CipherModeFinalTemplate_ExternalCipher : public BASE
00260 {
00261 public:
00262 CipherModeFinalTemplate_ExternalCipher(BlockCipher &cipher, const byte *iv = NULL, int feedbackSize = 0)
00263 {
00264 m_cipher = &cipher;
00265 ResizeBuffers();
00266 SetFeedbackSize(feedbackSize);
00267 SetIV(iv);
00268 }
00269 };
00270
00271
00272 template <class CIPHER>
00273 struct CFB_Mode : public CipherModeDocumentation
00274 {
00275 typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Encryption;
00276 typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Decryption;
00277 };
00278
00279
00280 struct CFB_Mode_ExternalCipher : public CipherModeDocumentation
00281 {
00282 typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Encryption;
00283 typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Decryption;
00284 };
00285
00286
00287 template <class CIPHER>
00288 struct OFB_Mode : public CipherModeDocumentation
00289 {
00290 typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, OFB_ModePolicy> > > > Encryption;
00291 typedef Encryption Decryption;
00292 };
00293
00294
00295 struct OFB_Mode_ExternalCipher : public CipherModeDocumentation
00296 {
00297 typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, OFB_ModePolicy> > > > Encryption;
00298 typedef Encryption Decryption;
00299 };
00300
00301
00302 template <class CIPHER>
00303 struct CTR_Mode : public CipherModeDocumentation
00304 {
00305 typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, CTR_ModePolicy> > > > Encryption;
00306 typedef Encryption Decryption;
00307 };
00308
00309
00310 struct CTR_Mode_ExternalCipher : public CipherModeDocumentation
00311 {
00312 typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, CTR_ModePolicy> > > > Encryption;
00313 typedef Encryption Decryption;
00314 };
00315
00316
00317 template <class CIPHER>
00318 struct ECB_Mode : public CipherModeDocumentation
00319 {
00320 typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ECB_OneWay> Encryption;
00321 typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Decryption, ECB_OneWay> Decryption;
00322 };
00323
00324
00325 struct ECB_Mode_ExternalCipher : public CipherModeDocumentation
00326 {
00327 typedef CipherModeFinalTemplate_ExternalCipher<ECB_OneWay> Encryption;
00328 typedef Encryption Decryption;
00329 };
00330
00331
00332 template <class CIPHER>
00333 struct CBC_Mode : public CipherModeDocumentation
00334 {
00335 typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, CBC_Encryption> Encryption;
00336 typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Decryption, CBC_Decryption> Decryption;
00337 };
00338
00339
00340 struct CBC_Mode_ExternalCipher : public CipherModeDocumentation
00341 {
00342 typedef CipherModeFinalTemplate_ExternalCipher<CBC_Encryption> Encryption;
00343 typedef CipherModeFinalTemplate_ExternalCipher<CBC_Decryption> Decryption;
00344 };
00345
00346
00347 template <class CIPHER>
00348 struct CBC_CTS_Mode : public CipherModeDocumentation
00349 {
00350 typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, CBC_CTS_Encryption> Encryption;
00351 typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Decryption, CBC_CTS_Decryption> Decryption;
00352 };
00353
00354
00355 struct CBC_CTS_Mode_ExternalCipher : public CipherModeDocumentation
00356 {
00357 typedef CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Encryption> Encryption;
00358 typedef CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Decryption> Decryption;
00359 };
00360
00361 #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
00362 typedef CFB_Mode_ExternalCipher::Encryption CFBEncryption;
00363 typedef CFB_Mode_ExternalCipher::Decryption CFBDecryption;
00364 typedef OFB_Mode_ExternalCipher::Encryption OFB;
00365 typedef CTR_Mode_ExternalCipher::Encryption CounterMode;
00366 #endif
00367
00368 NAMESPACE_END
00369
00370 #endif