00001
00002
00003 #include "pch.h"
00004
00005
00006 #if !defined(__SUNPRO_CC) || defined(CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES)
00007
00008 #ifndef CRYPTOPP_IMPORTS
00009
00010 #include "strciphr.h"
00011
00012 NAMESPACE_BEGIN(CryptoPP)
00013
00014 template <class S>
00015 void AdditiveCipherTemplate<S>::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms)
00016 {
00017 PolicyInterface &policy = this->AccessPolicy();
00018 policy.CipherSetKey(params, key, length);
00019 m_leftOver = 0;
00020 m_buffer.New(GetBufferByteSize(policy));
00021
00022 if (this->IsResynchronizable())
00023 policy.CipherResynchronize(m_buffer, this->GetIVAndThrowIfInvalid(params));
00024 }
00025
00026 template <class S>
00027 byte AdditiveCipherTemplate<S>::GenerateByte()
00028 {
00029 PolicyInterface &policy = this->AccessPolicy();
00030
00031 if (m_leftOver == 0)
00032 {
00033 policy.WriteKeystream(m_buffer, policy.GetIterationsToBuffer());
00034 m_leftOver = policy.GetBytesPerIteration();
00035 }
00036
00037 return *(KeystreamBufferEnd()-m_leftOver--);
00038 }
00039
00040 template <class S>
00041 void AdditiveCipherTemplate<S>::ProcessData(byte *outString, const byte *inString, size_t length)
00042 {
00043 if (m_leftOver > 0)
00044 {
00045 size_t len = STDMIN(m_leftOver, length);
00046 xorbuf(outString, inString, KeystreamBufferEnd()-m_leftOver, len);
00047 length -= len;
00048 m_leftOver -= len;
00049 inString += len;
00050 outString += len;
00051 }
00052
00053 if (!length)
00054 return;
00055
00056 assert(m_leftOver == 0);
00057
00058 PolicyInterface &policy = this->AccessPolicy();
00059 unsigned int bytesPerIteration = policy.GetBytesPerIteration();
00060 unsigned int alignment = policy.GetAlignment();
00061
00062 if (policy.CanOperateKeystream() && length >= bytesPerIteration && IsAlignedOn(outString, alignment))
00063 {
00064 if (IsAlignedOn(inString, alignment))
00065 policy.OperateKeystream(XOR_KEYSTREAM, outString, inString, length / bytesPerIteration);
00066 else
00067 {
00068 memcpy(outString, inString, length);
00069 policy.OperateKeystream(XOR_KEYSTREAM_INPLACE, outString, outString, length / bytesPerIteration);
00070 }
00071 inString += length - length % bytesPerIteration;
00072 outString += length - length % bytesPerIteration;
00073 length %= bytesPerIteration;
00074
00075 if (!length)
00076 return;
00077 }
00078
00079 unsigned int bufferByteSize = GetBufferByteSize(policy);
00080 unsigned int bufferIterations = policy.GetIterationsToBuffer();
00081
00082 while (length >= bufferByteSize)
00083 {
00084 policy.WriteKeystream(m_buffer, bufferIterations);
00085 xorbuf(outString, inString, KeystreamBufferBegin(), bufferByteSize);
00086 length -= bufferByteSize;
00087 inString += bufferByteSize;
00088 outString += bufferByteSize;
00089 }
00090
00091 if (length > 0)
00092 {
00093 policy.WriteKeystream(m_buffer, bufferIterations);
00094 xorbuf(outString, inString, KeystreamBufferBegin(), length);
00095 m_leftOver = bytesPerIteration - length;
00096 }
00097 }
00098
00099 template <class S>
00100 void AdditiveCipherTemplate<S>::Resynchronize(const byte *iv)
00101 {
00102 PolicyInterface &policy = this->AccessPolicy();
00103 m_leftOver = 0;
00104 m_buffer.New(GetBufferByteSize(policy));
00105 policy.CipherResynchronize(m_buffer, iv);
00106 }
00107
00108 template <class BASE>
00109 void AdditiveCipherTemplate<BASE>::Seek(lword position)
00110 {
00111 PolicyInterface &policy = this->AccessPolicy();
00112 unsigned int bytesPerIteration = policy.GetBytesPerIteration();
00113
00114 policy.SeekToIteration(position / bytesPerIteration);
00115 position %= bytesPerIteration;
00116
00117 if (position > 0)
00118 {
00119 policy.WriteKeystream(m_buffer, 1);
00120 m_leftOver = bytesPerIteration - (unsigned int)position;
00121 }
00122 else
00123 m_leftOver = 0;
00124 }
00125
00126 template <class BASE>
00127 void CFB_CipherTemplate<BASE>::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms)
00128 {
00129 PolicyInterface &policy = this->AccessPolicy();
00130 policy.CipherSetKey(params, key, length);
00131
00132 if (this->IsResynchronizable())
00133 policy.CipherResynchronize(this->GetIVAndThrowIfInvalid(params));
00134
00135 m_leftOver = policy.GetBytesPerIteration();
00136 }
00137
00138 template <class BASE>
00139 void CFB_CipherTemplate<BASE>::Resynchronize(const byte *iv)
00140 {
00141 PolicyInterface &policy = this->AccessPolicy();
00142 policy.CipherResynchronize(iv);
00143 m_leftOver = policy.GetBytesPerIteration();
00144 }
00145
00146 template <class BASE>
00147 void CFB_CipherTemplate<BASE>::ProcessData(byte *outString, const byte *inString, size_t length)
00148 {
00149 assert(length % this->MandatoryBlockSize() == 0);
00150
00151 PolicyInterface &policy = this->AccessPolicy();
00152 unsigned int bytesPerIteration = policy.GetBytesPerIteration();
00153 unsigned int alignment = policy.GetAlignment();
00154 byte *reg = policy.GetRegisterBegin();
00155
00156 if (m_leftOver)
00157 {
00158 size_t len = STDMIN(m_leftOver, length);
00159 CombineMessageAndShiftRegister(outString, reg + bytesPerIteration - m_leftOver, inString, len);
00160 m_leftOver -= len;
00161 length -= len;
00162 inString += len;
00163 outString += len;
00164 }
00165
00166 if (!length)
00167 return;
00168
00169 assert(m_leftOver == 0);
00170
00171 if (policy.CanIterate() && length >= bytesPerIteration && IsAlignedOn(outString, alignment))
00172 {
00173 if (IsAlignedOn(inString, alignment))
00174 policy.Iterate(outString, inString, GetCipherDir(*this), length / bytesPerIteration);
00175 else
00176 {
00177 memcpy(outString, inString, length);
00178 policy.Iterate(outString, outString, GetCipherDir(*this), length / bytesPerIteration);
00179 }
00180 inString += length - length % bytesPerIteration;
00181 outString += length - length % bytesPerIteration;
00182 length %= bytesPerIteration;
00183 }
00184
00185 while (length >= bytesPerIteration)
00186 {
00187 policy.TransformRegister();
00188 CombineMessageAndShiftRegister(outString, reg, inString, bytesPerIteration);
00189 length -= bytesPerIteration;
00190 inString += bytesPerIteration;
00191 outString += bytesPerIteration;
00192 }
00193
00194 if (length > 0)
00195 {
00196 policy.TransformRegister();
00197 CombineMessageAndShiftRegister(outString, reg, inString, length);
00198 m_leftOver = bytesPerIteration - length;
00199 }
00200 }
00201
00202 template <class BASE>
00203 void CFB_EncryptionTemplate<BASE>::CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length)
00204 {
00205 xorbuf(reg, message, length);
00206 memcpy(output, reg, length);
00207 }
00208
00209 template <class BASE>
00210 void CFB_DecryptionTemplate<BASE>::CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length)
00211 {
00212 for (unsigned int i=0; i<length; i++)
00213 {
00214 byte b = message[i];
00215 output[i] = reg[i] ^ b;
00216 reg[i] = b;
00217 }
00218 }
00219
00220 NAMESPACE_END
00221
00222 #endif
00223
00224 #endif