int blockSize = engine.getBlockSize();
if (inLen < 2 * blockSize)
{
throw new InvalidCipherTextException("input too short");
}
byte[] cekBlock = new byte[inLen];
byte[] iv = new byte[blockSize];
System.arraycopy(in, inOff, cekBlock, 0, inLen);
System.arraycopy(in, inOff, iv, 0, iv.length);
engine.init(false, new ParametersWithIV(param.getParameters(), iv));
for (int i = blockSize; i < cekBlock.length; i += blockSize)
{
engine.processBlock(cekBlock, i, cekBlock, i);
}
System.arraycopy(cekBlock, cekBlock.length - iv.length, iv, 0, iv.length);
engine.init(false, new ParametersWithIV(param.getParameters(), iv));
engine.processBlock(cekBlock, 0, cekBlock, 0);
engine.init(false, param);
for (int i = 0; i < cekBlock.length; i += blockSize)
{
engine.processBlock(cekBlock, i, cekBlock, i);
}
if ((cekBlock[0] & 0xff) > cekBlock.length - 4)
{
throw new InvalidCipherTextException("wrapped key corrupted");
}
byte[] key = new byte[cekBlock[0] & 0xff];
System.arraycopy(cekBlock, 4, key, 0, cekBlock[0]);
for (int i = 0; i != 3; i++)
{
byte check = (byte)~cekBlock[1 + i];
if (check != key[i])
{
throw new InvalidCipherTextException("wrapped key fails checksum");
}
}
return key;
}