Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

cbc.cpp

00001 // cbc.cpp - written and placed in the public domain by Wei Dai
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         // pad last block
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;         // something's wrong with the padding
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         // output last full ciphertext block first
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         // steal ciphertext from next to last block
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         // decrypt last partial plaintext block
00186         cipher.ProcessBlock(pn1, temp);
00187         xorbuf(temp, pn, length);
00188 
00189         // decrypt next to last plaintext block
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

Generated at Mon Jan 15 01:16:29 2001 for Crypto++ by doxygen1.2.4 written by Dimitri van Heesch, © 1997-2000