//Decrypt from Input Buffer to Output Buffer //Returns false if n is multiple of 8 void BlowFish::Decrypt(const unsigned char* in, unsigned char* out, unsigned int n, int iMode) { //Check the buffer's length - should be > 0 and multiple of 8 if((n==0)||(n%8!=0)) //throw exception("Incorrect buffer length"); return; SBlock work; if(iMode == CBC) //CBC mode, using the Chain { SBlock crypt, chain(m_oChain); for(; n >= 8; n -= 8, in += 8) { BytesToBlock(in, work); crypt = work; Decrypt(work); work ^= chain; chain = crypt; BlockToBytes(work, out+=8); } } else if(iMode == CFB) //CFB mode, using the Chain, not using Decrypt() { SBlock crypt, chain(m_oChain); for(; n >= 8; n -= 8, in += 8) { BytesToBlock(in, work); Encrypt(chain); crypt = work; work ^= chain; chain = crypt; BlockToBytes(work, out+=8); } } else //ECB mode, not using the Chain { for(; n >= 8; n -= 8, in += 8) { BytesToBlock(in, work); Decrypt(work); BlockToBytes(work, out+=8); } } }
//Decrypt Buffer in Place //Returns false if n is multiple of 8 void CBlowFish::Decrypt(unsigned char* buf, size_t n, int iMode) { //Check the buffer's length - should be > 0 and multiple of 8 if((n==0)||(n%8!=0)) throw std::exception("Incorrect buffer length"); SBlock work; if(iMode == CBC) //CBC mode, using the Chain { SBlock crypt, chain(m_oChain); for(; n >= 8; n -= 8) { BytesToBlock(buf, work); crypt = work; Decrypt(work); work ^= chain; chain = crypt; BlockToBytes(work, buf+=8); } } else if(iMode == CFB) //CFB mode, using the Chain, not using Decrypt() { SBlock crypt, chain(m_oChain); for(; n >= 8; n -= 8) { BytesToBlock(buf, work); Encrypt(chain); crypt = work; work ^= chain; chain = crypt; BlockToBytes(work, buf+=8); } } else //ECB mode, not using the Chain { for(; n >= 8; n -= 8) { BytesToBlock(buf, work); Decrypt(work); BlockToBytes(work, buf+=8); } } }
//Encrypt Buffer in Place //Returns false if n is multiple of 8 void BlowFish::Encrypt(unsigned char* buf, unsigned int n, int iMode) { //Check the buffer's length - should be > 0 and multiple of 8 if((n==0)||(n%8!=0)) //throw exception("Incorrect buffer length"); return; SBlock work; if(iMode == CBC) //CBC mode, using the Chain { SBlock chain(m_oChain); for(; n >= 8; n -= 8) { BytesToBlock(buf, work); work ^= chain; Encrypt(work); chain = work; BlockToBytes(work, buf+=8); } } else if(iMode == CFB) //CFB mode, using the Chain { SBlock chain(m_oChain); for(; n >= 8; n -= 8) { Encrypt(chain); BytesToBlock(buf, work); work ^= chain; chain = work; BlockToBytes(work, buf+=8); } } else //ECB mode, not using the Chain { for(; n >= 8; n -= 8) { BytesToBlock(buf, work); Encrypt(work); BlockToBytes(work, buf+=8); } } }