14c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrompackage org.bouncycastle.jcajce.provider.symmetric.util;
24c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
34c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.security.AlgorithmParameters;
44c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.security.InvalidAlgorithmParameterException;
54c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.security.InvalidKeyException;
65db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Rootimport java.security.InvalidParameterException;
74c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.security.Key;
8028ab6e01e3b911024b9b9243e9a0f4ac377c0faSergio Giroimport java.security.Provider;
94c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.security.SecureRandom;
104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.security.spec.AlgorithmParameterSpec;
114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport javax.crypto.Cipher;
134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport javax.crypto.NoSuchPaddingException;
144c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport javax.crypto.SecretKey;
154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport javax.crypto.ShortBufferException;
164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport javax.crypto.spec.IvParameterSpec;
174c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport javax.crypto.spec.PBEParameterSpec;
184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom// BEGIN android-removed
194c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom// import javax.crypto.spec.RC2ParameterSpec;
204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom// import javax.crypto.spec.RC5ParameterSpec;
214c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom// END android-removed
224c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
234c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.crypto.CipherParameters;
244c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.crypto.DataLengthException;
254c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.crypto.StreamCipher;
264c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.crypto.params.KeyParameter;
274c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.crypto.params.ParametersWithIV;
284c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.jce.provider.BouncyCastleProvider;
294c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
304c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrompublic class BaseStreamCipher
314c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    extends BaseWrapCipher
324c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    implements PBE
334c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom{
344c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    //
354c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    // specs we can handle.
364c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    //
374c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private Class[]                 availableSpecs =
384c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                                    {
394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                                        // BEGIN android-removed
404c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                                        // RC2ParameterSpec.class,
414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                                        // RC5ParameterSpec.class,
424c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                                        // END android-removed
434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                                        IvParameterSpec.class,
444c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                                        PBEParameterSpec.class
454c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                                    };
464c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
474c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private StreamCipher       cipher;
484c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private ParametersWithIV   ivParam;
494c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
504c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private int                     ivLength = 0;
514c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
524c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private PBEParameterSpec        pbeSpec = null;
534c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private String                  pbeAlgorithm = null;
544c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
554c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    protected BaseStreamCipher(
564c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        StreamCipher engine,
574c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        int ivLength)
584c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
594c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        cipher = engine;
604c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.ivLength = ivLength;
614c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
624c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
634c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    protected int engineGetBlockSize()
644c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
654c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return 0;
664c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
674c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
684c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    protected byte[] engineGetIV()
694c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
704c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return (ivParam != null) ? ivParam.getIV() : null;
714c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
724c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
734c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    protected int engineGetKeySize(
744c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        Key     key)
754c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
764c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return key.getEncoded().length * 8;
774c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
784c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
794c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    protected int engineGetOutputSize(
804c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        int     inputLen)
814c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
824c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return inputLen;
834c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
844c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
854c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    protected AlgorithmParameters engineGetParameters()
864c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
874c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (engineParams == null)
884c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
894c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            if (pbeSpec != null)
904c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
914c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                try
924c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                {
93028ab6e01e3b911024b9b9243e9a0f4ac377c0faSergio Giro                    AlgorithmParameters engineParams = createParametersInstance(pbeAlgorithm);
944c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    engineParams.init(pbeSpec);
954c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
964c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    return engineParams;
974c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                }
984c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                catch (Exception e)
994c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                {
1004c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    return null;
1014c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                }
1024c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
1034c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
1044c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1054c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return engineParams;
1064c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
1074c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1084c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    /**
1094c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * should never be called.
1104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     */
1114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    protected void engineSetMode(
1124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        String  mode)
1134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
1144c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (!mode.equalsIgnoreCase("ECB"))
1154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
1164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            throw new IllegalArgumentException("can't support mode " + mode);
1174c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
1184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
1194c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    /**
1214c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * should never be called.
1224c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     */
1234c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    protected void engineSetPadding(
1244c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        String  padding)
1254c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    throws NoSuchPaddingException
1264c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
1274c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (!padding.equalsIgnoreCase("NoPadding"))
1284c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
1294c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            throw new NoSuchPaddingException("Padding " + padding + " unknown.");
1304c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
1314c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
1324c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1334c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    protected void engineInit(
1344c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        int                     opmode,
1354c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        Key                     key,
1364c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        AlgorithmParameterSpec  params,
1374c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        SecureRandom            random)
1384c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        throws InvalidKeyException, InvalidAlgorithmParameterException
1394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
1404c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        CipherParameters        param;
1414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1424c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.pbeSpec = null;
1434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.pbeAlgorithm = null;
1444c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1454c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.engineParams = null;
1464c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1474c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        //
1484c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        // basic key check
1494c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        //
1504c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (!(key instanceof SecretKey))
1514c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
1524c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            throw new InvalidKeyException("Key for algorithm " + key.getAlgorithm() + " not suitable for symmetric enryption.");
1534c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
1544c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1554c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (key instanceof BCPBEKey)
1564c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
1574c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            BCPBEKey k = (BCPBEKey)key;
1584c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1594c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            if (k.getOID() != null)
1604c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
1614c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                pbeAlgorithm = k.getOID().getId();
1624c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
1634c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            else
1644c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
1654c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                pbeAlgorithm = k.getAlgorithm();
1664c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
1674c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1684c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            if (k.getParam() != null)
1694c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
1704c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                param = k.getParam();
1714c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                pbeSpec = new PBEParameterSpec(k.getSalt(), k.getIterationCount());
1724c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
1734c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            else if (params instanceof PBEParameterSpec)
1744c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
1754c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                param = PBE.Util.makePBEParameters(k, params, cipher.getAlgorithmName());
1764c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                pbeSpec = (PBEParameterSpec)params;
1774c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
1784c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            else
1794c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
1804c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                throw new InvalidAlgorithmParameterException("PBE requires PBE parameters to be set.");
1814c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
1824c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1834c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            if (k.getIvSize() != 0)
1844c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
1854c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                ivParam = (ParametersWithIV)param;
1864c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
1874c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
1884c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        else if (params == null)
1894c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
1904c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            param = new KeyParameter(key.getEncoded());
1914c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
1924c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        else if (params instanceof IvParameterSpec)
1934c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
1944c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            param = new ParametersWithIV(new KeyParameter(key.getEncoded()), ((IvParameterSpec)params).getIV());
1954c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            ivParam = (ParametersWithIV)param;
1964c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
1974c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        else
1984c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
1995db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Root            throw new InvalidAlgorithmParameterException("unknown parameter type.");
2004c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
2014c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2024c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if ((ivLength != 0) && !(param instanceof ParametersWithIV))
2034c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
2044c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            SecureRandom    ivRandom = random;
2054c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2064c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            if (ivRandom == null)
2074c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
2084c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                ivRandom = new SecureRandom();
2094c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
2104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            if ((opmode == Cipher.ENCRYPT_MODE) || (opmode == Cipher.WRAP_MODE))
2124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
2134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                byte[]  iv = new byte[ivLength];
2144c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                ivRandom.nextBytes(iv);
2164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                param = new ParametersWithIV(param, iv);
2174c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                ivParam = (ParametersWithIV)param;
2184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
2194c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            else
2204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
2214c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                throw new InvalidAlgorithmParameterException("no IV set when one expected");
2224c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
2234c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
2244c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2255db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Root        try
2264c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
2275db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Root            switch (opmode)
2285db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Root            {
2295db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Root            case Cipher.ENCRYPT_MODE:
2305db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Root            case Cipher.WRAP_MODE:
2315db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Root                cipher.init(true, param);
2325db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Root                break;
2335db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Root            case Cipher.DECRYPT_MODE:
2345db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Root            case Cipher.UNWRAP_MODE:
2355db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Root                cipher.init(false, param);
2365db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Root                break;
2375db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Root            default:
2385db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Root                throw new InvalidParameterException("unknown opmode " + opmode + " passed");
2395db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Root            }
2405db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Root        }
2415db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Root        catch (Exception e)
2425db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Root        {
2435db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Root            throw new InvalidKeyException(e.getMessage());
2444c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
2454c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
2464c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2474c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    protected void engineInit(
2484c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        int                 opmode,
2494c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        Key                 key,
2504c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        AlgorithmParameters params,
2514c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        SecureRandom        random)
2524c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        throws InvalidKeyException, InvalidAlgorithmParameterException
2534c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
2544c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        AlgorithmParameterSpec  paramSpec = null;
2554c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2564c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (params != null)
2574c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
2584c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            for (int i = 0; i != availableSpecs.length; i++)
2594c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
2604c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                try
2614c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                {
2624c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    paramSpec = params.getParameterSpec(availableSpecs[i]);
2634c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    break;
2644c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                }
2654c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                catch (Exception e)
2664c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                {
2674c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    continue;
2684c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                }
2694c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
2704c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2714c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            if (paramSpec == null)
2724c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
2734c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                throw new InvalidAlgorithmParameterException("can't handle parameter " + params.toString());
2744c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
2754c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
2764c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2774c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        engineInit(opmode, key, paramSpec, random);
2784c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        engineParams = params;
2794c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
2804c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2814c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    protected void engineInit(
2824c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        int                 opmode,
2834c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        Key                 key,
2844c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        SecureRandom        random)
2854c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        throws InvalidKeyException
2864c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
2874c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        try
2884c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
2894c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            engineInit(opmode, key, (AlgorithmParameterSpec)null, random);
2904c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
2914c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        catch (InvalidAlgorithmParameterException e)
2924c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
2934c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            throw new InvalidKeyException(e.getMessage());
2944c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
2954c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
2964c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2974c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    protected byte[] engineUpdate(
2984c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        byte[]  input,
2994c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        int     inputOffset,
3004c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        int     inputLen)
3014c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
3024c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        byte[]  out = new byte[inputLen];
3034c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3044c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        cipher.processBytes(input, inputOffset, inputLen, out, 0);
3054c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3064c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return out;
3074c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
3084c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3094c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    protected int engineUpdate(
3104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        byte[]  input,
3114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        int     inputOffset,
3124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        int     inputLen,
3134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        byte[]  output,
3144c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        int     outputOffset)
3154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        throws ShortBufferException
3164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
3174c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        try
3184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
3194c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        cipher.processBytes(input, inputOffset, inputLen, output, outputOffset);
3204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3214c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return inputLen;
3224c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
3234c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        catch (DataLengthException e)
3244c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
3254c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            throw new ShortBufferException(e.getMessage());
3264c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
3274c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
3284c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3294c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    protected byte[] engineDoFinal(
3304c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        byte[]  input,
3314c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        int     inputOffset,
3324c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        int     inputLen)
3334c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
3344c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (inputLen != 0)
3354c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
3364c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            byte[] out = engineUpdate(input, inputOffset, inputLen);
3374c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3384c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            cipher.reset();
3394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3404c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            return out;
3414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
3424c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        cipher.reset();
3444c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3454c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return new byte[0];
3464c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
3474c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3484c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    protected int engineDoFinal(
3494c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        byte[]  input,
3504c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        int     inputOffset,
3514c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        int     inputLen,
3524c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        byte[]  output,
3534c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        int     outputOffset)
3544c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
3554c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (inputLen != 0)
3564c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
3574c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            cipher.processBytes(input, inputOffset, inputLen, output, outputOffset);
3584c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
3594c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3604c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        cipher.reset();
3614c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3624c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return inputLen;
3634c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
3644c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom}
365