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