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