00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
#ifndef CRYPTOPP_STRCIPHR_H
00029
#define CRYPTOPP_STRCIPHR_H
00030
00031
#include "seckey.h"
00032
#include "secblock.h"
00033
#include "argnames.h"
00034
00035 NAMESPACE_BEGIN(CryptoPP)
00036
00037 template <class POLICY_INTERFACE, class BASE = Empty>
00038 class CRYPTOPP_NO_VTABLE AbstractPolicyHolder : public BASE
00039 {
00040
public:
00041
typedef POLICY_INTERFACE PolicyInterface;
00042
00043
protected:
00044
virtual const POLICY_INTERFACE & GetPolicy() const =0;
00045 virtual POLICY_INTERFACE & AccessPolicy() =0;
00046 };
00047
00048 template <class POLICY, class BASE, class POLICY_INTERFACE = CPP_TYPENAME BASE::PolicyInterface>
00049 class ConcretePolicyHolder : public BASE, protected POLICY
00050 {
00051
protected:
00052
const POLICY_INTERFACE & GetPolicy()
const {
return *
this;}
00053 POLICY_INTERFACE & AccessPolicy() {
return *
this;}
00054 };
00055
00056
enum KeystreamOperation {WRITE_KEYSTREAM, XOR_KEYSTREAM, XOR_KEYSTREAM_INPLACE};
00057
00058
struct CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AdditiveCipherAbstractPolicy
00059 {
00060
virtual unsigned int GetAlignment() const =0;
00061 virtual
unsigned int GetBytesPerIteration() const =0;
00062 virtual
unsigned int GetIterationsToBuffer() const =0;
00063 virtual
void WriteKeystream(byte *keystreamBuffer,
unsigned int iterationCount) =0;
00064 virtual
bool CanOperateKeystream()
const {
return false;}
00065
virtual void OperateKeystream(KeystreamOperation operation, byte *output,
const byte *input,
unsigned int iterationCount) {assert(
false);}
00066
virtual void CipherSetKey(
const NameValuePairs ¶ms,
const byte *key,
unsigned int length) =0;
00067
virtual void CipherResynchronize(byte *keystreamBuffer,
const byte *iv) {
throw NotImplemented(
"StreamTransformation: this object doesn't support resynchronization");}
00068
virtual bool IsRandomAccess() const =0;
00069 virtual
void SeekToIteration(lword iterationCount) {assert(!IsRandomAccess());
throw NotImplemented(
"StreamTransformation: this object doesn't support random access");}
00070 };
00071
00072
template <
typename WT,
unsigned int W,
unsigned int X = 1,
class BASE = AdditiveCipherAbstractPolicy>
00073
struct CRYPTOPP_NO_VTABLE AdditiveCipherConcretePolicy :
public BASE
00074 {
00075
typedef WT WordType;
00076
00077
unsigned int GetAlignment()
const {
return sizeof(WordType);}
00078
unsigned int GetBytesPerIteration()
const {
return sizeof(WordType) * W;}
00079
unsigned int GetIterationsToBuffer()
const {
return X;}
00080
void WriteKeystream(byte *buffer,
unsigned int iterationCount)
00081 {OperateKeystream(WRITE_KEYSTREAM, buffer, NULL, iterationCount);}
00082
bool CanOperateKeystream()
const {
return true;}
00083
virtual void OperateKeystream(KeystreamOperation operation, byte *output,
const byte *input,
unsigned int iterationCount) =0;
00084
00085
template <
class B>
00086
struct KeystreamOutput
00087 {
00088 KeystreamOutput(KeystreamOperation operation, byte *output,
const byte *input)
00089 : m_operation(operation), m_output(output), m_input(input) {}
00090
00091
inline KeystreamOutput & operator()(WordType keystreamWord)
00092 {
00093 assert(IsAligned<WordType>(m_input));
00094 assert(IsAligned<WordType>(m_output));
00095
00096
if (!NativeByteOrderIs(B::ToEnum()))
00097 keystreamWord = ByteReverse(keystreamWord);
00098
00099
if (m_operation == WRITE_KEYSTREAM)
00100 *(WordType*)m_output = keystreamWord;
00101
else if (m_operation == XOR_KEYSTREAM)
00102 {
00103 *(WordType*)m_output = keystreamWord ^ *(WordType*)m_input;
00104 m_input +=
sizeof(WordType);
00105 }
00106
else if (m_operation == XOR_KEYSTREAM_INPLACE)
00107 *(WordType*)m_output ^= keystreamWord;
00108
00109 m_output +=
sizeof(WordType);
00110
00111
return *
this;
00112 }
00113
00114 KeystreamOperation m_operation;
00115 byte *m_output;
00116
const byte *m_input;
00117 };
00118 };
00119
00120
template <
class BASE = AbstractPolicyHolder<AdditiveCipherAbstractPolicy, TwoBases<SymmetricCipher, RandomNumberGenerator> > >
00121
class CRYPTOPP_NO_VTABLE AdditiveCipherTemplate :
public BASE
00122 {
00123
public:
00124 byte GenerateByte();
00125
void ProcessData(byte *outString,
const byte *inString,
unsigned int length);
00126
void Resynchronize(
const byte *iv);
00127
unsigned int OptimalBlockSize()
const {
return this->GetPolicy().GetBytesPerIteration();}
00128
unsigned int GetOptimalNextBlockSize()
const {
return this->m_leftOver;}
00129
unsigned int OptimalDataAlignment()
const {
return this->GetPolicy().GetAlignment();}
00130
bool IsSelfInverting()
const {
return true;}
00131
bool IsForwardTransformation()
const {
return true;}
00132
bool IsRandomAccess()
const {
return this->GetPolicy().IsRandomAccess();}
00133
void Seek(lword position);
00134
00135
typedef typename BASE::PolicyInterface PolicyInterface;
00136
00137
protected:
00138
void UncheckedSetKey(
const NameValuePairs ¶ms,
const byte *key,
unsigned int length,
const byte *iv);
00139
00140
unsigned int GetBufferByteSize(
const PolicyInterface &policy)
const {
return policy.GetBytesPerIteration() * policy.GetIterationsToBuffer();}
00141
00142
inline byte * KeystreamBufferBegin() {
return this->m_buffer.data();}
00143
inline byte * KeystreamBufferEnd() {
return (this->m_buffer.data() + this->m_buffer.size());}
00144
00145
SecByteBlock m_buffer;
00146
unsigned int m_leftOver;
00147 };
00148
00149 CRYPTOPP_DLL_TEMPLATE_CLASS
TwoBases<SymmetricCipher, RandomNumberGenerator>;
00150 CRYPTOPP_DLL_TEMPLATE_CLASS AbstractPolicyHolder<AdditiveCipherAbstractPolicy, TwoBases<SymmetricCipher, RandomNumberGenerator> >;
00151 CRYPTOPP_DLL_TEMPLATE_CLASS AdditiveCipherTemplate<>;
00152
00153
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CFB_CipherAbstractPolicy
00154 {
00155
public:
00156
virtual unsigned int GetAlignment() const =0;
00157 virtual
unsigned int GetBytesPerIteration() const =0;
00158 virtual byte * GetRegisterBegin() =0;
00159 virtual
void TransformRegister() =0;
00160 virtual
bool CanIterate()
const {
return false;}
00161
virtual void Iterate(byte *output,
const byte *input, CipherDir dir,
unsigned int iterationCount) {assert(
false);}
00162
virtual void CipherSetKey(
const NameValuePairs ¶ms,
const byte *key,
unsigned int length) =0;
00163
virtual void CipherResynchronize(
const byte *iv) {
throw NotImplemented(
"StreamTransformation: this object doesn't support resynchronization");}
00164 };
00165
00166
template <
typename WT,
unsigned int W,
class BASE = CFB_CipherAbstractPolicy>
00167
struct CRYPTOPP_NO_VTABLE CFB_CipherConcretePolicy :
public BASE
00168 {
00169
typedef WT WordType;
00170
00171
unsigned int GetAlignment()
const {
return sizeof(WordType);}
00172
unsigned int GetBytesPerIteration()
const {
return sizeof(WordType) * W;}
00173
bool CanIterate()
const {
return true;}
00174
void TransformRegister() {this->Iterate(NULL, NULL, ENCRYPTION, 1);}
00175
00176
template <
class B>
00177
struct RegisterOutput
00178 {
00179 RegisterOutput(byte *output,
const byte *input, CipherDir dir)
00180 : m_output(output), m_input(input), m_dir(dir) {}
00181
00182
inline RegisterOutput& operator()(WordType ®isterWord)
00183 {
00184 assert(IsAligned<WordType>(m_output));
00185 assert(IsAligned<WordType>(m_input));
00186
00187
if (!NativeByteOrderIs(B::ToEnum()))
00188 registerWord = ByteReverse(registerWord);
00189
00190
if (m_dir == ENCRYPTION)
00191 {
00192 WordType ct = *(
const WordType *)m_input ^ registerWord;
00193 registerWord = ct;
00194 *(WordType*)m_output = ct;
00195 m_input +=
sizeof(WordType);
00196 m_output +=
sizeof(WordType);
00197 }
00198
else
00199 {
00200 WordType ct = *(
const WordType *)m_input;
00201 *(WordType*)m_output = registerWord ^ ct;
00202 registerWord = ct;
00203 m_input +=
sizeof(WordType);
00204 m_output +=
sizeof(WordType);
00205 }
00206
00207
00208
00209
return *
this;
00210 }
00211
00212 byte *m_output;
00213
const byte *m_input;
00214
CipherDir m_dir;
00215 };
00216 };
00217
00218
template <
class BASE>
00219
class CRYPTOPP_NO_VTABLE CFB_CipherTemplate :
public BASE
00220 {
00221
public:
00222
void ProcessData(byte *outString,
const byte *inString,
unsigned int length);
00223
void Resynchronize(
const byte *iv);
00224
unsigned int OptimalBlockSize()
const {
return this->GetPolicy().GetBytesPerIteration();}
00225
unsigned int GetOptimalNextBlockSize()
const {
return m_leftOver;}
00226
unsigned int OptimalDataAlignment()
const {
return this->GetPolicy().GetAlignment();}
00227
bool IsRandomAccess()
const {
return false;}
00228
bool IsSelfInverting()
const {
return false;}
00229
00230
typedef typename BASE::PolicyInterface PolicyInterface;
00231
00232
protected:
00233
virtual void CombineMessageAndShiftRegister(byte *output, byte *reg,
const byte *message,
unsigned int length) =0;
00234
00235
void UncheckedSetKey(
const NameValuePairs ¶ms,
const byte *key,
unsigned int length,
const byte *iv);
00236
00237
unsigned int m_leftOver;
00238 };
00239
00240
template <
class BASE = AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >
00241
class CRYPTOPP_NO_VTABLE CFB_EncryptionTemplate :
public CFB_CipherTemplate<BASE>
00242 {
00243
bool IsForwardTransformation()
const {
return true;}
00244
void CombineMessageAndShiftRegister(byte *output, byte *reg,
const byte *message,
unsigned int length);
00245 };
00246
00247
template <
class BASE = AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >
00248
class CRYPTOPP_NO_VTABLE CFB_DecryptionTemplate :
public CFB_CipherTemplate<BASE>
00249 {
00250
bool IsForwardTransformation()
const {
return false;}
00251
void CombineMessageAndShiftRegister(byte *output, byte *reg,
const byte *message,
unsigned int length);
00252 };
00253
00254
template <
class BASE>
00255
class CFB_RequireFullDataBlocks :
public BASE
00256 {
00257
public:
00258
unsigned int MandatoryBlockSize()
const {
return this->OptimalBlockSize();}
00259 };
00260
00261
00262 CRYPTOPP_DLL_TEMPLATE_CLASS CFB_CipherTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >;
00263 CRYPTOPP_DLL_TEMPLATE_CLASS CFB_EncryptionTemplate<>;
00264 CRYPTOPP_DLL_TEMPLATE_CLASS CFB_DecryptionTemplate<>;
00265
00266
00267
template <
class BASE,
class INFO = BASE>
00268
class SymmetricCipherFinal :
public AlgorithmImpl<SimpleKeyingInterfaceImpl<BASE, INFO>, INFO>
00269 {
00270
public:
00271
SymmetricCipherFinal() {}
00272
SymmetricCipherFinal(
const byte *key)
00273 {SetKey(key, this->DEFAULT_KEYLENGTH);}
00274
SymmetricCipherFinal(
const byte *key,
unsigned int length)
00275 {SetKey(key, length);}
00276
SymmetricCipherFinal(
const byte *key,
unsigned int length,
const byte *iv)
00277 {this->SetKeyWithIV(key, length, iv);}
00278
00279
void SetKey(
const byte *key,
unsigned int length,
const NameValuePairs ¶ms = g_nullNameValuePairs)
00280 {
00281 this->ThrowIfInvalidKeyLength(length);
00282 this->UncheckedSetKey(params, key, length, this->GetIVAndThrowIfInvalid(params));
00283 }
00284
00285
Clonable * Clone()
const {
return static_cast<SymmetricCipher *>(
new SymmetricCipherFinal<BASE, INFO>(*this));}
00286 };
00287
00288
template <
class S>
00289
void AdditiveCipherTemplate<S>::UncheckedSetKey(
const NameValuePairs ¶ms,
const byte *key,
unsigned int length,
const byte *iv)
00290 {
00291 PolicyInterface &policy = this->AccessPolicy();
00292 policy.CipherSetKey(params, key, length);
00293 m_leftOver = 0;
00294 m_buffer.New(GetBufferByteSize(policy));
00295
00296
if (this->IsResynchronizable())
00297 policy.CipherResynchronize(m_buffer, iv);
00298 }
00299
00300
template <
class BASE>
00301
void CFB_CipherTemplate<BASE>::UncheckedSetKey(
const NameValuePairs ¶ms,
const byte *key,
unsigned int length,
const byte *iv)
00302 {
00303 PolicyInterface &policy = this->AccessPolicy();
00304 policy.CipherSetKey(params, key, length);
00305
00306
if (this->IsResynchronizable())
00307 policy.CipherResynchronize(iv);
00308
00309 m_leftOver = policy.GetBytesPerIteration();
00310 }
00311
00312 NAMESPACE_END
00313
00314
#endif