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 void AdditiveCipherTemplate<S>::GenerateBlock(byte *outString, size_t length)
00028 {
00029 if (m_leftOver > 0)
00030 {
00031 size_t len = STDMIN(m_leftOver, length);
00032 memcpy(outString, KeystreamBufferEnd()-m_leftOver, len);
00033 length -= len;
00034 m_leftOver -= len;
00035 outString += len;
00036
00037 if (!length)
00038 return;
00039 }
00040 assert(m_leftOver == 0);
00041
00042 PolicyInterface &policy = this->AccessPolicy();
00043 unsigned int bytesPerIteration = policy.GetBytesPerIteration();
00044
00045 if (length >= bytesPerIteration)
00046 {
00047 size_t iterations = length / bytesPerIteration;
00048 policy.WriteKeystream(outString, iterations);
00049 outString += iterations * bytesPerIteration;
00050 length -= iterations * bytesPerIteration;
00051
00052 if (!length)
00053 return;
00054 }
00055
00056 unsigned int bufferByteSize = GetBufferByteSize(policy);
00057 unsigned int bufferIterations = policy.GetIterationsToBuffer();
00058
00059 while (length >= bufferByteSize)
00060 {
00061 policy.WriteKeystream(m_buffer, bufferIterations);
00062 memcpy(outString, KeystreamBufferBegin(), bufferByteSize);
00063 length -= bufferByteSize;
00064 outString += bufferByteSize;
00065 }
00066
00067 if (length > 0)
00068 {
00069 policy.WriteKeystream(m_buffer, bufferIterations);
00070 memcpy(outString, KeystreamBufferBegin(), length);
00071 m_leftOver = bytesPerIteration - length;
00072 }
00073 }
00074
00075 template <class S>
00076 void AdditiveCipherTemplate<S>::ProcessData(byte *outString, const byte *inString, size_t length)
00077 {
00078 if (m_leftOver > 0)
00079 {
00080 size_t len = STDMIN(m_leftOver, length);
00081 xorbuf(outString, inString, KeystreamBufferEnd()-m_leftOver, len);
00082 length -= len;
00083 m_leftOver -= len;
00084 inString += len;
00085 outString += len;
00086
00087 if (!length)
00088 return;
00089 }
00090 assert(m_leftOver == 0);
00091
00092 PolicyInterface &policy = this->AccessPolicy();
00093 unsigned int bytesPerIteration = policy.GetBytesPerIteration();
00094
00095 if (policy.CanOperateKeystream() && length >= bytesPerIteration)
00096 {
00097 size_t iterations = length / bytesPerIteration;
00098 unsigned int alignment = policy.GetAlignment();
00099 KeystreamOperation operation = KeystreamOperation((IsAlignedOn(inString, alignment) * 2) | (int)IsAlignedOn(outString, alignment));
00100
00101 policy.OperateKeystream(operation, outString, inString, iterations);
00102
00103 inString += iterations * bytesPerIteration;
00104 outString += iterations * bytesPerIteration;
00105 length -= iterations * bytesPerIteration;
00106
00107 if (!length)
00108 return;
00109 }
00110
00111 unsigned int bufferByteSize = GetBufferByteSize(policy);
00112 unsigned int bufferIterations = policy.GetIterationsToBuffer();
00113
00114 while (length >= bufferByteSize)
00115 {
00116 policy.WriteKeystream(m_buffer, bufferIterations);
00117 xorbuf(outString, inString, KeystreamBufferBegin(), bufferByteSize);
00118 length -= bufferByteSize;
00119 inString += bufferByteSize;
00120 outString += bufferByteSize;
00121 }
00122
00123 if (length > 0)
00124 {
00125 policy.WriteKeystream(m_buffer, bufferIterations);
00126 xorbuf(outString, inString, KeystreamBufferBegin(), length);
00127 m_leftOver = bytesPerIteration - length;
00128 }
00129 }
00130
00131 template <class S>
00132 void AdditiveCipherTemplate<S>::Resynchronize(const byte *iv)
00133 {
00134 PolicyInterface &policy = this->AccessPolicy();
00135 m_leftOver = 0;
00136 m_buffer.New(GetBufferByteSize(policy));
00137 policy.CipherResynchronize(m_buffer, iv);
00138 }
00139
00140 template <class BASE>
00141 void AdditiveCipherTemplate<BASE>::Seek(lword position)
00142 {
00143 PolicyInterface &policy = this->AccessPolicy();
00144 unsigned int bytesPerIteration = policy.GetBytesPerIteration();
00145
00146 policy.SeekToIteration(position / bytesPerIteration);
00147 position %= bytesPerIteration;
00148
00149 if (position > 0)
00150 {
00151 policy.WriteKeystream(m_buffer, 1);
00152 m_leftOver = bytesPerIteration - (unsigned int)position;
00153 }
00154 else
00155 m_leftOver = 0;
00156 }
00157
00158 template <class BASE>
00159 void CFB_CipherTemplate<BASE>::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms)
00160 {
00161 PolicyInterface &policy = this->AccessPolicy();
00162 policy.CipherSetKey(params, key, length);
00163
00164 if (this->IsResynchronizable())
00165 policy.CipherResynchronize(this->GetIVAndThrowIfInvalid(params));
00166
00167 m_leftOver = policy.GetBytesPerIteration();
00168 }
00169
00170 template <class BASE>
00171 void CFB_CipherTemplate<BASE>::Resynchronize(const byte *iv)
00172 {
00173 PolicyInterface &policy = this->AccessPolicy();
00174 policy.CipherResynchronize(iv);
00175 m_leftOver = policy.GetBytesPerIteration();
00176 }
00177
00178 template <class BASE>
00179 void CFB_CipherTemplate<BASE>::ProcessData(byte *outString, const byte *inString, size_t length)
00180 {
00181 assert(length % this->MandatoryBlockSize() == 0);
00182
00183 PolicyInterface &policy = this->AccessPolicy();
00184 unsigned int bytesPerIteration = policy.GetBytesPerIteration();
00185 unsigned int alignment = policy.GetAlignment();
00186 byte *reg = policy.GetRegisterBegin();
00187
00188 if (m_leftOver)
00189 {
00190 size_t len = STDMIN(m_leftOver, length);
00191 CombineMessageAndShiftRegister(outString, reg + bytesPerIteration - m_leftOver, inString, len);
00192 m_leftOver -= len;
00193 length -= len;
00194 inString += len;
00195 outString += len;
00196 }
00197
00198 if (!length)
00199 return;
00200
00201 assert(m_leftOver == 0);
00202
00203 if (policy.CanIterate() && length >= bytesPerIteration && IsAlignedOn(outString, alignment))
00204 {
00205 if (IsAlignedOn(inString, alignment))
00206 policy.Iterate(outString, inString, GetCipherDir(*this), length / bytesPerIteration);
00207 else
00208 {
00209 memcpy(outString, inString, length);
00210 policy.Iterate(outString, outString, GetCipherDir(*this), length / bytesPerIteration);
00211 }
00212 inString += length - length % bytesPerIteration;
00213 outString += length - length % bytesPerIteration;
00214 length %= bytesPerIteration;
00215 }
00216
00217 while (length >= bytesPerIteration)
00218 {
00219 policy.TransformRegister();
00220 CombineMessageAndShiftRegister(outString, reg, inString, bytesPerIteration);
00221 length -= bytesPerIteration;
00222 inString += bytesPerIteration;
00223 outString += bytesPerIteration;
00224 }
00225
00226 if (length > 0)
00227 {
00228 policy.TransformRegister();
00229 CombineMessageAndShiftRegister(outString, reg, inString, length);
00230 m_leftOver = bytesPerIteration - length;
00231 }
00232 }
00233
00234 template <class BASE>
00235 void CFB_EncryptionTemplate<BASE>::CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length)
00236 {
00237 xorbuf(reg, message, length);
00238 memcpy(output, reg, length);
00239 }
00240
00241 template <class BASE>
00242 void CFB_DecryptionTemplate<BASE>::CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length)
00243 {
00244 for (unsigned int i=0; i<length; i++)
00245 {
00246 byte b = message[i];
00247 output[i] = reg[i] ^ b;
00248 reg[i] = b;
00249 }
00250 }
00251
00252 NAMESPACE_END
00253
00254 #endif
00255
00256 #endif