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