1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  this work for additional information regarding copyright ownership.
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  (the "License"); you may not use this file except in compliance with
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  the License.  You may obtain a copy of the License at
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  See the License for the specific language governing permissions and
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  limitations under the License.
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage javax.crypto;
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.nio.ByteBuffer;
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.security.AlgorithmParameters;
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.security.InvalidAlgorithmParameterException;
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.security.InvalidKeyException;
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.security.InvalidParameterException;
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.security.Key;
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.security.NoSuchAlgorithmException;
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.security.NoSuchProviderException;
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.security.Provider;
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.security.SecureRandom;
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.security.Security;
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.security.cert.Certificate;
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.security.cert.X509Certificate;
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.security.spec.AlgorithmParameterSpec;
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Set;
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.StringTokenizer;
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.apache.harmony.crypto.internal.NullCipherSpi;
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.apache.harmony.crypto.internal.nls.Messages;
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.apache.harmony.security.fortress.Engine;
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This class provides access to implementations of cryptographic ciphers for
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * encryption and decryption. Cipher classes can not be instantiated directly,
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * one has to call the Cipher's {@code getInstance} method with the name of a
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * requested transformation, optionally with a provider. A transformation
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * specifies an operation (or a set of operations) as a string in the form:
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <ul>
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <li><i>"algorithm/mode/padding"</i></li> or
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <li><i>"algorithm"</i></li>
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * </ul>
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <i>algorithm</i> is the name of a cryptographic algorithm, <i>mode</i> is the
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * name of a feedback mode and <i>padding</i> is the name of a padding scheme.
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If <i>mode</i> and/or <i>padding</i> values are omitted, provider specific
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * default values will be used.
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p>
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * A valid transformation would be:
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <ul>
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@code Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");}
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * </ul>
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * When a block cipher is requested in in stream cipher mode, the number of bits
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to be processed at a time can be optionally specified by appending it to the
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * mode name. e.g. <i>"AES/CFB8/NoPadding"</i>. If no number is specified, a
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * provider specific default value is used.
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class Cipher {
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constant for decryption operation mode.
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static final int DECRYPT_MODE = 2;
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constant for encryption operation mode.
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static final int ENCRYPT_MODE = 1;
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constant indicating that the key to be unwrapped is a private key.
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static final int PRIVATE_KEY = 2;
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constant indicating that the key to be unwrapped is a public key.
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static final int PUBLIC_KEY = 1;
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constant indicating that the key to be unwrapped is a secret key.
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static final int SECRET_KEY = 3;
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constant for key unwrapping operation mode.
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static final int UNWRAP_MODE = 4;
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constant for key wrapping operation mode.
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static final int WRAP_MODE = 3;
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int mode;
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The service name.
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final String SERVICE = "Cipher"; //$NON-NLS-1$
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Used to access common engine functionality.
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final Engine engine = new Engine(SERVICE);
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The provider.
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private Provider provider;
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The SPI implementation.
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private CipherSpi spiImpl;
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The transformation.
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private String transformation;
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static SecureRandom sec_rand;
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Creates a new Cipher instance.
1338207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     *
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param cipherSpi
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the implementation delegate of the cipher.
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param provider
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the provider of the implementation of this cipher.
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param transformation
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the name of the transformation that this cipher performs.
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws NullPointerException
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if either cipherSpi is {@code null} or provider is {@code
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             null} and {@code cipherSpi} is a {@code NullCipherSpi}.
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected Cipher(CipherSpi cipherSpi, Provider provider,
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            String transformation) {
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (cipherSpi == null) {
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException();
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!(cipherSpi instanceof NullCipherSpi) && provider == null) {
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException();
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.provider = provider;
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.transformation = transformation;
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.spiImpl = cipherSpi;
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Creates a new Cipher for the specified transformation. The installed
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * providers are searched in order for an implementation of the specified
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * transformation. The first found provider providing the transformation is
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * used to create the cipher. If no provider is found an exception is
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * thrown.
1638207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     *
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param transformation
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the name of the transformation to create a cipher for.
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return a cipher for the requested transformation.
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws NoSuchAlgorithmException
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if no installed provider can provide the
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             <i>transformation</i>, or it is {@code null}, empty or in an
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             invalid format.
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws NoSuchPaddingException
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if no installed provider can provide the padding scheme in
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             the <i>transformation</i>.
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static final Cipher getInstance(String transformation)
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throws NoSuchAlgorithmException, NoSuchPaddingException {
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return getCipher(transformation, null);
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Creates a new cipher for the specified transformation provided by the
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * specified provider.
1838207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     *
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param transformation
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the name of the transformation to create a cipher for.
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param provider
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the name of the provider to ask for the transformation.
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return a cipher for the requested transformation.
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws NoSuchAlgorithmException
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the specified provider can not provide the
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             <i>transformation</i>, or it is {@code null}, empty or in an
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             invalid format.
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws NoSuchProviderException
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if no provider with the specified name can be found.
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws NoSuchPaddingException
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the requested padding scheme in the <i>transformation</i>
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             is not available.
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalArgumentException
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the specified provider is {@code null}.
200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static final Cipher getInstance(String transformation,
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            String provider) throws NoSuchAlgorithmException,
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            NoSuchProviderException, NoSuchPaddingException {
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (provider == null) {
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException(Messages.getString("crypto.04")); //$NON-NLS-1$
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Provider p = Security.getProvider(provider);
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (p == null) {
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NoSuchProviderException(Messages.getString("crypto.16", provider)); //$NON-NLS-1$
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return getInstance(transformation, p);
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Creates a new cipher for the specified transformation.
2188207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     *
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param transformation
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the name of the transformation to create a cipher for.
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param provider
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the provider to ask for the transformation.
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return a cipher for the requested transformation.
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws NoSuchAlgorithmException
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the specified provider can not provide the
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             <i>transformation</i>, or it is {@code null}, empty or in an
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             invalid format.
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws NoSuchPaddingException
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the requested padding scheme in the <i>transformation</i>
230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             is not available.
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalArgumentException
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the provider is {@code null}.
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static final Cipher getInstance(String transformation,
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Provider provider) throws NoSuchAlgorithmException,
236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            NoSuchPaddingException {
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (provider == null) {
238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException(Messages.getString("crypto.04")); //$NON-NLS-1$
239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Cipher c = getCipher(transformation, provider);
241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return c;
242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Find appropriate Cipher according the specification rules
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param transformation
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param provider
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws NoSuchAlgorithmException
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws NoSuchPaddingException
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static synchronized Cipher getCipher(String transformation, Provider provider)
254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throws NoSuchAlgorithmException, NoSuchPaddingException {
255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (transformation == null || "".equals(transformation)) { //$NON-NLS-1$
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NoSuchAlgorithmException(Messages.getString("crypto.17", //$NON-NLS-1$
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    transformation));
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String[] transf = checkTransformation(transformation);
262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        boolean needSetPadding = false;
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        boolean needSetMode = false;
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (transf[1] == null && transf[2] == null) { // "algorithm"
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (provider == null) {
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                engine.getInstance(transf[0], null);
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else {
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                engine.getInstance(transf[0], provider, null);
270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            String[] searhOrder = {
273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    transf[0] + "/" + transf[1] + "/" + transf[2], // "algorithm/mode/padding" //$NON-NLS-1$ //$NON-NLS-2$
274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    transf[0] + "/" + transf[1], // "algorithm/mode" //$NON-NLS-1$
275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    transf[0] + "//" + transf[2], // "algorithm//padding" //$NON-NLS-1$
276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    transf[0] // "algorithm"
277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            };
278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int i;
279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (i = 0; i < searhOrder.length; i++) {
280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                try {
281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    if (provider == null) {
282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        engine.getInstance(searhOrder[i], null);
283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    } else {
284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        engine.getInstance(searhOrder[i], provider, null);
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                } catch (NoSuchAlgorithmException e) {
288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    if ( i == searhOrder.length-1) {
289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        throw new NoSuchAlgorithmException(transformation);
290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            switch (i) {
294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 1: // "algorithm/mode"
295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                needSetPadding = true;
296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                break;
297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 2: // "algorithm//padding"
298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                needSetMode = true;
299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                break;
300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 3: // "algorithm"
301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                needSetPadding = true;
302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                needSetMode = true;
303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CipherSpi cspi;
306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        try {
307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            cspi = (CipherSpi) engine.spi;
308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (ClassCastException e) {
309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NoSuchAlgorithmException(e);
310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Cipher c = new Cipher(cspi, engine.provider, transformation);
312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (needSetMode) {
313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            c.spiImpl.engineSetMode(transf[1]);
314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (needSetPadding) {
316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            c.spiImpl.engineSetPadding(transf[2]);
317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return c;
319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static String[] checkTransformation(String transformation)
322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throws NoSuchAlgorithmException {
323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String[] transf = { null, null, null };
324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        StringTokenizer st;
325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int i = 0;
326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (st = new StringTokenizer(transformation, "/"); st //$NON-NLS-1$
327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                .hasMoreElements();) {
328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (i > 2) {
329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                throw new NoSuchAlgorithmException(Messages.getString("crypto.17", //$NON-NLS-1$
330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        transformation));
331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            transf[i] = st.nextToken();
333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (transf[i] != null) {
334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                transf[i] = transf[i].trim();
335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if ("".equals(transf[i])) { //$NON-NLS-1$
336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    transf[i] = null;
337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                i++;
339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (transf[0] == null) {
342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NoSuchAlgorithmException(Messages.getString("crypto.17", //$NON-NLS-1$
343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    transformation));
344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!(transf[1] == null && transf[2] == null)
346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                && (transf[1] == null || transf[2] == null)) {
347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NoSuchAlgorithmException(Messages.getString("crypto.17", //$NON-NLS-1$
348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    transformation));
349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return transf;
351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the provider of this cipher instance.
3558207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     *
356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the provider of this cipher instance.
357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final Provider getProvider() {
359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return provider;
360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the name of the algorithm of this cipher instance.
364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * This is the name of the <i>transformation</i> argument used in the
366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@code getInstance} call creating this object.
3678207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     *
368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the name of the algorithm of this cipher instance.
369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final String getAlgorithm() {
371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return transformation;
372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns this ciphers block size (in bytes).
3768207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     *
377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return this ciphers block size.
378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final int getBlockSize() {
380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return spiImpl.engineGetBlockSize();
381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the length in bytes an output buffer needs to be when this cipher
385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * is updated with {@code inputLen} bytes.
3868207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     *
387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param inputLen
388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the number of bytes of the input.
389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the output buffer length for the input length.
390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalStateException
391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if this cipher instance is in an invalid state.
392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final int getOutputSize(int inputLen) {
394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (mode == 0) {
395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalStateException(
396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    Messages.getString("crypto.18")); //$NON-NLS-1$
397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return spiImpl.engineGetOutputSize(inputLen);
399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the <i>initialization vector</i> for this cipher instance.
4038207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     *
404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the <i>initialization vector</i> for this cipher instance.
405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final byte[] getIV() {
407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return spiImpl.engineGetIV();
408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the parameters that where used to create this cipher instance.
412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * These may be a the same parameters that were used to create this cipher
414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * instance, or may be a combination of default and random parameters,
415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * depending on the underlying cipher implementation.
4168207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     *
417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the parameters that where used to create this cipher instance, or
418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         {@code null} if this cipher instance does not have any
419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         parameters.
420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final AlgorithmParameters getParameters() {
422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return spiImpl.engineGetParameters();
423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the exemption mechanism associated with this cipher.
4278207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     *
428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return currently {@code null}
429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final ExemptionMechanism getExemptionMechanism() {
431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //FIXME implement getExemptionMechanism
432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //        try {
434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //            return ExemptionMechanism.getInstance(transformation, provider);
435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //        } catch (NoSuchAlgorithmException e) {
436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return null;
437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //        }
438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Initializes this cipher instance with the specified key.
443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The cipher is initialized for the specified operational mode (one of:
445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * encryption, decryption, key wrapping or key unwrapping) depending on
446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@code opmode}.
4478207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     * <p>
448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * If this cipher instance needs any algorithm parameters or random values
449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * that the specified key can not provide, the underlying implementation of
450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * this cipher is supposed to generate the required parameters (using its
451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * provider or random values).
452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * When a cipher instance is initialized by a call to any of the {@code
454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * init} methods, the state of the instance is overridden, meaning that it
455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * is equivalent to creating a new instance and calling its {@code init}
456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * method.
4578207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     *
458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param opmode
459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the operation this cipher instance should be initialized for
460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code
461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            WRAP_MODE} or {@code UNWRAP_MODE}).
462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param key
463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the input key for the operation.
464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws InvalidKeyException
465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the specified key can not be used to initialize this
466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             cipher instance.
467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final void init(int opmode, Key key) throws InvalidKeyException {
469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (sec_rand == null) {
470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // In theory it might be thread-unsafe but in the given case it's OK
471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // since it does not matter which SecureRandom instance is passed
472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // to the init()
473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sec_rand = new SecureRandom();
474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        init(opmode, key, sec_rand);
476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Initializes this cipher instance with the specified key and a source of
480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * randomness.
481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The cipher is initialized for the specified operational mode (one of:
483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * encryption, decryption, key wrapping or key unwrapping) depending on
484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@code opmode}.
4858207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     * <p>
486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * If this cipher instance needs any algorithm parameters or random values
487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * that the specified key can not provide, the underlying implementation of
488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * this cipher is supposed to generate the required parameters (using its
489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * provider or random values). Random values are generated using {@code
490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * random};
491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * When a cipher instance is initialized by a call to any of the {@code
493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * init} methods, the state of the instance is overridden, means it is
494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * equivalent to creating a new instance and calling it {@code init} method.
4958207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     *
496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param opmode
497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the operation this cipher instance should be initialized for
498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code
499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            WRAP_MODE} or {@code UNWRAP_MODE}).
500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param key
501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the input key for the operation.
502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param random
503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the source of randomness to use.
504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws InvalidKeyException
505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the specified key can not be used to initialize this
506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             cipher instance.
507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws InvalidParameterException
508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the specified opmode is invalid.
509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final void init(int opmode, Key key, SecureRandom random)
511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throws InvalidKeyException {
512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (opmode != ENCRYPT_MODE && opmode != DECRYPT_MODE
513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                && opmode != UNWRAP_MODE && opmode != WRAP_MODE) {
514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new InvalidParameterException(Messages.getString("crypto.19")); //$NON-NLS-1$
515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //        FIXME InvalidKeyException
517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //        if keysize exceeds the maximum allowable keysize
518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //        (jurisdiction policy files)
519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        spiImpl.engineInit(opmode, key, random);
520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        mode = opmode;
521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Initializes this cipher instance with the specified key and algorithm
525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * parameters.
526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The cipher is initialized for the specified operational mode (one of:
528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * encryption, decryption, key wrapping or key unwrapping).
5298207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     * <p>
530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * If this cipher instance needs any algorithm parameters and {@code params}
531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * is {@code null}, the underlying implementation of this cipher is supposed
532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * to generate the required parameters (using its provider or random
533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * values).
534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * When a cipher instance is initialized by a call to any of the {@code
536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * init} methods, the state of the instance is overridden, means it is
537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * equivalent to creating a new instance and calling it {@code init} method.
5388207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     *
539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param opmode
540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the operation this cipher instance should be initialized for
541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code
542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            WRAP_MODE} or {@code UNWRAP_MODE}).
543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param key
544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the input key for the operation.
545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param params
546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the algorithm parameters.
547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws InvalidKeyException
548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the specified key can not be used to initialize this
549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             cipher instance.
550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws InvalidAlgorithmParameterException
551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             it the specified parameters are inappropriate for this
552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             cipher.
553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final void init(int opmode, Key key, AlgorithmParameterSpec params)
555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throws InvalidKeyException, InvalidAlgorithmParameterException {
556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (sec_rand == null) {
557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sec_rand = new SecureRandom();
558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        init(opmode, key, params, sec_rand);
560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Initializes this cipher instance with the specified key, algorithm
564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * parameters and a source of randomness.
565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The cipher is initialized for the specified operational mode (one of:
567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * encryption, decryption, key wrapping or key unwrapping) depending on
568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@code opmode}.
569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * If this cipher instance needs any algorithm parameters and {@code params}
571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * is {@code null}, the underlying implementation of this cipher is supposed
572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * to generate the required parameters (using its provider or random
573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * values). Random values are generated using {@code random};
574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * When a cipher instance is initialized by a call to any of the {@code
576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * init} methods, the state of the instance is overridden, meaning that it
577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * is equivalent to creating a new instance and calling it {@code init}
578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * method.
5798207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     *
580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param opmode
581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the operation this cipher instance should be initialized for
582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code
583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            WRAP_MODE} or {@code UNWRAP_MODE}).
584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param key
585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the input key for the operation.
586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param params
587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the algorithm parameters.
588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param random
589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the source of randomness to use.
590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws InvalidKeyException
591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the specified key can not be used to initialize this
592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             cipher instance.
593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws InvalidAlgorithmParameterException
594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             it the specified parameters are inappropriate for this
595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             cipher.
596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws InvalidParameterException
597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the specified {@code opmode} is invalid.
598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final void init(int opmode, Key key, AlgorithmParameterSpec params,
600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            SecureRandom random) throws InvalidKeyException,
601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            InvalidAlgorithmParameterException {
602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (opmode != ENCRYPT_MODE && opmode != DECRYPT_MODE
603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                && opmode != UNWRAP_MODE && opmode != WRAP_MODE) {
604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new InvalidParameterException(Messages.getString("crypto.19")); //$NON-NLS-1$
605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //        FIXME InvalidKeyException
607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //        if keysize exceeds the maximum allowable keysize
608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //        (jurisdiction policy files)
609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //        FIXME InvalidAlgorithmParameterException
610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //        cryptographic strength exceed the legal limits
611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //        (jurisdiction policy files)
612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        spiImpl.engineInit(opmode, key, params, random);
613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        mode = opmode;
614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Initializes this cipher instance with the specified key and algorithm
618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * parameters.
619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The cipher is initialized for the specified operation (one of:
621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * encryption, decryption, key wrapping or key unwrapping) depending on
622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@code opmode}.
6238207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     * <p>
624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * If this cipher instance needs any algorithm parameters and {@code params}
625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * is {@code null}, the underlying implementation of this cipher is supposed
626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * to generate the required parameters (using its provider or random
627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * values).
628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * When a cipher instance is initialized by a call to any of the {@code
630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * init} methods, the state of the instance is overridden, meaning that it
631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * is equivalent to creating a new instance and calling it {@code init}
632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * method.
6338207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     *
634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param opmode
635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the operation this cipher instance should be initialized for
636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code
637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            WRAP_MODE} or {@code UNWRAP_MODE}).
638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param key
639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the input key for the operation.
640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param params
641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the algorithm parameters.
642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws InvalidKeyException
643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the specified key can not be used to initialize this
644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             cipher instance.
645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws InvalidAlgorithmParameterException
646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             it the specified parameters are inappropriate for this
647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             cipher.
648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final void init(int opmode, Key key, AlgorithmParameters params)
650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throws InvalidKeyException, InvalidAlgorithmParameterException {
651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (sec_rand == null) {
652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sec_rand = new SecureRandom();
653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        init(opmode, key, params, sec_rand);
655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Initializes this cipher instance with the specified key, algorithm
659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * parameters and a source of randomness.
660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The cipher will be initialized for the specified operation (one of:
662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * encryption, decryption, key wrapping or key unwrapping) depending on
663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@code opmode}.
6648207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     * <p>
665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * If this cipher instance needs any algorithm parameters and {@code params}
666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * is {@code null}, the underlying implementation of this cipher is supposed
667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * to generate the required parameters (using its provider or random
668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * values). Random values are generated using {@code random}.
669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * When a cipher instance is initialized by a call to any of the {@code
671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * init} methods, the state of the instance is overridden, means it is
672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * equivalent to creating a new instance and calling it {@code init} method.
6738207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     *
674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param opmode
675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the operation this cipher instance should be initialized for
676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code
677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            WRAP_MODE} or {@code UNWRAP_MODE}).
678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param key
679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the input key for the operation.
680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param params
681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the algorithm parameters.
682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param random
683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the source of randomness to use.
684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws InvalidKeyException
685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the specified key can not be used to initialize this
686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             cipher instance.
687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws InvalidAlgorithmParameterException
688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the specified parameters are inappropriate for this
689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             cipher.
690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws InvalidParameterException
691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the specified {@code opmode} is invalid.
692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final void init(int opmode, Key key, AlgorithmParameters params,
694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            SecureRandom random) throws InvalidKeyException,
695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            InvalidAlgorithmParameterException {
696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (opmode != ENCRYPT_MODE && opmode != DECRYPT_MODE
697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                && opmode != UNWRAP_MODE && opmode != WRAP_MODE) {
698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new InvalidParameterException(Messages.getString("crypto.19")); //$NON-NLS-1$
699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //        FIXME InvalidKeyException
701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //        if keysize exceeds the maximum allowable keysize
702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //        (jurisdiction policy files)
703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //        FIXME InvalidAlgorithmParameterException
704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //        cryptographic strength exceed the legal limits
705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //        (jurisdiction policy files)
706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        spiImpl.engineInit(opmode, key, params, random);
707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        mode = opmode;
708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Initializes this cipher instance with the public key from the specified
712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * certificate.
713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The cipher will be initialized for the specified operation (one of:
715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * encryption, decryption, key wrapping or key unwrapping) depending on
716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@code opmode}.
717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * It the type of the certificate is X.509 and the certificate has a <i>key
719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * usage</i> extension field marked as critical, the specified {@code
720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * opmode} has the be enabled for this key, otherwise an {@code
721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * InvalidKeyException} is thrown.
722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * If this cipher instance needs any algorithm parameters that the key in
724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * the certificate can not provide, the underlying implementation of this
725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * cipher is supposed to generate the required parameters (using its
726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * provider or random values).
727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * When a cipher instance is initialized by a call to any of the {@code
729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * init} methods, the state of the instance is overridden, means it is
730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * equivalent to creating a new instance and calling it {@code init} method.
7318207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     *
732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param opmode
733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the operation this cipher instance should be initialized for
734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code
735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            WRAP_MODE} or {@code UNWRAP_MODE}).
736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param certificate
737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the certificate.
738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws InvalidKeyException
739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the public key in the certificate can not be used to
740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             initialize this cipher instance.
741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final void init(int opmode, Certificate certificate)
743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throws InvalidKeyException {
744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (sec_rand == null) {
745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sec_rand = new SecureRandom();
746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        init(opmode, certificate, sec_rand);
748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Initializes this cipher instance with the public key from the specified
752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * certificate and a source of randomness.
753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The cipher will be initialized for the specified operation (one of:
755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * encryption, decryption, key wrapping or key unwrapping) depending on
756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@code opmode}.
7578207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     * <p>
758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * It the type of the certificate is X.509 and the certificate has a <i>key
759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * usage</i> extension field marked as critical, the specified {@code
760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * opmode} has the be enabled for this key, otherwise an {@code
761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * InvalidKeyException} is thrown.
762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * If this cipher instance needs any algorithm parameters that the key in
764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * the certificate can not provide, the underlying implementation of this
765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * cipher is supposed to generate the required parameters (using its
766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * provider or random values). Random values are generated using {@code
767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * random}.
7688207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     * <p>
769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * When a cipher instance is initialized by a call to any of the {@code
770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * init} methods, the state of the instance is overridden, means it is
771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * equivalent to creating a new instance and calling it {@code init} method.
7728207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     *
773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param opmode
774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the operation this cipher instance should be initialized for
775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code
776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            WRAP_MODE} or {@code UNWRAP_MODE}).
777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param certificate
778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the certificate.
779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param random
780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the source of randomness to be used.
781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws InvalidKeyException
782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the public key in the certificate can not be used to
783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             initialize this cipher instance.
784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final void init(int opmode, Certificate certificate,
786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            SecureRandom random) throws InvalidKeyException {
787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (opmode != ENCRYPT_MODE && opmode != DECRYPT_MODE
788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                && opmode != UNWRAP_MODE && opmode != WRAP_MODE) {
789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new InvalidParameterException(Messages.getString("crypto.19")); //$NON-NLS-1$
790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (certificate instanceof X509Certificate) {
792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Set<String> ce = ((X509Certificate) certificate).getCriticalExtensionOIDs();
793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            boolean critical = false;
794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (ce != null && !ce.isEmpty()) {
795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                for (String oid : ce) {
796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    if (oid.equals("2.5.29.15")) { //KeyUsage OID = 2.5.29.15 //$NON-NLS-1$
797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        critical = true;
798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        break;
799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (critical) {
802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    boolean[] keyUsage = ((X509Certificate) certificate)
803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            .getKeyUsage();
804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    // As specified in RFC 3280 -
805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    // Internet X.509 Public Key Infrastructure
806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    // Certificate and Certificate Revocation List (CRL) Profile.
807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    // (http://www.ietf.org/rfc/rfc3280.txt)
808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    //
809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    // KeyUsage ::= BIT STRING {digitalSignature (0),
810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    //                          ...
811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    //                          encipherOnly (7),
812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    //                          decipherOnly (8) }
813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    if (keyUsage != null) {
814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        if (opmode == ENCRYPT_MODE && (!keyUsage[7])) {
815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            throw new InvalidKeyException(
816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                    Messages.getString("crypto.1A")); //$NON-NLS-1$
817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        } else if (opmode == DECRYPT_MODE && (!keyUsage[8])) {
818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            throw new InvalidKeyException(
819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                    Messages.getString("crypto.1B")); //$NON-NLS-1$
820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        }
821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //        FIXME InvalidKeyException
826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //        if keysize exceeds the maximum allowable keysize
827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //        (jurisdiction policy files)
828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        spiImpl.engineInit(opmode, certificate.getPublicKey(), random);
829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        mode = opmode;
830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Continues a multi-part transformation (encryption or decryption). The
834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * transformed bytes are returned.
8358207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     *
836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param input
837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the input bytes to transform.
838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the transformed bytes in a new buffer, or {@code null} if the
839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         input has zero length.
840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalStateException
841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if this cipher instance is not initialized for encryption or
842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             decryption.
843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalArgumentException
844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the input is {@code null}.
845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final byte[] update(byte[] input) {
847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) {
848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalStateException(
849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    Messages.getString("crypto.1C")); //$NON-NLS-1$
850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (input == null) {
852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException(Messages.getString("crypto.1D")); //$NON-NLS-1$
853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (input.length == 0) {
855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return null;
856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return spiImpl.engineUpdate(input, 0, input.length);
858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Continues a multi-part transformation (encryption or decryption). The
862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * transformed bytes are returned.
8638207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     *
864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param input
865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the input bytes to transform.
866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param inputOffset
867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the offset in the input to start.
868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param inputLen
869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the length of the input to transform.
870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the transformed bytes in a new buffer, or {@code null} if the
871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         input has zero length.
872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalStateException
873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if this cipher instance is not initialized for encryption or
874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             decryption.
875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalArgumentException
876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the input is {@code null}, or if {@code inputOffset} and
877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             {@code inputLen} do not specify a valid chunk in the input
878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             buffer.
879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final byte[] update(byte[] input, int inputOffset, int inputLen) {
881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) {
882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalStateException(
883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    Messages.getString("crypto.1C")); //$NON-NLS-1$
884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (input == null) {
886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException(Messages.getString("crypto.1D")); //$NON-NLS-1$
887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (inputOffset < 0 || inputLen < 0
889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                || inputLen > input.length
890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                || inputOffset > input.length - inputLen) {
891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException(
892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    Messages.getString("crypto.1E")); //$NON-NLS-1$
893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (input.length == 0) {
895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return null;
896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return spiImpl.engineUpdate(input, inputOffset, inputLen);
898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Continues a multi-part transformation (encryption or decryption). The
902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * transformed bytes are stored in the {@code output} buffer.
903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * If the size of the {@code output} buffer is too small to hold the result,
905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * a {@code ShortBufferException} is thrown. Use
906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@link Cipher#getOutputSize getOutputSize} to check for the size of the
907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * output buffer.
9088207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     *
909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param input
910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the input bytes to transform.
911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param inputOffset
912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the offset in the input to start.
913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param inputLen
914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the length of the input to transform.
915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param output
916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the output buffer.
917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the number of bytes placed in output.
918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws ShortBufferException
919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the size of the {@code output} buffer is too small.
920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalStateException
921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if this cipher instance is not initialized for encryption or
922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             decryption.
923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalArgumentException
924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the input is {@code null}, the output is {@code null}, or
925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if {@code inputOffset} and {@code inputLen} do not specify a
926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             valid chunk in the input buffer.
927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final int update(byte[] input, int inputOffset, int inputLen,
929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            byte[] output) throws ShortBufferException {
930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return update(input, inputOffset, inputLen, output, 0);
931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Continues a multi-part transformation (encryption or decryption). The
935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * transformed bytes are stored in the {@code output} buffer.
936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * If the size of the {@code output} buffer is too small to hold the result,
938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * a {@code ShortBufferException} is thrown. Use
939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@link Cipher#getOutputSize getOutputSize} to check for the size of the
940f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * output buffer.
9418207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     *
942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param input
943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the input bytes to transform.
944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param inputOffset
945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the offset in the input to start.
946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param inputLen
947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the length of the input to transform.
948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param output
949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the output buffer.
950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param outputOffset
951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the offset in the output buffer.
952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the number of bytes placed in output.
953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws ShortBufferException
954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the size of the {@code output} buffer is too small.
955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalStateException
956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if this cipher instance is not initialized for encryption or
957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             decryption.
958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalArgumentException
959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the input is {@code null}, the output is {@code null}, or
960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if {@code inputOffset} and {@code inputLen} do not specify a
961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             valid chunk in the input buffer.
962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final int update(byte[] input, int inputOffset, int inputLen,
964f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            byte[] output, int outputOffset) throws ShortBufferException {
965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) {
966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalStateException(
967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    Messages.getString("crypto.1C")); //$NON-NLS-1$
968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (input == null) {
970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException(Messages.getString("crypto.1D")); //$NON-NLS-1$
971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (output == null) {
973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException(Messages.getString("crypto.1F")); //$NON-NLS-1$
974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
975f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (outputOffset < 0) {
976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException(
977f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    Messages.getString("crypto.20")); //$NON-NLS-1$
978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
979f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (inputOffset < 0 || inputLen < 0
980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                || inputLen > input.length
981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                || inputOffset > input.length - inputLen) {
982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException(
983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    Messages.getString("crypto.21")); //$NON-NLS-1$
984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (input.length == 0) {
986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return 0;
987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return spiImpl.engineUpdate(input, inputOffset, inputLen, output,
989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                outputOffset);
990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Continues a multi-part transformation (encryption or decryption). The
994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@code input.remaining()} bytes starting at {@code input.position()} are
995f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * transformed and stored in the {@code output} buffer.
996f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * If the {@code output.remaining()} is too small to hold the transformed
998f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * bytes a {@code ShortBufferException} is thrown. Use
999f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@link Cipher#getOutputSize getOutputSize} to check for the size of the
1000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * output buffer.
10018207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     *
1002f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param input
1003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the input buffer to transform.
1004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param output
1005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the output buffer to store the result within.
1006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the number of bytes stored in the output buffer.
1007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws ShortBufferException
1008f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the size of the {@code output} buffer is too small.
1009f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalStateException
1010f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if this cipher instance is not initialized for encryption or
1011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             decryption.
1012f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalArgumentException
1013f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the input buffer and the output buffer are the identical
1014f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             object.
1015f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
1016f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final int update(ByteBuffer input, ByteBuffer output)
1017f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throws ShortBufferException {
1018f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) {
1019f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalStateException(
1020f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    Messages.getString("crypto.1C")); //$NON-NLS-1$
1021f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1022f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (input == output) {
1023f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException(
1024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    Messages.getString("crypto.22")); //$NON-NLS-1$
1025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return spiImpl.engineUpdate(input, output);
1027f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1028f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1029f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
1030f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Finishes a multi-part transformation (encryption or decryption).
1031f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
1032f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Processes any bytes that may have been buffered in previous {@code
1033f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * update} calls.
10348207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     *
1035f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the final bytes from the transformation.
1036f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalBlockSizeException
1037f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the size of the resulting bytes is not a multiple of the
1038f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             cipher block size.
1039f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws BadPaddingException
1040f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the padding of the data does not match the padding scheme.
1041f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalStateException
1042f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if this cipher instance is not initialized for encryption or
1043f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             decryption.
1044f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
1045f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final byte[] doFinal() throws IllegalBlockSizeException,
1046f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            BadPaddingException {
1047f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) {
1048f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalStateException(
1049f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    Messages.getString("crypto.1C")); //$NON-NLS-1$
1050f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1051f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return spiImpl.engineDoFinal(null, 0, 0);
1052f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1053f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1054f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
1055f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Finishes a multi-part transformation (encryption or decryption).
1056f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
1057f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Processes any bytes that may have been buffered in previous {@code
1058f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * update} calls.
10598207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     * <p>
1060f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The final transformed bytes are stored in the {@code output} buffer.
10618207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     *
1062f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param output
1063f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the output buffer.
1064f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param outputOffset
1065f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the offset in the output buffer.
1066f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the number of bytes placed in the output buffer.
1067f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalBlockSizeException
1068f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the size of the resulting bytes is not a multiple of the
1069f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             cipher block size.
1070f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws ShortBufferException
1071f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the size of the {@code output} buffer is too small.
1072f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws BadPaddingException
1073f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the padding of the data does not match the padding scheme.
1074f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalStateException
1075f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if this cipher instance is not initialized for encryption or
1076f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             decryption.
1077f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
1078f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final int doFinal(byte[] output, int outputOffset)
1079f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throws IllegalBlockSizeException, ShortBufferException,
1080f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            BadPaddingException {
1081f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) {
1082f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalStateException(
1083f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    Messages.getString("crypto.1C")); //$NON-NLS-1$
1084f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1085f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (outputOffset < 0) {
1086f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException(
1087f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    Messages.getString("crypto.20")); //$NON-NLS-1$
1088f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1089f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return spiImpl.engineDoFinal(null, 0, 0, output, outputOffset);
1090f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1091f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1092f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
1093f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Finishes a multi-part transformation (encryption or decryption).
1094f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
1095f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Processes the bytes in {@code input} buffer, and any bytes that have been
1096f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * buffered in previous {@code update} calls.
10978207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     *
1098f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param input
1099f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the input buffer.
1100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the final bytes from the transformation.
1101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalBlockSizeException
1102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the size of the resulting bytes is not a multiple of the
1103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             cipher block size.
1104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws BadPaddingException
1105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the padding of the data does not match the padding scheme.
1106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalStateException
1107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if this cipher instance is not initialized for encryption or
1108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             decryption.
1109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
1110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final byte[] doFinal(byte[] input) throws IllegalBlockSizeException,
1111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            BadPaddingException {
1112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) {
1113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalStateException(
1114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    Messages.getString("crypto.1C")); //$NON-NLS-1$
1115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return spiImpl.engineDoFinal(input, 0, input.length);
1117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
1120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Finishes a multi-part transformation (encryption or decryption).
1121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
1122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Processes the {@code inputLen} bytes in {@code input} buffer at {@code
1123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * inputOffset}, and any bytes that have been buffered in previous {@code
1124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * update} calls.
11258207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     *
1126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param input
1127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the input buffer.
1128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param inputOffset
1129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the offset in the input buffer.
1130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param inputLen
1131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the length of the input
1132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the final bytes from the transformation.
1133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalBlockSizeException
1134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the size of the resulting bytes is not a multiple of the
1135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             cipher block size.
1136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws BadPaddingException
1137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the padding of the data does not match the padding scheme.
1138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalStateException
1139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if this cipher instance is not initialized for encryption or
1140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             decryption.
1141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalArgumentException
1142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if {@code inputOffset} and {@code inputLen} do not specify an
1143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             valid chunk in the input buffer.
1144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
1145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final byte[] doFinal(byte[] input, int inputOffset, int inputLen)
1146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throws IllegalBlockSizeException, BadPaddingException {
1147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) {
1148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalStateException(
1149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    Messages.getString("crypto.1C")); //$NON-NLS-1$
1150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (inputOffset < 0 || inputLen < 0
1152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                || inputOffset + inputLen > input.length) {
1153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException(
1154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    Messages.getString("crypto.1E")); //$NON-NLS-1$
1155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return spiImpl.engineDoFinal(input, inputOffset, inputLen);
1157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
1160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Finishes a multi-part transformation (encryption or decryption).
1161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
1162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Processes the {@code inputLen} bytes in {@code input} buffer at {@code
1163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * inputOffset}, and any bytes that have been buffered in previous {@code
1164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * update} calls.
11658207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     *
1166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param input
1167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the input buffer.
1168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param inputOffset
1169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the offset in the input buffer.
1170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param inputLen
1171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the length of the input.
1172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param output
1173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the output buffer for the transformed bytes.
1174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the number of bytes placed in the output buffer.
1175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws ShortBufferException
1176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the size of the {@code output} buffer is too small.
1177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalBlockSizeException
1178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the size of the resulting bytes is not a multiple of the
1179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             cipher block size.
1180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws BadPaddingException
1181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the padding of the data does not match the padding scheme.
1182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalStateException
1183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if this cipher instance is not initialized for encryption or
1184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             decryption.
1185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalArgumentException
1186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if {@code inputOffset} and {@code inputLen} do not specify an
1187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             valid chunk in the input buffer.
1188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
1189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final int doFinal(byte[] input, int inputOffset, int inputLen,
1190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            byte[] output) throws ShortBufferException,
1191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            IllegalBlockSizeException, BadPaddingException {
1192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return doFinal(input, inputOffset, inputLen, output, 0);
1193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
1196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Finishes a multi-part transformation (encryption or decryption).
1197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
1198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Processes the {@code inputLen} bytes in {@code input} buffer at {@code
1199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * inputOffset}, and any bytes that have been buffered in previous {@code
1200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * update} calls.
12018207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     *
1202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param input
1203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the input buffer.
1204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param inputOffset
1205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the offset in the input buffer.
1206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param inputLen
1207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the length of the input.
1208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param output
1209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the output buffer for the transformed bytes.
1210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param outputOffset
1211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the offset in the output buffer.
1212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the number of bytes placed in the output buffer.
1213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws ShortBufferException
1214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the size of the {@code output} buffer is too small.
1215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalBlockSizeException
1216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the size of the resulting bytes is not a multiple of the
1217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             cipher block size.
1218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws BadPaddingException
1219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the padding of the data does not match the padding scheme.
1220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalStateException
1221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if this cipher instance is not initialized for encryption or
1222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             decryption.
1223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalArgumentException
1224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if {@code inputOffset} and {@code inputLen} do not specify an
1225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             valid chunk in the input buffer.
1226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
1227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final int doFinal(byte[] input, int inputOffset, int inputLen,
1228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            byte[] output, int outputOffset) throws ShortBufferException,
1229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            IllegalBlockSizeException, BadPaddingException {
1230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) {
1231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalStateException(
1232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    Messages.getString("crypto.1C")); //$NON-NLS-1$
1233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (inputOffset < 0 || inputLen < 0
1235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                || inputOffset + inputLen > input.length) {
1236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException(
1237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    Messages.getString("crypto.1E")); //$NON-NLS-1$
1238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return spiImpl.engineDoFinal(input, inputOffset, inputLen, output,
1240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                outputOffset);
1241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
1244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Finishes a multi-part transformation (encryption or decryption).
1245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
1246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Processes the {@code input.remaining()} bytes in {@code input} buffer at
1247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@code input.position()}, and any bytes that have been buffered in
1248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * previous {@code update} calls. The transformed bytes are placed into
1249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@code output} buffer.
12508207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     *
1251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param input
1252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the input buffer.
1253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param output
1254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the output buffer.
1255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the number of bytes placed into the output buffer.
1256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws ShortBufferException
1257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the size of the {@code output} buffer is too small.
1258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalBlockSizeException
1259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the size of the resulting bytes is not a multiple of the
1260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             cipher block size.
1261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws BadPaddingException
1262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the padding of the data does not match the padding scheme.
1263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalArgumentException
1264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the input buffer and the output buffer are the same
1265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             object.
1266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalStateException
1267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if this cipher instance is not initialized for encryption or
1268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             decryption.
1269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
1270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final int doFinal(ByteBuffer input, ByteBuffer output)
1271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throws ShortBufferException, IllegalBlockSizeException,
1272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            BadPaddingException {
1273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) {
1274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalStateException(
1275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    Messages.getString("crypto.1C")); //$NON-NLS-1$
1276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (input == output) {
1278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException(
1279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    Messages.getString("crypto.2E")); //$NON-NLS-1$
1280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return spiImpl.engineDoFinal(input, output);
1282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
1285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Wraps a key using this cipher instance.
12868207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     *
1287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param key
1288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the key to wrap.
1289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the wrapped key.
1290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalBlockSizeException
1291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the size of the resulting bytes is not a multiple of the
1292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             cipher block size.
1293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws InvalidKeyException
1294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if this cipher instance can not wrap this key.
1295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalStateException
1296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if this cipher instance is not initialized for wrapping.
1297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
1298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final byte[] wrap(Key key) throws IllegalBlockSizeException,
1299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            InvalidKeyException {
1300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (mode != WRAP_MODE) {
1301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalStateException(
1302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    Messages.getString("crypto.1C")); //$NON-NLS-1$
1303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return spiImpl.engineWrap(key);
1305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
1308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Unwraps a key using this cipher instance.
13098207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     *
1310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param wrappedKey
1311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the wrapped key to unwrap.
1312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param wrappedKeyAlgorithm
1313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the algorithm for the wrapped key.
1314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param wrappedKeyType
1315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the type of the wrapped key (one of: {@code SECRET_KEY
1316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            <code>, <code>PRIVATE_KEY} or {@code PUBLIC_KEY})
1317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the unwrapped key
1318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws InvalidKeyException
1319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the {@code wrappedKey} can not be unwrapped to a key of
1320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             type {@code wrappedKeyType} for the {@code
1321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             wrappedKeyAlgorithm}.
1322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws NoSuchAlgorithmException
1323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if no provider can be found that can create a key of type
1324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             {@code wrappedKeyType} for the {@code wrappedKeyAlgorithm}.
1325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalStateException
1326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if this cipher instance is not initialized for unwrapping.
1327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
1328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final Key unwrap(byte[] wrappedKey, String wrappedKeyAlgorithm,
1329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int wrappedKeyType) throws InvalidKeyException,
1330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            NoSuchAlgorithmException {
1331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (mode != UNWRAP_MODE) {
1332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalStateException(
1333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    Messages.getString("crypto.1C")); //$NON-NLS-1$
1334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return spiImpl.engineUnwrap(wrappedKey, wrappedKeyAlgorithm,
1336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                wrappedKeyType);
1337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
1340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the maximum key length for the specified transformation.
13418207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     *
1342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param transformation
1343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the transformation name.
1344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the maximum key length, currently {@code Integer.MAX_VALUE}.
1345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws NoSuchAlgorithmException
1346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if no provider for the specified {@code transformation} can
1347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             be found.
1348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws NullPointerException
1349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if {@code transformation} is {@code null}.
1350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
1351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static final int getMaxAllowedKeyLength(String transformation)
1352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throws NoSuchAlgorithmException {
1353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (transformation == null) {
1354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException();
1355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        checkTransformation(transformation);
1357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //FIXME jurisdiction policy files
1358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return Integer.MAX_VALUE;
1359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
1362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the maximum cipher parameter value for the specified
1363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * transformation. If there is no maximum limit, {@code null} is returned.
13648207f1e8dbc63916f238f81dc46567c55090e95bJesse Wilson     *
1365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param transformation
1366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the transformation name.
1367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return a parameter spec holding the maximum value or {@code null}.
1368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         Currently {@code null}.
1369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws NoSuchAlgorithmException
1370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if no provider for the specified {@code transformation} can
1371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             be found.
1372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws NullPointerException
1373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if {@code transformation} is {@code null}.
1374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
1375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static final AlgorithmParameterSpec getMaxAllowedParameterSpec(
1376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            String transformation) throws NoSuchAlgorithmException {
1377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (transformation == null) {
1378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException();
1379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        checkTransformation(transformation);
1381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //FIXME jurisdiction policy files
1382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return null;
1383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1385