FileDocCategorySizeDatePackage
CBCBlockCipherMac.javaAPI DocAndroid 1.5 API6265Wed May 06 22:41:06 BST 2009org.bouncycastle.crypto.macs

CBCBlockCipherMac

public class CBCBlockCipherMac extends Object implements org.bouncycastle.crypto.Mac
standard CBC Block Cipher MAC - if no padding is specified the default of pad of zeroes is used.

Fields Summary
private byte[]
mac
private byte[]
buf
private int
bufOff
private org.bouncycastle.crypto.BlockCipher
cipher
private org.bouncycastle.crypto.paddings.BlockCipherPadding
padding
private int
macSize
Constructors Summary
public CBCBlockCipherMac(org.bouncycastle.crypto.BlockCipher cipher)
create a standard MAC based on a CBC block cipher. This will produce an authentication code half the length of the block size of the cipher.

param
cipher the cipher to be used as the basis of the MAC generation.

        this(cipher, (cipher.getBlockSize() * 8) / 2, null);
    
public CBCBlockCipherMac(org.bouncycastle.crypto.BlockCipher cipher, org.bouncycastle.crypto.paddings.BlockCipherPadding padding)
create a standard MAC based on a CBC block cipher. This will produce an authentication code half the length of the block size of the cipher.

param
cipher the cipher to be used as the basis of the MAC generation.
param
padding the padding to be used to complete the last block.

        this(cipher, (cipher.getBlockSize() * 8) / 2, padding);
    
public CBCBlockCipherMac(org.bouncycastle.crypto.BlockCipher cipher, int macSizeInBits)
create a standard MAC based on a block cipher with the size of the MAC been given in bits. This class uses CBC mode as the basis for the MAC generation.

Note: the size of the MAC must be at least 24 bits (FIPS Publication 81), or 16 bits if being used as a data authenticator (FIPS Publication 113), and in general should be less than the size of the block cipher as it reduces the chance of an exhaustive attack (see Handbook of Applied Cryptography).

param
cipher the cipher to be used as the basis of the MAC generation.
param
macSizeInBits the size of the MAC in bits, must be a multiple of 8.

        this(cipher, macSizeInBits, null);
    
public CBCBlockCipherMac(org.bouncycastle.crypto.BlockCipher cipher, int macSizeInBits, org.bouncycastle.crypto.paddings.BlockCipherPadding padding)
create a standard MAC based on a block cipher with the size of the MAC been given in bits. This class uses CBC mode as the basis for the MAC generation.

Note: the size of the MAC must be at least 24 bits (FIPS Publication 81), or 16 bits if being used as a data authenticator (FIPS Publication 113), and in general should be less than the size of the block cipher as it reduces the chance of an exhaustive attack (see Handbook of Applied Cryptography).

param
cipher the cipher to be used as the basis of the MAC generation.
param
macSizeInBits the size of the MAC in bits, must be a multiple of 8.
param
padding the padding to be used to complete the last block.

        if ((macSizeInBits % 8) != 0)
        {
            throw new IllegalArgumentException("MAC size must be multiple of 8");
        }

        this.cipher = new CBCBlockCipher(cipher);
        this.padding = padding;
        this.macSize = macSizeInBits / 8;

        mac = new byte[cipher.getBlockSize()];

        buf = new byte[cipher.getBlockSize()];
        bufOff = 0;
    
Methods Summary
public intdoFinal(byte[] out, int outOff)

        int blockSize = cipher.getBlockSize();

        if (padding == null)
        {
            //
            // pad with zeroes
            //
            while (bufOff < blockSize)
            {
                buf[bufOff] = 0;
                bufOff++;
            }
        }
        else
        {
            if (bufOff == blockSize)
            {
                cipher.processBlock(buf, 0, mac, 0);
                bufOff = 0;
            }

            padding.addPadding(buf, bufOff);
        }

        cipher.processBlock(buf, 0, mac, 0);

        System.arraycopy(mac, 0, out, outOff, macSize);

        reset();

        return macSize;
    
public java.lang.StringgetAlgorithmName()

        return cipher.getAlgorithmName();
    
public intgetMacSize()

        return macSize;
    
public voidinit(org.bouncycastle.crypto.CipherParameters params)

        reset();

        cipher.init(true, params);
    
public voidreset()
Reset the mac generator.

        /*
         * clean the buffer.
         */
        for (int i = 0; i < buf.length; i++)
        {
            buf[i] = 0;
        }

        bufOff = 0;

        /*
         * reset the underlying cipher.
         */
        cipher.reset();
    
public voidupdate(byte in)

        int         resultLen = 0;

        if (bufOff == buf.length)
        {
            resultLen = cipher.processBlock(buf, 0, mac, 0);
            bufOff = 0;
        }

        buf[bufOff++] = in;
    
public voidupdate(byte[] in, int inOff, int len)

        if (len < 0)
        {
            throw new IllegalArgumentException("Can't have a negative input length!");
        }

        int blockSize = cipher.getBlockSize();
        int resultLen = 0;
        int gapLen = blockSize - bufOff;

        if (len > gapLen)
        {
            System.arraycopy(in, inOff, buf, bufOff, gapLen);

            resultLen += cipher.processBlock(buf, 0, mac, 0);

            bufOff = 0;
            len -= gapLen;
            inOff += gapLen;

            while (len > blockSize)
            {
                resultLen += cipher.processBlock(in, inOff, mac, 0);

                len -= blockSize;
                inOff += blockSize;
            }
        }

        System.arraycopy(in, inOff, buf, bufOff, len);

        bufOff += len;