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