package railo.runtime.crypt; //package maddany.crypto; /* Coding by maddany@madloutre.org * 01-01-2000 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ public final class BlowfishCBC extends BlowfishECB { // here we hold the CBC IV long m_lCBCIV; /** * get the current CBC IV (for cipher resets) * @return current CBC IV */ public long getCBCIV() { return m_lCBCIV; }; /** * get the current CBC IV (for cipher resets) * @param dest wher eto put current CBC IV in network byte ordered array */ public void getCBCIV(byte[] dest) { BinConverter.longToByteArray(m_lCBCIV, dest, 0); }; /** * set the current CBC IV (for cipher resets) * @param lNewCBCIV the new CBC IV */ public void setCBCIV(long lNewCBCIV) { m_lCBCIV = lNewCBCIV; }; /** * set the current CBC IV (for cipher resets) * @param newCBCIV the new CBC IV in network byte ordered array */ public void setCBCIV(byte[] newCBCIV) { m_lCBCIV = BinConverter.byteArrayToLong(newCBCIV, 0); }; /** * constructor, stores a zero CBC IV * @param bfkey key material, up to MAXKEYLENGTH bytes */ public BlowfishCBC(byte[] bfkey) { super(bfkey); // store zero CBCB IV setCBCIV(0); }; /** * constructor * @param bfkey key material, up to MAXKEYLENGTH bytes * @param lInitCBCIV the CBC IV */ public BlowfishCBC(byte[] bfkey, long lInitCBCIV) { super(bfkey); // store the CBCB IV setCBCIV(lInitCBCIV); }; /** * constructor * @param bfkey key material, up to MAXKEYLENGTH bytes * @param lInitCBCIV the CBC IV (array with min. BLOCKSIZE bytes) */ public BlowfishCBC(byte[] bfkey, byte[] initCBCIV) { super(bfkey); // store the CBCB IV setCBCIV(initCBCIV); }; /** * cleans up all critical internals, * call this if you don't need an instance anymore */ public void cleanUp() { m_lCBCIV = 0; super.cleanUp(); }; // internal routine to encrypt a block in CBC mode protected long encryptBlock(long lPlainblock) { // chain with the CBC IV lPlainblock ^= m_lCBCIV; // encrypt the block lPlainblock = super.encryptBlock(lPlainblock); // the encrypted block is the new CBC IV return (m_lCBCIV = lPlainblock); }; // internal routine to decrypt a block in CBC mode protected long decryptBlock(long lCipherblock) { // save the current block long lTemp = lCipherblock; // decrypt the block lCipherblock = super.decryptBlock(lCipherblock); // dechain the block lCipherblock ^= m_lCBCIV; // set the new CBC IV m_lCBCIV = lTemp; // return the decrypted block return lCipherblock; }; /** * encrypts a byte buffer (should be aligned to an 8 byte border) * to another buffer (of the same size or bigger) * @param inbuffer buffer with plaintext data * @param outbuffer buffer to get the ciphertext data */ public void encrypt(byte[] inbuffer, byte[] outbuffer) { int nLen = inbuffer.length; long lTemp; for (int nI = 0; nI < nLen; nI +=8) { // encrypt a temporary 64bit block lTemp = BinConverter.byteArrayToLong(inbuffer, nI); lTemp = encryptBlock(lTemp); BinConverter.longToByteArray(lTemp, outbuffer, nI); }; }; /** * encrypts a byte buffer (should be aligned to an 8 byte border) to itself * @param buffer buffer to encrypt */ public void encrypt(byte[] buffer) { int nLen = buffer.length; long lTemp; for (int nI = 0; nI < nLen; nI +=8) { // encrypt a temporary 64bit block lTemp = BinConverter.byteArrayToLong(buffer, nI); lTemp = encryptBlock(lTemp); BinConverter.longToByteArray(lTemp, buffer, nI); }; }; /** * encrypts an int buffer (should be aligned to an * two integer border) to another int buffer (of the same * size or bigger) * @param inbuffer buffer with plaintext data * @param outBuffer buffer to get the ciphertext data */ public void encrypt(int[] inbuffer, int[] outbuffer) { int nLen = inbuffer.length; long lTemp; for (int nI = 0; nI < nLen; nI +=2) { // encrypt a temporary 64bit block lTemp = BinConverter.intArrayToLong(inbuffer, nI); lTemp = encryptBlock(lTemp); BinConverter.longToIntArray(lTemp, outbuffer, nI); }; }; /** * encrypts an integer buffer (should be aligned to an * @param buffer buffer to encrypt */ public void encrypt(int[] buffer) { int nLen = buffer.length; long lTemp; for (int nI = 0; nI < nLen; nI +=2) { // encrypt a temporary 64bit block lTemp = BinConverter.intArrayToLong(buffer, nI); lTemp = encryptBlock(lTemp); BinConverter.longToIntArray(lTemp, buffer, nI); }; }; /** * encrypts a long buffer to another long buffer (of the same size or bigger) * @param inbuffer buffer with plaintext data * @param outbuffer buffer to get the ciphertext data */ public void encrypt(long[] inbuffer, long[] outbuffer) { int nLen = inbuffer.length; for (int nI = 0; nI < nLen; nI++) outbuffer[nI] = encryptBlock(inbuffer[nI]); }; /** * encrypts a long buffer to itself * @param buffer buffer to encrypt */ public void encrypt(long[] buffer) { int nLen = buffer.length; for (int nI = 0; nI < nLen; nI++) { buffer[nI] = encryptBlock(buffer[nI]); }; }; /** * decrypts a byte buffer (should be aligned to an 8 byte border) * to another buffer (of the same size or bigger) * @param inbuffer buffer with ciphertext data * @param outBuffer buffer to get the plaintext data */ public void decrypt(byte[] inbuffer, byte[] outbuffer) { int nLen = inbuffer.length; long lTemp; for (int nI = 0; nI < nLen; nI +=8) { // decrypt a temporary 64bit block lTemp = BinConverter.byteArrayToLong(inbuffer, nI); lTemp = decryptBlock(lTemp); BinConverter.longToByteArray(lTemp, outbuffer, nI); }; }; /** * decrypts a byte buffer (should be aligned to an 8 byte border) to itself * @param buffer buffer to decrypt */ public void decrypt(byte[] buffer) { int nLen = buffer.length; long lTemp; for (int nI = 0; nI < nLen; nI +=8) { // decrypt over a temporary 64bit block lTemp = BinConverter.byteArrayToLong(buffer, nI); lTemp = decryptBlock(lTemp); BinConverter.longToByteArray(lTemp, buffer, nI); }; }; /** * decrypts an integer buffer (should be aligned to an * two integer border) to another int buffer (of the same size or bigger) * @param inbuffer buffer with ciphertext data * @param outbuffer buffer to get the plaintext data */ public void decrypt(int[] inbuffer, int[] outbuffer) { int nLen = inbuffer.length; long lTemp; for (int nI = 0; nI < nLen; nI +=2) { // decrypt a temporary 64bit block lTemp = BinConverter.intArrayToLong(inbuffer, nI); lTemp = decryptBlock(lTemp); BinConverter.longToIntArray(lTemp, outbuffer, nI); }; }; /** * decrypts an int buffer (should be aligned to a * two integer border) * @param buffer buffer to decrypt */ public void decrypt(int[] buffer) { int nLen = buffer.length; long lTemp; for (int nI = 0; nI < nLen; nI +=2) { // decrypt a temporary 64bit block lTemp = BinConverter.intArrayToLong(buffer, nI); lTemp = decryptBlock(lTemp); BinConverter.longToIntArray(lTemp, buffer, nI); }; }; /** * decrypts a long buffer to another long buffer (of the same size or bigger) * @param inbuffer buffer with ciphertext data * @param outbuffer buffer to get the plaintext data */ public void decrypt(long[] inbuffer, long[] outbuffer) { int nLen = inbuffer.length; for (int nI = 0; nI < nLen; nI++) outbuffer[nI] = decryptBlock(inbuffer[nI]); }; /** * decrypts a long buffer to itself * @param buffer buffer to decrypt */ public void decrypt(long[] buffer) { int nLen = buffer.length; for (int nI = 0; nI < nLen; nI++) buffer[nI] = decryptBlock(buffer[nI]); }; };