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 CipherGetNextIV(byte *iv) {throw NotImplemented("SimpleKeyingInterface: this object doesn't support GetNextIV()");}
00068 virtual void CipherResynchronize(byte *keystreamBuffer, const byte *iv) {throw NotImplemented("SimpleKeyingInterface: this object doesn't support resynchronization");}
00069 virtual bool IsRandomAccess() const =0;
00070 virtual void SeekToIteration(lword iterationCount) {assert(!IsRandomAccess()); throw NotImplemented("StreamTransformation: this object doesn't support random access");}
00071 };
00072
00073 template <typename WT, unsigned int W, unsigned int X = 1, class BASE = AdditiveCipherAbstractPolicy>
00074 struct CRYPTOPP_NO_VTABLE AdditiveCipherConcretePolicy : public BASE
00075 {
00076 typedef WT WordType;
00077
00078 unsigned int GetAlignment() const {return sizeof(WordType);}
00079 unsigned int GetBytesPerIteration() const {return sizeof(WordType) * W;}
00080 unsigned int GetIterationsToBuffer() const {return X;}
00081 void WriteKeystream(byte *buffer, size_t iterationCount)
00082 {OperateKeystream(WRITE_KEYSTREAM, buffer, NULL, iterationCount);}
00083 bool CanOperateKeystream() const {return true;}
00084 virtual void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) =0;
00085
00086 template <class B>
00087 struct KeystreamOutput
00088 {
00089 KeystreamOutput(KeystreamOperation operation, byte *output, const byte *input)
00090 : m_operation(operation), m_output(output), m_input(input) {}
00091
00092 inline KeystreamOutput & operator()(WordType keystreamWord)
00093 {
00094 assert(IsAligned<WordType>(m_input));
00095 assert(IsAligned<WordType>(m_output));
00096
00097 if (!NativeByteOrderIs(B::ToEnum()))
00098 keystreamWord = ByteReverse(keystreamWord);
00099
00100 if (m_operation == WRITE_KEYSTREAM)
00101 *(WordType*)m_output = keystreamWord;
00102 else if (m_operation == XOR_KEYSTREAM)
00103 {
00104 *(WordType*)m_output = keystreamWord ^ *(WordType*)m_input;
00105 m_input += sizeof(WordType);
00106 }
00107 else if (m_operation == XOR_KEYSTREAM_INPLACE)
00108 *(WordType*)m_output ^= keystreamWord;
00109
00110 m_output += sizeof(WordType);
00111
00112 return *this;
00113 }
00114
00115 KeystreamOperation m_operation;
00116 byte *m_output;
00117 const byte *m_input;
00118 };
00119 };
00120
00121 template <class BASE = AbstractPolicyHolder<AdditiveCipherAbstractPolicy, TwoBases<SymmetricCipher, RandomNumberGenerator> > >
00122 class CRYPTOPP_NO_VTABLE AdditiveCipherTemplate : public BASE
00123 {
00124 public:
00125 byte GenerateByte();
00126 void ProcessData(byte *outString, const byte *inString, size_t length);
00127 void GetNextIV(byte *iv) {this->AccessPolicy().CipherGetNextIV(iv);}
00128 void Resynchronize(const byte *iv);
00129 unsigned int OptimalBlockSize() const {return this->GetPolicy().GetBytesPerIteration();}
00130 unsigned int GetOptimalNextBlockSize() const {return (unsigned int)this->m_leftOver;}
00131 unsigned int OptimalDataAlignment() const {return this->GetPolicy().GetAlignment();}
00132 bool IsSelfInverting() const {return true;}
00133 bool IsForwardTransformation() const {return true;}
00134 bool IsRandomAccess() const {return this->GetPolicy().IsRandomAccess();}
00135 void Seek(lword position);
00136
00137 typedef typename BASE::PolicyInterface PolicyInterface;
00138
00139 protected:
00140 void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms);
00141
00142 unsigned int GetBufferByteSize(const PolicyInterface &policy) const {return policy.GetBytesPerIteration() * policy.GetIterationsToBuffer();}
00143
00144 inline byte * KeystreamBufferBegin() {return this->m_buffer.data();}
00145 inline byte * KeystreamBufferEnd() {return (this->m_buffer.data() + this->m_buffer.size());}
00146
00147 SecByteBlock m_buffer;
00148 size_t m_leftOver;
00149 };
00150
00151 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CFB_CipherAbstractPolicy
00152 {
00153 public:
00154 virtual unsigned int GetAlignment() const =0;
00155 virtual unsigned int GetBytesPerIteration() const =0;
00156 virtual byte * GetRegisterBegin() =0;
00157 virtual void TransformRegister() =0;
00158 virtual bool CanIterate() const {return false;}
00159 virtual void Iterate(byte *output, const byte *input, CipherDir dir, size_t iterationCount) {assert(false);}
00160 virtual void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length) =0;
00161 virtual void CipherGetNextIV(byte *iv) {throw NotImplemented("SimpleKeyingInterface: this object doesn't support GetNextIV()");}
00162 virtual void CipherResynchronize(const byte *iv) {throw NotImplemented("SimpleKeyingInterface: this object doesn't support resynchronization");}
00163 };
00164
00165 template <typename WT, unsigned int W, class BASE = CFB_CipherAbstractPolicy>
00166 struct CRYPTOPP_NO_VTABLE 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() {this->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 if (m_input == NULL)
00192 assert(m_output == NULL);
00193 else
00194 {
00195 WordType ct = *(const WordType *)m_input ^ registerWord;
00196 registerWord = ct;
00197 *(WordType*)m_output = ct;
00198 m_input += sizeof(WordType);
00199 m_output += sizeof(WordType);
00200 }
00201 }
00202 else
00203 {
00204 WordType ct = *(const WordType *)m_input;
00205 *(WordType*)m_output = registerWord ^ ct;
00206 registerWord = ct;
00207 m_input += sizeof(WordType);
00208 m_output += sizeof(WordType);
00209 }
00210
00211
00212
00213 return *this;
00214 }
00215
00216 byte *m_output;
00217 const byte *m_input;
00218 CipherDir m_dir;
00219 };
00220 };
00221
00222 template <class BASE>
00223 class CRYPTOPP_NO_VTABLE CFB_CipherTemplate : public BASE
00224 {
00225 public:
00226 void ProcessData(byte *outString, const byte *inString, size_t length);
00227 void GetNextIV(byte *iv) {this->AccessPolicy().CipherGetNextIV(iv);}
00228 void Resynchronize(const byte *iv);
00229 unsigned int OptimalBlockSize() const {return this->GetPolicy().GetBytesPerIteration();}
00230 unsigned int GetOptimalNextBlockSize() const {return (unsigned int)m_leftOver;}
00231 unsigned int OptimalDataAlignment() const {return this->GetPolicy().GetAlignment();}
00232 bool IsRandomAccess() const {return false;}
00233 bool IsSelfInverting() const {return false;}
00234
00235 typedef typename BASE::PolicyInterface PolicyInterface;
00236
00237 protected:
00238 virtual void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length) =0;
00239
00240 void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms);
00241
00242 size_t m_leftOver;
00243 };
00244
00245 template <class BASE = AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >
00246 class CRYPTOPP_NO_VTABLE CFB_EncryptionTemplate : public CFB_CipherTemplate<BASE>
00247 {
00248 bool IsForwardTransformation() const {return true;}
00249 void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length);
00250 };
00251
00252 template <class BASE = AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >
00253 class CRYPTOPP_NO_VTABLE CFB_DecryptionTemplate : public CFB_CipherTemplate<BASE>
00254 {
00255 bool IsForwardTransformation() const {return false;}
00256 void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length);
00257 };
00258
00259 template <class BASE>
00260 class CFB_RequireFullDataBlocks : public BASE
00261 {
00262 public:
00263 unsigned int MandatoryBlockSize() const {return this->OptimalBlockSize();}
00264 };
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 {this->SetKey(key, this->DEFAULT_KEYLENGTH);}
00274 SymmetricCipherFinal(const byte *key, size_t length)
00275 {this->SetKey(key, length);}
00276 SymmetricCipherFinal(const byte *key, size_t length, const byte *iv)
00277 {this->SetKeyWithIV(key, length, iv);}
00278
00279 Clonable * Clone() const {return static_cast<SymmetricCipher *>(new SymmetricCipherFinal<BASE, INFO>(*this));}
00280 };
00281
00282 NAMESPACE_END
00283
00284 #ifdef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES
00285 #include "strciphr.cpp"
00286 #endif
00287
00288 NAMESPACE_BEGIN(CryptoPP)
00289 CRYPTOPP_DLL_TEMPLATE_CLASS TwoBases<SymmetricCipher, RandomNumberGenerator>;
00290 CRYPTOPP_DLL_TEMPLATE_CLASS AbstractPolicyHolder<AdditiveCipherAbstractPolicy, TwoBases<SymmetricCipher, RandomNumberGenerator> >;
00291 CRYPTOPP_DLL_TEMPLATE_CLASS AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, TwoBases<SymmetricCipher, RandomNumberGenerator> > >;
00292 CRYPTOPP_DLL_TEMPLATE_CLASS CFB_CipherTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >;
00293 CRYPTOPP_DLL_TEMPLATE_CLASS CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >;
00294 CRYPTOPP_DLL_TEMPLATE_CLASS CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >;
00295 NAMESPACE_END
00296
00297 #endif