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