//Decrypt Buffer in Place void cpl::crypt::blowfish::decrypt(buffer &buf, int iMode) { int n = buf.size(); // n MUST be a power of 8. If not, then we are going to get very strange results. int rem = 8-(n%8); if (rem != 8) { buf.insert(buf.end(), rem, '\0'); n += rem; } assert( n % 8 == 0 ) ; if (n == 0) return; // Nothing to do... block work; buffer bytes(8); block crypt, chain(m_oChain); switch (iMode) { case CBC: //CBC mode, using the Chain for(; n >= 8; n -= 8) { copy(buf.begin()+n-8, buf.begin()+n, bytes.begin()); work = bytesToBlock(bytes); crypt = work; decrypt(work); work ^= chain; chain = crypt; bytes = blockToBytes(work); copy(bytes.begin(), bytes.end(), buf.begin()+n-8); } break; case CFB: //CFB mode, using the Chain, not using Decrypt() for(; n >= 8; n -= 8) { copy(buf.begin()+n-8, buf.begin()+n, bytes.begin()); work = bytesToBlock(bytes); encrypt(chain); crypt = work; work ^= chain; chain = crypt; bytes = blockToBytes(work); copy(bytes.begin(), bytes.end(), buf.begin()+n-8); } break; case ECB: //ECB mode, not using the Chain default: for(; n >= 8; n -= 8) { copy(buf.begin()+n-8, buf.begin()+n, bytes.begin()); work = bytesToBlock(bytes); decrypt(work); bytes = blockToBytes(work); copy(bytes.begin(), bytes.end(), buf.begin()+n-8); } break; } // get the size out of the first 8 chars in the buffer, and then resize it. buffer sizeBuf(8); copy(buf.begin(), buf.begin()+8, sizeBuf.begin()); buf.erase(buf.begin(), buf.begin()+8); int size = decodeInt(sizeBuf); // remove the padding from the end of the file buf.erase(buf.end() - (buf.size() - size), buf.end()); }
//Encrypt Buffer in Place void cpl::crypt::blowfish::encrypt(buffer &buf, int iMode) { int n = buf.size(); // encode & prepend the buffer size buffer sizeBuf = encodeInt(n); buf.insert(buf.begin(), sizeBuf.begin(), sizeBuf.end()); n+=8; // make sure the size of the whole buffer is a factor of 8 by padding it with '\0' characters int rem = 8-(n%8); if (rem != 8) { buf.insert(buf.end(), rem, '\0'); n += rem; } if (n == 0) return; // Nothing to do... block work; buffer bytes(8); block chain(m_oChain); switch (iMode) { case CBC: //CBC mode, using the Chain for(; n >= 8; n -= 8) { copy(buf.begin()+n-8, buf.begin()+n, bytes.begin()); work = bytesToBlock(bytes); work ^= chain; encrypt(work); chain = work; bytes = blockToBytes(work); copy(bytes.begin(), bytes.end(), buf.begin()+n-8); } break; case CFB: //CFB mode, using the Chain for(; n >= 8; n -= 8) { encrypt(chain); copy(buf.begin()+n-8, buf.begin()+n, bytes.begin()); work = bytesToBlock(bytes); work ^= chain; chain = work; bytes = blockToBytes(work); copy(bytes.begin(), bytes.end(), buf.begin()+n-8); } break; case ECB: //ECB mode, not using the Chain default: for(; n >= 8; n -= 8) { std::copy(buf.begin()+n-8, buf.begin()+n, bytes.begin()); work = bytesToBlock(bytes); encrypt(work); bytes = blockToBytes(work); copy(bytes.begin(), bytes.end(), buf.begin()+n-8); } break; } }