org.bouncycastle.crypto.fpe.FPEEngine Maven / Gradle / Ivy
package org.bouncycastle.crypto.fpe;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.OutputLengthException;
import org.bouncycastle.crypto.params.FPEParameters;
import org.bouncycastle.util.Pack;
/**
* Base class for format-preserving encryption.
*/
public abstract class FPEEngine
{
protected final BlockCipher baseCipher;
protected boolean forEncryption;
protected FPEParameters fpeParameters;
protected FPEEngine(BlockCipher baseCipher)
{
this.baseCipher = baseCipher;
}
/**
* Process length bytes from inBuf, writing the output to outBuf.
*
* @param inBuf input data.
* @param inOff offset in input data to start at.
* @param length number of bytes to process.
* @param outBuf destination buffer.
* @param outOff offset to start writing at in destination buffer.
* @return number of bytes output.
*/
public int processBlock(byte[] inBuf, int inOff, int length, byte[] outBuf, int outOff)
{
if (fpeParameters == null)
{
throw new IllegalStateException("FPE engine not initialized");
}
if (length < 0)
{
throw new IllegalArgumentException("input length cannot be negative");
}
if (inBuf == null || outBuf == null)
{
throw new NullPointerException("buffer value is null");
}
if (inBuf.length < inOff + length)
{
throw new DataLengthException("input buffer too short");
}
if (outBuf.length < outOff + length)
{
throw new OutputLengthException("output buffer too short");
}
if (forEncryption)
{
return encryptBlock(inBuf, inOff, length, outBuf, outOff);
}
else
{
return decryptBlock(inBuf, inOff, length, outBuf, outOff);
}
}
protected static short[] toShortArray(byte[] buf)
{
if ((buf.length & 1) != 0)
{
throw new IllegalArgumentException("data must be an even number of bytes for a wide radix");
}
short[] rv = new short[buf.length / 2];
for (int i = 0; i != rv.length; i++)
{
rv[i] = Pack.bigEndianToShort(buf, i * 2);
}
return rv;
}
protected static byte[] toByteArray(short[] buf)
{
byte[] rv = new byte[buf.length * 2];
for (int i = 0; i != buf.length; i++)
{
Pack.shortToBigEndian(buf[i], rv, i * 2);
}
return rv;
}
/**
* Initialize the FPE engine for encryption/decryption.
*
* @param forEncryption true if initialising for encryption, false otherwise.
* @param parameters the key and other parameters to use to set the engine up.
*/
public abstract void init(boolean forEncryption, CipherParameters parameters);
/**
* Return the name of the algorithm the cipher implements.
*
* @return the name of the algorithm the cipher implements.
*/
public abstract String getAlgorithmName();
protected abstract int encryptBlock(byte[] inBuf, int inOff, int length, byte[] outBuf, int outOff);
protected abstract int decryptBlock(byte[] inBuf, int inOff, int length, byte[] outBuf, int outOff);
}