FileDocCategorySizeDatePackage
CBCBlockCipher.javaAPI DocAndroid 1.5 API6872Wed May 06 22:41:06 BST 2009org.bouncycastle.crypto.modes

CBCBlockCipher

public class CBCBlockCipher extends Object implements org.bouncycastle.crypto.BlockCipher
implements Cipher-Block-Chaining (CBC) mode on top of a simple cipher.

Fields Summary
private byte[]
IV
private byte[]
cbcV
private byte[]
cbcNextV
private int
blockSize
private org.bouncycastle.crypto.BlockCipher
cipher
private boolean
encrypting
Constructors Summary
public CBCBlockCipher(org.bouncycastle.crypto.BlockCipher cipher)
Basic constructor.

param
cipher the block cipher to be used as the basis of chaining.


                        
     
         
    
        this.cipher = cipher;
        this.blockSize = cipher.getBlockSize();

        this.IV = new byte[blockSize];
        this.cbcV = new byte[blockSize];
        this.cbcNextV = new byte[blockSize];
    
Methods Summary
private intdecryptBlock(byte[] in, int inOff, byte[] out, int outOff)
Do the appropriate chaining step for CBC mode decryption.

param
in the array containing the data to be decrypted.
param
inOff offset into the in array the data starts at.
param
out the array the decrypted data will be copied into.
param
outOff the offset into the out array the output will start at.
exception
DataLengthException if there isn't enough data in in, or space in out.
exception
IllegalStateException if the cipher isn't initialised.
return
the number of bytes processed and produced.

        if ((inOff + blockSize) > in.length)
        {
            throw new DataLengthException("input buffer too short");
        }

        System.arraycopy(in, inOff, cbcNextV, 0, blockSize);

        int length = cipher.processBlock(in, inOff, out, outOff);

        /*
         * XOR the cbcV and the output
         */
        for (int i = 0; i < blockSize; i++)
        {
            out[outOff + i] ^= cbcV[i];
        }

        /*
         * swap the back up buffer into next position
         */
        byte[]  tmp;

        tmp = cbcV;
        cbcV = cbcNextV;
        cbcNextV = tmp;

        return length;
    
private intencryptBlock(byte[] in, int inOff, byte[] out, int outOff)
Do the appropriate chaining step for CBC mode encryption.

param
in the array containing the data to be encrypted.
param
inOff offset into the in array the data starts at.
param
out the array the encrypted data will be copied into.
param
outOff the offset into the out array the output will start at.
exception
DataLengthException if there isn't enough data in in, or space in out.
exception
IllegalStateException if the cipher isn't initialised.
return
the number of bytes processed and produced.

        if ((inOff + blockSize) > in.length)
        {
            throw new DataLengthException("input buffer too short");
        }

        /*
         * XOR the cbcV and the input,
         * then encrypt the cbcV
         */
        for (int i = 0; i < blockSize; i++)
        {
            cbcV[i] ^= in[inOff + i];
        }

        int length = cipher.processBlock(cbcV, 0, out, outOff);

        /*
         * copy ciphertext to cbcV
         */
        System.arraycopy(out, outOff, cbcV, 0, cbcV.length);

        return length;
    
public java.lang.StringgetAlgorithmName()
return the algorithm name and mode.

return
the name of the underlying algorithm followed by "/CBC".

        return cipher.getAlgorithmName() + "/CBC";
    
public intgetBlockSize()
return the block size of the underlying cipher.

return
the block size of the underlying cipher.

        return cipher.getBlockSize();
    
public org.bouncycastle.crypto.BlockCiphergetUnderlyingCipher()
return the underlying block cipher that we are wrapping.

return
the underlying block cipher that we are wrapping.

        return cipher;
    
public voidinit(boolean encrypting, org.bouncycastle.crypto.CipherParameters params)
Initialise the cipher and, possibly, the initialisation vector (IV). If an IV isn't passed as part of the parameter, the IV will be all zeros.

param
encrypting if true the cipher is initialised for encryption, if false for decryption.
param
params the key and other data required by the cipher.
exception
IllegalArgumentException if the params argument is inappropriate.

        this.encrypting = encrypting;
        
        if (params instanceof ParametersWithIV)
        {
                ParametersWithIV ivParam = (ParametersWithIV)params;
                byte[]      iv = ivParam.getIV();

                if (iv.length != blockSize)
                {
                    throw new IllegalArgumentException("initialisation vector must be the same length as block size");
                }

                System.arraycopy(iv, 0, IV, 0, iv.length);

                reset();

                cipher.init(encrypting, ivParam.getParameters());
        }
        else
        {
                reset();

                cipher.init(encrypting, params);
        }
    
public intprocessBlock(byte[] in, int inOff, byte[] out, int outOff)
Process one block of input from the array in and write it to the out array.

param
in the array containing the input data.
param
inOff offset into the in array the data starts at.
param
out the array the output data will be copied into.
param
outOff the offset into the out array the output will start at.
exception
DataLengthException if there isn't enough data in in, or space in out.
exception
IllegalStateException if the cipher isn't initialised.
return
the number of bytes processed and produced.

        return (encrypting) ? encryptBlock(in, inOff, out, outOff) : decryptBlock(in, inOff, out, outOff);
    
public voidreset()
reset the chaining vector back to the IV and reset the underlying cipher.

        System.arraycopy(IV, 0, cbcV, 0, IV.length);

        cipher.reset();