byte[] iv = new byte[blockSize];
iv[0] = (byte)((q - 1) & 0x7);
System.arraycopy(nonce, 0, iv, 1, nonce.length);
BlockCipher ctrCipher = new SICBlockCipher(cipher);
ctrCipher.init(forEncryption, new ParametersWithIV(keyParam, iv));
int index = inOff;
int outOff = 0;
byte[] output;
if (forEncryption)
{
output = new byte[inLen + macSize];
calculateMac(in, inOff, inLen, macBlock);
ctrCipher.processBlock(macBlock, 0, macBlock, 0); // S0
while (index < inLen - blockSize) // S1...
{
ctrCipher.processBlock(in, index, output, outOff);
outOff += blockSize;
index += blockSize;
}
byte[] block = new byte[blockSize];
System.arraycopy(in, index, block, 0, inLen - index);
ctrCipher.processBlock(block, 0, block, 0);
System.arraycopy(block, 0, output, outOff, inLen - index);
outOff += inLen - index;
System.arraycopy(macBlock, 0, output, outOff, output.length - outOff);
}
else
{
output = new byte[inLen - macSize];
System.arraycopy(in, inOff + inLen - macSize, macBlock, 0, macSize);
ctrCipher.processBlock(macBlock, 0, macBlock, 0);
for (int i = macSize; i != macBlock.length; i++)
{
macBlock[i] = 0;
}
while (outOff < output.length - blockSize)
{
ctrCipher.processBlock(in, index, output, outOff);
outOff += blockSize;
index += blockSize;
}
byte[] block = new byte[blockSize];
System.arraycopy(in, index, block, 0, output.length - outOff);
ctrCipher.processBlock(block, 0, block, 0);
System.arraycopy(block, 0, output, outOff, output.length - outOff);
byte[] calculatedMacBlock = new byte[blockSize];