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