116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giropackage org.bouncycastle.jcajce.provider.symmetric.util; 216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giroimport java.lang.reflect.Constructor; 480261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giroimport java.lang.reflect.Method; 580261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giroimport java.nio.ByteBuffer; 616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport java.security.AlgorithmParameters; 716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport java.security.InvalidAlgorithmParameterException; 816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport java.security.InvalidKeyException; 916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport java.security.InvalidParameterException; 1016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport java.security.Key; 1116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport java.security.NoSuchAlgorithmException; 1216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport java.security.SecureRandom; 1316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport java.security.spec.AlgorithmParameterSpec; 1416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 1516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport javax.crypto.BadPaddingException; 1616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport javax.crypto.Cipher; 1716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport javax.crypto.IllegalBlockSizeException; 1816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport javax.crypto.NoSuchPaddingException; 1916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport javax.crypto.SecretKey; 2016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport javax.crypto.ShortBufferException; 2179d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giroimport javax.crypto.interfaces.PBEKey; 2216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport javax.crypto.spec.IvParameterSpec; 234936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian// BEGIN Android-added: Various key-handling modifications 2464fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giroimport javax.crypto.spec.PBEKeySpec; 254936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian// END Android-added: Various key-handling modifications 2616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport javax.crypto.spec.PBEParameterSpec; 274936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian// Android-removed: Unsupported algorithms 28c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro// import javax.crypto.spec.RC2ParameterSpec; 29c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro// import javax.crypto.spec.RC5ParameterSpec; 3016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 3180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giroimport org.bouncycastle.asn1.cms.GCMParameters; 3216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.BlockCipher; 3316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.BufferedBlockCipher; 3416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.CipherParameters; 3516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.DataLengthException; 3616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.InvalidCipherTextException; 3716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.OutputLengthException; 3816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.modes.AEADBlockCipher; 3916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.modes.CBCBlockCipher; 4016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.modes.CCMBlockCipher; 4116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.modes.CFBBlockCipher; 4216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.modes.CTSBlockCipher; 434936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian// Android-removed: Unsupported algorithms 44c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro// import org.bouncycastle.crypto.modes.EAXBlockCipher; 45c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro// import org.bouncycastle.crypto.modes.GCFBBlockCipher; 4616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.modes.GCMBlockCipher; 474936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian// Android-removed: Unsupported algorithms 48c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro// import org.bouncycastle.crypto.modes.GOFBBlockCipher; 49c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro// import org.bouncycastle.crypto.modes.OCBBlockCipher; 5016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.modes.OFBBlockCipher; 514936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian// Android-removed: Unsupported algorithms 52c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro// import org.bouncycastle.crypto.modes.OpenPGPCFBBlockCipher; 53c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro// import org.bouncycastle.crypto.modes.PGPCFBBlockCipher; 5416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.modes.SICBlockCipher; 5516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.paddings.BlockCipherPadding; 5616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.paddings.ISO10126d2Padding; 5716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.paddings.ISO7816d4Padding; 5816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; 5916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.paddings.TBCPadding; 6016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.paddings.X923Padding; 6116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.paddings.ZeroBytePadding; 6280261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giroimport org.bouncycastle.crypto.params.AEADParameters; 6316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.params.KeyParameter; 6416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.params.ParametersWithIV; 6516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.params.ParametersWithRandom; 664936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian// Android-removed: Unsupported algorithms 67c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro// import org.bouncycastle.crypto.params.ParametersWithSBox; 6816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.params.RC2Parameters; 694936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian// Android-removed: Unsupported algorithms 70c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro// import org.bouncycastle.crypto.params.RC5Parameters; 7179d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro// import org.bouncycastle.jcajce.PBKDF1Key; 7279d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro// import org.bouncycastle.jcajce.PBKDF1KeyWithParameters; 7379d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giroimport org.bouncycastle.jcajce.PKCS12Key; 7479d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giroimport org.bouncycastle.jcajce.PKCS12KeyWithParameters; 754caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giroimport org.bouncycastle.jcajce.spec.AEADParameterSpec; 764936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian// Android-removed: Unsupported algorithms 77c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro// import org.bouncycastle.jcajce.spec.GOST28147ParameterSpec; 78c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro// import org.bouncycastle.jcajce.spec.RepeatedSecretKeySpec; 7916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.util.Strings; 8016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 8116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giropublic class BaseBlockCipher 8216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro extends BaseWrapCipher 8316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro implements PBE 8416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro{ 8580261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro private static final Class gcmSpecClass = lookup("javax.crypto.spec.GCMParameterSpec"); 8680261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro 8716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro // 8816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro // specs we can handle. 8916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro // 9016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro private Class[] availableSpecs = 9116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 924936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // Android-removed: Unsupported algorithms 93c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // RC2ParameterSpec.class, 94c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // RC5ParameterSpec.class, 9579d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro gcmSpecClass, 9616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro IvParameterSpec.class, 9716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro PBEParameterSpec.class, 984936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // Android-removed: Unsupported algorithms 9979d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro // GOST28147ParameterSpec.class 10016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro }; 10116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 10216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro private BlockCipher baseEngine; 10316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro private BlockCipherProvider engineProvider; 10416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro private GenericBlockCipher cipher; 10516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro private ParametersWithIV ivParam; 10680261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro private AEADParameters aeadParams; 10716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 10879d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro private int keySizeInBits; 10979d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro private int scheme = -1; 11079d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro private int digest; 11179d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro 11216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro private int ivLength = 0; 11316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 11416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro private boolean padded; 11579d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro private boolean fixedIv = true; 11616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro private PBEParameterSpec pbeSpec = null; 11716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro private String pbeAlgorithm = null; 11816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 11916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro private String modeName = null; 12016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 12180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro private static Class lookup(String className) 12280261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro { 12380261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro try 12480261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro { 12580261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro Class def = BaseBlockCipher.class.getClassLoader().loadClass(className); 12680261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro 12780261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro return def; 12880261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro } 12980261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro catch (Exception e) 13080261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro { 13180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro return null; 13280261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro } 13380261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro } 13480261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro 13516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro protected BaseBlockCipher( 13616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro BlockCipher engine) 13716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 13816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro baseEngine = engine; 13916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 14016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro cipher = new BufferedGenericBlockCipher(engine); 14116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 14216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 14316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro protected BaseBlockCipher( 14479d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro BlockCipher engine, 14579d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro int scheme, 14679d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro int digest, 14779d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro int keySizeInBits, 14879d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro int ivLength) 14979d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro { 15079d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro baseEngine = engine; 15179d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro 15279d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro this.scheme = scheme; 15379d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro this.digest = digest; 15479d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro this.keySizeInBits = keySizeInBits; 15579d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro this.ivLength = ivLength; 15679d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro 15779d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro cipher = new BufferedGenericBlockCipher(engine); 15879d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro } 15979d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro 16079d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro protected BaseBlockCipher( 16116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro BlockCipherProvider provider) 16216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 16316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro baseEngine = provider.get(); 16416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro engineProvider = provider; 16516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 16616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro cipher = new BufferedGenericBlockCipher(provider.get()); 16716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 16816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 16916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro protected BaseBlockCipher( 17080261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro AEADBlockCipher engine) 17180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro { 1724caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro this.baseEngine = engine.getUnderlyingCipher(); 1734caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro this.ivLength = baseEngine.getBlockSize(); 1744caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro this.cipher = new AEADGenericBlockCipher(engine); 17580261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro } 17680261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro 17780261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro protected BaseBlockCipher( 17879d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro AEADBlockCipher engine, 17979d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro boolean fixedIv, 18079d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro int ivLength) 18179d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro { 18279d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro this.baseEngine = engine.getUnderlyingCipher(); 18379d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro this.fixedIv = fixedIv; 18479d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro this.ivLength = ivLength; 18579d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro this.cipher = new AEADGenericBlockCipher(engine); 18679d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro } 18779d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro 18879d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro protected BaseBlockCipher( 18916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro org.bouncycastle.crypto.BlockCipher engine, 19016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int ivLength) 19116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 19216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro baseEngine = engine; 19316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 19416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro this.cipher = new BufferedGenericBlockCipher(engine); 19516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro this.ivLength = ivLength / 8; 19616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 19716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 19816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro protected BaseBlockCipher( 19916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro BufferedBlockCipher engine, 20016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int ivLength) 20116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 20216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro baseEngine = engine.getUnderlyingCipher(); 20316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 20416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro this.cipher = new BufferedGenericBlockCipher(engine); 20516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro this.ivLength = ivLength / 8; 20616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 20716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 20816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro protected int engineGetBlockSize() 20916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 21016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return baseEngine.getBlockSize(); 21116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 21216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 21316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro protected byte[] engineGetIV() 21416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 21553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro if (aeadParams != null) 21653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 21753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro return aeadParams.getNonce(); 21853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 21953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 22016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return (ivParam != null) ? ivParam.getIV() : null; 22116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 22216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 22316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro protected int engineGetKeySize( 22416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro Key key) 22516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 22616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return key.getEncoded().length * 8; 22716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 22816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 22916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro protected int engineGetOutputSize( 23016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int inputLen) 23116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 23216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return cipher.getOutputSize(inputLen); 23316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 23416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 23516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro protected AlgorithmParameters engineGetParameters() 23616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 23716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (engineParams == null) 23816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 23916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (pbeSpec != null) 24016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 24116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro try 24216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 24353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro engineParams = createParametersInstance(pbeAlgorithm); 24416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro engineParams.init(pbeSpec); 24516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 24616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro catch (Exception e) 24716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 24816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return null; 24916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 25016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 2514caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro else if (aeadParams != null) 2524caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro { 2534caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro try 2544caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro { 2554caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro engineParams = createParametersInstance("GCM"); 2564caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro engineParams.init(new GCMParameters(aeadParams.getNonce(), aeadParams.getMacSize() / 8).getEncoded()); 2574caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro } 2584caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro catch (Exception e) 2594caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro { 2604caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro throw new RuntimeException(e.toString()); 2614caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro } 2624caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro } 26316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else if (ivParam != null) 26416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 26516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro String name = cipher.getUnderlyingCipher().getAlgorithmName(); 26616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 26716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (name.indexOf('/') >= 0) 26816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 26916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro name = name.substring(0, name.indexOf('/')); 27016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 27116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 27216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro try 27316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 27453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro engineParams = createParametersInstance(name); 2756b5b8b2f1e184da74aa4b2d083cb3f6a3c227844Adam Vartanian // Android-changed: Use IvParameterSpec instead of passing raw bytes. 2766b5b8b2f1e184da74aa4b2d083cb3f6a3c227844Adam Vartanian // The documentation of init() says that a byte array should be decoded 2776b5b8b2f1e184da74aa4b2d083cb3f6a3c227844Adam Vartanian // as ASN.1, and Conscrypt's implementations follow that requirement, 2786b5b8b2f1e184da74aa4b2d083cb3f6a3c227844Adam Vartanian // even though Bouncy Castle's implementations don't. Wrapping it in 2796b5b8b2f1e184da74aa4b2d083cb3f6a3c227844Adam Vartanian // an IvParameterSpec makes the interpretation unambiguous to both. 2806b5b8b2f1e184da74aa4b2d083cb3f6a3c227844Adam Vartanian engineParams.init(new IvParameterSpec(ivParam.getIV())); 28116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 28216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro catch (Exception e) 28316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 28416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throw new RuntimeException(e.toString()); 28516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 28616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 28716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 28816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 28916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return engineParams; 29016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 29116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 29216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro protected void engineSetMode( 29316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro String mode) 29416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throws NoSuchAlgorithmException 29516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 29616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro modeName = Strings.toUpperCase(mode); 29716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 29816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (modeName.equals("ECB")) 29916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 30016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro ivLength = 0; 30116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro cipher = new BufferedGenericBlockCipher(baseEngine); 30216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 30316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else if (modeName.equals("CBC")) 30416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 30516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro ivLength = baseEngine.getBlockSize(); 30616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro cipher = new BufferedGenericBlockCipher( 30716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro new CBCBlockCipher(baseEngine)); 30816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 30916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else if (modeName.startsWith("OFB")) 31016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 31116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro ivLength = baseEngine.getBlockSize(); 31216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (modeName.length() != 3) 31316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 31416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int wordSize = Integer.parseInt(modeName.substring(3)); 31516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 31616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro cipher = new BufferedGenericBlockCipher( 31716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro new OFBBlockCipher(baseEngine, wordSize)); 31816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 31916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else 32016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 32116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro cipher = new BufferedGenericBlockCipher( 32216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro new OFBBlockCipher(baseEngine, 8 * baseEngine.getBlockSize())); 32316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 32416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 32516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else if (modeName.startsWith("CFB")) 32616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 32716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro ivLength = baseEngine.getBlockSize(); 32816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (modeName.length() != 3) 32916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 33016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int wordSize = Integer.parseInt(modeName.substring(3)); 33116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 33216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro cipher = new BufferedGenericBlockCipher( 33316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro new CFBBlockCipher(baseEngine, wordSize)); 33416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 33516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else 33616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 33716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro cipher = new BufferedGenericBlockCipher( 33816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro new CFBBlockCipher(baseEngine, 8 * baseEngine.getBlockSize())); 33916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 34016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 3414936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // BEGIN Android-removed: Unsupported modes 3424936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian /* 3434936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian else if (modeName.startsWith("PGP")) 3444936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 3454936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian boolean inlineIV = modeName.equalsIgnoreCase("PGPCFBwithIV"); 3464936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian 3474936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian ivLength = baseEngine.getBlockSize(); 3484936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian cipher = new BufferedGenericBlockCipher( 3494936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian new PGPCFBBlockCipher(baseEngine, inlineIV)); 3504936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 3514936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian else if (modeName.equalsIgnoreCase("OpenPGPCFB")) 3524936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 3534936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian ivLength = 0; 3544936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian cipher = new BufferedGenericBlockCipher( 3554936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian new OpenPGPCFBBlockCipher(baseEngine)); 3564936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 3574936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian else if (modeName.startsWith("SIC")) 3584936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 3594936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian ivLength = baseEngine.getBlockSize(); 3604936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian if (ivLength < 16) 3614936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 3624936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian throw new IllegalArgumentException("Warning: SIC-Mode can become a twotime-pad if the blocksize of the cipher is too small. Use a cipher with a block size of at least 128 bits (e.g. AES)"); 3634936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 3644936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian fixedIv = false; 3654936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher( 3664936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian new SICBlockCipher(baseEngine))); 3674936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 3684936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian */ 3694936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // END Android-removed: Unsupported modes 37016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else if (modeName.startsWith("CTR")) 37116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 37216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro ivLength = baseEngine.getBlockSize(); 37379d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro fixedIv = false; 37416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher( 37516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro new SICBlockCipher(baseEngine))); 37616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 3774936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // BEGIN Android-removed: Unsupported modes 3784936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian /* 3794936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian else if (modeName.startsWith("GOFB")) 3804936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 3814936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian ivLength = baseEngine.getBlockSize(); 3824936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher( 3834936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian new GOFBBlockCipher(baseEngine))); 3844936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 3854936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian else if (modeName.startsWith("GCFB")) 3864936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 3874936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian ivLength = baseEngine.getBlockSize(); 3884936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher( 3894936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian new GCFBBlockCipher(baseEngine))); 3904936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 3914936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian */ 3924936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // END Android-removed: Unsupported modes 39316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else if (modeName.startsWith("CTS")) 39416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 39516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro ivLength = baseEngine.getBlockSize(); 39616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro cipher = new BufferedGenericBlockCipher(new CTSBlockCipher(new CBCBlockCipher(baseEngine))); 39716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 39816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else if (modeName.startsWith("CCM")) 39916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 40080261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro ivLength = 13; // CCM nonce 7..13 bytes 40116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro cipher = new AEADGenericBlockCipher(new CCMBlockCipher(baseEngine)); 40216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 4034936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // BEGIN Android-removed: Unsupported modes 4044936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian /* 4054936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian else if (modeName.startsWith("OCB")) 4064936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 4074936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian if (engineProvider != null) 4084936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 4094936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian /* 4104936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian * RFC 7253 4.2. Nonce is a string of no more than 120 bits 4114936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian * 4124936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian ivLength = 15; 4134936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian cipher = new AEADGenericBlockCipher(new OCBBlockCipher(baseEngine, engineProvider.get())); 4144936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 4154936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian else 4164936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 4174936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian throw new NoSuchAlgorithmException("can't support mode " + mode); 4184936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 4194936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 4204936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian else if (modeName.startsWith("EAX")) 4214936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 4224936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian ivLength = baseEngine.getBlockSize(); 4234936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian cipher = new AEADGenericBlockCipher(new EAXBlockCipher(baseEngine)); 4244936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 4254936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian */ 4264936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // END Android-removed: Unsupported modes 42716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else if (modeName.startsWith("GCM")) 42816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 42916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro ivLength = baseEngine.getBlockSize(); 43016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro cipher = new AEADGenericBlockCipher(new GCMBlockCipher(baseEngine)); 43116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 43216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else 43316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 43416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throw new NoSuchAlgorithmException("can't support mode " + mode); 43516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 43616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 43716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 43816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro protected void engineSetPadding( 43916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro String padding) 44016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throws NoSuchPaddingException 44116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 44216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro String paddingName = Strings.toUpperCase(padding); 44316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 44416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (paddingName.equals("NOPADDING")) 44516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 44616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (cipher.wrapOnNoPadding()) 44716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 44816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(cipher.getUnderlyingCipher())); 44916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 45016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 45116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else if (paddingName.equals("WITHCTS")) 45216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 45316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro cipher = new BufferedGenericBlockCipher(new CTSBlockCipher(cipher.getUnderlyingCipher())); 45416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 45516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else 45616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 45716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro padded = true; 45816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 45916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (isAEADModeName(modeName)) 46016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 46116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throw new NoSuchPaddingException("Only NoPadding can be used with AEAD modes."); 46216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 46316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else if (paddingName.equals("PKCS5PADDING") || paddingName.equals("PKCS7PADDING")) 46416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 46516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro cipher = new BufferedGenericBlockCipher(cipher.getUnderlyingCipher()); 46616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 46716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else if (paddingName.equals("ZEROBYTEPADDING")) 46816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 46916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro cipher = new BufferedGenericBlockCipher(cipher.getUnderlyingCipher(), new ZeroBytePadding()); 47016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 47116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else if (paddingName.equals("ISO10126PADDING") || paddingName.equals("ISO10126-2PADDING")) 47216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 47316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro cipher = new BufferedGenericBlockCipher(cipher.getUnderlyingCipher(), new ISO10126d2Padding()); 47416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 47516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else if (paddingName.equals("X9.23PADDING") || paddingName.equals("X923PADDING")) 47616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 47716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro cipher = new BufferedGenericBlockCipher(cipher.getUnderlyingCipher(), new X923Padding()); 47816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 47916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else if (paddingName.equals("ISO7816-4PADDING") || paddingName.equals("ISO9797-1PADDING")) 48016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 48116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro cipher = new BufferedGenericBlockCipher(cipher.getUnderlyingCipher(), new ISO7816d4Padding()); 48216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 48316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else if (paddingName.equals("TBCPADDING")) 48416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 48516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro cipher = new BufferedGenericBlockCipher(cipher.getUnderlyingCipher(), new TBCPadding()); 48616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 48716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else 48816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 48916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throw new NoSuchPaddingException("Padding " + padding + " unknown."); 49016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 49116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 49216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 49316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 4944936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // BEGIN Android-added: Handling missing IVs 4956ba5cb51e71a3b359d6bc5815f3d378336a51cb6Sergio Giro private boolean isBCPBEKeyWithoutIV(Key key) { 4966ba5cb51e71a3b359d6bc5815f3d378336a51cb6Sergio Giro return (key instanceof BCPBEKey) && !(((BCPBEKey)key).getParam() instanceof ParametersWithIV); 4976ba5cb51e71a3b359d6bc5815f3d378336a51cb6Sergio Giro } 4984936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // END Android-added: Handling missing IVs 4996ba5cb51e71a3b359d6bc5815f3d378336a51cb6Sergio Giro 50016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro protected void engineInit( 50116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int opmode, 50216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro Key key, 50316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro AlgorithmParameterSpec params, 50416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro SecureRandom random) 50516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throws InvalidKeyException, InvalidAlgorithmParameterException 50616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 50716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro CipherParameters param; 50816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 50916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro this.pbeSpec = null; 51016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro this.pbeAlgorithm = null; 51116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro this.engineParams = null; 51280261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro this.aeadParams = null; 51316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 51416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro // 51516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro // basic key check 51616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro // 51716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (!(key instanceof SecretKey)) 51816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 5194caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro throw new InvalidKeyException("Key for algorithm " + ((key != null) ? key.getAlgorithm() : null) + " not suitable for symmetric enryption."); 52016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 52116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 52216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro // 52316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro // for RC5-64 we must have some default parameters 52416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro // 52516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (params == null && baseEngine.getAlgorithmName().startsWith("RC5-64")) 52616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 52716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throw new InvalidAlgorithmParameterException("RC5 requires an RC5ParametersSpec to be passed in."); 52816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 52916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 53016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro // 53116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro // a note on iv's - if ivLength is zero the IV gets ignored (we don't use it). 53216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro // 5334936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // BEGIN Android-changed: Don't use PKCS12 with missing IV. 5346ba5cb51e71a3b359d6bc5815f3d378336a51cb6Sergio Giro // If the key is a BCPBE one without an IV, ignore the fact that the scheme is PKCS12. 5354936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // if (scheme == PKCS12 || key instanceof PKCS12Key) 5366ba5cb51e71a3b359d6bc5815f3d378336a51cb6Sergio Giro if ((scheme == PKCS12 || key instanceof PKCS12Key) && !isBCPBEKeyWithoutIV(key)) 5374936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // END Android-changed: Don't use PKCS12 with missing IV. 53879d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro { 53979d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro SecretKey k; 54079d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro try 54179d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro { 54279d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro k = (SecretKey)key; 54379d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro } 54479d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro catch (Exception e) 54579d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro { 54679d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro throw new InvalidKeyException("PKCS12 requires a SecretKey/PBEKey"); 54779d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro } 54879d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro 54979d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro if (params instanceof PBEParameterSpec) 55079d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro { 55179d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro pbeSpec = (PBEParameterSpec)params; 55279d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro } 55379d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro 55479d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro if (k instanceof PBEKey && pbeSpec == null) 55579d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro { 5564caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro PBEKey pbeKey = (PBEKey)k; 5574caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro if (pbeKey.getSalt() == null) 5584caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro { 5594caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro throw new InvalidAlgorithmParameterException("PBEKey requires parameters to specify salt"); 56079d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro } 5614caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro pbeSpec = new PBEParameterSpec(pbeKey.getSalt(), pbeKey.getIterationCount()); 56279d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro } 56379d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro 56479d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro if (pbeSpec == null && !(k instanceof PBEKey)) 56579d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro { 56679d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro throw new InvalidKeyException("Algorithm requires a PBE key"); 56779d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro } 5684caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro 56979d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro if (key instanceof BCPBEKey) 57079d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro { 5714caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro // PKCS#12 sets an IV, if we get a key that doesn't have ParametersWithIV we need to reject it. If the 5724caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro // key has no parameters it means it's an old-school JCE PBE Key - we use getEncoded() on it. 5734caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro CipherParameters pbeKeyParam = ((BCPBEKey)key).getParam(); 5744caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro if (pbeKeyParam instanceof ParametersWithIV) 57579d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro { 5764caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro param = pbeKeyParam; 57779d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro } 5784caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro else if (pbeKeyParam == null) 57979d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro { 5804936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // BEGIN Android-changed: Unreachable code 581d07596fb6810cd74cf719bf6467b7bc96d07e9f9Adam Vartanian // See above for the Android change that makes this code unreachable. 5824936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // param = PBE.Util.makePBEParameters(k.getEncoded(), PKCS12, digest, keySizeInBits, ivLength * 8, pbeSpec, cipher.getAlgorithmName()); 5834936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian throw new AssertionError("Unreachable code"); 5844936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // END Android-changed: Unreachable code 58579d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro } 5864caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro else 5874caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro { 5884caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro throw new InvalidKeyException("Algorithm requires a PBE key suitable for PKCS12"); 5894caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro } 59079d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro } 59179d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro else 59279d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro { 59379d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro param = PBE.Util.makePBEParameters(k.getEncoded(), PKCS12, digest, keySizeInBits, ivLength * 8, pbeSpec, cipher.getAlgorithmName()); 59479d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro } 59579d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro if (param instanceof ParametersWithIV) 59679d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro { 59779d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro ivParam = (ParametersWithIV)param; 59879d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro } 59979d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro } 6004936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // BEGIN Android-removed: Unsupported algorithms 6014936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian /* 6024936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian else if (key instanceof PBKDF1Key) 6034936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 6044936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian PBKDF1Key k = (PBKDF1Key)key; 6054936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian 6064936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian if (params instanceof PBEParameterSpec) 6074936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 6084936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian pbeSpec = (PBEParameterSpec)params; 6094936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 6104936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian if (k instanceof PBKDF1KeyWithParameters && pbeSpec == null) 6114936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 6124936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian pbeSpec = new PBEParameterSpec(((PBKDF1KeyWithParameters)k).getSalt(), ((PBKDF1KeyWithParameters)k).getIterationCount()); 6134936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 6144936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian 6154936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian param = PBE.Util.makePBEParameters(k.getEncoded(), PKCS5S1, digest, keySizeInBits, ivLength * 8, pbeSpec, cipher.getAlgorithmName()); 6164936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian if (param instanceof ParametersWithIV) 6174936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 6184936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian ivParam = (ParametersWithIV)param; 6194936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 6204936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 6214936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian */ 6224936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // END Android-removed: Unsupported algorithms 62379d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro else if (key instanceof BCPBEKey) 62416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 62516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro BCPBEKey k = (BCPBEKey)key; 62616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 62716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (k.getOID() != null) 62816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 62916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro pbeAlgorithm = k.getOID().getId(); 63016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 63116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else 63216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 63316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro pbeAlgorithm = k.getAlgorithm(); 63416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 63516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 63616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (k.getParam() != null) 63716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 63879d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro param = adjustParameters(params, k.getParam()); 63916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 64016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else if (params instanceof PBEParameterSpec) 64116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 64216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro pbeSpec = (PBEParameterSpec)params; 6434936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // BEGIN Android-added: Allow PBE keys with only passwords. 64465832e311cb5fda062d79599b149232b47294feaAdam Vartanian // At this point, k.getParam() == null, so the key hasn't been generated. If 64565832e311cb5fda062d79599b149232b47294feaAdam Vartanian // the parameters have non-default values, recreate the BCPBEKey from algorithm 64665832e311cb5fda062d79599b149232b47294feaAdam Vartanian // parameters as to generate the key. 64765832e311cb5fda062d79599b149232b47294feaAdam Vartanian if ((pbeSpec.getSalt().length != 0) && (pbeSpec.getIterationCount() > 0)) { 64865832e311cb5fda062d79599b149232b47294feaAdam Vartanian k = new BCPBEKey(k.getAlgorithm(), k.getOID(), k.getType(), k.getDigest(), 64965832e311cb5fda062d79599b149232b47294feaAdam Vartanian k.getKeySize(), k.getIvSize(), 65065832e311cb5fda062d79599b149232b47294feaAdam Vartanian new PBEKeySpec( 65165832e311cb5fda062d79599b149232b47294feaAdam Vartanian k.getPassword(), pbeSpec.getSalt(), pbeSpec.getIterationCount(), 65265832e311cb5fda062d79599b149232b47294feaAdam Vartanian k.getKeySize()), 65365832e311cb5fda062d79599b149232b47294feaAdam Vartanian null /* CipherParameters */); 65465832e311cb5fda062d79599b149232b47294feaAdam Vartanian } 6554936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // END Android-added: Allow PBE keys with only passwords. 65616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro param = PBE.Util.makePBEParameters(k, params, cipher.getUnderlyingCipher().getAlgorithmName()); 65716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 65816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else 65916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 66016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throw new InvalidAlgorithmParameterException("PBE requires PBE parameters to be set."); 66116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 66216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 66316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (param instanceof ParametersWithIV) 66416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 66516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro ivParam = (ParametersWithIV)param; 66616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 66716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 66879d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro else if (key instanceof PBEKey) 66916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 67079d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro PBEKey k = (PBEKey)key; 67179d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro pbeSpec = (PBEParameterSpec)params; 67279d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro if (k instanceof PKCS12KeyWithParameters && pbeSpec == null) 67379d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro { 67479d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro pbeSpec = new PBEParameterSpec(k.getSalt(), k.getIterationCount()); 67579d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro } 67679d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro 67779d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro param = PBE.Util.makePBEParameters(k.getEncoded(), scheme, digest, keySizeInBits, ivLength * 8, pbeSpec, cipher.getAlgorithmName()); 67879d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro if (param instanceof ParametersWithIV) 67979d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro { 68079d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro ivParam = (ParametersWithIV)param; 68179d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro } 68279d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro } 6834936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // BEGIN Android-changed: Unsupported algorithm 6844936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // else if (!(key instanceof RepeatedSecretKeySpec)) 68579d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro else 6864936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // END Android-changed: Unsupported algorithms 68779d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro { 68879d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro if (scheme == PKCS5S1 || scheme == PKCS5S1_UTF8 || scheme == PKCS5S2 || scheme == PKCS5S2_UTF8) 68979d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro { 69079d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro throw new InvalidKeyException("Algorithm requires a PBE key"); 69179d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro } 69216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro param = new KeyParameter(key.getEncoded()); 69316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 6944936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // BEGIN Android-removed: Unreachable 69579d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro // else 69679d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro // { 69779d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro // param = null; 69879d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro // } 6994936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // END Android-removed: Unreachable 70079d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro 7014caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro if (params instanceof AEADParameterSpec) 7024caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro { 7034caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro if (!isAEADModeName(modeName) && !(cipher instanceof AEADGenericBlockCipher)) 7044caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro { 7054caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro throw new InvalidAlgorithmParameterException("AEADParameterSpec can only be used with AEAD modes."); 7064caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro } 7074caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro 7084caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro AEADParameterSpec aeadSpec = (AEADParameterSpec)params; 7094caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro 7104caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro KeyParameter keyParam; 7114caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro if (param instanceof ParametersWithIV) 7124caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro { 7134caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro keyParam = (KeyParameter)((ParametersWithIV)param).getParameters(); 7144caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro } 7154caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro else 7164caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro { 7174caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro keyParam = (KeyParameter)param; 7184caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro } 7194caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro param = aeadParams = new AEADParameters(keyParam, aeadSpec.getMacSizeInBits(), aeadSpec.getNonce(), aeadSpec.getAssociatedData()); 7204caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro } 7214caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro else if (params instanceof IvParameterSpec) 72216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 72316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (ivLength != 0) 72416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 72516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro IvParameterSpec p = (IvParameterSpec)params; 72616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 72779d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro if (p.getIV().length != ivLength && !(cipher instanceof AEADGenericBlockCipher) && fixedIv) 72816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 72916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throw new InvalidAlgorithmParameterException("IV must be " + ivLength + " bytes long."); 73016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 73116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 73279d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro if (param instanceof ParametersWithIV) 73379d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro { 73479d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro param = new ParametersWithIV(((ParametersWithIV)param).getParameters(), p.getIV()); 73579d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro } 73679d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro else 73716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 73879d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro param = new ParametersWithIV(param, p.getIV()); 73916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 74079d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro ivParam = (ParametersWithIV)param; 74116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 74216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else 74316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 74416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (modeName != null && modeName.equals("ECB")) 74516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 74616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throw new InvalidAlgorithmParameterException("ECB mode does not use an IV"); 74716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 74816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 74916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 7504936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // BEGIN Android-removed: Unsupported algorithms 7514936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian /* 7524936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian else if (params instanceof GOST28147ParameterSpec) 7534936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 7544936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian GOST28147ParameterSpec gost28147Param = (GOST28147ParameterSpec)params; 7554936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian 7564936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian param = new ParametersWithSBox( 7574936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian new KeyParameter(key.getEncoded()), ((GOST28147ParameterSpec)params).getSbox()); 7584936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian 7594936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian if (gost28147Param.getIV() != null && ivLength != 0) 7604936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 7614936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian if (param instanceof ParametersWithIV) 7624936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 7634936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian param = new ParametersWithIV(((ParametersWithIV)param).getParameters(), gost28147Param.getIV()); 7644936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 7654936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian else 7664936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 7674936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian param = new ParametersWithIV(param, gost28147Param.getIV()); 7684936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 7694936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian ivParam = (ParametersWithIV)param; 7704936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 7714936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 7724936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian else if (params instanceof RC2ParameterSpec) 7734936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 7744936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian RC2ParameterSpec rc2Param = (RC2ParameterSpec)params; 7754936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian 7764936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian param = new RC2Parameters(key.getEncoded(), ((RC2ParameterSpec)params).getEffectiveKeyBits()); 7774936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian 7784936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian if (rc2Param.getIV() != null && ivLength != 0) 7794936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 7804936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian if (param instanceof ParametersWithIV) 7814936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 7824936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian param = new ParametersWithIV(((ParametersWithIV)param).getParameters(), rc2Param.getIV()); 7834936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 7844936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian else 7854936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 7864936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian param = new ParametersWithIV(param, rc2Param.getIV()); 7874936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 7884936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian ivParam = (ParametersWithIV)param; 7894936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 7904936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 7914936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian else if (params instanceof RC5ParameterSpec) 7924936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 7934936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian RC5ParameterSpec rc5Param = (RC5ParameterSpec)params; 7944936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian 7954936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian param = new RC5Parameters(key.getEncoded(), ((RC5ParameterSpec)params).getRounds()); 7964936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian if (baseEngine.getAlgorithmName().startsWith("RC5")) 7974936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 7984936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian if (baseEngine.getAlgorithmName().equals("RC5-32")) 7994936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 8004936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian if (rc5Param.getWordSize() != 32) 8014936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 8024936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian throw new InvalidAlgorithmParameterException("RC5 already set up for a word size of 32 not " + rc5Param.getWordSize() + "."); 8034936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 8044936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 8054936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian else if (baseEngine.getAlgorithmName().equals("RC5-64")) 8064936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 8074936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian if (rc5Param.getWordSize() != 64) 8084936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 8094936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian throw new InvalidAlgorithmParameterException("RC5 already set up for a word size of 64 not " + rc5Param.getWordSize() + "."); 8104936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 8114936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 8124936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 8134936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian else 8144936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 8154936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian throw new InvalidAlgorithmParameterException("RC5 parameters passed to a cipher that is not RC5."); 8164936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 8174936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian if ((rc5Param.getIV() != null) && (ivLength != 0)) 8184936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 8194936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian if (param instanceof ParametersWithIV) 8204936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 8214936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian param = new ParametersWithIV(((ParametersWithIV)param).getParameters(), rc5Param.getIV()); 8224936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 8234936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian else 8244936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 8254936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian param = new ParametersWithIV(param, rc5Param.getIV()); 8264936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 8274936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian ivParam = (ParametersWithIV)param; 8284936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 8294936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 8304936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian */ 8314936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // END Android-removed: Unsupported algorithms 83280261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro else if (gcmSpecClass != null && gcmSpecClass.isInstance(params)) 83380261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro { 83480261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro if (!isAEADModeName(modeName) && !(cipher instanceof AEADGenericBlockCipher)) 83580261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro { 83680261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro throw new InvalidAlgorithmParameterException("GCMParameterSpec can only be used with AEAD modes."); 83780261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro } 83880261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro 83980261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro try 84080261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro { 84180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro Method tLen = gcmSpecClass.getDeclaredMethod("getTLen", new Class[0]); 84280261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro Method iv= gcmSpecClass.getDeclaredMethod("getIV", new Class[0]); 84380261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro 84479d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro KeyParameter keyParam; 84579d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro if (param instanceof ParametersWithIV) 84680261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro { 84779d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro keyParam = (KeyParameter)((ParametersWithIV)param).getParameters(); 84880261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro } 84979d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro else 85079d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro { 85179d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro keyParam = (KeyParameter)param; 85279d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro } 85379d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro param = aeadParams = new AEADParameters(keyParam, ((Integer)tLen.invoke(params, new Object[0])).intValue(), (byte[])iv.invoke(params, new Object[0])); 85480261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro } 85580261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro catch (Exception e) 85680261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro { 85780261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro throw new InvalidAlgorithmParameterException("Cannot process GCMParameterSpec."); 85880261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro } 85980261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro } 86079d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro else if (params != null && !(params instanceof PBEParameterSpec)) 86116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 86216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throw new InvalidAlgorithmParameterException("unknown parameter type."); 86316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 86416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 86580261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro if ((ivLength != 0) && !(param instanceof ParametersWithIV) && !(param instanceof AEADParameters)) 86616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 86716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro SecureRandom ivRandom = random; 86816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 86916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (ivRandom == null) 87016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 87116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro ivRandom = new SecureRandom(); 87216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 8734936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian 87416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if ((opmode == Cipher.ENCRYPT_MODE) || (opmode == Cipher.WRAP_MODE)) 87516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 87616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro byte[] iv = new byte[ivLength]; 87716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 878d07596fb6810cd74cf719bf6467b7bc96d07e9f9Adam Vartanian // BEGIN Android-changed: For PBE keys with no IV, log and use IV of 0 879d07596fb6810cd74cf719bf6467b7bc96d07e9f9Adam Vartanian // These keys were accepted in BC 1.52 (and treated as having an IV of 0) but 880d07596fb6810cd74cf719bf6467b7bc96d07e9f9Adam Vartanian // rejected outright in BC 1.54 (even if an IV was passed in params). We 881d07596fb6810cd74cf719bf6467b7bc96d07e9f9Adam Vartanian // want the eventual state to be that an IV can be passed in params, but the key 882d07596fb6810cd74cf719bf6467b7bc96d07e9f9Adam Vartanian // is rejected otherwise. For now, log that these will be rejected in a future 883d07596fb6810cd74cf719bf6467b7bc96d07e9f9Adam Vartanian // release. See b/27995180 for historical details. 8844936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // ivRandom.nextBytes(iv); 8856ba5cb51e71a3b359d6bc5815f3d378336a51cb6Sergio Giro if (!isBCPBEKeyWithoutIV(key)) { 8866ba5cb51e71a3b359d6bc5815f3d378336a51cb6Sergio Giro ivRandom.nextBytes(iv); 887d07596fb6810cd74cf719bf6467b7bc96d07e9f9Adam Vartanian } else { 888d07596fb6810cd74cf719bf6467b7bc96d07e9f9Adam Vartanian // TODO(b/70275132): Change to rejecting these keys 889d07596fb6810cd74cf719bf6467b7bc96d07e9f9Adam Vartanian System.err.println(" ******** DEPRECATED FUNCTIONALITY ********"); 890d07596fb6810cd74cf719bf6467b7bc96d07e9f9Adam Vartanian System.err.println(" * You have initialized a cipher with a PBE key with no IV and"); 891d07596fb6810cd74cf719bf6467b7bc96d07e9f9Adam Vartanian System.err.println(" * have not provided an IV in the AlgorithmParameterSpec. This"); 892d07596fb6810cd74cf719bf6467b7bc96d07e9f9Adam Vartanian System.err.println(" * configuration is deprecated. The cipher will be initialized"); 893d07596fb6810cd74cf719bf6467b7bc96d07e9f9Adam Vartanian System.err.println(" * with an all-zero IV, but in a future release this call will"); 894d07596fb6810cd74cf719bf6467b7bc96d07e9f9Adam Vartanian System.err.println(" * throw an exception."); 895d07596fb6810cd74cf719bf6467b7bc96d07e9f9Adam Vartanian new InvalidAlgorithmParameterException("No IV set when using PBE key") 896d07596fb6810cd74cf719bf6467b7bc96d07e9f9Adam Vartanian .printStackTrace(System.err); 8976ba5cb51e71a3b359d6bc5815f3d378336a51cb6Sergio Giro } 898d07596fb6810cd74cf719bf6467b7bc96d07e9f9Adam Vartanian // END Android-changed: For PBE keys with no IV, log and use IV of 0 89916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro param = new ParametersWithIV(param, iv); 90016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro ivParam = (ParametersWithIV)param; 90116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 90216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else if (cipher.getUnderlyingCipher().getAlgorithmName().indexOf("PGPCFB") < 0) 90316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 904d07596fb6810cd74cf719bf6467b7bc96d07e9f9Adam Vartanian // BEGIN Android-changed: For PBE keys with no IV, log and use IV of 0 905d07596fb6810cd74cf719bf6467b7bc96d07e9f9Adam Vartanian // These keys were accepted in BC 1.52 (and treated as having an IV of 0) but 906d07596fb6810cd74cf719bf6467b7bc96d07e9f9Adam Vartanian // rejected outright in BC 1.54 (even if an IV was passed in params). We 907d07596fb6810cd74cf719bf6467b7bc96d07e9f9Adam Vartanian // want the eventual state to be that an IV can be passed in params, but the key 908d07596fb6810cd74cf719bf6467b7bc96d07e9f9Adam Vartanian // is rejected otherwise. For now, log that these will be rejected in a future 909d07596fb6810cd74cf719bf6467b7bc96d07e9f9Adam Vartanian // release. See b/27995180 for historical details. 9104936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // throw new InvalidAlgorithmParameterException("no IV set when one expected"); 9116ba5cb51e71a3b359d6bc5815f3d378336a51cb6Sergio Giro if (!isBCPBEKeyWithoutIV(key)) { 9126ba5cb51e71a3b359d6bc5815f3d378336a51cb6Sergio Giro throw new InvalidAlgorithmParameterException("no IV set when one expected"); 9136ba5cb51e71a3b359d6bc5815f3d378336a51cb6Sergio Giro } else { 914d07596fb6810cd74cf719bf6467b7bc96d07e9f9Adam Vartanian // TODO(b/70275132): Change to rejecting these keys 915d07596fb6810cd74cf719bf6467b7bc96d07e9f9Adam Vartanian System.err.println(" ******** DEPRECATED FUNCTIONALITY ********"); 916d07596fb6810cd74cf719bf6467b7bc96d07e9f9Adam Vartanian System.err.println(" * You have initialized a cipher with a PBE key with no IV and"); 917d07596fb6810cd74cf719bf6467b7bc96d07e9f9Adam Vartanian System.err.println(" * have not provided an IV in the AlgorithmParameterSpec. This"); 918d07596fb6810cd74cf719bf6467b7bc96d07e9f9Adam Vartanian System.err.println(" * configuration is deprecated. The cipher will be initialized"); 919d07596fb6810cd74cf719bf6467b7bc96d07e9f9Adam Vartanian System.err.println(" * with an all-zero IV, but in a future release this call will"); 920d07596fb6810cd74cf719bf6467b7bc96d07e9f9Adam Vartanian System.err.println(" * throw an exception."); 921d07596fb6810cd74cf719bf6467b7bc96d07e9f9Adam Vartanian new InvalidAlgorithmParameterException("No IV set when using PBE key") 922d07596fb6810cd74cf719bf6467b7bc96d07e9f9Adam Vartanian .printStackTrace(System.err); 9236ba5cb51e71a3b359d6bc5815f3d378336a51cb6Sergio Giro // Mimic behaviour in 1.52 by using an IV of 0's 9246ba5cb51e71a3b359d6bc5815f3d378336a51cb6Sergio Giro param = new ParametersWithIV(param, new byte[ivLength]); 9256ba5cb51e71a3b359d6bc5815f3d378336a51cb6Sergio Giro ivParam = (ParametersWithIV)param; 9266ba5cb51e71a3b359d6bc5815f3d378336a51cb6Sergio Giro } 927d07596fb6810cd74cf719bf6467b7bc96d07e9f9Adam Vartanian // END Android-changed: For PBE keys with no IV, log and use IV of 0 92816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 92916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 93016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 9314caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro 9324caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro 93316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (random != null && padded) 93416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 93516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro param = new ParametersWithRandom(param, random); 93616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 93716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 93816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro try 93916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 94016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro switch (opmode) 94116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 94216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro case Cipher.ENCRYPT_MODE: 94316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro case Cipher.WRAP_MODE: 94416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro cipher.init(true, param); 94516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro break; 94616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro case Cipher.DECRYPT_MODE: 94716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro case Cipher.UNWRAP_MODE: 94816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro cipher.init(false, param); 94916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro break; 95016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro default: 95116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throw new InvalidParameterException("unknown opmode " + opmode + " passed"); 95216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 9534caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro 9544caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro if (cipher instanceof AEADGenericBlockCipher && aeadParams == null) 9554caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro { 9564caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro AEADBlockCipher aeadCipher = ((AEADGenericBlockCipher)cipher).cipher; 9574caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro 9584caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro aeadParams = new AEADParameters((KeyParameter)ivParam.getParameters(), aeadCipher.getMac().length * 8, ivParam.getIV()); 9594caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro } 96016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 96179d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro catch (final Exception e) 96216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 9634caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro throw new InvalidKeyOrParametersException(e.getMessage(), e); 96416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 96516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 96616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 96779d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro private CipherParameters adjustParameters(AlgorithmParameterSpec params, CipherParameters param) 96879d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro { 96979d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro CipherParameters key; 97079d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro 97179d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro if (param instanceof ParametersWithIV) 97279d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro { 97379d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro key = ((ParametersWithIV)param).getParameters(); 97479d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro if (params instanceof IvParameterSpec) 97579d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro { 97679d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro IvParameterSpec iv = (IvParameterSpec)params; 97779d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro 97879d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro ivParam = new ParametersWithIV(key, iv.getIV()); 97979d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro param = ivParam; 98079d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro } 9814936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // BEGIN Android-removed: Unsupported algorithms 9824936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian /* 9834936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian else if (params instanceof GOST28147ParameterSpec) 9844936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 9854936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // need to pick up IV and SBox. 9864936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian GOST28147ParameterSpec gost28147Param = (GOST28147ParameterSpec)params; 9874936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian 9884936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian param = new ParametersWithSBox(param, gost28147Param.getSbox()); 9894936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian 9904936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian if (gost28147Param.getIV() != null && ivLength != 0) 9914936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 9924936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian ivParam = new ParametersWithIV(key, gost28147Param.getIV()); 9934936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian param = ivParam; 9944936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 9954936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 9964936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian */ 9974936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // END Android-removed: Unsupported algorithms 99879d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro } 99979d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro else 100079d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro { 100179d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro if (params instanceof IvParameterSpec) 100279d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro { 100379d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro IvParameterSpec iv = (IvParameterSpec)params; 100479d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro 100579d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro ivParam = new ParametersWithIV(param, iv.getIV()); 100679d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro param = ivParam; 100779d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro } 10084936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // BEGIN Android-removed: Unsupported algorithms 10094936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian /* 10104936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian else if (params instanceof GOST28147ParameterSpec) 10114936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 10124936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // need to pick up IV and SBox. 10134936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian GOST28147ParameterSpec gost28147Param = (GOST28147ParameterSpec)params; 10144936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian 10154936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian param = new ParametersWithSBox(param, gost28147Param.getSbox()); 10164936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian 10174936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian if (gost28147Param.getIV() != null && ivLength != 0) 10184936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian { 10194936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian param = new ParametersWithIV(param, gost28147Param.getIV()); 10204936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 10214936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian } 10224936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian */ 10234936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // END Android-removed: Unsupported algorithms 102479d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro } 102579d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro return param; 102679d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro } 102779d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro 102816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro protected void engineInit( 102916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int opmode, 103016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro Key key, 103116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro AlgorithmParameters params, 103216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro SecureRandom random) 103316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throws InvalidKeyException, InvalidAlgorithmParameterException 103416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 103516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro AlgorithmParameterSpec paramSpec = null; 103616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 103716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (params != null) 103816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 103916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro for (int i = 0; i != availableSpecs.length; i++) 104016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 104180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro if (availableSpecs[i] == null) 104280261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro { 104380261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro continue; 104480261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro } 104580261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro 104616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro try 104716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 104816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro paramSpec = params.getParameterSpec(availableSpecs[i]); 104916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro break; 105016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 105116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro catch (Exception e) 105216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 105316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro // try again if possible 105416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 105516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 105616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 105716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (paramSpec == null) 105816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 105916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throw new InvalidAlgorithmParameterException("can't handle parameter " + params.toString()); 106016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 106116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 106216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 106316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro engineInit(opmode, key, paramSpec, random); 106416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 106516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro engineParams = params; 106616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 106716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 106816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro protected void engineInit( 106916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int opmode, 107016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro Key key, 107116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro SecureRandom random) 107216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throws InvalidKeyException 107316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 107416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro try 107516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 107616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro engineInit(opmode, key, (AlgorithmParameterSpec)null, random); 107716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 107816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro catch (InvalidAlgorithmParameterException e) 107916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 108016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throw new InvalidKeyException(e.getMessage()); 108116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 108216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 108316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 108480261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro protected void engineUpdateAAD(byte[] input, int offset, int length) 108580261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro { 108680261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro cipher.updateAAD(input, offset, length); 108780261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro } 108880261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro 108980261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro protected void engineUpdateAAD(ByteBuffer bytebuffer) 109080261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro { 109180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro int offset = bytebuffer.arrayOffset() + bytebuffer.position(); 109280261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro int length = bytebuffer.limit() - bytebuffer.position(); 109380261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro engineUpdateAAD(bytebuffer.array(), offset, length); 109480261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro } 109580261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro 109616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro protected byte[] engineUpdate( 109716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro byte[] input, 109816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int inputOffset, 109916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int inputLen) 110016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 110116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int length = cipher.getUpdateOutputSize(inputLen); 110216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 110316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (length > 0) 110416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 110516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro byte[] out = new byte[length]; 110616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 110716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int len = cipher.processBytes(input, inputOffset, inputLen, out, 0); 110816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 110916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (len == 0) 111016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 111116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return null; 111216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 111316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else if (len != out.length) 111416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 111516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro byte[] tmp = new byte[len]; 111616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 111716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro System.arraycopy(out, 0, tmp, 0, len); 111816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 111916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return tmp; 112016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 112116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 112216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return out; 112316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 112416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 112516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro cipher.processBytes(input, inputOffset, inputLen, null, 0); 112616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 112716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return null; 112816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 112916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 113016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro protected int engineUpdate( 113116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro byte[] input, 113216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int inputOffset, 113316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int inputLen, 113416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro byte[] output, 113516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int outputOffset) 113616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throws ShortBufferException 113716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 113879d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro if (outputOffset + cipher.getUpdateOutputSize(inputLen) > output.length) 113979d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro { 114079d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro throw new ShortBufferException("output buffer too short for input."); 114179d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro } 114279d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro 114316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro try 114416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 114516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return cipher.processBytes(input, inputOffset, inputLen, output, outputOffset); 114616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 114716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro catch (DataLengthException e) 114816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 114979d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro // should never occur 115079d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro throw new IllegalStateException(e.toString()); 115116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 115216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 115316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 115416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro protected byte[] engineDoFinal( 115516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro byte[] input, 115616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int inputOffset, 115716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int inputLen) 115816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throws IllegalBlockSizeException, BadPaddingException 115916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 116016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int len = 0; 116116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro byte[] tmp = new byte[engineGetOutputSize(inputLen)]; 116216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 116316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (inputLen != 0) 116416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 116516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro len = cipher.processBytes(input, inputOffset, inputLen, tmp, 0); 116616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 116716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 116816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro try 116916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 117016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro len += cipher.doFinal(tmp, len); 117116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 117216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro catch (DataLengthException e) 117316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 117416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throw new IllegalBlockSizeException(e.getMessage()); 117516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 117616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 117716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (len == tmp.length) 117816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 117916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return tmp; 118016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 118116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 118216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro byte[] out = new byte[len]; 118316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 118416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro System.arraycopy(tmp, 0, out, 0, len); 118516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 118616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return out; 118716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 118816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 118916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro protected int engineDoFinal( 119016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro byte[] input, 119116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int inputOffset, 119216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int inputLen, 119316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro byte[] output, 119416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int outputOffset) 119516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throws IllegalBlockSizeException, BadPaddingException, ShortBufferException 119616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 119779d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro int len = 0; 119879d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro 119979d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro if (outputOffset + engineGetOutputSize(inputLen) > output.length) 120016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 120179d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro throw new ShortBufferException("output buffer too short for input."); 120279d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro } 120316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 120479d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro try 120579d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro { 120616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (inputLen != 0) 120716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 120816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro len = cipher.processBytes(input, inputOffset, inputLen, output, outputOffset); 120916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 121016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 121116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return (len + cipher.doFinal(output, outputOffset + len)); 121216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 121316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro catch (OutputLengthException e) 121416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 121579d3bf2425a53baab7feb744dad710b6c15533c9Sergio Giro throw new IllegalBlockSizeException(e.getMessage()); 121616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 121716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro catch (DataLengthException e) 121816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 121916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throw new IllegalBlockSizeException(e.getMessage()); 122016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 122116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 122216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 122316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro private boolean isAEADModeName( 122416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro String modeName) 122516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 12264936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // Android-changed: Unsupported modes 12274936950820c68699a4ace55a2a8e5f7f677a913dAdam Vartanian // return "CCM".equals(modeName) || "EAX".equals(modeName) || "GCM".equals(modeName) || "OCB".equals(modeName); 1228c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro return "CCM".equals(modeName) || "GCM".equals(modeName); 122916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 123016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 123116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro /* 123216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * The ciphers that inherit from us. 123316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro */ 123416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 123516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro static private interface GenericBlockCipher 123616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 123716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public void init(boolean forEncryption, CipherParameters params) 123816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throws IllegalArgumentException; 123916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 124016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public boolean wrapOnNoPadding(); 124116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 124216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public String getAlgorithmName(); 124316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 124416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public org.bouncycastle.crypto.BlockCipher getUnderlyingCipher(); 124516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 124616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public int getOutputSize(int len); 124716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 124816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public int getUpdateOutputSize(int len); 124916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 125080261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro public void updateAAD(byte[] input, int offset, int length); 125180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro 125216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public int processByte(byte in, byte[] out, int outOff) 125316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throws DataLengthException; 125416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 125516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff) 125616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throws DataLengthException; 125716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 125816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public int doFinal(byte[] out, int outOff) 125953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro throws IllegalStateException, 126053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro BadPaddingException; 126116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 126216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 126316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro private static class BufferedGenericBlockCipher 126416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro implements GenericBlockCipher 126516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 126616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro private BufferedBlockCipher cipher; 126716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 126816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro BufferedGenericBlockCipher(BufferedBlockCipher cipher) 126916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 127016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro this.cipher = cipher; 127116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 127216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 127316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro BufferedGenericBlockCipher(org.bouncycastle.crypto.BlockCipher cipher) 127416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 127516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro this.cipher = new PaddedBufferedBlockCipher(cipher); 127616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 127716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 127816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro BufferedGenericBlockCipher(org.bouncycastle.crypto.BlockCipher cipher, BlockCipherPadding padding) 127916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 128016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro this.cipher = new PaddedBufferedBlockCipher(cipher, padding); 128116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 128216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 128316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public void init(boolean forEncryption, CipherParameters params) 128416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throws IllegalArgumentException 128516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 128616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro cipher.init(forEncryption, params); 128716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 128816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 128916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public boolean wrapOnNoPadding() 129016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 129116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return !(cipher instanceof CTSBlockCipher); 129216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 129316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 129416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public String getAlgorithmName() 129516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 129616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return cipher.getUnderlyingCipher().getAlgorithmName(); 129716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 129816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 129916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public org.bouncycastle.crypto.BlockCipher getUnderlyingCipher() 130016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 130116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return cipher.getUnderlyingCipher(); 130216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 130316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 130416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public int getOutputSize(int len) 130516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 130616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return cipher.getOutputSize(len); 130716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 130816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 130916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public int getUpdateOutputSize(int len) 131016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 131116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return cipher.getUpdateOutputSize(len); 131216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 131316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 131480261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro public void updateAAD(byte[] input, int offset, int length) 131580261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro { 131680261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro throw new UnsupportedOperationException("AAD is not supported in the current mode."); 131780261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro } 131880261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro 131916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public int processByte(byte in, byte[] out, int outOff) throws DataLengthException 132016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 132116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return cipher.processByte(in, out, outOff); 132216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 132316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 132416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff) throws DataLengthException 132516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 132616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return cipher.processBytes(in, inOff, len, out, outOff); 132716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 132816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 132953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro public int doFinal(byte[] out, int outOff) throws IllegalStateException, BadPaddingException 133016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 133153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro try 133253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 133353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro return cipher.doFinal(out, outOff); 133453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 133553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro catch (InvalidCipherTextException e) 133653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 133753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro throw new BadPaddingException(e.getMessage()); 133853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 133916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 134016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 134116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 134216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro private static class AEADGenericBlockCipher 134316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro implements GenericBlockCipher 134416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 134553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro private static final Constructor aeadBadTagConstructor; 134653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 134753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro static { 134853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro Class aeadBadTagClass = lookup("javax.crypto.AEADBadTagException"); 134953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro if (aeadBadTagClass != null) 135053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 135153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro aeadBadTagConstructor = findExceptionConstructor(aeadBadTagClass); 135253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 135353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro else 135453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 135553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro aeadBadTagConstructor = null; 135653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 135753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 135853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 135953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro private static Constructor findExceptionConstructor(Class clazz) 136053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 136153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro try 136253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 136353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro return clazz.getConstructor(new Class[]{String.class}); 136453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 136553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro catch (Exception e) 136653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 136753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro return null; 136853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 136953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 137053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro 137116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro private AEADBlockCipher cipher; 137216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 137316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro AEADGenericBlockCipher(AEADBlockCipher cipher) 137416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 137516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro this.cipher = cipher; 137616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 137716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 137816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public void init(boolean forEncryption, CipherParameters params) 137916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throws IllegalArgumentException 138016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 138116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro cipher.init(forEncryption, params); 138216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 138316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 138416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public String getAlgorithmName() 138516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 138616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return cipher.getUnderlyingCipher().getAlgorithmName(); 138716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 138816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 138916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public boolean wrapOnNoPadding() 139016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 139116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return false; 139216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 139316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 139416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public org.bouncycastle.crypto.BlockCipher getUnderlyingCipher() 139516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 139616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return cipher.getUnderlyingCipher(); 139716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 139816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 139916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public int getOutputSize(int len) 140016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 140116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return cipher.getOutputSize(len); 140216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 140316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 140416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public int getUpdateOutputSize(int len) 140516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 140616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return cipher.getUpdateOutputSize(len); 140716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 140816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 140980261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro public void updateAAD(byte[] input, int offset, int length) 141080261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro { 141180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro cipher.processAADBytes(input, offset, length); 141280261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro } 141380261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro 141416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public int processByte(byte in, byte[] out, int outOff) throws DataLengthException 141516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 141616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return cipher.processByte(in, out, outOff); 141716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 141816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 141916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff) throws DataLengthException 142016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 142116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return cipher.processBytes(in, inOff, len, out, outOff); 142216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 142316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 142453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro public int doFinal(byte[] out, int outOff) throws IllegalStateException, BadPaddingException 142516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 142653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro try 142753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 142853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro return cipher.doFinal(out, outOff); 142953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 143053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro catch (InvalidCipherTextException e) 143153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 143253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro if (aeadBadTagConstructor != null) 143353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 143453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro BadPaddingException aeadBadTag = null; 143553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro try 143653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 143753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro aeadBadTag = (BadPaddingException)aeadBadTagConstructor 143853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro .newInstance(new Object[]{e.getMessage()}); 143953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 144053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro catch (Exception i) 144153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 144253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro // Shouldn't happen, but fall through to BadPaddingException 144353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 144453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro if (aeadBadTag != null) 144553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro { 144653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro throw aeadBadTag; 144753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 144853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 144953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro throw new BadPaddingException(e.getMessage()); 145053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro } 145116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 145216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 14534caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro 14544caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro private static class InvalidKeyOrParametersException 14554caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro extends InvalidKeyException 14564caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro { 14574caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro private final Throwable cause; 14584caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro 14594caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro InvalidKeyOrParametersException(String msg, Throwable cause) 14604caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro { 14614caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro super(msg); 14624caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro this.cause = cause; 14634caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro } 14644caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro 14654caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro public Throwable getCause() 14664caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro { 14674caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro return cause; 14684caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro } 14694caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro } 147016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro} 1471