1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage javax.crypto; 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.ByteBuffer; 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.AlgorithmParameters; 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.InvalidAlgorithmParameterException; 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.InvalidKeyException; 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.InvalidParameterException; 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.Key; 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.NoSuchAlgorithmException; 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.NoSuchProviderException; 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.Provider; 2985dab151e734557d356fb45c45cf7d4548dd6fdcKenny Rootimport java.security.Provider.Service; 3085dab151e734557d356fb45c45cf7d4548dd6fdcKenny Rootimport java.security.ProviderException; 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.SecureRandom; 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.Security; 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.cert.Certificate; 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.cert.X509Certificate; 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.spec.AlgorithmParameterSpec; 3685dab151e734557d356fb45c45cf7d4548dd6fdcKenny Rootimport java.util.ArrayList; 3785dab151e734557d356fb45c45cf7d4548dd6fdcKenny Rootimport java.util.Locale; 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Set; 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.crypto.internal.NullCipherSpi; 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.fortress.Engine; 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This class provides access to implementations of cryptographic ciphers for 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * encryption and decryption. Cipher classes can not be instantiated directly, 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * one has to call the Cipher's {@code getInstance} method with the name of a 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * requested transformation, optionally with a provider. A transformation 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specifies an operation (or a set of operations) as a string in the form: 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <ul> 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li><i>"algorithm/mode/padding"</i></li> or 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li><i>"algorithm"</i></li> 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </ul> 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <i>algorithm</i> is the name of a cryptographic algorithm, <i>mode</i> is the 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * name of a feedback mode and <i>padding</i> is the name of a padding scheme. 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If <i>mode</i> and/or <i>padding</i> values are omitted, provider specific 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * default values will be used. 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * A valid transformation would be: 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <ul> 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");} 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </ul> 61e722ddfbbd83104acea33d93a390c7fb233db1bbXizhi Zhu (Steven) * When a block cipher is requested in stream cipher mode, the number of bits 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * to be processed at a time can be optionally specified by appending it to the 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * mode name. e.g. <i>"AES/CFB8/NoPadding"</i>. If no number is specified, a 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * provider specific default value is used. 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class Cipher { 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constant for decryption operation mode. 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final int DECRYPT_MODE = 2; 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constant for encryption operation mode. 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final int ENCRYPT_MODE = 1; 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constant indicating that the key to be unwrapped is a private key. 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final int PRIVATE_KEY = 2; 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constant indicating that the key to be unwrapped is a public key. 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final int PUBLIC_KEY = 1; 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constant indicating that the key to be unwrapped is a secret key. 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final int SECRET_KEY = 3; 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constant for key unwrapping operation mode. 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final int UNWRAP_MODE = 4; 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constant for key wrapping operation mode. 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final int WRAP_MODE = 3; 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private int mode; 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 10585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root /** Items that need to be set on the Cipher instance. */ 10685dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root private enum NeedToSet { 10785dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root NONE, MODE, PADDING, BOTH, 10885dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root }; 10985dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The service name. 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 113f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes private static final String SERVICE = "Cipher"; 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Used to access common engine functionality. 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1180a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom private static final Engine ENGINE = new Engine(SERVICE); 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 12085dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root /** The attribute used for supported paddings. */ 12185dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root private static final String ATTRIBUTE_PADDINGS = "SupportedPaddings"; 12285dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root 12385dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root /** The attribute used for supported modes. */ 12485dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root private static final String ATTRIBUTE_MODES = "SupportedModes"; 12585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The provider. 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Provider provider; 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 132beff0f1375b635c692d48190aa69a06986b5111fKenny Root * The provider specified when instance created. 133beff0f1375b635c692d48190aa69a06986b5111fKenny Root */ 134beff0f1375b635c692d48190aa69a06986b5111fKenny Root private final Provider specifiedProvider; 135beff0f1375b635c692d48190aa69a06986b5111fKenny Root 136beff0f1375b635c692d48190aa69a06986b5111fKenny Root /** 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The SPI implementation. 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private CipherSpi spiImpl; 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 14216ec6489f8339c55fb65db423c4a997a9f91d089Kenny Root * The SPI implementation. 14316ec6489f8339c55fb65db423c4a997a9f91d089Kenny Root */ 14416ec6489f8339c55fb65db423c4a997a9f91d089Kenny Root private final CipherSpi specifiedSpi; 14516ec6489f8339c55fb65db423c4a997a9f91d089Kenny Root 14616ec6489f8339c55fb65db423c4a997a9f91d089Kenny Root /** 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The transformation. 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 14985dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root private final String transformation; 15085dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root 15185dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root /** 15285dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root * The transformation split into parts. 15385dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root */ 15485dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root private final String[] transformParts; 15585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root 15685dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root /** 15785dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root * Lock held while the SPI is initializing. 15885dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root */ 15985dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root private final Object initLock = new Object(); 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1619229d47c1288e25ead3a2dc27fac8a4a2ee932a3Elliott Hughes private static SecureRandom secureRandom; 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates a new Cipher instance. 165ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param cipherSpi 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the implementation delegate of the cipher. 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param provider 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the provider of the implementation of this cipher. 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param transformation 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the transformation that this cipher performs. 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if either cipherSpi is {@code null} or provider is {@code 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * null} and {@code cipherSpi} is a {@code NullCipherSpi}. 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17685dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root protected Cipher(CipherSpi cipherSpi, Provider provider, String transformation) { 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (cipherSpi == null) { 17886acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("cipherSpi == null"); 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!(cipherSpi instanceof NullCipherSpi) && provider == null) { 18186acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("provider == null"); 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 183beff0f1375b635c692d48190aa69a06986b5111fKenny Root this.specifiedProvider = provider; 18416ec6489f8339c55fb65db423c4a997a9f91d089Kenny Root this.specifiedSpi = cipherSpi; 18585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root this.transformation = transformation; 18685dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root this.transformParts = null; 18785dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 18885dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root 18985dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root private Cipher(String transformation, String[] transformParts, Provider provider) { 19085dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root this.transformation = transformation; 19185dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root this.transformParts = transformParts; 192beff0f1375b635c692d48190aa69a06986b5111fKenny Root this.specifiedProvider = provider; 19316ec6489f8339c55fb65db423c4a997a9f91d089Kenny Root this.specifiedSpi = null; 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 19685dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root 197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates a new Cipher for the specified transformation. The installed 199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * providers are searched in order for an implementation of the specified 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * transformation. The first found provider providing the transformation is 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * used to create the cipher. If no provider is found an exception is 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * thrown. 203ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param transformation 205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the transformation to create a cipher for. 206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a cipher for the requested transformation. 207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NoSuchAlgorithmException 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if no installed provider can provide the 209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <i>transformation</i>, or it is {@code null}, empty or in an 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * invalid format. 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NoSuchPaddingException 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if no installed provider can provide the padding scheme in 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the <i>transformation</i>. 214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final Cipher getInstance(String transformation) 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws NoSuchAlgorithmException, NoSuchPaddingException { 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return getCipher(transformation, null); 218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates a new cipher for the specified transformation provided by the 222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specified provider. 223ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param transformation 225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the transformation to create a cipher for. 226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param provider 227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the provider to ask for the transformation. 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a cipher for the requested transformation. 229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NoSuchAlgorithmException 230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the specified provider can not provide the 231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <i>transformation</i>, or it is {@code null}, empty or in an 232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * invalid format. 233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NoSuchProviderException 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if no provider with the specified name can be found. 235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NoSuchPaddingException 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the requested padding scheme in the <i>transformation</i> 237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is not available. 238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the specified provider is {@code null}. 240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final Cipher getInstance(String transformation, 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String provider) throws NoSuchAlgorithmException, 243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project NoSuchProviderException, NoSuchPaddingException { 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (provider == null) { 24680a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalArgumentException("provider == null"); 247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Provider p = Security.getProvider(provider); 250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (p == null) { 25180a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new NoSuchProviderException("Provider not available: " + provider); 252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return getInstance(transformation, p); 254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 2570a64887ae9127d081fc6e312ba1f06f727453800Kenny Root * Creates a new cipher for the specified transformation. The 2580a64887ae9127d081fc6e312ba1f06f727453800Kenny Root * {@code provider} supplied does not have to be registered. 259ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param transformation 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the transformation to create a cipher for. 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param provider 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the provider to ask for the transformation. 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a cipher for the requested transformation. 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NoSuchAlgorithmException 266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the specified provider can not provide the 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <i>transformation</i>, or it is {@code null}, empty or in an 268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * invalid format. 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NoSuchPaddingException 270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the requested padding scheme in the <i>transformation</i> 271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is not available. 272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the provider is {@code null}. 274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final Cipher getInstance(String transformation, 276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Provider provider) throws NoSuchAlgorithmException, 277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project NoSuchPaddingException { 278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (provider == null) { 27980a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalArgumentException("provider == null"); 280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 28185dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return getCipher(transformation, provider); 282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 28480a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes private static NoSuchAlgorithmException invalidTransformation(String transformation) 28580a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throws NoSuchAlgorithmException { 28680a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new NoSuchAlgorithmException("Invalid transformation: " + transformation); 28780a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes } 28880a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 29085dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root * Create a Cipher instance but don't choose a CipherSpi until we have more 29185dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root * information. 292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 29385dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root private static Cipher getCipher(String transformation, Provider provider) 294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws NoSuchAlgorithmException, NoSuchPaddingException { 29580a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes if (transformation == null || transformation.isEmpty()) { 29680a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw invalidTransformation(transformation); 297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 29985dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root String[] transformParts = checkTransformation(transformation); 30085dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root if (tryCombinations(null, provider, transformParts) == null) { 3016cdb6b7e6939270ccd21790ec95e42197cefc0c3Brian Carlstrom if (provider == null) { 30285dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root throw new NoSuchAlgorithmException("No provider found for " + transformation); 303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 30485dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root throw new NoSuchAlgorithmException("Provider " + provider.getName() 30585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root + " does not provide " + transformation); 3066cdb6b7e6939270ccd21790ec95e42197cefc0c3Brian Carlstrom } 307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 30885dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return new Cipher(transformation, transformParts, provider); 309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 31185dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root private static String[] checkTransformation(String transformation) 31285dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root throws NoSuchAlgorithmException { 313937b6c4ef5f8ad57279e2ebed4393a78d1729d8bBrian Carlstrom // ignore an extra prefix / characters such as in 31485dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root // "/DES/CBC/PKCS5Padding" http://b/3387688 315937b6c4ef5f8ad57279e2ebed4393a78d1729d8bBrian Carlstrom if (transformation.startsWith("/")) { 316937b6c4ef5f8ad57279e2ebed4393a78d1729d8bBrian Carlstrom transformation = transformation.substring(1); 317937b6c4ef5f8ad57279e2ebed4393a78d1729d8bBrian Carlstrom } 318118abc3050371812703e4fabf03f4399d01fb28cElliott Hughes // 'transformation' should be of the form "algorithm/mode/padding". 319118abc3050371812703e4fabf03f4399d01fb28cElliott Hughes String[] pieces = transformation.split("/"); 320118abc3050371812703e4fabf03f4399d01fb28cElliott Hughes if (pieces.length > 3) { 321118abc3050371812703e4fabf03f4399d01fb28cElliott Hughes throw invalidTransformation(transformation); 322118abc3050371812703e4fabf03f4399d01fb28cElliott Hughes } 323118abc3050371812703e4fabf03f4399d01fb28cElliott Hughes // Empty or missing pieces are represented by null. 324118abc3050371812703e4fabf03f4399d01fb28cElliott Hughes String[] result = new String[3]; 325118abc3050371812703e4fabf03f4399d01fb28cElliott Hughes for (int i = 0; i < pieces.length; ++i) { 326118abc3050371812703e4fabf03f4399d01fb28cElliott Hughes String piece = pieces[i].trim(); 327118abc3050371812703e4fabf03f4399d01fb28cElliott Hughes if (!piece.isEmpty()) { 328118abc3050371812703e4fabf03f4399d01fb28cElliott Hughes result[i] = piece; 329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 331118abc3050371812703e4fabf03f4399d01fb28cElliott Hughes // You MUST specify an algorithm. 332118abc3050371812703e4fabf03f4399d01fb28cElliott Hughes if (result[0] == null) { 33380a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw invalidTransformation(transformation); 334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 335118abc3050371812703e4fabf03f4399d01fb28cElliott Hughes if (!(result[1] == null && result[2] == null) && (result[1] == null || result[2] == null)) { 33680a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw invalidTransformation(transformation); 337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 338118abc3050371812703e4fabf03f4399d01fb28cElliott Hughes return result; 339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 34285dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root * Makes sure a CipherSpi that matches this type is selected. 34385dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root */ 34485dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root private CipherSpi getSpi(Key key) { 34516ec6489f8339c55fb65db423c4a997a9f91d089Kenny Root if (specifiedSpi != null) { 34616ec6489f8339c55fb65db423c4a997a9f91d089Kenny Root return specifiedSpi; 34716ec6489f8339c55fb65db423c4a997a9f91d089Kenny Root } 34816ec6489f8339c55fb65db423c4a997a9f91d089Kenny Root 34985dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root synchronized (initLock) { 350beff0f1375b635c692d48190aa69a06986b5111fKenny Root if (spiImpl != null && key == null) { 35185dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return spiImpl; 35285dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 35385dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root 354beff0f1375b635c692d48190aa69a06986b5111fKenny Root final Engine.SpiAndProvider sap = tryCombinations(key, specifiedProvider, 355beff0f1375b635c692d48190aa69a06986b5111fKenny Root transformParts); 35685dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root if (sap == null) { 35785dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root throw new ProviderException("No provider for " + transformation); 35885dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 35985dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root 36085dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root spiImpl = (CipherSpi) sap.spi; 36185dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root provider = sap.provider; 36285dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root 36385dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return spiImpl; 36485dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 36585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 36685dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root 36785dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root /** 36885dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root * Convenience call when the Key is not available. 36985dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root */ 37085dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root private CipherSpi getSpi() { 37185dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return getSpi(null); 37285dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 37385dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root 37485dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root /** 37585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root * Try all combinations of mode strings: 376ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 37785dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root * <pre> 37885dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root * [cipher]/[mode]/[padding] 37985dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root * [cipher]/[mode] 38085dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root * [cipher]//[padding] 38185dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root * [cipher] 38285dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root * </pre> 38385dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root */ 38485dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root private static Engine.SpiAndProvider tryCombinations(Key key, Provider provider, 38585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root String[] transformParts) { 38685dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root Engine.SpiAndProvider sap = null; 38785dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root 38885dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root if (transformParts[1] != null && transformParts[2] != null) { 38985dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root sap = tryTransform(key, provider, transformParts[0] + "/" + transformParts[1] + "/" 39085dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root + transformParts[2], transformParts, NeedToSet.NONE); 39185dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root if (sap != null) { 39285dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return sap; 39385dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 39485dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 39585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root 39685dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root if (transformParts[1] != null) { 39785dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root sap = tryTransform(key, provider, transformParts[0] + "/" + transformParts[1], 39885dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root transformParts, NeedToSet.PADDING); 39985dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root if (sap != null) { 40085dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return sap; 40185dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 40285dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 40385dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root 40485dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root if (transformParts[2] != null) { 40585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root sap = tryTransform(key, provider, transformParts[0] + "//" + transformParts[2], 40685dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root transformParts, NeedToSet.MODE); 40785dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root if (sap != null) { 40885dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return sap; 40985dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 41085dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 41185dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root 41285dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return tryTransform(key, provider, transformParts[0], transformParts, NeedToSet.BOTH); 41385dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 41485dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root 41585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root private static Engine.SpiAndProvider tryTransform(Key key, Provider provider, String transform, 41685dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root String[] transformParts, NeedToSet type) { 4173ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root if (provider != null) { 4183ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root Provider.Service service = provider.getService(SERVICE, transform); 4193ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root if (service == null) { 4203ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root return null; 4213ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root } 4223ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root return tryTransformWithProvider(key, transformParts, type, service); 4233ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root } 4243ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root ArrayList<Provider.Service> services = ENGINE.getServices(transform); 42585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root if (services == null) { 42685dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return null; 42785dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 42885dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root for (Provider.Service service : services) { 4293ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root Engine.SpiAndProvider sap = tryTransformWithProvider(key, transformParts, type, service); 4303ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root if (sap != null) { 43185dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return sap; 43285dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 43385dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 43485dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return null; 43585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 43685dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root 4373ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root private static Engine.SpiAndProvider tryTransformWithProvider(Key key, String[] transformParts, 4383ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root NeedToSet type, Provider.Service service) { 4393ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root try { 4403ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root if (key != null && !service.supportsParameter(key)) { 4413ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root return null; 4423ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root } 4433ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root 4443ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root /* 4453ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root * Check to see if the Cipher even supports the attributes before 4463ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root * trying to instantiate it. 4473ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root */ 4483ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root if (!matchAttribute(service, ATTRIBUTE_MODES, transformParts[1]) 4493ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root || !matchAttribute(service, ATTRIBUTE_PADDINGS, transformParts[2])) { 4503ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root return null; 4513ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root } 4523ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root 4533ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root Engine.SpiAndProvider sap = ENGINE.getInstance(service, null); 4543ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root if (sap.spi == null || sap.provider == null) { 45507c8c69f59b60684fe07b003b3462e8d9687f422Kenny Root return null; 4563ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root } 4573ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root if (!(sap.spi instanceof CipherSpi)) { 45807c8c69f59b60684fe07b003b3462e8d9687f422Kenny Root return null; 4593ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root } 4603ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root CipherSpi spi = (CipherSpi) sap.spi; 4613ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root if (((type == NeedToSet.MODE) || (type == NeedToSet.BOTH)) 4623ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root && (transformParts[1] != null)) { 4633ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root spi.engineSetMode(transformParts[1]); 4643ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root } 4653ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root if (((type == NeedToSet.PADDING) || (type == NeedToSet.BOTH)) 4663ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root && (transformParts[2] != null)) { 4673ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root spi.engineSetPadding(transformParts[2]); 4683ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root } 4693ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root return sap; 4703ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root } catch (NoSuchAlgorithmException ignored) { 4713ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root } catch (NoSuchPaddingException ignored) { 4723ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root } 4733ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root return null; 4743ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root } 4753ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root 47685dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root /** 47785dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root * If the attribute listed exists, check that it matches the regular 47885dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root * expression. 47985dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root */ 48085dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root private static boolean matchAttribute(Service service, String attr, String value) { 48185dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root if (value == null) { 48285dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return true; 48385dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 48485dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root final String pattern = service.getAttribute(attr); 48585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root if (pattern == null) { 48685dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return true; 48785dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 48885dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root final String valueUc = value.toUpperCase(Locale.US); 48985dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return valueUc.matches(pattern.toUpperCase(Locale.US)); 49085dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 49185dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root 49285dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root /** 49385dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root * Returns the provider of this cipher instance. 49407c8c69f59b60684fe07b003b3462e8d9687f422Kenny Root * 495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the provider of this cipher instance. 496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final Provider getProvider() { 49885dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root getSpi(); 499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return provider; 500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the name of the algorithm of this cipher instance. 504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This is the name of the <i>transformation</i> argument used in the 506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code getInstance} call creating this object. 507ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the name of the algorithm of this cipher instance. 509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final String getAlgorithm() { 511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return transformation; 512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns this ciphers block size (in bytes). 516ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return this ciphers block size. 518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final int getBlockSize() { 52085dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return getSpi().engineGetBlockSize(); 521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the length in bytes an output buffer needs to be when this cipher 525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is updated with {@code inputLen} bytes. 526ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param inputLen 528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the number of bytes of the input. 529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the output buffer length for the input length. 530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalStateException 531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this cipher instance is in an invalid state. 532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final int getOutputSize(int inputLen) { 534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (mode == 0) { 53580a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalStateException("Cipher has not yet been initialized"); 536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 53785dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return getSpi().engineGetOutputSize(inputLen); 538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the <i>initialization vector</i> for this cipher instance. 542ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the <i>initialization vector</i> for this cipher instance. 544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final byte[] getIV() { 54685dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return getSpi().engineGetIV(); 547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the parameters that where used to create this cipher instance. 551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * These may be a the same parameters that were used to create this cipher 553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * instance, or may be a combination of default and random parameters, 554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * depending on the underlying cipher implementation. 555ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the parameters that where used to create this cipher instance, or 557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code null} if this cipher instance does not have any 558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * parameters. 559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final AlgorithmParameters getParameters() { 56185dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return getSpi().engineGetParameters(); 562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the exemption mechanism associated with this cipher. 566ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return currently {@code null} 568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final ExemptionMechanism getExemptionMechanism() { 570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //FIXME implement getExemptionMechanism 571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // try { 573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // return ExemptionMechanism.getInstance(transformation, provider); 574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // } catch (NoSuchAlgorithmException e) { 575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // } 577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 58085dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root private void checkMode(int mode) { 58185dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE && mode != UNWRAP_MODE 58285dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root && mode != WRAP_MODE) { 58385dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root throw new InvalidParameterException("Invalid mode: " + mode); 58485dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 58585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 58685dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root 587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Initializes this cipher instance with the specified key. 589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The cipher is initialized for the specified operational mode (one of: 591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * encryption, decryption, key wrapping or key unwrapping) depending on 592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code opmode}. 593ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * <p> 594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If this cipher instance needs any algorithm parameters or random values 595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * that the specified key can not provide, the underlying implementation of 596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this cipher is supposed to generate the required parameters (using its 597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * provider or random values). 598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * When a cipher instance is initialized by a call to any of the {@code 600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * init} methods, the state of the instance is overridden, meaning that it 601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is equivalent to creating a new instance and calling its {@code init} 602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method. 603ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param opmode 605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the operation this cipher instance should be initialized for 606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code 607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WRAP_MODE} or {@code UNWRAP_MODE}). 608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key 609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input key for the operation. 610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidKeyException 611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the specified key can not be used to initialize this 612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher instance. 613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final void init(int opmode, Key key) throws InvalidKeyException { 6159229d47c1288e25ead3a2dc27fac8a4a2ee932a3Elliott Hughes if (secureRandom == null) { 616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // In theory it might be thread-unsafe but in the given case it's OK 617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // since it does not matter which SecureRandom instance is passed 618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // to the init() 6199229d47c1288e25ead3a2dc27fac8a4a2ee932a3Elliott Hughes secureRandom = new SecureRandom(); 620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 6219229d47c1288e25ead3a2dc27fac8a4a2ee932a3Elliott Hughes init(opmode, key, secureRandom); 622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Initializes this cipher instance with the specified key and a source of 626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * randomness. 627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The cipher is initialized for the specified operational mode (one of: 629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * encryption, decryption, key wrapping or key unwrapping) depending on 630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code opmode}. 631ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * <p> 632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If this cipher instance needs any algorithm parameters or random values 633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * that the specified key can not provide, the underlying implementation of 634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this cipher is supposed to generate the required parameters (using its 635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * provider or random values). Random values are generated using {@code 636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * random}; 637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * When a cipher instance is initialized by a call to any of the {@code 639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * init} methods, the state of the instance is overridden, means it is 640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * equivalent to creating a new instance and calling it {@code init} method. 641ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param opmode 643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the operation this cipher instance should be initialized for 644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code 645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WRAP_MODE} or {@code UNWRAP_MODE}). 646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key 647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input key for the operation. 648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param random 649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the source of randomness to use. 650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidKeyException 651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the specified key can not be used to initialize this 652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher instance. 653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidParameterException 654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the specified opmode is invalid. 655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 65680a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes public final void init(int opmode, Key key, SecureRandom random) throws InvalidKeyException { 6570c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom checkMode(opmode); 658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // FIXME InvalidKeyException 659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // if keysize exceeds the maximum allowable keysize 660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // (jurisdiction policy files) 66185dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root getSpi(key).engineInit(opmode, key, random); 662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project mode = opmode; 663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 665adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Initializes this cipher instance with the specified key and algorithm 667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * parameters. 668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The cipher is initialized for the specified operational mode (one of: 670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * encryption, decryption, key wrapping or key unwrapping). 671ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * <p> 672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If this cipher instance needs any algorithm parameters and {@code params} 673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is {@code null}, the underlying implementation of this cipher is supposed 674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * to generate the required parameters (using its provider or random 675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * values). 676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * When a cipher instance is initialized by a call to any of the {@code 678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * init} methods, the state of the instance is overridden, means it is 679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * equivalent to creating a new instance and calling it {@code init} method. 680ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param opmode 682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the operation this cipher instance should be initialized for 683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code 684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WRAP_MODE} or {@code UNWRAP_MODE}). 685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key 686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input key for the operation. 687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param params 688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the algorithm parameters. 689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidKeyException 690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the specified key can not be used to initialize this 691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher instance. 692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidAlgorithmParameterException 693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * it the specified parameters are inappropriate for this 694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher. 695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final void init(int opmode, Key key, AlgorithmParameterSpec params) 697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws InvalidKeyException, InvalidAlgorithmParameterException { 6989229d47c1288e25ead3a2dc27fac8a4a2ee932a3Elliott Hughes if (secureRandom == null) { 6999229d47c1288e25ead3a2dc27fac8a4a2ee932a3Elliott Hughes secureRandom = new SecureRandom(); 700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 7019229d47c1288e25ead3a2dc27fac8a4a2ee932a3Elliott Hughes init(opmode, key, params, secureRandom); 702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Initializes this cipher instance with the specified key, algorithm 706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * parameters and a source of randomness. 707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The cipher is initialized for the specified operational mode (one of: 709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * encryption, decryption, key wrapping or key unwrapping) depending on 710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code opmode}. 711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If this cipher instance needs any algorithm parameters and {@code params} 713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is {@code null}, the underlying implementation of this cipher is supposed 714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * to generate the required parameters (using its provider or random 715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * values). Random values are generated using {@code random}; 716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * When a cipher instance is initialized by a call to any of the {@code 718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * init} methods, the state of the instance is overridden, meaning that it 719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is equivalent to creating a new instance and calling it {@code init} 720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method. 721ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param opmode 723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the operation this cipher instance should be initialized for 724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code 725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WRAP_MODE} or {@code UNWRAP_MODE}). 726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key 727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input key for the operation. 728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param params 729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the algorithm parameters. 730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param random 731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the source of randomness to use. 732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidKeyException 733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the specified key can not be used to initialize this 734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher instance. 735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidAlgorithmParameterException 736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * it the specified parameters are inappropriate for this 737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher. 738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidParameterException 739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the specified {@code opmode} is invalid. 740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final void init(int opmode, Key key, AlgorithmParameterSpec params, 742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecureRandom random) throws InvalidKeyException, 743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project InvalidAlgorithmParameterException { 7440c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom checkMode(opmode); 745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // FIXME InvalidKeyException 746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // if keysize exceeds the maximum allowable keysize 747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // (jurisdiction policy files) 748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // FIXME InvalidAlgorithmParameterException 749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // cryptographic strength exceed the legal limits 750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // (jurisdiction policy files) 75185dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root getSpi(key).engineInit(opmode, key, params, random); 752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project mode = opmode; 753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Initializes this cipher instance with the specified key and algorithm 757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * parameters. 758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The cipher is initialized for the specified operation (one of: 760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * encryption, decryption, key wrapping or key unwrapping) depending on 761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code opmode}. 762ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * <p> 763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If this cipher instance needs any algorithm parameters and {@code params} 764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is {@code null}, the underlying implementation of this cipher is supposed 765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * to generate the required parameters (using its provider or random 766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * values). 767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 768adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * When a cipher instance is initialized by a call to any of the {@code 769adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * init} methods, the state of the instance is overridden, meaning that it 770adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is equivalent to creating a new instance and calling it {@code init} 771adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method. 772ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param opmode 774adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the operation this cipher instance should be initialized for 775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code 776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WRAP_MODE} or {@code UNWRAP_MODE}). 777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key 778adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input key for the operation. 779adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param params 780adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the algorithm parameters. 781adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidKeyException 782adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the specified key can not be used to initialize this 783adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher instance. 784adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidAlgorithmParameterException 785adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * it the specified parameters are inappropriate for this 786adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher. 787adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 788adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final void init(int opmode, Key key, AlgorithmParameters params) 789adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws InvalidKeyException, InvalidAlgorithmParameterException { 7909229d47c1288e25ead3a2dc27fac8a4a2ee932a3Elliott Hughes if (secureRandom == null) { 7919229d47c1288e25ead3a2dc27fac8a4a2ee932a3Elliott Hughes secureRandom = new SecureRandom(); 792adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 7939229d47c1288e25ead3a2dc27fac8a4a2ee932a3Elliott Hughes init(opmode, key, params, secureRandom); 794adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 795adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 797adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Initializes this cipher instance with the specified key, algorithm 798adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * parameters and a source of randomness. 799adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 800adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The cipher will be initialized for the specified operation (one of: 801adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * encryption, decryption, key wrapping or key unwrapping) depending on 802adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code opmode}. 803ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * <p> 804adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If this cipher instance needs any algorithm parameters and {@code params} 805adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is {@code null}, the underlying implementation of this cipher is supposed 806adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * to generate the required parameters (using its provider or random 807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * values). Random values are generated using {@code random}. 808adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 809adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * When a cipher instance is initialized by a call to any of the {@code 810adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * init} methods, the state of the instance is overridden, means it is 811adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * equivalent to creating a new instance and calling it {@code init} method. 812ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 813adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param opmode 814adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the operation this cipher instance should be initialized for 815adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code 816adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WRAP_MODE} or {@code UNWRAP_MODE}). 817adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key 818adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input key for the operation. 819adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param params 820adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the algorithm parameters. 821adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param random 822adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the source of randomness to use. 823adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidKeyException 824adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the specified key can not be used to initialize this 825adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher instance. 826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidAlgorithmParameterException 827adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the specified parameters are inappropriate for this 828adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher. 829adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidParameterException 830adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the specified {@code opmode} is invalid. 831adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 832adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final void init(int opmode, Key key, AlgorithmParameters params, 833adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecureRandom random) throws InvalidKeyException, 834adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project InvalidAlgorithmParameterException { 8350c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom checkMode(opmode); 836adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // FIXME InvalidKeyException 837adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // if keysize exceeds the maximum allowable keysize 838adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // (jurisdiction policy files) 839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // FIXME InvalidAlgorithmParameterException 840adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // cryptographic strength exceed the legal limits 841adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // (jurisdiction policy files) 84285dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root getSpi(key).engineInit(opmode, key, params, random); 843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project mode = opmode; 844adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 845adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 846adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 847adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Initializes this cipher instance with the public key from the specified 848adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * certificate. 849adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 850adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The cipher will be initialized for the specified operation (one of: 851adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * encryption, decryption, key wrapping or key unwrapping) depending on 852adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code opmode}. 853adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 854adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * It the type of the certificate is X.509 and the certificate has a <i>key 855adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * usage</i> extension field marked as critical, the specified {@code 856adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * opmode} has the be enabled for this key, otherwise an {@code 857adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * InvalidKeyException} is thrown. 858adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 859adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If this cipher instance needs any algorithm parameters that the key in 860adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the certificate can not provide, the underlying implementation of this 861adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher is supposed to generate the required parameters (using its 862adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * provider or random values). 863adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 864adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * When a cipher instance is initialized by a call to any of the {@code 865adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * init} methods, the state of the instance is overridden, means it is 866adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * equivalent to creating a new instance and calling it {@code init} method. 867ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 868adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param opmode 869adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the operation this cipher instance should be initialized for 870adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code 871adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WRAP_MODE} or {@code UNWRAP_MODE}). 872adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param certificate 873adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the certificate. 874adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidKeyException 875adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the public key in the certificate can not be used to 876adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * initialize this cipher instance. 877adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 878adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final void init(int opmode, Certificate certificate) 879adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws InvalidKeyException { 8809229d47c1288e25ead3a2dc27fac8a4a2ee932a3Elliott Hughes if (secureRandom == null) { 8819229d47c1288e25ead3a2dc27fac8a4a2ee932a3Elliott Hughes secureRandom = new SecureRandom(); 882adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 8839229d47c1288e25ead3a2dc27fac8a4a2ee932a3Elliott Hughes init(opmode, certificate, secureRandom); 884adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 885adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 886adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 887adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Initializes this cipher instance with the public key from the specified 888adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * certificate and a source of randomness. 889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 890adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The cipher will be initialized for the specified operation (one of: 891adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * encryption, decryption, key wrapping or key unwrapping) depending on 892adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code opmode}. 893ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * <p> 894adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * It the type of the certificate is X.509 and the certificate has a <i>key 895adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * usage</i> extension field marked as critical, the specified {@code 896adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * opmode} has the be enabled for this key, otherwise an {@code 897adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * InvalidKeyException} is thrown. 898adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 899adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If this cipher instance needs any algorithm parameters that the key in 900adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the certificate can not provide, the underlying implementation of this 901adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher is supposed to generate the required parameters (using its 902adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * provider or random values). Random values are generated using {@code 903adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * random}. 904ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * <p> 905adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * When a cipher instance is initialized by a call to any of the {@code 906adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * init} methods, the state of the instance is overridden, means it is 907adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * equivalent to creating a new instance and calling it {@code init} method. 908ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 909adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param opmode 910adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the operation this cipher instance should be initialized for 911adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code 912adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WRAP_MODE} or {@code UNWRAP_MODE}). 913adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param certificate 914adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the certificate. 915adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param random 916adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the source of randomness to be used. 917adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidKeyException 918adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the public key in the certificate can not be used to 919adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * initialize this cipher instance. 920adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 921adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final void init(int opmode, Certificate certificate, 922adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecureRandom random) throws InvalidKeyException { 9230c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom checkMode(opmode); 924adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (certificate instanceof X509Certificate) { 925adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Set<String> ce = ((X509Certificate) certificate).getCriticalExtensionOIDs(); 926adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean critical = false; 927adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (ce != null && !ce.isEmpty()) { 928adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (String oid : ce) { 9290d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom if (oid.equals("2.5.29.15")) { // KeyUsage OID = 2.5.29.15 930adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project critical = true; 931adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 932adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 933adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 934adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (critical) { 9350d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom boolean[] keyUsage = ((X509Certificate) certificate).getKeyUsage(); 9360d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom // As specified in RFC 3280: 9370d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom // Internet X.509 Public Key Infrastructure 9380d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom // Certificate and Certificate Revocation List (CRL) Profile. 9390d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom // Section 4.2.1.3 Key Usage 9400d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom // http://www.ietf.org/rfc/rfc3280.txt 941adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // 942adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // KeyUsage ::= BIT STRING {digitalSignature (0), 9430d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom // nonRepudiation (1), 9440d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom // keyEncipherment (2), 9450d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom // dataEncipherment (3), 9460d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom // keyAgreement (4), 9470d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom // keyCertSign (5), 9480d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom // cRLSign (6), 9490d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom // encipherOnly (7), 9500d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom // decipherOnly (8) } 951adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (keyUsage != null) { 9520d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom if (opmode == ENCRYPT_MODE && !keyUsage[3]) { 9530a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom throw new InvalidKeyException("The public key in the certificate " 9540a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom + "cannot be used for ENCRYPT_MODE"); 9550d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom } else if (opmode == WRAP_MODE && !keyUsage[2]) { 9560a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom throw new InvalidKeyException("The public key in the certificate " 9570d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom + "cannot be used for WRAP_MODE"); 958adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 959adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 960adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 961adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 962adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 963adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // FIXME InvalidKeyException 964adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // if keysize exceeds the maximum allowable keysize 965adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // (jurisdiction policy files) 96685dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root final Key key = certificate.getPublicKey(); 96785dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root getSpi(key).engineInit(opmode, key, random); 968adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project mode = opmode; 969adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 970adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 971adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 972adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Continues a multi-part transformation (encryption or decryption). The 973adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * transformed bytes are returned. 974ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 975adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param input 976adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input bytes to transform. 977adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the transformed bytes in a new buffer, or {@code null} if the 978adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * input has zero length. 979adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalStateException 980adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this cipher instance is not initialized for encryption or 981adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * decryption. 982adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 983adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the input is {@code null}. 984adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 985adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final byte[] update(byte[] input) { 986adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { 98780a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalStateException(); 988adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 989adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (input == null) { 99080a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalArgumentException("input == null"); 991adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 992adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (input.length == 0) { 993adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 994adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 99585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return getSpi().engineUpdate(input, 0, input.length); 996adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 997adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 998adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 999adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Continues a multi-part transformation (encryption or decryption). The 1000adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * transformed bytes are returned. 1001ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 1002adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param input 1003adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input bytes to transform. 1004adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param inputOffset 1005adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the offset in the input to start. 1006adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param inputLen 1007adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the length of the input to transform. 1008adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the transformed bytes in a new buffer, or {@code null} if the 1009adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * input has zero length. 1010adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalStateException 1011adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this cipher instance is not initialized for encryption or 1012adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * decryption. 1013adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 1014d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * if {@code input} is {@code null}, or if {@code inputOffset} and 1015adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code inputLen} do not specify a valid chunk in the input 1016adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * buffer. 1017adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1018adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final byte[] update(byte[] input, int inputOffset, int inputLen) { 1019adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { 102080a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalStateException(); 1021adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1022adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (input == null) { 102380a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalArgumentException("input == null"); 1024adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1025c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom checkInputOffsetAndCount(input.length, inputOffset, inputLen); 1026adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (input.length == 0) { 1027adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 1028adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 102985dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return getSpi().engineUpdate(input, inputOffset, inputLen); 1030adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1031adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1032c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom private static void checkInputOffsetAndCount(int inputArrayLength, 1033c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom int inputOffset, 1034c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom int inputLen) { 1035c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom if ((inputOffset | inputLen) < 0 1036c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom || inputOffset > inputArrayLength 1037c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom || inputArrayLength - inputOffset < inputLen) { 1038c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom throw new IllegalArgumentException("input.length=" + inputArrayLength 1039c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom + "; inputOffset=" + inputOffset 1040c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom + "; inputLen=" + inputLen); 1041c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom } 1042c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom } 1043c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom 1044adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1045adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Continues a multi-part transformation (encryption or decryption). The 1046adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * transformed bytes are stored in the {@code output} buffer. 1047adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 1048adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If the size of the {@code output} buffer is too small to hold the result, 1049adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a {@code ShortBufferException} is thrown. Use 1050adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link Cipher#getOutputSize getOutputSize} to check for the size of the 1051adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * output buffer. 1052ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 1053adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param input 1054adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input bytes to transform. 1055adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param inputOffset 1056adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the offset in the input to start. 1057adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param inputLen 1058adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the length of the input to transform. 1059adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param output 1060adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the output buffer. 1061adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the number of bytes placed in output. 1062adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ShortBufferException 1063adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the size of the {@code output} buffer is too small. 1064adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalStateException 1065adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this cipher instance is not initialized for encryption or 1066adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * decryption. 1067adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 1068adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the input is {@code null}, the output is {@code null}, or 1069adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code inputOffset} and {@code inputLen} do not specify a 1070adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * valid chunk in the input buffer. 1071adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1072adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final int update(byte[] input, int inputOffset, int inputLen, 1073adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project byte[] output) throws ShortBufferException { 1074adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return update(input, inputOffset, inputLen, output, 0); 1075adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1076adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1077adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1078adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Continues a multi-part transformation (encryption or decryption). The 1079adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * transformed bytes are stored in the {@code output} buffer. 1080adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 1081adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If the size of the {@code output} buffer is too small to hold the result, 1082adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a {@code ShortBufferException} is thrown. Use 1083adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link Cipher#getOutputSize getOutputSize} to check for the size of the 1084adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * output buffer. 1085ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 1086adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param input 1087adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input bytes to transform. 1088adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param inputOffset 1089adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the offset in the input to start. 1090adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param inputLen 1091adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the length of the input to transform. 1092adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param output 1093adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the output buffer. 1094adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param outputOffset 1095adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the offset in the output buffer. 1096adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the number of bytes placed in output. 1097adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ShortBufferException 1098adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the size of the {@code output} buffer is too small. 1099adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalStateException 1100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this cipher instance is not initialized for encryption or 1101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * decryption. 1102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 1103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the input is {@code null}, the output is {@code null}, or 1104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code inputOffset} and {@code inputLen} do not specify a 1105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * valid chunk in the input buffer. 1106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final int update(byte[] input, int inputOffset, int inputLen, 1108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project byte[] output, int outputOffset) throws ShortBufferException { 1109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { 111080a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalStateException(); 1111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (input == null) { 111380a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalArgumentException("input == null"); 1114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (output == null) { 111680a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalArgumentException("output == null"); 1117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (outputOffset < 0) { 1119c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom throw new IllegalArgumentException("outputOffset < 0. outputOffset=" + outputOffset); 1120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1121c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom checkInputOffsetAndCount(input.length, inputOffset, inputLen); 1122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (input.length == 0) { 1123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 0; 1124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 112585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return getSpi().engineUpdate(input, inputOffset, inputLen, output, 1126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project outputOffset); 1127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Continues a multi-part transformation (encryption or decryption). The 1131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code input.remaining()} bytes starting at {@code input.position()} are 1132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * transformed and stored in the {@code output} buffer. 1133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 1134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If the {@code output.remaining()} is too small to hold the transformed 1135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * bytes a {@code ShortBufferException} is thrown. Use 1136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link Cipher#getOutputSize getOutputSize} to check for the size of the 1137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * output buffer. 1138ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 1139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param input 1140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input buffer to transform. 1141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param output 1142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the output buffer to store the result within. 1143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the number of bytes stored in the output buffer. 1144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ShortBufferException 1145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the size of the {@code output} buffer is too small. 1146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalStateException 1147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this cipher instance is not initialized for encryption or 1148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * decryption. 1149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 1150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the input buffer and the output buffer are the identical 1151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * object. 1152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final int update(ByteBuffer input, ByteBuffer output) 1154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws ShortBufferException { 1155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { 115680a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalStateException(); 1157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (input == output) { 115980a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalArgumentException("input == output"); 1160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 116185dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return getSpi().engineUpdate(input, output); 1162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1165d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * Continues a multi-part transformation (encryption or decryption) with 1166d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * Authenticated Additional Data (AAD). AAD may only be added after the 1167d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * {@code Cipher} is initialized and before any data is passed to the 1168d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * instance. 1169d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * <p> 1170d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * This is only usable with cipher modes that support Authenticated 1171d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * Encryption with Additional Data (AEAD) such as Galois/Counter Mode (GCM). 1172d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * 1173d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * @param input bytes of AAD to use with the cipher 1174d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * @throws IllegalStateException 1175d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * if this cipher instance is not initialized for encryption or 1176d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * decryption. 1177d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * @throws IllegalArgumentException 1178d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * if {@code input} is {@code null} 1179d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * @throws UnsupportedOperationException if the cipher does not support AEAD 1180d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * @since 1.7 1181d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root */ 1182d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root public final void updateAAD(byte[] input) { 1183d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root if (input == null) { 1184d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root throw new IllegalArgumentException("input == null"); 1185d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root } 1186d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { 1187d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root throw new IllegalStateException(); 1188d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root } 1189d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root if (input.length == 0) { 1190d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root return; 1191d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root } 119285dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root getSpi().engineUpdateAAD(input, 0, input.length); 1193d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root } 1194d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root 1195d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root /** 1196d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * Continues a multi-part transformation (encryption or decryption) with 1197d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * Authenticated Additional Data (AAD). AAD may only be added after the 1198d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * {@code Cipher} is initialized and before any data is passed to the 1199d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * instance. 1200d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * <p> 1201d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * This is only usable with cipher modes that support Authenticated 1202d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * Encryption with Additional Data (AEAD) such as Galois/Counter Mode (GCM). 1203d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * 1204d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * @param input bytes of AAD to use with the cipher 1205d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * @param inputOffset offset within bytes of additional data to add to cipher 1206d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * @param inputLen length of bytes of additional data to add to cipher 1207d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * @throws IllegalStateException 1208d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * if this cipher instance is not initialized for encryption or 1209d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * decryption. 1210d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * @throws IllegalArgumentException 1211d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * if {@code input} is {@code null}, or if {@code inputOffset} and 1212d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * {@code inputLen} do not specify a valid chunk in the input 1213d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * buffer. 1214d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * @throws UnsupportedOperationException if the cipher does not support AEAD 1215d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * @since 1.7 1216d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root */ 1217d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root public final void updateAAD(byte[] input, int inputOffset, int inputLen) { 1218d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { 1219d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root throw new IllegalStateException(); 1220d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root } 122157323260f130e086301b1b7c0d3124a6c51f9fa8Kenny Root if (input == null) { 122257323260f130e086301b1b7c0d3124a6c51f9fa8Kenny Root throw new IllegalArgumentException("input == null"); 122357323260f130e086301b1b7c0d3124a6c51f9fa8Kenny Root } 1224d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root checkInputOffsetAndCount(input.length, inputOffset, inputLen); 1225d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root if (input.length == 0) { 1226d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root return; 1227d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root } 122885dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root getSpi().engineUpdateAAD(input, inputOffset, inputLen); 1229d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root } 1230d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root 1231d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root /** 1232d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * Continues a multi-part transformation (encryption or decryption) with 1233d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * Authenticated Additional Data (AAD). AAD may only be added after the 1234d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * {@code Cipher} is initialized and before any data is passed to the 1235d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * instance. 1236d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * <p> 1237d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * This is only usable with cipher modes that support Authenticated 1238d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * Encryption with Additional Data (AEAD) such as Galois/Counter Mode (GCM). 1239d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * 1240d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * @param input buffer of AAD to be used 1241d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * @throws IllegalStateException 1242d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * if this cipher instance is not initialized for encryption or 1243d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * decryption. 1244d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * @throws UnsupportedOperationException if the cipher does not support AEAD 1245d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * @since 1.7 1246d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root */ 1247d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root public final void updateAAD(ByteBuffer input) { 1248d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { 1249d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root throw new IllegalStateException("Cipher is not initialized"); 1250d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root } 1251d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root if (input == null) { 1252d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root throw new IllegalArgumentException("input == null"); 1253d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root } 125485dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root getSpi().engineUpdateAAD(input); 1255d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root } 1256d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root 1257d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root /** 1258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Finishes a multi-part transformation (encryption or decryption). 1259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 1260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Processes any bytes that may have been buffered in previous {@code 1261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * update} calls. 1262ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 1263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the final bytes from the transformation. 1264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalBlockSizeException 1265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the size of the resulting bytes is not a multiple of the 1266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher block size. 1267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BadPaddingException 1268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the padding of the data does not match the padding scheme. 1269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalStateException 1270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this cipher instance is not initialized for encryption or 1271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * decryption. 1272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final byte[] doFinal() throws IllegalBlockSizeException, 1274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project BadPaddingException { 1275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { 127680a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalStateException(); 1277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 127885dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return getSpi().engineDoFinal(null, 0, 0); 1279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Finishes a multi-part transformation (encryption or decryption). 1283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 1284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Processes any bytes that may have been buffered in previous {@code 1285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * update} calls. 1286ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * <p> 1287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The final transformed bytes are stored in the {@code output} buffer. 1288ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 1289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param output 1290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the output buffer. 1291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param outputOffset 1292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the offset in the output buffer. 1293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the number of bytes placed in the output buffer. 1294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalBlockSizeException 1295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the size of the resulting bytes is not a multiple of the 1296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher block size. 1297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ShortBufferException 1298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the size of the {@code output} buffer is too small. 1299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BadPaddingException 1300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the padding of the data does not match the padding scheme. 1301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalStateException 1302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this cipher instance is not initialized for encryption or 1303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * decryption. 1304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final int doFinal(byte[] output, int outputOffset) 1306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IllegalBlockSizeException, ShortBufferException, 1307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project BadPaddingException { 1308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { 130980a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalStateException(); 1310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (outputOffset < 0) { 1312c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom throw new IllegalArgumentException("outputOffset < 0. outputOffset=" + outputOffset); 1313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 131485dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return getSpi().engineDoFinal(null, 0, 0, output, outputOffset); 1315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Finishes a multi-part transformation (encryption or decryption). 1319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 1320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Processes the bytes in {@code input} buffer, and any bytes that have been 1321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * buffered in previous {@code update} calls. 1322ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 1323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param input 1324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input buffer. 1325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the final bytes from the transformation. 1326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalBlockSizeException 1327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the size of the resulting bytes is not a multiple of the 1328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher block size. 1329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BadPaddingException 1330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the padding of the data does not match the padding scheme. 1331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalStateException 1332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this cipher instance is not initialized for encryption or 1333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * decryption. 1334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final byte[] doFinal(byte[] input) throws IllegalBlockSizeException, 1336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project BadPaddingException { 1337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { 133880a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalStateException(); 1339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 134085dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return getSpi().engineDoFinal(input, 0, input.length); 1341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Finishes a multi-part transformation (encryption or decryption). 1345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 1346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Processes the {@code inputLen} bytes in {@code input} buffer at {@code 1347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * inputOffset}, and any bytes that have been buffered in previous {@code 1348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * update} calls. 1349ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 1350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param input 1351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input buffer. 1352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param inputOffset 1353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the offset in the input buffer. 1354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param inputLen 1355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the length of the input 1356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the final bytes from the transformation. 1357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalBlockSizeException 1358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the size of the resulting bytes is not a multiple of the 1359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher block size. 1360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BadPaddingException 1361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the padding of the data does not match the padding scheme. 1362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalStateException 1363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this cipher instance is not initialized for encryption or 1364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * decryption. 1365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 1366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code inputOffset} and {@code inputLen} do not specify an 1367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * valid chunk in the input buffer. 1368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final byte[] doFinal(byte[] input, int inputOffset, int inputLen) 1370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IllegalBlockSizeException, BadPaddingException { 1371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { 137280a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalStateException(); 1373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1374c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom checkInputOffsetAndCount(input.length, inputOffset, inputLen); 137585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return getSpi().engineDoFinal(input, inputOffset, inputLen); 1376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Finishes a multi-part transformation (encryption or decryption). 1380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 1381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Processes the {@code inputLen} bytes in {@code input} buffer at {@code 1382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * inputOffset}, and any bytes that have been buffered in previous {@code 1383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * update} calls. 1384ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 1385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param input 1386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input buffer. 1387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param inputOffset 1388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the offset in the input buffer. 1389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param inputLen 1390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the length of the input. 1391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param output 1392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the output buffer for the transformed bytes. 1393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the number of bytes placed in the output buffer. 1394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ShortBufferException 1395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the size of the {@code output} buffer is too small. 1396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalBlockSizeException 1397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the size of the resulting bytes is not a multiple of the 1398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher block size. 1399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BadPaddingException 1400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the padding of the data does not match the padding scheme. 1401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalStateException 1402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this cipher instance is not initialized for encryption or 1403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * decryption. 1404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 1405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code inputOffset} and {@code inputLen} do not specify an 1406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * valid chunk in the input buffer. 1407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final int doFinal(byte[] input, int inputOffset, int inputLen, 1409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project byte[] output) throws ShortBufferException, 1410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project IllegalBlockSizeException, BadPaddingException { 1411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return doFinal(input, inputOffset, inputLen, output, 0); 1412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Finishes a multi-part transformation (encryption or decryption). 1416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 1417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Processes the {@code inputLen} bytes in {@code input} buffer at {@code 1418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * inputOffset}, and any bytes that have been buffered in previous {@code 1419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * update} calls. 1420ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 1421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param input 1422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input buffer. 1423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param inputOffset 1424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the offset in the input buffer. 1425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param inputLen 1426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the length of the input. 1427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param output 1428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the output buffer for the transformed bytes. 1429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param outputOffset 1430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the offset in the output buffer. 1431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the number of bytes placed in the output buffer. 1432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ShortBufferException 1433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the size of the {@code output} buffer is too small. 1434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalBlockSizeException 1435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the size of the resulting bytes is not a multiple of the 1436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher block size. 1437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BadPaddingException 1438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the padding of the data does not match the padding scheme. 1439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalStateException 1440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this cipher instance is not initialized for encryption or 1441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * decryption. 1442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 1443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code inputOffset} and {@code inputLen} do not specify an 1444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * valid chunk in the input buffer. 1445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final int doFinal(byte[] input, int inputOffset, int inputLen, 1447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project byte[] output, int outputOffset) throws ShortBufferException, 1448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project IllegalBlockSizeException, BadPaddingException { 1449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { 145080a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalStateException(); 1451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1452c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom checkInputOffsetAndCount(input.length, inputOffset, inputLen); 145385dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return getSpi().engineDoFinal(input, inputOffset, inputLen, output, 1454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project outputOffset); 1455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Finishes a multi-part transformation (encryption or decryption). 1459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 1460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Processes the {@code input.remaining()} bytes in {@code input} buffer at 1461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code input.position()}, and any bytes that have been buffered in 1462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * previous {@code update} calls. The transformed bytes are placed into 1463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code output} buffer. 1464ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 1465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param input 1466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input buffer. 1467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param output 1468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the output buffer. 1469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the number of bytes placed into the output buffer. 1470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ShortBufferException 1471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the size of the {@code output} buffer is too small. 1472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalBlockSizeException 1473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the size of the resulting bytes is not a multiple of the 1474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher block size. 1475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BadPaddingException 1476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the padding of the data does not match the padding scheme. 1477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 1478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the input buffer and the output buffer are the same 1479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * object. 1480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalStateException 1481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this cipher instance is not initialized for encryption or 1482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * decryption. 1483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final int doFinal(ByteBuffer input, ByteBuffer output) 1485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws ShortBufferException, IllegalBlockSizeException, 1486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project BadPaddingException { 1487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { 148880a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalStateException(); 1489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (input == output) { 149180a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalArgumentException("input == output"); 1492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 149385dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return getSpi().engineDoFinal(input, output); 1494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Wraps a key using this cipher instance. 1498ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 1499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key 1500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the key to wrap. 1501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the wrapped key. 1502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalBlockSizeException 1503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the size of the resulting bytes is not a multiple of the 1504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher block size. 1505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidKeyException 1506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this cipher instance can not wrap this key. 1507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalStateException 1508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this cipher instance is not initialized for wrapping. 1509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final byte[] wrap(Key key) throws IllegalBlockSizeException, 1511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project InvalidKeyException { 1512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (mode != WRAP_MODE) { 151380a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalStateException(); 1514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 151585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return getSpi().engineWrap(key); 1516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unwraps a key using this cipher instance. 1520ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 1521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param wrappedKey 1522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the wrapped key to unwrap. 1523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param wrappedKeyAlgorithm 1524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the algorithm for the wrapped key. 1525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param wrappedKeyType 1526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the type of the wrapped key (one of: {@code SECRET_KEY 1527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <code>, <code>PRIVATE_KEY} or {@code PUBLIC_KEY}) 1528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the unwrapped key 1529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidKeyException 1530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the {@code wrappedKey} can not be unwrapped to a key of 1531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * type {@code wrappedKeyType} for the {@code 1532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * wrappedKeyAlgorithm}. 1533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NoSuchAlgorithmException 1534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if no provider can be found that can create a key of type 1535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code wrappedKeyType} for the {@code wrappedKeyAlgorithm}. 1536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalStateException 1537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this cipher instance is not initialized for unwrapping. 1538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final Key unwrap(byte[] wrappedKey, String wrappedKeyAlgorithm, 1540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int wrappedKeyType) throws InvalidKeyException, 1541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project NoSuchAlgorithmException { 1542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (mode != UNWRAP_MODE) { 154380a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalStateException(); 1544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 154585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return getSpi().engineUnwrap(wrappedKey, wrappedKeyAlgorithm, 1546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project wrappedKeyType); 1547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the maximum key length for the specified transformation. 1551ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 1552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param transformation 1553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the transformation name. 1554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the maximum key length, currently {@code Integer.MAX_VALUE}. 1555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NoSuchAlgorithmException 1556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if no provider for the specified {@code transformation} can 1557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * be found. 1558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException 1559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code transformation} is {@code null}. 1560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final int getMaxAllowedKeyLength(String transformation) 1562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws NoSuchAlgorithmException { 1563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (transformation == null) { 156486acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("transformation == null"); 1565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkTransformation(transformation); 1567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //FIXME jurisdiction policy files 1568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return Integer.MAX_VALUE; 1569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the maximum cipher parameter value for the specified 1573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * transformation. If there is no maximum limit, {@code null} is returned. 1574ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 1575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param transformation 1576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the transformation name. 1577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a parameter spec holding the maximum value or {@code null}. 1578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Currently {@code null}. 1579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NoSuchAlgorithmException 1580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if no provider for the specified {@code transformation} can 1581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * be found. 1582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException 1583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code transformation} is {@code null}. 1584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final AlgorithmParameterSpec getMaxAllowedParameterSpec( 1586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String transformation) throws NoSuchAlgorithmException { 1587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (transformation == null) { 158886acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("transformation == null"); 1589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkTransformation(transformation); 1591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //FIXME jurisdiction policy files 1592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 1593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 1595