All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bouncycastle.crypto.modes.KCTRBlockCipher Maven / Gradle / Ivy

Go to download

The Bouncy Castle Java APIs for CMS, PKCS, EAC, TSP, CMP, CRMF, OCSP, and certificate generation. This jar contains APIs for JDK 1.5 and up. The APIs can be used in conjunction with a JCE/JCA provider such as the one provided with the Bouncy Castle Cryptography APIs.

There is a newer version: 1.2.2.1-jre17
Show newest version
package org.bouncycastle.crypto.modes;

import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.OutputLengthException;
import org.bouncycastle.crypto.StreamBlockCipher;
import org.bouncycastle.crypto.params.ParametersWithIV;
import org.bouncycastle.util.Arrays;

/**
 * Implementation of DSTU7624 CTR mode
 */
public class KCTRBlockCipher
    extends StreamBlockCipher
{
    private byte[] iv;
    private byte[] ofbV;
    private byte[] ofbOutV;

    private int             byteCount;

    private boolean initialised;
    private BlockCipher engine;

    public KCTRBlockCipher(BlockCipher engine)
    {
        super(engine);

        this.engine = engine;
        this.iv = new byte[engine.getBlockSize()];
        this.ofbV = new byte[engine.getBlockSize()];
        this.ofbOutV = new byte[engine.getBlockSize()];
    }

    public void init(boolean forEncryption, CipherParameters params)
        throws IllegalArgumentException
    {
        this.initialised = true;

        if (params instanceof ParametersWithIV)
        {
            ParametersWithIV ivParam = (ParametersWithIV)params;
            byte[] iv = ivParam.getIV();
            int diff = this.iv.length - iv.length;

            Arrays.fill(this.iv, (byte)0);
            System.arraycopy(iv, 0, this.iv, diff, iv.length);
            params = ivParam.getParameters();
        }
        else
        {
            throw new IllegalArgumentException("invalid parameter passed");
        }
 
        if (params != null)
        {
            engine.init(true, params);
        }

        reset();
    }

    public String getAlgorithmName()
    {
        return engine.getAlgorithmName() + "/KCTR";
    }

    public int getBlockSize()
    {
        return engine.getBlockSize();
    }

    protected byte calculateByte(byte b)
    {
        if (byteCount == 0)
        {
            incrementCounterAt(0);

            checkCounter();

            engine.processBlock(ofbV, 0, ofbOutV, 0);

            return (byte)(ofbOutV[byteCount++] ^ b);
        }

        byte rv = (byte)(ofbOutV[byteCount++] ^ b);

        if (byteCount == ofbV.length)
        {
            byteCount = 0;
        }

        return rv;
    }

    public int processBlock(byte[] in, int inOff, byte[] out, int outOff)
        throws DataLengthException, IllegalStateException
    {
        if (in.length - inOff < getBlockSize())
        {
            throw new DataLengthException("input buffer too short");
        }
        if (out.length - outOff < getBlockSize())
        {
            throw new OutputLengthException("output buffer too short");
        }
        
        processBytes(in, inOff, getBlockSize(), out, outOff);

        return getBlockSize();
    }

    public void reset()
    {
        if (initialised)
        {
            engine.processBlock(this.iv, 0, ofbV, 0);
        }
        engine.reset();
        byteCount = 0;
    }

    private void incrementCounterAt(int pos)
    {
        int i = pos;
        while (i < ofbV.length)
        {
            if (++ofbV[i++] != 0)
            {
                break;
            }
        }
    }

    private void checkCounter()
    {
        // TODO:
        // if the IV is the same as the blocksize we assume the user knows what they are doing
//        if (IV.length < ofbV.length)
//        {
//            for (int i = 0; i != IV.length; i++)
//            {
//                if (ofbV[i] != IV[i])
//                {
//                    throw new IllegalStateException("Counter in KCTR mode out of range.");
//                }
//            }
//        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy