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