00001
00002
00003 #include "pch.h"
00004 #include "cbc.h"
00005
00006 NAMESPACE_BEGIN(CryptoPP)
00007
00008 CBCRawEncryptor::CBCRawEncryptor(const BlockTransformation &cipher, const byte *IV, BufferedTransformation *outQueue)
00009 : CipherMode(cipher, IV), FilterWithBufferedInput(0, S, 0, outQueue)
00010 {
00011 }
00012
00013 void CBCRawEncryptor::NextPut(const byte *inString, unsigned int)
00014 {
00015 xorbuf(reg, inString, S);
00016 cipher.ProcessBlock(reg);
00017 AttachedTransformation()->Put(reg, S);
00018 }
00019
00020 void CBCRawEncryptor::LastPut(const byte *inString, unsigned int length)
00021 {
00022 assert(length < S);
00023 if (length > 0)
00024 {
00025 xorbuf(reg, inString, length);
00026 cipher.ProcessBlock(reg);
00027 AttachedTransformation()->Put(reg, S);
00028 }
00029 }
00030
00031 CBCRawDecryptor::CBCRawDecryptor(const BlockTransformation &cipher, const byte *IV, BufferedTransformation *outQueue)
00032 : CipherMode(cipher, IV), FilterWithBufferedInput(0, S, 0, outQueue)
00033 {
00034 }
00035
00036 void CBCRawDecryptor::NextPut(const byte *inString, unsigned int)
00037 {
00038 cipher.ProcessBlock(inString, buffer);
00039 xorbuf(buffer, reg, S);
00040 AttachedTransformation()->Put(buffer, S);
00041 memcpy(reg, inString, S);
00042 }
00043
00044 void CBCRawDecryptor::LastPut(const byte *inString, unsigned int length)
00045 {
00046 }
00047
00048 CBCPaddedEncryptor::CBCPaddedEncryptor(const BlockTransformation &cipher, const byte *IV, BufferedTransformation *outQueue)
00049 : CipherMode(cipher, IV), FilterWithBufferedInput(0, S, 0, outQueue)
00050 {
00051 }
00052
00053 void CBCPaddedEncryptor::NextPut(const byte *inString, unsigned int)
00054 {
00055 xorbuf(reg, inString, S);
00056 cipher.ProcessBlock(reg);
00057 AttachedTransformation()->Put(reg, S);
00058 }
00059
00060 void CBCPaddedEncryptor::LastPut(const byte *inString, unsigned int length)
00061 {
00062
00063 assert(length < S);
00064 xorbuf(reg, inString, length);
00065 byte pad = S-length;
00066 for (unsigned int i=0; i<pad; i++)
00067 reg[length+i] ^= pad;
00068 cipher.ProcessBlock(reg);
00069 AttachedTransformation()->Put(reg, S);
00070 }
00071
00072 CBCPaddedDecryptor::CBCPaddedDecryptor(const BlockTransformation &cipher, const byte *IV, BufferedTransformation *outQueue)
00073 : CipherMode(cipher, IV), FilterWithBufferedInput(0, S, S, outQueue)
00074 {
00075 }
00076
00077 void CBCPaddedDecryptor::NextPut(const byte *inString, unsigned int)
00078 {
00079 cipher.ProcessBlock(inString, buffer);
00080 xorbuf(buffer, reg, S);
00081 AttachedTransformation()->Put(buffer, S);
00082 memcpy(reg, inString, S);
00083 }
00084
00085 void CBCPaddedDecryptor::LastPut(const byte *inString, unsigned int length)
00086 {
00087 if (length >= S)
00088 {
00089 cipher.ProcessBlock(inString, buffer);
00090 xorbuf(buffer, reg, S);
00091 if (buffer[S-1] > S)
00092 buffer[S-1] = 0;
00093 AttachedTransformation()->Put(buffer, S-buffer[S-1]);
00094 }
00095 }
00096
00097
00098
00099 CBC_CTS_Encryptor::CBC_CTS_Encryptor(const BlockTransformation &cipher, byte *IV, BufferedTransformation *outQueue, bool stealIV)
00100 : CipherMode(cipher, IV), FilterWithBufferedInput(S, S, 1, outQueue), m_iv(stealIV ? IV : NULL)
00101 {
00102 }
00103
00104 CBC_CTS_Encryptor::CBC_CTS_Encryptor(const BlockTransformation &cipher, const byte *IV, BufferedTransformation *outQueue)
00105 : CipherMode(cipher, IV), FilterWithBufferedInput(S, S, 1, outQueue), m_iv(NULL)
00106 {
00107 }
00108
00109 void CBC_CTS_Encryptor::FirstPut(const byte *inString)
00110 {
00111 xorbuf(reg, inString, S);
00112 cipher.ProcessBlock(reg);
00113 }
00114
00115 void CBC_CTS_Encryptor::NextPut(const byte *inString, unsigned int)
00116 {
00117 AttachedTransformation()->Put(reg, S);
00118 xorbuf(reg, inString, S);
00119 cipher.ProcessBlock(reg);
00120 }
00121
00122 void CBC_CTS_Encryptor::LastPut(const byte *inString, unsigned int length)
00123 {
00124 assert(length <= S);
00125 if (length == 0)
00126 return;
00127
00128 if (!DidFirstPut() && !m_iv)
00129 {
00130 xorbuf(reg, inString, length);
00131 cipher.ProcessBlock(reg);
00132 length = 0;
00133 }
00134
00135
00136 memcpy(buffer, reg, S);
00137 xorbuf(reg, inString, length);
00138 cipher.ProcessBlock(reg);
00139 if (!DidFirstPut() && m_iv)
00140 memcpy(m_iv, reg, S);
00141 else
00142 AttachedTransformation()->Put(reg, S);
00143
00144 AttachedTransformation()->Put(buffer, STDMAX(1U, length));
00145 }
00146
00147 CBC_CTS_Decryptor::CBC_CTS_Decryptor(const BlockTransformation &cipher, const byte *IV, BufferedTransformation *outQueue)
00148 : CipherMode(cipher, IV), FilterWithBufferedInput(0, S, S+1, outQueue)
00149 {
00150 }
00151
00152 void CBC_CTS_Decryptor::NextPut(const byte *inString, unsigned int)
00153 {
00154 cipher.ProcessBlock(inString, buffer);
00155 xorbuf(buffer, reg, S);
00156 memcpy(reg, inString, S);
00157 AttachedTransformation()->Put(buffer, S);
00158 }
00159
00160 void CBC_CTS_Decryptor::LastPut(const byte *inString, unsigned int length)
00161 {
00162 assert(length <= 2*S);
00163 if (length == 0)
00164 return;
00165
00166 const byte *pn, *pn1;
00167 bool stealIV;
00168
00169 if (length < S+1)
00170 {
00171 pn = inString;
00172 pn1 = reg;
00173 stealIV = true;
00174 }
00175 else
00176 {
00177 pn = inString + S;
00178 pn1 = inString;
00179 length -= S;
00180 stealIV = false;
00181 }
00182
00183 SecByteBlock temp(S);
00184
00185
00186 cipher.ProcessBlock(pn1, temp);
00187 xorbuf(temp, pn, length);
00188
00189
00190 memcpy(buffer, pn, length);
00191 memcpy(buffer+length, temp+length, S-length);
00192 cipher.ProcessBlock(buffer);
00193 xorbuf(buffer, reg, S);
00194
00195 if (!stealIV)
00196 AttachedTransformation()->Put(buffer, S);
00197
00198 AttachedTransformation()->Put(temp, length);
00199 }
00200
00201 NAMESPACE_END