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 KeystreamOperationFlags {OUTPUT_ALIGNED=1, INPUT_ALIGNED=2, INPUT_NULL = 4};
00057 enum KeystreamOperation {
00058 WRITE_KEYSTREAM = INPUT_NULL,
00059 WRITE_KEYSTREAM_ALIGNED = INPUT_NULL | OUTPUT_ALIGNED,
00060 XOR_KEYSTREAM = 0,
00061 XOR_KEYSTREAM_INPUT_ALIGNED = INPUT_ALIGNED,
00062 XOR_KEYSTREAM_OUTPUT_ALIGNED= OUTPUT_ALIGNED,
00063 XOR_KEYSTREAM_BOTH_ALIGNED = OUTPUT_ALIGNED | INPUT_ALIGNED};
00064
00065 struct CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AdditiveCipherAbstractPolicy
00066 {
00067 virtual unsigned int GetAlignment() const {return 1;}
00068 virtual unsigned int GetBytesPerIteration() const =0;
00069 virtual unsigned int GetOptimalBlockSize() const {return GetBytesPerIteration();}
00070 virtual unsigned int GetIterationsToBuffer() const =0;
00071 virtual void WriteKeystream(byte *keystream, size_t iterationCount)
00072 {OperateKeystream(KeystreamOperation(INPUT_NULL | (KeystreamOperationFlags)IsAlignedOn(keystream, GetAlignment())), keystream, NULL, iterationCount);}
00073 virtual bool CanOperateKeystream() const {return false;}
00074 virtual void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) {assert(false);}
00075 virtual void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length) =0;
00076 virtual void CipherResynchronize(byte *keystreamBuffer, const byte *iv) {throw NotImplemented("SimpleKeyingInterface: this object doesn't support resynchronization");}
00077 virtual bool IsRandomAccess() const =0;
00078 virtual void SeekToIteration(lword iterationCount) {assert(!IsRandomAccess()); throw NotImplemented("StreamTransformation: this object doesn't support random access");}
00079 };
00080
00081 template <typename WT, unsigned int W, unsigned int X = 1, class BASE = AdditiveCipherAbstractPolicy>
00082 struct CRYPTOPP_NO_VTABLE AdditiveCipherConcretePolicy : public BASE
00083 {
00084 typedef WT WordType;
00085 CRYPTOPP_CONSTANT(BYTES_PER_ITERATION = sizeof(WordType) * W)
00086
00087 #if !(CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X64)
00088 unsigned int GetAlignment() const {return GetAlignmentOf<WordType>();}
00089 #endif
00090 unsigned int GetBytesPerIteration() const {return BYTES_PER_ITERATION;}
00091 unsigned int GetIterationsToBuffer() const {return X;}
00092 bool CanOperateKeystream() const {return true;}
00093 virtual void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) =0;
00094 };
00095
00096
00097 #define CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, b, i, a) \
00098 PutWord(bool(x & OUTPUT_ALIGNED), b, output+i*sizeof(WordType), (x & INPUT_NULL) ? a : a ^ GetWord<WordType>(bool(x & INPUT_ALIGNED), b, input+i*sizeof(WordType)));
00099 #define CRYPTOPP_KEYSTREAM_OUTPUT_XMM(x, i, a) {\
00100 __m128i t = (x & INPUT_NULL) ? a : _mm_xor_si128(a, (x & INPUT_ALIGNED) ? _mm_load_si128((__m128i *)input+i) : _mm_loadu_si128((__m128i *)input+i));\
00101 if (x & OUTPUT_ALIGNED) _mm_store_si128((__m128i *)output+i, t);\
00102 else _mm_storeu_si128((__m128i *)output+i, t);}
00103 #define CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(x, y) \
00104 switch (operation) \
00105 { \
00106 case WRITE_KEYSTREAM: \
00107 x(WRITE_KEYSTREAM) \
00108 break; \
00109 case XOR_KEYSTREAM: \
00110 x(XOR_KEYSTREAM) \
00111 input += y; \
00112 break; \
00113 case XOR_KEYSTREAM_INPUT_ALIGNED: \
00114 x(XOR_KEYSTREAM_INPUT_ALIGNED) \
00115 input += y; \
00116 break; \
00117 case XOR_KEYSTREAM_OUTPUT_ALIGNED: \
00118 x(XOR_KEYSTREAM_OUTPUT_ALIGNED) \
00119 input += y; \
00120 break; \
00121 case WRITE_KEYSTREAM_ALIGNED: \
00122 x(WRITE_KEYSTREAM_ALIGNED) \
00123 break; \
00124 case XOR_KEYSTREAM_BOTH_ALIGNED: \
00125 x(XOR_KEYSTREAM_BOTH_ALIGNED) \
00126 input += y; \
00127 break; \
00128 } \
00129 output += y;
00130
00131 template <class BASE = AbstractPolicyHolder<AdditiveCipherAbstractPolicy, TwoBases<SymmetricCipher, RandomNumberGenerator> > >
00132 class CRYPTOPP_NO_VTABLE AdditiveCipherTemplate : public BASE
00133 {
00134 public:
00135 void GenerateBlock(byte *output, size_t size);
00136 void ProcessData(byte *outString, const byte *inString, size_t length);
00137 void Resynchronize(const byte *iv);
00138 unsigned int OptimalBlockSize() const {return this->GetPolicy().GetOptimalBlockSize();}
00139 unsigned int GetOptimalNextBlockSize() const {return (unsigned int)this->m_leftOver;}
00140 unsigned int OptimalDataAlignment() const {return this->GetPolicy().GetAlignment();}
00141 bool IsSelfInverting() const {return true;}
00142 bool IsForwardTransformation() const {return true;}
00143 bool IsRandomAccess() const {return this->GetPolicy().IsRandomAccess();}
00144 void Seek(lword position);
00145
00146 typedef typename BASE::PolicyInterface PolicyInterface;
00147
00148 protected:
00149 void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms);
00150
00151 unsigned int GetBufferByteSize(const PolicyInterface &policy) const {return policy.GetBytesPerIteration() * policy.GetIterationsToBuffer();}
00152
00153 inline byte * KeystreamBufferBegin() {return this->m_buffer.data();}
00154 inline byte * KeystreamBufferEnd() {return (this->m_buffer.data() + this->m_buffer.size());}
00155
00156 SecByteBlock m_buffer;
00157 size_t m_leftOver;
00158 };
00159
00160 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CFB_CipherAbstractPolicy
00161 {
00162 public:
00163 virtual unsigned int GetAlignment() const =0;
00164 virtual unsigned int GetBytesPerIteration() const =0;
00165 virtual byte * GetRegisterBegin() =0;
00166 virtual void TransformRegister() =0;
00167 virtual bool CanIterate() const {return false;}
00168 virtual void Iterate(byte *output, const byte *input, CipherDir dir, size_t iterationCount) {assert(false);}
00169 virtual void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length) =0;
00170 virtual void CipherResynchronize(const byte *iv) {throw NotImplemented("SimpleKeyingInterface: this object doesn't support resynchronization");}
00171 };
00172
00173 template <typename WT, unsigned int W, class BASE = CFB_CipherAbstractPolicy>
00174 struct CRYPTOPP_NO_VTABLE CFB_CipherConcretePolicy : public BASE
00175 {
00176 typedef WT WordType;
00177
00178 unsigned int GetAlignment() const {return sizeof(WordType);}
00179 unsigned int GetBytesPerIteration() const {return sizeof(WordType) * W;}
00180 bool CanIterate() const {return true;}
00181 void TransformRegister() {this->Iterate(NULL, NULL, ENCRYPTION, 1);}
00182
00183 template <class B>
00184 struct RegisterOutput
00185 {
00186 RegisterOutput(byte *output, const byte *input, CipherDir dir)
00187 : m_output(output), m_input(input), m_dir(dir) {}
00188
00189 inline RegisterOutput& operator()(WordType ®isterWord)
00190 {
00191 assert(IsAligned<WordType>(m_output));
00192 assert(IsAligned<WordType>(m_input));
00193
00194 if (!NativeByteOrderIs(B::ToEnum()))
00195 registerWord = ByteReverse(registerWord);
00196
00197 if (m_dir == ENCRYPTION)
00198 {
00199 if (m_input == NULL)
00200 assert(m_output == NULL);
00201 else
00202 {
00203 WordType ct = *(const WordType *)m_input ^ registerWord;
00204 registerWord = ct;
00205 *(WordType*)m_output = ct;
00206 m_input += sizeof(WordType);
00207 m_output += sizeof(WordType);
00208 }
00209 }
00210 else
00211 {
00212 WordType ct = *(const WordType *)m_input;
00213 *(WordType*)m_output = registerWord ^ ct;
00214 registerWord = ct;
00215 m_input += sizeof(WordType);
00216 m_output += sizeof(WordType);
00217 }
00218
00219
00220
00221 return *this;
00222 }
00223
00224 byte *m_output;
00225 const byte *m_input;
00226 CipherDir m_dir;
00227 };
00228 };
00229
00230 template <class BASE>
00231 class CRYPTOPP_NO_VTABLE CFB_CipherTemplate : public BASE
00232 {
00233 public:
00234 void ProcessData(byte *outString, const byte *inString, size_t length);
00235 void Resynchronize(const byte *iv);
00236 unsigned int OptimalBlockSize() const {return this->GetPolicy().GetBytesPerIteration();}
00237 unsigned int GetOptimalNextBlockSize() const {return (unsigned int)m_leftOver;}
00238 unsigned int OptimalDataAlignment() const {return this->GetPolicy().GetAlignment();}
00239 bool IsRandomAccess() const {return false;}
00240 bool IsSelfInverting() const {return false;}
00241
00242 typedef typename BASE::PolicyInterface PolicyInterface;
00243
00244 protected:
00245 virtual void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length) =0;
00246
00247 void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms);
00248
00249 size_t m_leftOver;
00250 };
00251
00252 template <class BASE = AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >
00253 class CRYPTOPP_NO_VTABLE CFB_EncryptionTemplate : public CFB_CipherTemplate<BASE>
00254 {
00255 bool IsForwardTransformation() const {return true;}
00256 void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length);
00257 };
00258
00259 template <class BASE = AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >
00260 class CRYPTOPP_NO_VTABLE CFB_DecryptionTemplate : public CFB_CipherTemplate<BASE>
00261 {
00262 bool IsForwardTransformation() const {return false;}
00263 void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length);
00264 };
00265
00266 template <class BASE>
00267 class CFB_RequireFullDataBlocks : public BASE
00268 {
00269 public:
00270 unsigned int MandatoryBlockSize() const {return this->OptimalBlockSize();}
00271 };
00272
00273
00274 template <class BASE, class INFO = BASE>
00275 class SymmetricCipherFinal : public AlgorithmImpl<SimpleKeyingInterfaceImpl<BASE, INFO>, INFO>
00276 {
00277 public:
00278 SymmetricCipherFinal() {}
00279 SymmetricCipherFinal(const byte *key)
00280 {this->SetKey(key, this->DEFAULT_KEYLENGTH);}
00281 SymmetricCipherFinal(const byte *key, size_t length)
00282 {this->SetKey(key, length);}
00283 SymmetricCipherFinal(const byte *key, size_t length, const byte *iv)
00284 {this->SetKeyWithIV(key, length, iv);}
00285
00286 Clonable * Clone() const {return static_cast<SymmetricCipher *>(new SymmetricCipherFinal<BASE, INFO>(*this));}
00287 };
00288
00289 NAMESPACE_END
00290
00291 #ifdef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES
00292 #include "strciphr.cpp"
00293 #endif
00294
00295 NAMESPACE_BEGIN(CryptoPP)
00296 CRYPTOPP_DLL_TEMPLATE_CLASS TwoBases<SymmetricCipher, RandomNumberGenerator>;
00297 CRYPTOPP_DLL_TEMPLATE_CLASS AbstractPolicyHolder<AdditiveCipherAbstractPolicy, TwoBases<SymmetricCipher, RandomNumberGenerator> >;
00298 CRYPTOPP_DLL_TEMPLATE_CLASS AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, TwoBases<SymmetricCipher, RandomNumberGenerator> > >;
00299 CRYPTOPP_DLL_TEMPLATE_CLASS CFB_CipherTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >;
00300 CRYPTOPP_DLL_TEMPLATE_CLASS CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >;
00301 CRYPTOPP_DLL_TEMPLATE_CLASS CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >;
00302 NAMESPACE_END
00303
00304 #endif