Geremia G / Crypto

Dependents:   AES_example shaun_larada Smartage

Fork of Crypto by Francois Berder

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BlockCipher.cpp Source File

BlockCipher.cpp

00001 #include "BlockCipher.h"
00002 #include <string.h>
00003 
00004 BlockCipher::BlockCipher(uint32_t bs, BLOCK_CIPHER_MODE m, uint8_t *iv):
00005 Cipher(),
00006 blockSize(bs),
00007 mode(m),
00008 IV(0),
00009 tmpIV(0),
00010 tmpdata(0)
00011 {
00012     if(mode != ECB_MODE)
00013     {
00014         IV = new uint8_t[blockSize];
00015         tmpIV = new uint8_t[blockSize];
00016         tmpdatain = new uint8_t[blockSize];
00017         tmpdata = new uint8_t[blockSize];
00018         memcpy(IV, iv, blockSize); 
00019     }
00020 }
00021 
00022 BlockCipher::~BlockCipher()
00023 {
00024     if(IV != 0) delete[] IV;
00025     if(tmpIV != 0) delete[] tmpIV;
00026     if(tmpdatain != 0) delete[] tmpdatain;
00027     if(tmpdata != 0) delete[] tmpdata;
00028 }
00029 
00030 CIPHER_TYPE BlockCipher::getType() const
00031 {
00032     return BLOCK_CIPHER;
00033 }
00034 
00035 uint32_t BlockCipher::getBlockSize() const
00036 {
00037     return blockSize;
00038 }
00039 
00040 void BlockCipher::encrypt(uint8_t *out, uint8_t *in, uint32_t length)
00041 {
00042     
00043     switch (mode)
00044     {
00045         case ECB_MODE:
00046             for(uint32_t i = 0; i < length; i += blockSize)
00047             {
00048                 encryptBlock(out+i, in+i);
00049             }
00050             break;
00051         case PCBC_MODE:
00052         case CBC_MODE:
00053             memcpy(tmpIV, IV, blockSize);  
00054             for(uint32_t i = 0; i < length; i += blockSize)
00055             {
00056                 if(mode==PCBC_MODE) memcpy(tmpdata, in+i, blockSize);
00057                 memcpy(tmpdatain, in+i, blockSize);
00058                 for(int j = 0; j < blockSize; ++j) tmpdatain[j] ^= tmpIV[j];
00059                 encryptBlock(out+i, tmpdatain);
00060                 memcpy(tmpIV, out+i, blockSize);
00061                 if(mode==PCBC_MODE)
00062                 {
00063                     for(int j = 0; j < blockSize; ++j) tmpIV[j] ^= tmpdata[j];
00064                 }
00065             }
00066             break;
00067     }
00068 }
00069 
00070 void BlockCipher::decrypt(uint8_t *out, uint8_t *in, uint32_t length)
00071 {
00072     switch (mode)
00073     {
00074         case ECB_MODE:
00075             for(uint32_t i = 0; i < length; i += blockSize)
00076             {
00077                 decryptBlock(out+i, in+i);
00078             }
00079             break;
00080         case PCBC_MODE:
00081         case CBC_MODE:
00082             memcpy(tmpIV, IV, blockSize);
00083             for(uint32_t i = 0; i < length; i += blockSize)
00084             {
00085                 memcpy(tmpdatain, in+i, blockSize);
00086                 decryptBlock(out+i, tmpdatain);
00087                 for(int j = 0; j < blockSize; ++j) out[i+j] ^= tmpIV[j];
00088                 memcpy(tmpIV, tmpdatain, blockSize); 
00089                 if(mode==PCBC_MODE)
00090                 {
00091                     for(int j = 0; j < blockSize; ++j) tmpIV[j] ^= out[i+j];
00092                 }
00093             }
00094             break;
00095     }
00096 }
00097 
00098 void BlockCipher::setIV(uint8_t *iv)
00099 {
00100     if(IV!=0) memcpy(IV, iv, blockSize);
00101 }