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 /** 111484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * Used to keep track of which underlying {@code CipherSpi#engineInit(...)} 112484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * variant to call when testing suitability. 113484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root */ 114484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root private static enum InitType { 115484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root KEY, ALGORITHM_PARAMS, ALGORITHM_PARAM_SPEC, 116484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root }; 117484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root 118484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root /** 119484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * Keeps track of the possible arguments to {@code Cipher#init(...)}. 120484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root */ 121484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root private static class InitParams { 122484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root private final InitType initType; 123484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root private final int opmode; 124484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root private final Key key; 125484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root private final SecureRandom random; 126484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root private final AlgorithmParameterSpec spec; 127484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root private final AlgorithmParameters params; 128484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root 129484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root private InitParams(InitType initType, int opmode, Key key, SecureRandom random, 130484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root AlgorithmParameterSpec spec, AlgorithmParameters params) { 131484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root this.initType = initType; 132484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root this.opmode = opmode; 133484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root this.key = key; 134484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root this.random = random; 135484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root this.spec = spec; 136484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root this.params = params; 137484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root } 138484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root } 139484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root 140484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root /** 141484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * Expresses the various types of transforms that may be used during 142484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * initialization. 143484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root */ 144484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root private static class Transform { 145484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root private final String name; 146484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root private final NeedToSet needToSet; 147484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root 148484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root public Transform(String name, NeedToSet needToSet) { 149484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root this.name = name; 150484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root this.needToSet = needToSet; 151484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root } 152484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root } 153484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root 154484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root /** 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The service name. 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 157f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes private static final String SERVICE = "Cipher"; 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Used to access common engine functionality. 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1620a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom private static final Engine ENGINE = new Engine(SERVICE); 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 16485dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root /** The attribute used for supported paddings. */ 16585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root private static final String ATTRIBUTE_PADDINGS = "SupportedPaddings"; 16685dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root 16785dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root /** The attribute used for supported modes. */ 16885dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root private static final String ATTRIBUTE_MODES = "SupportedModes"; 16985dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The provider. 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Provider provider; 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 176beff0f1375b635c692d48190aa69a06986b5111fKenny Root * The provider specified when instance created. 177beff0f1375b635c692d48190aa69a06986b5111fKenny Root */ 178beff0f1375b635c692d48190aa69a06986b5111fKenny Root private final Provider specifiedProvider; 179beff0f1375b635c692d48190aa69a06986b5111fKenny Root 180beff0f1375b635c692d48190aa69a06986b5111fKenny Root /** 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The SPI implementation. 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private CipherSpi spiImpl; 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 18616ec6489f8339c55fb65db423c4a997a9f91d089Kenny Root * The SPI implementation. 18716ec6489f8339c55fb65db423c4a997a9f91d089Kenny Root */ 18816ec6489f8339c55fb65db423c4a997a9f91d089Kenny Root private final CipherSpi specifiedSpi; 18916ec6489f8339c55fb65db423c4a997a9f91d089Kenny Root 19016ec6489f8339c55fb65db423c4a997a9f91d089Kenny Root /** 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The transformation. 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 19385dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root private final String transformation; 19485dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root 19585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root /** 19685dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root * The transformation split into parts. 19785dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root */ 19885dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root private final String[] transformParts; 19985dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root 20085dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root /** 20185dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root * Lock held while the SPI is initializing. 20285dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root */ 20385dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root private final Object initLock = new Object(); 204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2059229d47c1288e25ead3a2dc27fac8a4a2ee932a3Elliott Hughes private static SecureRandom secureRandom; 206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates a new Cipher instance. 209ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param cipherSpi 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the implementation delegate of the cipher. 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param provider 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the provider of the implementation of this cipher. 214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param transformation 215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the transformation that this cipher performs. 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if either cipherSpi is {@code null} or provider is {@code 218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * null} and {@code cipherSpi} is a {@code NullCipherSpi}. 219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 22085dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root protected Cipher(CipherSpi cipherSpi, Provider provider, String transformation) { 221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (cipherSpi == null) { 22286acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("cipherSpi == null"); 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!(cipherSpi instanceof NullCipherSpi) && provider == null) { 22586acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("provider == null"); 226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 227beff0f1375b635c692d48190aa69a06986b5111fKenny Root this.specifiedProvider = provider; 22816ec6489f8339c55fb65db423c4a997a9f91d089Kenny Root this.specifiedSpi = cipherSpi; 22985dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root this.transformation = transformation; 23085dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root this.transformParts = null; 23185dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 23285dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root 23385dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root private Cipher(String transformation, String[] transformParts, Provider provider) { 23485dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root this.transformation = transformation; 23585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root this.transformParts = transformParts; 236beff0f1375b635c692d48190aa69a06986b5111fKenny Root this.specifiedProvider = provider; 23716ec6489f8339c55fb65db423c4a997a9f91d089Kenny Root this.specifiedSpi = null; 238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 24085dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates a new Cipher for the specified transformation. The installed 243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * providers are searched in order for an implementation of the specified 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * transformation. The first found provider providing the transformation is 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * used to create the cipher. If no provider is found an exception is 246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * thrown. 247ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param transformation 249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the transformation to create a cipher for. 250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a cipher for the requested transformation. 251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NoSuchAlgorithmException 252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if no installed provider can provide the 253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <i>transformation</i>, or it is {@code null}, empty or in an 254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * invalid format. 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NoSuchPaddingException 256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if no installed provider can provide the padding scheme in 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the <i>transformation</i>. 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final Cipher getInstance(String transformation) 260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws NoSuchAlgorithmException, NoSuchPaddingException { 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return getCipher(transformation, null); 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates a new cipher for the specified transformation provided by the 266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specified provider. 267ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param transformation 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the transformation to create a cipher for. 270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param provider 271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the provider to ask for the transformation. 272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a cipher for the requested transformation. 273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NoSuchAlgorithmException 274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the specified provider can not provide the 275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <i>transformation</i>, or it is {@code null}, empty or in an 276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * invalid format. 277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NoSuchProviderException 278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if no provider with the specified name can be found. 279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NoSuchPaddingException 280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the requested padding scheme in the <i>transformation</i> 281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is not available. 282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the specified provider is {@code null}. 284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final Cipher getInstance(String transformation, 286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String provider) throws NoSuchAlgorithmException, 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project NoSuchProviderException, NoSuchPaddingException { 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (provider == null) { 29080a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalArgumentException("provider == null"); 291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Provider p = Security.getProvider(provider); 294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (p == null) { 29580a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new NoSuchProviderException("Provider not available: " + provider); 296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return getInstance(transformation, p); 298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 3010a64887ae9127d081fc6e312ba1f06f727453800Kenny Root * Creates a new cipher for the specified transformation. The 3020a64887ae9127d081fc6e312ba1f06f727453800Kenny Root * {@code provider} supplied does not have to be registered. 303ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param transformation 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the transformation to create a cipher for. 306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param provider 307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the provider to ask for the transformation. 308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a cipher for the requested transformation. 309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NoSuchAlgorithmException 310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the specified provider can not provide the 311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <i>transformation</i>, or it is {@code null}, empty or in an 312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * invalid format. 313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NoSuchPaddingException 314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the requested padding scheme in the <i>transformation</i> 315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is not available. 316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the provider is {@code null}. 318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final Cipher getInstance(String transformation, 320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Provider provider) throws NoSuchAlgorithmException, 321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project NoSuchPaddingException { 322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (provider == null) { 32380a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalArgumentException("provider == null"); 324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 32585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return getCipher(transformation, provider); 326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 32880a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes private static NoSuchAlgorithmException invalidTransformation(String transformation) 32980a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throws NoSuchAlgorithmException { 33080a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new NoSuchAlgorithmException("Invalid transformation: " + transformation); 33180a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes } 33280a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes 333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 33485dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root * Create a Cipher instance but don't choose a CipherSpi until we have more 33585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root * information. 336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 33785dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root private static Cipher getCipher(String transformation, Provider provider) 338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws NoSuchAlgorithmException, NoSuchPaddingException { 33980a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes if (transformation == null || transformation.isEmpty()) { 34080a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw invalidTransformation(transformation); 341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 34385dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root String[] transformParts = checkTransformation(transformation); 3442ae508725e0b6c4dd4c23717bc1625bd745670b6Sergio Giro 345484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root Engine.SpiAndProvider sap; 346484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root try { 347484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root sap = tryCombinations(null /* params */, provider, transformation, transformParts); 348484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root } catch (InvalidKeyException | InvalidAlgorithmParameterException e) { 349484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root // should never happen since we passed in null params 350484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root throw new ProviderException(e); 351484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root } 352484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root 353484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root if (sap == null) { 3546cdb6b7e6939270ccd21790ec95e42197cefc0c3Brian Carlstrom if (provider == null) { 35585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root throw new NoSuchAlgorithmException("No provider found for " + transformation); 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 35785dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root throw new NoSuchAlgorithmException("Provider " + provider.getName() 35885dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root + " does not provide " + transformation); 3596cdb6b7e6939270ccd21790ec95e42197cefc0c3Brian Carlstrom } 360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 36185dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return new Cipher(transformation, transformParts, provider); 362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 364484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root /** 365484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * Checks that the provided algorithm {@code transformation} string is a 366484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * valid input. The algorithm is the only mandatory field and input can be 367484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * of the form: 368484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * <ul> 369484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * <li><code>"[cipher]"</code> 370484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * <li><code>"[cipher]/[mode]/[padding]"</code> 371484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * <li><code>"[cipher]//[padding]"</code> 372484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * <li><code>"[cipher]/[mode]"</code> 373484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * </ul> 374484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * <p> 375484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * Returns the specified transformation split up into three parts 376484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * corresponding to their function: 377484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * <p> 378484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * <code> 379484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * {<algorithm>, <mode>, <padding>} 380484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * </code> 381484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * <p> 382484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root */ 38385dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root private static String[] checkTransformation(String transformation) 38485dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root throws NoSuchAlgorithmException { 385937b6c4ef5f8ad57279e2ebed4393a78d1729d8bBrian Carlstrom // ignore an extra prefix / characters such as in 38685dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root // "/DES/CBC/PKCS5Padding" http://b/3387688 387937b6c4ef5f8ad57279e2ebed4393a78d1729d8bBrian Carlstrom if (transformation.startsWith("/")) { 388937b6c4ef5f8ad57279e2ebed4393a78d1729d8bBrian Carlstrom transformation = transformation.substring(1); 389937b6c4ef5f8ad57279e2ebed4393a78d1729d8bBrian Carlstrom } 390118abc3050371812703e4fabf03f4399d01fb28cElliott Hughes // 'transformation' should be of the form "algorithm/mode/padding". 391118abc3050371812703e4fabf03f4399d01fb28cElliott Hughes String[] pieces = transformation.split("/"); 392118abc3050371812703e4fabf03f4399d01fb28cElliott Hughes if (pieces.length > 3) { 393118abc3050371812703e4fabf03f4399d01fb28cElliott Hughes throw invalidTransformation(transformation); 394118abc3050371812703e4fabf03f4399d01fb28cElliott Hughes } 395118abc3050371812703e4fabf03f4399d01fb28cElliott Hughes // Empty or missing pieces are represented by null. 396118abc3050371812703e4fabf03f4399d01fb28cElliott Hughes String[] result = new String[3]; 397118abc3050371812703e4fabf03f4399d01fb28cElliott Hughes for (int i = 0; i < pieces.length; ++i) { 398118abc3050371812703e4fabf03f4399d01fb28cElliott Hughes String piece = pieces[i].trim(); 399118abc3050371812703e4fabf03f4399d01fb28cElliott Hughes if (!piece.isEmpty()) { 400118abc3050371812703e4fabf03f4399d01fb28cElliott Hughes result[i] = piece; 401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 403118abc3050371812703e4fabf03f4399d01fb28cElliott Hughes // You MUST specify an algorithm. 404118abc3050371812703e4fabf03f4399d01fb28cElliott Hughes if (result[0] == null) { 40580a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw invalidTransformation(transformation); 406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 407118abc3050371812703e4fabf03f4399d01fb28cElliott Hughes if (!(result[1] == null && result[2] == null) && (result[1] == null || result[2] == null)) { 40880a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw invalidTransformation(transformation); 409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 410118abc3050371812703e4fabf03f4399d01fb28cElliott Hughes return result; 411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 414484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * Makes sure a CipherSpi that matches this type is selected. If 415484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * {@code key != null} then it assumes that a suitable provider exists for 416484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * this instance (used by {@link #init}. If the {@code initParams} is passed 417484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * in, then the {@code CipherSpi} returned will be initialized. 41830bc3f8566f9b089ce02a7a22b51991d896f5524Sergio Giro * 4192ae508725e0b6c4dd4c23717bc1625bd745670b6Sergio Giro * @throws InvalidKeyException if the specified key cannot be used to 4202ae508725e0b6c4dd4c23717bc1625bd745670b6Sergio Giro * initialize this cipher. 421484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * @throws InvalidAlgorithmParameterException 42285dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root */ 423484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root private CipherSpi getSpi(InitParams initParams) throws InvalidKeyException, 424484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root InvalidAlgorithmParameterException { 42516ec6489f8339c55fb65db423c4a997a9f91d089Kenny Root if (specifiedSpi != null) { 42616ec6489f8339c55fb65db423c4a997a9f91d089Kenny Root return specifiedSpi; 42716ec6489f8339c55fb65db423c4a997a9f91d089Kenny Root } 42816ec6489f8339c55fb65db423c4a997a9f91d089Kenny Root 42985dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root synchronized (initLock) { 43030bc3f8566f9b089ce02a7a22b51991d896f5524Sergio Giro // This is not only a matter of performance. Many methods like update, doFinal, etc. 431484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root // call {@code #getSpi()} (ie, {@code #getSpi(null /* params */)}) and without this 43230bc3f8566f9b089ce02a7a22b51991d896f5524Sergio Giro // shortcut they would override an spi that was chosen using the key. 433484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root if (spiImpl != null && initParams == null) { 43485dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return spiImpl; 43585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 43685dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root 437484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root final Engine.SpiAndProvider sap = tryCombinations(initParams, specifiedProvider, 438484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root transformation, transformParts); 43985dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root if (sap == null) { 440484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root throw new ProviderException("No provider found for " + transformation); 44185dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 44285dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root 44385dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root spiImpl = (CipherSpi) sap.spi; 44485dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root provider = sap.provider; 44585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root 44685dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return spiImpl; 44785dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 44885dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 44985dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root 45085dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root /** 45185dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root * Convenience call when the Key is not available. 45285dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root */ 453834660d9ce0cdcedf256e4b90b7bd4b4d3832daaAlex Klyubin private CipherSpi getSpi() { 4542ae508725e0b6c4dd4c23717bc1625bd745670b6Sergio Giro try { 4552ae508725e0b6c4dd4c23717bc1625bd745670b6Sergio Giro return getSpi(null); 456484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root } catch (InvalidKeyException | InvalidAlgorithmParameterException e) { 457484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root throw new ProviderException("Exception thrown when params == null", e); 4582ae508725e0b6c4dd4c23717bc1625bd745670b6Sergio Giro } 45985dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 46085dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root 46185dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root /** 4624ec153a9ae62f6f62694fd0a320db16c254174c9Alex Klyubin * Returns the {@code CipherSpi} backing this {@code Cipher} or {@code null} if no 4634ec153a9ae62f6f62694fd0a320db16c254174c9Alex Klyubin * {@code CipherSpi} is backing this {@code Cipher}. 4644ec153a9ae62f6f62694fd0a320db16c254174c9Alex Klyubin * 4654ec153a9ae62f6f62694fd0a320db16c254174c9Alex Klyubin * @hide 4664ec153a9ae62f6f62694fd0a320db16c254174c9Alex Klyubin */ 4674ec153a9ae62f6f62694fd0a320db16c254174c9Alex Klyubin public CipherSpi getCurrentSpi() { 4684ec153a9ae62f6f62694fd0a320db16c254174c9Alex Klyubin if (specifiedSpi != null) { 4694ec153a9ae62f6f62694fd0a320db16c254174c9Alex Klyubin return specifiedSpi; 4704ec153a9ae62f6f62694fd0a320db16c254174c9Alex Klyubin } 4714ec153a9ae62f6f62694fd0a320db16c254174c9Alex Klyubin 4724ec153a9ae62f6f62694fd0a320db16c254174c9Alex Klyubin synchronized (initLock) { 4734ec153a9ae62f6f62694fd0a320db16c254174c9Alex Klyubin return spiImpl; 4744ec153a9ae62f6f62694fd0a320db16c254174c9Alex Klyubin } 4754ec153a9ae62f6f62694fd0a320db16c254174c9Alex Klyubin } 4764ec153a9ae62f6f62694fd0a320db16c254174c9Alex Klyubin 4774ec153a9ae62f6f62694fd0a320db16c254174c9Alex Klyubin /** 478484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * Tries to find the correct {@code Cipher} transform to use. Returns a 479484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * {@link Engine.SpiAndProvider}, throws the first exception that was 480484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * encountered during attempted initialization, or {@code null} if there are 481484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * no providers that support the {@code initParams}. 482484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * <p> 483484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * {@code transformParts} must be in the format returned by 484484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * {@link #checkTransformation(String)}. The combinations of mode strings 485484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * tried are as follows: 486484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * <ul> 487484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * <li><code>[cipher]/[mode]/[padding]</code> 488484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * <li><code>[cipher]/[mode]</code> 489484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * <li><code>[cipher]//[padding]</code> 490484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * <li><code>[cipher]</code> 491484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * </ul> 49285dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root */ 493484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root private static Engine.SpiAndProvider tryCombinations(InitParams initParams, Provider provider, 494484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root String transformation, String[] transformParts) throws InvalidKeyException, 495484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root InvalidAlgorithmParameterException { 496484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root // Enumerate all the transforms we need to try 497484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root ArrayList<Transform> transforms = new ArrayList<Transform>(); 49885dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root if (transformParts[1] != null && transformParts[2] != null) { 499484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root transforms.add(new Transform(transformParts[0] + "/" + transformParts[1] + "/" 500484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root + transformParts[2], NeedToSet.NONE)); 50185dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 50285dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root if (transformParts[1] != null) { 503484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root transforms.add(new Transform(transformParts[0] + "/" + transformParts[1], 504484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root NeedToSet.PADDING)); 50585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 50685dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root if (transformParts[2] != null) { 507484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root transforms.add(new Transform(transformParts[0] + "//" + transformParts[2], 508484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root NeedToSet.MODE)); 50985dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 510484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root transforms.add(new Transform(transformParts[0], NeedToSet.BOTH)); 511484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root 512484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root // Try each of the transforms and keep track of the first exception 513484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root // encountered. 514484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root Exception cause = null; 515484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root for (Transform transform : transforms) { 516484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root if (provider != null) { 517484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root Provider.Service service = provider.getService(SERVICE, transform.name); 518484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root if (service == null) { 519484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root continue; 520484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root } 521484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root return tryTransformWithProvider(initParams, transformParts, transform.needToSet, 522484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root service); 5233ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root } 524484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root ArrayList<Provider.Service> services = ENGINE.getServices(transform.name); 525484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root if (services == null || services.isEmpty()) { 526484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root continue; 527484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root } 528484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root for (Provider.Service service : services) { 529484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root if (initParams == null || initParams.key == null 530484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root || service.supportsParameter(initParams.key)) { 531484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root try { 532484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root Engine.SpiAndProvider sap = tryTransformWithProvider(initParams, 533484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root transformParts, transform.needToSet, service); 534484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root if (sap != null) { 535484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root return sap; 536484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root } 537484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root } catch (Exception e) { 538484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root if (cause == null) { 539484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root cause = e; 540484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root } 541484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root } 5422ae508725e0b6c4dd4c23717bc1625bd745670b6Sergio Giro } 54385dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 54485dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 545484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root if (cause instanceof InvalidKeyException) { 546484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root throw (InvalidKeyException) cause; 547484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root } else if (cause instanceof InvalidAlgorithmParameterException) { 548484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root throw (InvalidAlgorithmParameterException) cause; 549484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root } else if (cause instanceof RuntimeException) { 550484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root throw (RuntimeException) cause; 551484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root } else if (cause != null) { 552484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root throw new InvalidKeyException("No provider can be initialized with given key", cause); 553484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root } else if (initParams == null || initParams.key == null) { 554484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root return null; 555484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root } else { 556484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root // Since the key is not null, a suitable provider exists, 557484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root // and it is an InvalidKeyException. 558484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root throw new InvalidKeyException("No provider offers " + transformation + " for " 559484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root + initParams.key.getAlgorithm() + " key of class " 560484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root + initParams.key.getClass().getName() + " and export format " 561484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root + initParams.key.getFormat()); 562484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root } 56385dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 56485dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root 565484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root /** 566484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * Tries to initialize the {@code Cipher} from a given {@code service}. If 567484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * initialization is successful, the initialized {@code spi} is returned. If 568484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * the {@code service} cannot be initialized with the specified 569484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * {@code initParams}, then it's expected to throw 570484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * {@code InvalidKeyException} or {@code InvalidAlgorithmParameterException} 571484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * as a hint to the caller that it should continue searching for a 572484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * {@code Service} that will work. 573484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root */ 574484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root private static Engine.SpiAndProvider tryTransformWithProvider(InitParams initParams, 575484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root String[] transformParts, NeedToSet type, Provider.Service service) 576484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root throws InvalidKeyException, InvalidAlgorithmParameterException { 5773ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root try { 5783ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root /* 5793ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root * Check to see if the Cipher even supports the attributes before 5803ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root * trying to instantiate it. 5813ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root */ 5823ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root if (!matchAttribute(service, ATTRIBUTE_MODES, transformParts[1]) 5833ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root || !matchAttribute(service, ATTRIBUTE_PADDINGS, transformParts[2])) { 5843ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root return null; 5853ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root } 5863ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root 5873ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root Engine.SpiAndProvider sap = ENGINE.getInstance(service, null); 5883ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root if (sap.spi == null || sap.provider == null) { 58907c8c69f59b60684fe07b003b3462e8d9687f422Kenny Root return null; 5903ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root } 5913ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root CipherSpi spi = (CipherSpi) sap.spi; 5923ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root if (((type == NeedToSet.MODE) || (type == NeedToSet.BOTH)) 5933ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root && (transformParts[1] != null)) { 5943ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root spi.engineSetMode(transformParts[1]); 5953ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root } 5963ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root if (((type == NeedToSet.PADDING) || (type == NeedToSet.BOTH)) 5973ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root && (transformParts[2] != null)) { 5983ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root spi.engineSetPadding(transformParts[2]); 5993ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root } 600484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root 601484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root if (initParams != null) { 602484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root switch (initParams.initType) { 603484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root case ALGORITHM_PARAMS: 604484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root spi.engineInit(initParams.opmode, initParams.key, initParams.params, 605484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root initParams.random); 606484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root break; 607484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root case ALGORITHM_PARAM_SPEC: 608484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root spi.engineInit(initParams.opmode, initParams.key, initParams.spec, 609484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root initParams.random); 610484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root break; 611484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root case KEY: 612484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root spi.engineInit(initParams.opmode, initParams.key, initParams.random); 613484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root break; 614484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root default: 615484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root throw new AssertionError("This should never be reached"); 616484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root } 617484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root } 6183ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root return sap; 6193ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root } catch (NoSuchAlgorithmException ignored) { 6203ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root } catch (NoSuchPaddingException ignored) { 6213ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root } 6223ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root return null; 6233ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root } 6243ed78a8925825daccdba23fda1f69cbb3aa77a24Kenny Root 62585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root /** 62685dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root * If the attribute listed exists, check that it matches the regular 62785dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root * expression. 62885dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root */ 62985dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root private static boolean matchAttribute(Service service, String attr, String value) { 63085dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root if (value == null) { 63185dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return true; 63285dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 63385dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root final String pattern = service.getAttribute(attr); 63485dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root if (pattern == null) { 63585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return true; 63685dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 63785dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root final String valueUc = value.toUpperCase(Locale.US); 63885dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return valueUc.matches(pattern.toUpperCase(Locale.US)); 63985dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 64085dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root 64185dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root /** 64285dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root * Returns the provider of this cipher instance. 64307c8c69f59b60684fe07b003b3462e8d9687f422Kenny Root * 644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the provider of this cipher instance. 645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final Provider getProvider() { 64785dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root getSpi(); 648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return provider; 649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the name of the algorithm of this cipher instance. 653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This is the name of the <i>transformation</i> argument used in the 655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code getInstance} call creating this object. 656ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the name of the algorithm of this cipher instance. 658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final String getAlgorithm() { 660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return transformation; 661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns this ciphers block size (in bytes). 665ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return this ciphers block size. 667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final int getBlockSize() { 66985dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return getSpi().engineGetBlockSize(); 670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the length in bytes an output buffer needs to be when this cipher 674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is updated with {@code inputLen} bytes. 675ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param inputLen 677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the number of bytes of the input. 678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the output buffer length for the input length. 679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalStateException 680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this cipher instance is in an invalid state. 681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final int getOutputSize(int inputLen) { 683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (mode == 0) { 68480a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalStateException("Cipher has not yet been initialized"); 685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 68685dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return getSpi().engineGetOutputSize(inputLen); 687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the <i>initialization vector</i> for this cipher instance. 691ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the <i>initialization vector</i> for this cipher instance. 693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final byte[] getIV() { 69585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return getSpi().engineGetIV(); 696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the parameters that where used to create this cipher instance. 700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * These may be a the same parameters that were used to create this cipher 702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * instance, or may be a combination of default and random parameters, 703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * depending on the underlying cipher implementation. 704ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the parameters that where used to create this cipher instance, or 706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code null} if this cipher instance does not have any 707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * parameters. 708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final AlgorithmParameters getParameters() { 71085dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return getSpi().engineGetParameters(); 711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the exemption mechanism associated with this cipher. 715ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return currently {@code null} 717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final ExemptionMechanism getExemptionMechanism() { 719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //FIXME implement getExemptionMechanism 720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // try { 722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // return ExemptionMechanism.getInstance(transformation, provider); 723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // } catch (NoSuchAlgorithmException e) { 724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // } 726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 729484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root /** 730484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * Checks that the provided {@code mode} is one that is valid for 731484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root * {@code Cipher}. 732484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root */ 73385dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root private void checkMode(int mode) { 73485dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE && mode != UNWRAP_MODE 73585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root && mode != WRAP_MODE) { 73685dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root throw new InvalidParameterException("Invalid mode: " + mode); 73785dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 73885dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root } 73985dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root 740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Initializes this cipher instance with the specified key. 742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The cipher is initialized for the specified operational mode (one of: 744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * encryption, decryption, key wrapping or key unwrapping) depending on 745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code opmode}. 746ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * <p> 747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If this cipher instance needs any algorithm parameters or random values 748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * that the specified key can not provide, the underlying implementation of 749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this cipher is supposed to generate the required parameters (using its 750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * provider or random values). 751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * When a cipher instance is initialized by a call to any of the {@code 753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * init} methods, the state of the instance is overridden, meaning that it 754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is equivalent to creating a new instance and calling its {@code init} 755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method. 756ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param opmode 758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the operation this cipher instance should be initialized for 759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code 760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WRAP_MODE} or {@code UNWRAP_MODE}). 761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key 762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input key for the operation. 763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidKeyException 764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the specified key can not be used to initialize this 765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher instance. 766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final void init(int opmode, Key key) throws InvalidKeyException { 7689229d47c1288e25ead3a2dc27fac8a4a2ee932a3Elliott Hughes if (secureRandom == null) { 769adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // In theory it might be thread-unsafe but in the given case it's OK 770adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // since it does not matter which SecureRandom instance is passed 771adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // to the init() 7729229d47c1288e25ead3a2dc27fac8a4a2ee932a3Elliott Hughes secureRandom = new SecureRandom(); 773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 7749229d47c1288e25ead3a2dc27fac8a4a2ee932a3Elliott Hughes init(opmode, key, secureRandom); 775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 778adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Initializes this cipher instance with the specified key and a source of 779adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * randomness. 780adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 781adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The cipher is initialized for the specified operational mode (one of: 782adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * encryption, decryption, key wrapping or key unwrapping) depending on 783adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code opmode}. 784ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * <p> 785adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If this cipher instance needs any algorithm parameters or random values 786adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * that the specified key can not provide, the underlying implementation of 787adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this cipher is supposed to generate the required parameters (using its 788adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * provider or random values). Random values are generated using {@code 789adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * random}; 790adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 791adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * When a cipher instance is initialized by a call to any of the {@code 792adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * init} methods, the state of the instance is overridden, means it is 793adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * equivalent to creating a new instance and calling it {@code init} method. 794ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 795adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param opmode 796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the operation this cipher instance should be initialized for 797adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code 798adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WRAP_MODE} or {@code UNWRAP_MODE}). 799adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key 800adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input key for the operation. 801adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param random 802adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the source of randomness to use. 803adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidKeyException 804adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the specified key can not be used to initialize this 805adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher instance. 806adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidParameterException 807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the specified opmode is invalid. 808adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 80980a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes public final void init(int opmode, Key key, SecureRandom random) throws InvalidKeyException { 8100c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom checkMode(opmode); 811adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // FIXME InvalidKeyException 812adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // if keysize exceeds the maximum allowable keysize 813adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // (jurisdiction policy files) 814484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root try { 815484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root getSpi(new InitParams(InitType.KEY, opmode, key, random, null, null)); 816484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root } catch (InvalidAlgorithmParameterException e) { 817484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root // Should never happen since we only specified the key. 818484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root throw new ProviderException("Invalid parameters when params == null", e); 819484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root } 820adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project mode = opmode; 821adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 822adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 823adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 824adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Initializes this cipher instance with the specified key and algorithm 825adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * parameters. 826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 827adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The cipher is initialized for the specified operational mode (one of: 828adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * encryption, decryption, key wrapping or key unwrapping). 829ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * <p> 830adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If this cipher instance needs any algorithm parameters and {@code params} 831adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is {@code null}, the underlying implementation of this cipher is supposed 832adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * to generate the required parameters (using its provider or random 833adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * values). 834adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 835adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * When a cipher instance is initialized by a call to any of the {@code 836adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * init} methods, the state of the instance is overridden, means it is 837adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * equivalent to creating a new instance and calling it {@code init} method. 838ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param opmode 840adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the operation this cipher instance should be initialized for 841adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code 842adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WRAP_MODE} or {@code UNWRAP_MODE}). 843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key 844adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input key for the operation. 845adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param params 846adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the algorithm parameters. 847adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidKeyException 848adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the specified key can not be used to initialize this 849adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher instance. 850adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidAlgorithmParameterException 851adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * it the specified parameters are inappropriate for this 852adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher. 853adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 854adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final void init(int opmode, Key key, AlgorithmParameterSpec params) 855adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws InvalidKeyException, InvalidAlgorithmParameterException { 8569229d47c1288e25ead3a2dc27fac8a4a2ee932a3Elliott Hughes if (secureRandom == null) { 8579229d47c1288e25ead3a2dc27fac8a4a2ee932a3Elliott Hughes secureRandom = new SecureRandom(); 858adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 8599229d47c1288e25ead3a2dc27fac8a4a2ee932a3Elliott Hughes init(opmode, key, params, secureRandom); 860adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 861adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 862adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 863adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Initializes this cipher instance with the specified key, algorithm 864adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * parameters and a source of randomness. 865adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 866adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The cipher is initialized for the specified operational mode (one of: 867adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * encryption, decryption, key wrapping or key unwrapping) depending on 868adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code opmode}. 869adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 870adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If this cipher instance needs any algorithm parameters and {@code params} 871adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is {@code null}, the underlying implementation of this cipher is supposed 872adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * to generate the required parameters (using its provider or random 873adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * values). Random values are generated using {@code random}; 874adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 875adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * When a cipher instance is initialized by a call to any of the {@code 876adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * init} methods, the state of the instance is overridden, meaning that it 877adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is equivalent to creating a new instance and calling it {@code init} 878adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method. 879ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 880adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param opmode 881adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the operation this cipher instance should be initialized for 882adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code 883adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WRAP_MODE} or {@code UNWRAP_MODE}). 884adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key 885adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input key for the operation. 886adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param params 887adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the algorithm parameters. 888adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param random 889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the source of randomness to use. 890adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidKeyException 891adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the specified key can not be used to initialize this 892adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher instance. 893adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidAlgorithmParameterException 894adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * it the specified parameters are inappropriate for this 895adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher. 896adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidParameterException 897adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the specified {@code opmode} is invalid. 898adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 899adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final void init(int opmode, Key key, AlgorithmParameterSpec params, 900adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecureRandom random) throws InvalidKeyException, 901adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project InvalidAlgorithmParameterException { 9020c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom checkMode(opmode); 903adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // FIXME InvalidKeyException 904adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // if keysize exceeds the maximum allowable keysize 905adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // (jurisdiction policy files) 906adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // FIXME InvalidAlgorithmParameterException 907adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // cryptographic strength exceed the legal limits 908adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // (jurisdiction policy files) 909484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root getSpi(new InitParams(InitType.ALGORITHM_PARAM_SPEC, opmode, key, random, params, null)); 910adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project mode = opmode; 911adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 912adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 913adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 914adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Initializes this cipher instance with the specified key and algorithm 915adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * parameters. 916adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 917adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The cipher is initialized for the specified operation (one of: 918adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * encryption, decryption, key wrapping or key unwrapping) depending on 919adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code opmode}. 920ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * <p> 921adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If this cipher instance needs any algorithm parameters and {@code params} 922adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is {@code null}, the underlying implementation of this cipher is supposed 923adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * to generate the required parameters (using its provider or random 924adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * values). 925adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 926adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * When a cipher instance is initialized by a call to any of the {@code 927adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * init} methods, the state of the instance is overridden, meaning that it 928adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is equivalent to creating a new instance and calling it {@code init} 929adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method. 930ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 931adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param opmode 932adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the operation this cipher instance should be initialized for 933adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code 934adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WRAP_MODE} or {@code UNWRAP_MODE}). 935adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key 936adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input key for the operation. 937adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param params 938adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the algorithm parameters. 939adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidKeyException 940adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the specified key can not be used to initialize this 941adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher instance. 942adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidAlgorithmParameterException 943adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * it the specified parameters are inappropriate for this 944adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher. 945adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 946adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final void init(int opmode, Key key, AlgorithmParameters params) 947adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws InvalidKeyException, InvalidAlgorithmParameterException { 9489229d47c1288e25ead3a2dc27fac8a4a2ee932a3Elliott Hughes if (secureRandom == null) { 9499229d47c1288e25ead3a2dc27fac8a4a2ee932a3Elliott Hughes secureRandom = new SecureRandom(); 950adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 9519229d47c1288e25ead3a2dc27fac8a4a2ee932a3Elliott Hughes init(opmode, key, params, secureRandom); 952adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 953adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 954adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 955adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Initializes this cipher instance with the specified key, algorithm 956adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * parameters and a source of randomness. 957adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 958adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The cipher will be initialized for the specified operation (one of: 959adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * encryption, decryption, key wrapping or key unwrapping) depending on 960adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code opmode}. 961ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * <p> 962adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If this cipher instance needs any algorithm parameters and {@code params} 963adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is {@code null}, the underlying implementation of this cipher is supposed 964adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * to generate the required parameters (using its provider or random 965adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * values). Random values are generated using {@code random}. 966adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 967adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * When a cipher instance is initialized by a call to any of the {@code 968adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * init} methods, the state of the instance is overridden, means it is 969adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * equivalent to creating a new instance and calling it {@code init} method. 970ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 971adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param opmode 972adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the operation this cipher instance should be initialized for 973adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code 974adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WRAP_MODE} or {@code UNWRAP_MODE}). 975adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key 976adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input key for the operation. 977adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param params 978adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the algorithm parameters. 979adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param random 980adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the source of randomness to use. 981adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidKeyException 982adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the specified key can not be used to initialize this 983adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher instance. 984adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidAlgorithmParameterException 985adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the specified parameters are inappropriate for this 986adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher. 987adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidParameterException 988adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the specified {@code opmode} is invalid. 989adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 990adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final void init(int opmode, Key key, AlgorithmParameters params, 991adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecureRandom random) throws InvalidKeyException, 992adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project InvalidAlgorithmParameterException { 9930c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom checkMode(opmode); 994adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // FIXME InvalidKeyException 995adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // if keysize exceeds the maximum allowable keysize 996adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // (jurisdiction policy files) 997adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // FIXME InvalidAlgorithmParameterException 998adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // cryptographic strength exceed the legal limits 999adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // (jurisdiction policy files) 1000484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root getSpi(new InitParams(InitType.ALGORITHM_PARAMS, opmode, key, random, null, params)); 1001adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project mode = opmode; 1002adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1003adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1004adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1005adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Initializes this cipher instance with the public key from the specified 1006adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * certificate. 1007adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 1008adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The cipher will be initialized for the specified operation (one of: 1009adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * encryption, decryption, key wrapping or key unwrapping) depending on 1010adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code opmode}. 1011adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 1012adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * It the type of the certificate is X.509 and the certificate has a <i>key 1013adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * usage</i> extension field marked as critical, the specified {@code 1014adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * opmode} has the be enabled for this key, otherwise an {@code 1015adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * InvalidKeyException} is thrown. 1016adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 1017adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If this cipher instance needs any algorithm parameters that the key in 1018adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the certificate can not provide, the underlying implementation of this 1019adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher is supposed to generate the required parameters (using its 1020adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * provider or random values). 1021adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 1022adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * When a cipher instance is initialized by a call to any of the {@code 1023adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * init} methods, the state of the instance is overridden, means it is 1024adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * equivalent to creating a new instance and calling it {@code init} method. 1025ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 1026adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param opmode 1027adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the operation this cipher instance should be initialized for 1028adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code 1029adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WRAP_MODE} or {@code UNWRAP_MODE}). 1030adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param certificate 1031adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the certificate. 1032adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidKeyException 1033adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the public key in the certificate can not be used to 1034adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * initialize this cipher instance. 1035adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1036adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final void init(int opmode, Certificate certificate) 1037adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws InvalidKeyException { 10389229d47c1288e25ead3a2dc27fac8a4a2ee932a3Elliott Hughes if (secureRandom == null) { 10399229d47c1288e25ead3a2dc27fac8a4a2ee932a3Elliott Hughes secureRandom = new SecureRandom(); 1040adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 10419229d47c1288e25ead3a2dc27fac8a4a2ee932a3Elliott Hughes init(opmode, certificate, secureRandom); 1042adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1043adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1044adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1045adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Initializes this cipher instance with the public key from the specified 1046adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * certificate and a source of randomness. 1047adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 1048adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The cipher will be initialized for the specified operation (one of: 1049adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * encryption, decryption, key wrapping or key unwrapping) depending on 1050adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code opmode}. 1051ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * <p> 1052adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * It the type of the certificate is X.509 and the certificate has a <i>key 1053adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * usage</i> extension field marked as critical, the specified {@code 1054adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * opmode} has the be enabled for this key, otherwise an {@code 1055adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * InvalidKeyException} is thrown. 1056adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 1057adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If this cipher instance needs any algorithm parameters that the key in 1058adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the certificate can not provide, the underlying implementation of this 1059adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher is supposed to generate the required parameters (using its 1060adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * provider or random values). Random values are generated using {@code 1061adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * random}. 1062ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * <p> 1063adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * When a cipher instance is initialized by a call to any of the {@code 1064adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * init} methods, the state of the instance is overridden, means it is 1065adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * equivalent to creating a new instance and calling it {@code init} method. 1066ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 1067adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param opmode 1068adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the operation this cipher instance should be initialized for 1069adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code 1070adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WRAP_MODE} or {@code UNWRAP_MODE}). 1071adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param certificate 1072adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the certificate. 1073adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param random 1074adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the source of randomness to be used. 1075adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidKeyException 1076adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the public key in the certificate can not be used to 1077adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * initialize this cipher instance. 1078adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1079adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final void init(int opmode, Certificate certificate, 1080adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecureRandom random) throws InvalidKeyException { 10810c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstrom checkMode(opmode); 1082adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (certificate instanceof X509Certificate) { 1083adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Set<String> ce = ((X509Certificate) certificate).getCriticalExtensionOIDs(); 1084adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean critical = false; 1085adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (ce != null && !ce.isEmpty()) { 1086adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (String oid : ce) { 10870d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom if (oid.equals("2.5.29.15")) { // KeyUsage OID = 2.5.29.15 1088adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project critical = true; 1089adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 1090adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1091adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1092adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (critical) { 10930d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom boolean[] keyUsage = ((X509Certificate) certificate).getKeyUsage(); 10940d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom // As specified in RFC 3280: 10950d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom // Internet X.509 Public Key Infrastructure 10960d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom // Certificate and Certificate Revocation List (CRL) Profile. 10970d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom // Section 4.2.1.3 Key Usage 10980d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom // http://www.ietf.org/rfc/rfc3280.txt 1099adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // 1100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // KeyUsage ::= BIT STRING {digitalSignature (0), 11010d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom // nonRepudiation (1), 11020d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom // keyEncipherment (2), 11030d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom // dataEncipherment (3), 11040d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom // keyAgreement (4), 11050d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom // keyCertSign (5), 11060d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom // cRLSign (6), 11070d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom // encipherOnly (7), 11080d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom // decipherOnly (8) } 1109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (keyUsage != null) { 11100d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom if (opmode == ENCRYPT_MODE && !keyUsage[3]) { 11110a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom throw new InvalidKeyException("The public key in the certificate " 11120a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom + "cannot be used for ENCRYPT_MODE"); 11130d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom } else if (opmode == WRAP_MODE && !keyUsage[2]) { 11140a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom throw new InvalidKeyException("The public key in the certificate " 11150d5c7588179fb373da70ce04362be5ce74a98eb4Brian Carlstrom + "cannot be used for WRAP_MODE"); 1116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // FIXME InvalidKeyException 1122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // if keysize exceeds the maximum allowable keysize 1123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // (jurisdiction policy files) 112485dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root final Key key = certificate.getPublicKey(); 1125484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root try { 1126484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root getSpi(new InitParams(InitType.KEY, opmode, key, random, null, null)); 1127484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root } catch (InvalidAlgorithmParameterException e) { 1128484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root // Should never happen since we only specified the key. 1129484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root throw new ProviderException("Invalid parameters when params == null", e); 1130484509de8262bb0a56b303016e93f4be1cf0d795Kenny Root } 1131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project mode = opmode; 1132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Continues a multi-part transformation (encryption or decryption). The 1136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * transformed bytes are returned. 1137ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 1138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param input 1139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input bytes to transform. 1140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the transformed bytes in a new buffer, or {@code null} if the 1141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * input has zero length. 1142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalStateException 1143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this cipher instance is not initialized for encryption or 1144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * decryption. 1145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 1146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the input is {@code null}. 1147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final byte[] update(byte[] input) { 1149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { 115080a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalStateException(); 1151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (input == null) { 115380a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalArgumentException("input == null"); 1154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (input.length == 0) { 1156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 1157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 115885dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return getSpi().engineUpdate(input, 0, input.length); 1159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Continues a multi-part transformation (encryption or decryption). The 1163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * transformed bytes are returned. 1164ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 1165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param input 1166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input bytes to transform. 1167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param inputOffset 1168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the offset in the input to start. 1169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param inputLen 1170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the length of the input to transform. 1171b8211a7b902b559da234264f5fa1fcf09677f54bAlex Klyubin * @return the transformed bytes in a new buffer, or {@code null} if {@code inputLen} is zero. 1172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalStateException 1173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this cipher instance is not initialized for encryption or 1174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * decryption. 1175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 1176d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * if {@code input} is {@code null}, or if {@code inputOffset} and 1177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code inputLen} do not specify a valid chunk in the input 1178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * buffer. 1179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final byte[] update(byte[] input, int inputOffset, int inputLen) { 1181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { 118280a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalStateException(); 1183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (input == null) { 118580a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalArgumentException("input == null"); 1186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1187c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom checkInputOffsetAndCount(input.length, inputOffset, inputLen); 1188b8211a7b902b559da234264f5fa1fcf09677f54bAlex Klyubin if (inputLen == 0) { 1189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 1190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 119185dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return getSpi().engineUpdate(input, inputOffset, inputLen); 1192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1194c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom private static void checkInputOffsetAndCount(int inputArrayLength, 1195c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom int inputOffset, 1196c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom int inputLen) { 1197c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom if ((inputOffset | inputLen) < 0 1198c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom || inputOffset > inputArrayLength 1199c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom || inputArrayLength - inputOffset < inputLen) { 1200c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom throw new IllegalArgumentException("input.length=" + inputArrayLength 1201c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom + "; inputOffset=" + inputOffset 1202c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom + "; inputLen=" + inputLen); 1203c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom } 1204c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom } 1205c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom 1206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Continues a multi-part transformation (encryption or decryption). The 1208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * transformed bytes are stored in the {@code output} buffer. 1209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 1210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If the size of the {@code output} buffer is too small to hold the result, 1211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a {@code ShortBufferException} is thrown. Use 1212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link Cipher#getOutputSize getOutputSize} to check for the size of the 1213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * output buffer. 1214ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 1215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param input 1216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input bytes to transform. 1217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param inputOffset 1218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the offset in the input to start. 1219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param inputLen 1220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the length of the input to transform. 1221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param output 1222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the output buffer. 1223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the number of bytes placed in output. 1224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ShortBufferException 1225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the size of the {@code output} buffer is too small. 1226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalStateException 1227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this cipher instance is not initialized for encryption or 1228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * decryption. 1229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 1230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the input is {@code null}, the output is {@code null}, or 1231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code inputOffset} and {@code inputLen} do not specify a 1232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * valid chunk in the input buffer. 1233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final int update(byte[] input, int inputOffset, int inputLen, 1235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project byte[] output) throws ShortBufferException { 1236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return update(input, inputOffset, inputLen, output, 0); 1237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Continues a multi-part transformation (encryption or decryption). The 1241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * transformed bytes are stored in the {@code output} buffer. 1242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 1243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If the size of the {@code output} buffer is too small to hold the result, 1244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a {@code ShortBufferException} is thrown. Use 1245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link Cipher#getOutputSize getOutputSize} to check for the size of the 1246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * output buffer. 1247ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 1248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param input 1249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input bytes to transform. 1250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param inputOffset 1251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the offset in the input to start. 1252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param inputLen 1253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the length of the input to transform. 1254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param output 1255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the output buffer. 1256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param outputOffset 1257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the offset in the output buffer. 1258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the number of bytes placed in output. 1259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ShortBufferException 1260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the size of the {@code output} buffer is too small. 1261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalStateException 1262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this cipher instance is not initialized for encryption or 1263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * decryption. 1264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 1265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the input is {@code null}, the output is {@code null}, or 1266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code inputOffset} and {@code inputLen} do not specify a 1267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * valid chunk in the input buffer. 1268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final int update(byte[] input, int inputOffset, int inputLen, 1270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project byte[] output, int outputOffset) throws ShortBufferException { 1271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { 127280a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalStateException(); 1273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (input == null) { 127580a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalArgumentException("input == null"); 1276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (output == null) { 127880a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalArgumentException("output == null"); 1279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (outputOffset < 0) { 1281c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom throw new IllegalArgumentException("outputOffset < 0. outputOffset=" + outputOffset); 1282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1283c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom checkInputOffsetAndCount(input.length, inputOffset, inputLen); 1284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (input.length == 0) { 1285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 0; 1286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 128785dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return getSpi().engineUpdate(input, inputOffset, inputLen, output, 1288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project outputOffset); 1289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Continues a multi-part transformation (encryption or decryption). The 1293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code input.remaining()} bytes starting at {@code input.position()} are 1294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * transformed and stored in the {@code output} buffer. 1295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 1296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If the {@code output.remaining()} is too small to hold the transformed 1297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * bytes a {@code ShortBufferException} is thrown. Use 1298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link Cipher#getOutputSize getOutputSize} to check for the size of the 1299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * output buffer. 1300ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 1301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param input 1302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input buffer to transform. 1303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param output 1304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the output buffer to store the result within. 1305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the number of bytes stored in the output buffer. 1306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ShortBufferException 1307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the size of the {@code output} buffer is too small. 1308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalStateException 1309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this cipher instance is not initialized for encryption or 1310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * decryption. 1311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 1312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the input buffer and the output buffer are the identical 1313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * object. 1314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final int update(ByteBuffer input, ByteBuffer output) 1316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws ShortBufferException { 1317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { 131880a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalStateException(); 1319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (input == output) { 132180a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalArgumentException("input == output"); 1322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 132385dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return getSpi().engineUpdate(input, output); 1324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1327d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * Continues a multi-part transformation (encryption or decryption) with 1328d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * Authenticated Additional Data (AAD). AAD may only be added after the 1329d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * {@code Cipher} is initialized and before any data is passed to the 1330d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * instance. 1331d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * <p> 1332d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * This is only usable with cipher modes that support Authenticated 1333d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * Encryption with Additional Data (AEAD) such as Galois/Counter Mode (GCM). 1334d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * 1335d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * @param input bytes of AAD to use with the cipher 1336d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * @throws IllegalStateException 1337d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * if this cipher instance is not initialized for encryption or 1338d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * decryption. 1339d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * @throws IllegalArgumentException 1340d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * if {@code input} is {@code null} 1341d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * @throws UnsupportedOperationException if the cipher does not support AEAD 1342d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * @since 1.7 1343d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root */ 1344d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root public final void updateAAD(byte[] input) { 1345d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root if (input == null) { 1346d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root throw new IllegalArgumentException("input == null"); 1347d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root } 1348d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { 1349d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root throw new IllegalStateException(); 1350d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root } 1351d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root if (input.length == 0) { 1352d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root return; 1353d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root } 135485dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root getSpi().engineUpdateAAD(input, 0, input.length); 1355d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root } 1356d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root 1357d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root /** 1358d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * Continues a multi-part transformation (encryption or decryption) with 1359d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * Authenticated Additional Data (AAD). AAD may only be added after the 1360d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * {@code Cipher} is initialized and before any data is passed to the 1361d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * instance. 1362d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * <p> 1363d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * This is only usable with cipher modes that support Authenticated 1364d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * Encryption with Additional Data (AEAD) such as Galois/Counter Mode (GCM). 1365d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * 1366d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * @param input bytes of AAD to use with the cipher 1367d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * @param inputOffset offset within bytes of additional data to add to cipher 1368d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * @param inputLen length of bytes of additional data to add to cipher 1369d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * @throws IllegalStateException 1370d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * if this cipher instance is not initialized for encryption or 1371d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * decryption. 1372d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * @throws IllegalArgumentException 1373d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * if {@code input} is {@code null}, or if {@code inputOffset} and 1374d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * {@code inputLen} do not specify a valid chunk in the input 1375d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * buffer. 1376d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * @throws UnsupportedOperationException if the cipher does not support AEAD 1377d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * @since 1.7 1378d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root */ 1379d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root public final void updateAAD(byte[] input, int inputOffset, int inputLen) { 1380d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { 1381d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root throw new IllegalStateException(); 1382d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root } 138357323260f130e086301b1b7c0d3124a6c51f9fa8Kenny Root if (input == null) { 138457323260f130e086301b1b7c0d3124a6c51f9fa8Kenny Root throw new IllegalArgumentException("input == null"); 138557323260f130e086301b1b7c0d3124a6c51f9fa8Kenny Root } 1386d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root checkInputOffsetAndCount(input.length, inputOffset, inputLen); 1387d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root if (input.length == 0) { 1388d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root return; 1389d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root } 139085dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root getSpi().engineUpdateAAD(input, inputOffset, inputLen); 1391d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root } 1392d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root 1393d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root /** 1394d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * Continues a multi-part transformation (encryption or decryption) with 1395d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * Authenticated Additional Data (AAD). AAD may only be added after the 1396d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * {@code Cipher} is initialized and before any data is passed to the 1397d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * instance. 1398d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * <p> 1399d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * This is only usable with cipher modes that support Authenticated 1400d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * Encryption with Additional Data (AEAD) such as Galois/Counter Mode (GCM). 1401d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * 1402d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * @param input buffer of AAD to be used 1403d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * @throws IllegalStateException 1404d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * if this cipher instance is not initialized for encryption or 1405d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * decryption. 1406d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * @throws UnsupportedOperationException if the cipher does not support AEAD 1407d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root * @since 1.7 1408d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root */ 1409d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root public final void updateAAD(ByteBuffer input) { 1410d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { 1411d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root throw new IllegalStateException("Cipher is not initialized"); 1412d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root } 1413d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root if (input == null) { 1414d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root throw new IllegalArgumentException("input == null"); 1415d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root } 141685dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root getSpi().engineUpdateAAD(input); 1417d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root } 1418d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root 1419d416195acbc08f2b3bdd5d5532d40438465d99e9Kenny Root /** 1420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Finishes a multi-part transformation (encryption or decryption). 1421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 1422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Processes any bytes that may have been buffered in previous {@code 1423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * update} calls. 1424ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 1425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the final bytes from the transformation. 1426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalBlockSizeException 1427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the size of the resulting bytes is not a multiple of the 1428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher block size. 1429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BadPaddingException 1430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the padding of the data does not match the padding scheme. 1431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalStateException 1432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this cipher instance is not initialized for encryption or 1433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * decryption. 1434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final byte[] doFinal() throws IllegalBlockSizeException, 1436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project BadPaddingException { 1437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { 143880a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalStateException(); 1439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 144085dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return getSpi().engineDoFinal(null, 0, 0); 1441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Finishes a multi-part transformation (encryption or decryption). 1445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 1446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Processes any bytes that may have been buffered in previous {@code 1447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * update} calls. 1448ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * <p> 1449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The final transformed bytes are stored in the {@code output} buffer. 1450ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 1451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param output 1452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the output buffer. 1453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param outputOffset 1454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the offset in the output buffer. 1455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the number of bytes placed in the output buffer. 1456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalBlockSizeException 1457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the size of the resulting bytes is not a multiple of the 1458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher block size. 1459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ShortBufferException 1460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the size of the {@code output} buffer is too small. 1461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BadPaddingException 1462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the padding of the data does not match the padding scheme. 1463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalStateException 1464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this cipher instance is not initialized for encryption or 1465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * decryption. 1466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final int doFinal(byte[] output, int outputOffset) 1468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IllegalBlockSizeException, ShortBufferException, 1469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project BadPaddingException { 1470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { 147180a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalStateException(); 1472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (outputOffset < 0) { 1474c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom throw new IllegalArgumentException("outputOffset < 0. outputOffset=" + outputOffset); 1475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 147685dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return getSpi().engineDoFinal(null, 0, 0, output, outputOffset); 1477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Finishes a multi-part transformation (encryption or decryption). 1481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 1482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Processes the bytes in {@code input} buffer, and any bytes that have been 1483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * buffered in previous {@code update} calls. 1484ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 1485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param input 1486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input buffer. 1487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the final bytes from the transformation. 1488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalBlockSizeException 1489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the size of the resulting bytes is not a multiple of the 1490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher block size. 1491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BadPaddingException 1492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the padding of the data does not match the padding scheme. 1493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalStateException 1494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this cipher instance is not initialized for encryption or 1495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * decryption. 1496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final byte[] doFinal(byte[] input) throws IllegalBlockSizeException, 1498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project BadPaddingException { 1499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { 150080a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalStateException(); 1501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 150285dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return getSpi().engineDoFinal(input, 0, input.length); 1503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Finishes a multi-part transformation (encryption or decryption). 1507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 1508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Processes the {@code inputLen} bytes in {@code input} buffer at {@code 1509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * inputOffset}, and any bytes that have been buffered in previous {@code 1510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * update} calls. 1511ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 1512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param input 1513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input buffer. 1514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param inputOffset 1515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the offset in the input buffer. 1516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param inputLen 1517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the length of the input 1518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the final bytes from the transformation. 1519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalBlockSizeException 1520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the size of the resulting bytes is not a multiple of the 1521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher block size. 1522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BadPaddingException 1523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the padding of the data does not match the padding scheme. 1524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalStateException 1525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this cipher instance is not initialized for encryption or 1526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * decryption. 1527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 1528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code inputOffset} and {@code inputLen} do not specify an 1529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * valid chunk in the input buffer. 1530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final byte[] doFinal(byte[] input, int inputOffset, int inputLen) 1532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IllegalBlockSizeException, BadPaddingException { 1533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { 153480a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalStateException(); 1535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1536c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom checkInputOffsetAndCount(input.length, inputOffset, inputLen); 153785dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return getSpi().engineDoFinal(input, inputOffset, inputLen); 1538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Finishes a multi-part transformation (encryption or decryption). 1542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 1543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Processes the {@code inputLen} bytes in {@code input} buffer at {@code 1544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * inputOffset}, and any bytes that have been buffered in previous {@code 1545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * update} calls. 1546ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 1547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param input 1548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input buffer. 1549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param inputOffset 1550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the offset in the input buffer. 1551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param inputLen 1552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the length of the input. 1553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param output 1554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the output buffer for the transformed bytes. 1555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the number of bytes placed in the output buffer. 1556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ShortBufferException 1557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the size of the {@code output} buffer is too small. 1558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalBlockSizeException 1559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the size of the resulting bytes is not a multiple of the 1560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher block size. 1561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BadPaddingException 1562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the padding of the data does not match the padding scheme. 1563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalStateException 1564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this cipher instance is not initialized for encryption or 1565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * decryption. 1566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 1567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code inputOffset} and {@code inputLen} do not specify an 1568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * valid chunk in the input buffer. 1569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final int doFinal(byte[] input, int inputOffset, int inputLen, 1571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project byte[] output) throws ShortBufferException, 1572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project IllegalBlockSizeException, BadPaddingException { 1573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return doFinal(input, inputOffset, inputLen, output, 0); 1574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Finishes a multi-part transformation (encryption or decryption). 1578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 1579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Processes the {@code inputLen} bytes in {@code input} buffer at {@code 1580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * inputOffset}, and any bytes that have been buffered in previous {@code 1581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * update} calls. 1582ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 1583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param input 1584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input buffer. 1585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param inputOffset 1586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the offset in the input buffer. 1587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param inputLen 1588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the length of the input. 1589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param output 1590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the output buffer for the transformed bytes. 1591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param outputOffset 1592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the offset in the output buffer. 1593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the number of bytes placed in the output buffer. 1594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ShortBufferException 1595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the size of the {@code output} buffer is too small. 1596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalBlockSizeException 1597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the size of the resulting bytes is not a multiple of the 1598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher block size. 1599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BadPaddingException 1600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the padding of the data does not match the padding scheme. 1601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalStateException 1602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this cipher instance is not initialized for encryption or 1603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * decryption. 1604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 1605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code inputOffset} and {@code inputLen} do not specify an 1606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * valid chunk in the input buffer. 1607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final int doFinal(byte[] input, int inputOffset, int inputLen, 1609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project byte[] output, int outputOffset) throws ShortBufferException, 1610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project IllegalBlockSizeException, BadPaddingException { 1611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { 161280a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalStateException(); 1613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1614c1e57ed799a4fea200144330823f4acbb5330395Brian Carlstrom checkInputOffsetAndCount(input.length, inputOffset, inputLen); 161585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return getSpi().engineDoFinal(input, inputOffset, inputLen, output, 1616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project outputOffset); 1617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Finishes a multi-part transformation (encryption or decryption). 1621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 1622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Processes the {@code input.remaining()} bytes in {@code input} buffer at 1623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code input.position()}, and any bytes that have been buffered in 1624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * previous {@code update} calls. The transformed bytes are placed into 1625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code output} buffer. 1626ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 1627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param input 1628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input buffer. 1629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param output 1630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the output buffer. 1631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the number of bytes placed into the output buffer. 1632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws ShortBufferException 1633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the size of the {@code output} buffer is too small. 1634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalBlockSizeException 1635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the size of the resulting bytes is not a multiple of the 1636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher block size. 1637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BadPaddingException 1638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the padding of the data does not match the padding scheme. 1639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 1640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the input buffer and the output buffer are the same 1641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * object. 1642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalStateException 1643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this cipher instance is not initialized for encryption or 1644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * decryption. 1645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final int doFinal(ByteBuffer input, ByteBuffer output) 1647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws ShortBufferException, IllegalBlockSizeException, 1648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project BadPaddingException { 1649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) { 165080a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalStateException(); 1651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (input == output) { 165380a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalArgumentException("input == output"); 1654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 165585dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return getSpi().engineDoFinal(input, output); 1656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Wraps a key using this cipher instance. 1660ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 1661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key 1662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the key to wrap. 1663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the wrapped key. 1664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalBlockSizeException 1665adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the size of the resulting bytes is not a multiple of the 1666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cipher block size. 1667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidKeyException 1668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this cipher instance can not wrap this key. 1669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalStateException 1670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this cipher instance is not initialized for wrapping. 1671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final byte[] wrap(Key key) throws IllegalBlockSizeException, 1673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project InvalidKeyException { 1674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (mode != WRAP_MODE) { 167580a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalStateException(); 1676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 167785dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return getSpi().engineWrap(key); 1678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unwraps a key using this cipher instance. 1682ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 1683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param wrappedKey 1684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the wrapped key to unwrap. 1685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param wrappedKeyAlgorithm 1686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the algorithm for the wrapped key. 1687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param wrappedKeyType 1688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the type of the wrapped key (one of: {@code SECRET_KEY 1689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <code>, <code>PRIVATE_KEY} or {@code PUBLIC_KEY}) 1690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the unwrapped key 1691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws InvalidKeyException 1692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the {@code wrappedKey} can not be unwrapped to a key of 1693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * type {@code wrappedKeyType} for the {@code 1694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * wrappedKeyAlgorithm}. 1695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NoSuchAlgorithmException 1696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if no provider can be found that can create a key of type 1697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code wrappedKeyType} for the {@code wrappedKeyAlgorithm}. 1698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalStateException 1699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this cipher instance is not initialized for unwrapping. 1700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final Key unwrap(byte[] wrappedKey, String wrappedKeyAlgorithm, 1702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int wrappedKeyType) throws InvalidKeyException, 1703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project NoSuchAlgorithmException { 1704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (mode != UNWRAP_MODE) { 170580a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes throw new IllegalStateException(); 1706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 170785dab151e734557d356fb45c45cf7d4548dd6fdcKenny Root return getSpi().engineUnwrap(wrappedKey, wrappedKeyAlgorithm, 1708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project wrappedKeyType); 1709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the maximum key length for the specified transformation. 1713ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 1714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param transformation 1715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the transformation name. 1716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the maximum key length, currently {@code Integer.MAX_VALUE}. 1717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NoSuchAlgorithmException 1718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if no provider for the specified {@code transformation} can 1719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * be found. 1720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException 1721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code transformation} is {@code null}. 1722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final int getMaxAllowedKeyLength(String transformation) 1724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws NoSuchAlgorithmException { 1725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (transformation == null) { 172686acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("transformation == null"); 1727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkTransformation(transformation); 1729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //FIXME jurisdiction policy files 1730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return Integer.MAX_VALUE; 1731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the maximum cipher parameter value for the specified 1735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * transformation. If there is no maximum limit, {@code null} is returned. 1736ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson * 1737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param transformation 1738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the transformation name. 1739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a parameter spec holding the maximum value or {@code null}. 1740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Currently {@code null}. 1741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NoSuchAlgorithmException 1742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if no provider for the specified {@code transformation} can 1743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * be found. 1744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException 1745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code transformation} is {@code null}. 1746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final AlgorithmParameterSpec getMaxAllowedParameterSpec( 1748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String transformation) throws NoSuchAlgorithmException { 1749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (transformation == null) { 175086acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("transformation == null"); 1751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkTransformation(transformation); 1753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //FIXME jurisdiction policy files 1754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 1755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 1757