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 CRYPTOPP_DLL 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 CRYPTOPP_DLL_TEMPLATE_CLASS TwoBases<SymmetricCipher, RandomNumberGenerator>;
00149 CRYPTOPP_DLL_TEMPLATE_CLASS AbstractPolicyHolder<AdditiveCipherAbstractPolicy, TwoBases<SymmetricCipher, RandomNumberGenerator> >;
00150 CRYPTOPP_DLL_TEMPLATE_CLASS AdditiveCipherTemplate<>;
00151
00152 class CRYPTOPP_DLL CFB_CipherAbstractPolicy
00153 {
00154 public:
00155 virtual unsigned int GetAlignment() const =0;
00156 virtual unsigned int GetBytesPerIteration() const =0;
00157 virtual byte * GetRegisterBegin() =0;
00158 virtual void TransformRegister() =0;
00159 virtual bool CanIterate() const {return false;}
00160 virtual void Iterate(byte *output, const byte *input, CipherDir dir, unsigned int iterationCount) {assert(false);}
00161 virtual void CipherSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length) =0;
00162 virtual void CipherResynchronize(const byte *iv) {throw NotImplemented("StreamTransformation: this object doesn't support resynchronization");}
00163 };
00164
00165 template <typename WT, unsigned int W, class BASE = CFB_CipherAbstractPolicy>
00166 struct CFB_CipherConcretePolicy : public BASE
00167 {
00168 typedef WT WordType;
00169
00170 unsigned int GetAlignment() const {return sizeof(WordType);}
00171 unsigned int GetBytesPerIteration() const {return sizeof(WordType) * W;}
00172 bool CanIterate() const {return true;}
00173 void TransformRegister() {Iterate(NULL, NULL, ENCRYPTION, 1);}
00174
00175 template <class B>
00176 struct RegisterOutput
00177 {
00178 RegisterOutput(byte *output, const byte *input, CipherDir dir)
00179 : m_output(output), m_input(input), m_dir(dir) {}
00180
00181 inline RegisterOutput& operator()(WordType ®isterWord)
00182 {
00183 assert(IsAligned<WordType>(m_output));
00184 assert(IsAligned<WordType>(m_input));
00185
00186 if (!NativeByteOrderIs(B::ToEnum()))
00187 registerWord = ByteReverse(registerWord);
00188
00189 if (m_dir == ENCRYPTION)
00190 {
00191 WordType ct = *(const WordType *)m_input ^ registerWord;
00192 registerWord = ct;
00193 *(WordType*)m_output = ct;
00194 m_input += sizeof(WordType);
00195 m_output += sizeof(WordType);
00196 }
00197 else
00198 {
00199 WordType ct = *(const WordType *)m_input;
00200 *(WordType*)m_output = registerWord ^ ct;
00201 registerWord = ct;
00202 m_input += sizeof(WordType);
00203 m_output += sizeof(WordType);
00204 }
00205
00206
00207
00208 return *this;
00209 }
00210
00211 byte *m_output;
00212 const byte *m_input;
00213 CipherDir m_dir;
00214 };
00215 };
00216
00217 template <class BASE>
00218 class CFB_CipherTemplate : public BASE
00219 {
00220 public:
00221 void ProcessData(byte *outString, const byte *inString, unsigned int length);
00222 void Resynchronize(const byte *iv);
00223 unsigned int OptimalBlockSize() const {return GetPolicy().GetBytesPerIteration();}
00224 unsigned int GetOptimalNextBlockSize() const {return m_leftOver;}
00225 unsigned int OptimalDataAlignment() const {return GetPolicy().GetAlignment();}
00226 bool IsRandomAccess() const {return false;}
00227 bool IsSelfInverting() const {return false;}
00228
00229 typedef typename BASE::PolicyInterface PolicyInterface;
00230
00231 protected:
00232 virtual void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, unsigned int length) =0;
00233
00234 void UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length);
00235
00236 unsigned int m_leftOver;
00237 };
00238
00239 template <class BASE = AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >
00240 class CFB_EncryptionTemplate : public CFB_CipherTemplate<BASE>
00241 {
00242 bool IsForwardTransformation() const {return true;}
00243 void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, unsigned int length);
00244 };
00245
00246 template <class BASE = AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >
00247 class CFB_DecryptionTemplate : public CFB_CipherTemplate<BASE>
00248 {
00249 bool IsForwardTransformation() const {return false;}
00250 void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, unsigned int length);
00251 };
00252
00253 CRYPTOPP_DLL_TEMPLATE_CLASS AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher>;
00254 CRYPTOPP_DLL_TEMPLATE_CLASS CFB_CipherTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >;
00255 CRYPTOPP_DLL_TEMPLATE_CLASS CFB_EncryptionTemplate<>;
00256 CRYPTOPP_DLL_TEMPLATE_CLASS CFB_DecryptionTemplate<>;
00257
00258 template <class BASE, class INFO = BASE>
00259 class SymmetricCipherFinalTemplate : public AlgorithmImpl<SimpleKeyingInterfaceImpl<BASE, INFO>, INFO>
00260 {
00261 public:
00262 SymmetricCipherFinalTemplate() {}
00263 SymmetricCipherFinalTemplate(const byte *key)
00264 {SetKey(key, DEFAULT_KEYLENGTH);}
00265 SymmetricCipherFinalTemplate(const byte *key, unsigned int length)
00266 {SetKey(key, length);}
00267 SymmetricCipherFinalTemplate(const byte *key, unsigned int length, const byte *iv)
00268 {SetKey(key, length); Resynchronize(iv);}
00269
00270 void SetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms = g_nullNameValuePairs)
00271 {
00272 ThrowIfInvalidKeyLength(length);
00273 UncheckedSetKey(params, key, length);
00274 }
00275
00276 Clonable * Clone() {return new SymmetricCipherFinalTemplate<BASE, INFO>(*this);}
00277 };
00278
00279 template <class S>
00280 void AdditiveCipherTemplate<S>::UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length)
00281 {
00282 PolicyInterface &policy = AccessPolicy();
00283 policy.CipherSetKey(params, key, length);
00284 m_buffer.New(GetBufferByteSize(policy));
00285 m_leftOver = 0;
00286 }
00287
00288 template <class BASE>
00289 void CFB_CipherTemplate<BASE>::UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length)
00290 {
00291 PolicyInterface &policy = AccessPolicy();
00292 policy.CipherSetKey(params, key, length);
00293 m_leftOver = policy.GetBytesPerIteration();
00294 }
00295
00296 NAMESPACE_END
00297
00298 #endif