blob: 7968f2fc628d992831d487878e257546dfa385bb [file] [log] [blame]
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001/*
Narayan Kamath2c87ad32015-12-21 13:53:32 +00002 * Copyright (C) 2014 The Android Open Source Project
Adam Vartanian11bd3492017-10-20 16:18:34 +01003 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00004 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation. Oracle designates this
9 * particular file as subject to the "Classpath" exception as provided
10 * by Oracle in the LICENSE file that accompanied this code.
11 *
12 * This code is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * version 2 for more details (a copy is included in the LICENSE file that
16 * accompanied this code).
17 *
18 * You should have received a copy of the GNU General Public License version
19 * 2 along with this work; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23 * or visit www.oracle.com if you need additional information or have any
24 * questions.
25 */
26
27package javax.crypto;
28
29import java.util.*;
30import java.util.concurrent.ConcurrentHashMap;
31import java.util.concurrent.ConcurrentMap;
32import java.util.regex.*;
33
34import static java.util.Locale.ENGLISH;
35
36import java.security.*;
37import java.security.Provider.Service;
38import java.security.spec.AlgorithmParameterSpec;
39import java.security.spec.InvalidParameterSpecException;
40import java.security.cert.Certificate;
41import java.security.cert.X509Certificate;
42
43import javax.crypto.spec.*;
44
45import java.nio.ByteBuffer;
46import java.nio.ReadOnlyBufferException;
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +000047import sun.security.jca.*;
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +000048
49/**
50 * This class provides the functionality of a cryptographic cipher for
51 * encryption and decryption. It forms the core of the Java Cryptographic
52 * Extension (JCE) framework.
53 *
54 * <p>In order to create a Cipher object, the application calls the
55 * Cipher's <code>getInstance</code> method, and passes the name of the
56 * requested <i>transformation</i> to it. Optionally, the name of a provider
57 * may be specified.
58 *
59 * <p>A <i>transformation</i> is a string that describes the operation (or
60 * set of operations) to be performed on the given input, to produce some
61 * output. A transformation always includes the name of a cryptographic
62 * algorithm (e.g., <i>DES</i>), and may be followed by a feedback mode and
63 * padding scheme.
64 *
Sergio Giro17982542016-08-03 19:21:52 +010065 * <p> A transformation is of the form:
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +000066 *
67 * <ul>
68 * <li>"<i>algorithm/mode/padding</i>" or
Sergio Giro17982542016-08-03 19:21:52 +010069 *
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +000070 * <li>"<i>algorithm</i>"
71 * </ul>
72 *
73 * <P> (in the latter case,
74 * provider-specific default values for the mode and padding scheme are used).
Sergio Giro17982542016-08-03 19:21:52 +010075 * For example, the following is a valid transformation:
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +000076 *
77 * <pre>
78 * Cipher c = Cipher.getInstance("<i>DES/CBC/PKCS5Padding</i>");
79 * </pre>
80 *
81 * Using modes such as <code>CFB</code> and <code>OFB</code>, block
82 * ciphers can encrypt data in units smaller than the cipher's actual
83 * block size. When requesting such a mode, you may optionally specify
84 * the number of bits to be processed at a time by appending this number
85 * to the mode name as shown in the "<code>DES/CFB8/NoPadding</code>" and
86 * "<code>DES/OFB32/PKCS5Padding</code>" transformations. If no such
87 * number is specified, a provider-specific default is used. (For
88 * example, the SunJCE provider uses a default of 64 bits for DES.)
89 * Thus, block ciphers can be turned into byte-oriented stream ciphers by
90 * using an 8 bit mode such as CFB8 or OFB8.
91 * <p>
92 * Modes such as Authenticated Encryption with Associated Data (AEAD)
93 * provide authenticity assurances for both confidential data and
94 * Additional Associated Data (AAD) that is not encrypted. (Please see
95 * <a href="http://www.ietf.org/rfc/rfc5116.txt"> RFC 5116 </a> for more
96 * information on AEAD and AEAD algorithms such as GCM/CCM.) Both
97 * confidential and AAD data can be used when calculating the
98 * authentication tag (similar to a {@link Mac}). This tag is appended
99 * to the ciphertext during encryption, and is verified on decryption.
100 * <p>
101 * AEAD modes such as GCM/CCM perform all AAD authenticity calculations
102 * before starting the ciphertext authenticity calculations. To avoid
103 * implementations having to internally buffer ciphertext, all AAD data
104 * must be supplied to GCM/CCM implementations (via the {@code
105 * updateAAD} methods) <b>before</b> the ciphertext is processed (via
106 * the {@code update} and {@code doFinal} methods).
Sergio Giro17982542016-08-03 19:21:52 +0100107 * <p>
108 * Note that GCM mode has a uniqueness requirement on IVs used in
109 * encryption with a given key. When IVs are repeated for GCM
110 * encryption, such usages are subject to forgery attacks. Thus, after
111 * each encryption operation using GCM mode, callers should re-initialize
112 * the cipher objects with GCM parameters which has a different IV value.
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000113 * <pre>
Sergio Giro17982542016-08-03 19:21:52 +0100114 * GCMParameterSpec s = ...;
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000115 * cipher.init(..., s);
116 *
Sergio Giro17982542016-08-03 19:21:52 +0100117 * // If the GCM parameters were generated by the provider, it can
118 * // be retrieved by:
119 * // cipher.getParameters().getParameterSpec(GCMParameterSpec.class);
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000120 *
121 * cipher.updateAAD(...); // AAD
122 * cipher.update(...); // Multi-part update
123 * cipher.doFinal(...); // conclusion of operation
Sergio Giro17982542016-08-03 19:21:52 +0100124 *
125 * // Use a different IV value for every encryption
126 * byte[] newIv = ...;
127 * s = new GCMParameterSpec(s.getTLen(), newIv);
128 * cipher.init(..., s);
129 * ...
130 *
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000131 * </pre>
Przemyslaw Szczepaniak444325b2016-05-18 13:09:39 +0100132 * <p> Android provides the following <code>Cipher</code> transformations:
133 * <table>
Adam Vartaniana52aa9f2017-03-20 11:32:38 +0000134 * <thead>
135 * <tr>
136 * <th>Algorithm</th>
137 * <th>Modes</th>
138 * <th>Paddings</th>
139 * <th>Supported API Levels</th>
Adam Vartanian11796722018-02-02 14:09:14 +0000140 * <th>Notes</th>
Adam Vartaniana52aa9f2017-03-20 11:32:38 +0000141 * </tr>
142 * </thead>
143 * <tbody>
144 * <tr>
Adam Vartanian11796722018-02-02 14:09:14 +0000145 * <td rowspan="2"><span style="white-space: nowrap">AES</span></td>
146 * <td><span style="white-space: nowrap">CBC</span><br><span style="white-space: nowrap">CFB</span><br><span style="white-space: nowrap">CTR</span><br><span style="white-space: nowrap">CTS</span><br><span style="white-space: nowrap">ECB</span><br><span style="white-space: nowrap">OFB</span></td>
147 * <td><span style="white-space: nowrap">ISO10126Padding</span><br><span style="white-space: nowrap">NoPadding</span><br><span style="white-space: nowrap">PKCS5Padding</span></td>
148 * <td><span style="white-space: nowrap">1+</span></td>
149 * <td></td>
Adam Vartaniana52aa9f2017-03-20 11:32:38 +0000150 * </tr>
151 * <tr>
Adam Vartanian11796722018-02-02 14:09:14 +0000152 * <td><span style="white-space: nowrap">GCM</span></td>
153 * <td><span style="white-space: nowrap">NoPadding</span></td>
154 * <td><span style="white-space: nowrap">10+</span></td>
155 * <td></td>
Adam Vartaniana52aa9f2017-03-20 11:32:38 +0000156 * </tr>
157 * <tr>
Adam Vartanian11796722018-02-02 14:09:14 +0000158 * <td rowspan="2"><span style="white-space: nowrap">AES_128</span></td>
159 * <td><span style="white-space: nowrap">CBC</span><br><span style="white-space: nowrap">ECB</span></td>
160 * <td><span style="white-space: nowrap">NoPadding</span><br><span style="white-space: nowrap">PKCS5Padding</span></td>
161 * <td><span style="white-space: nowrap">26+</span></td>
162 * <td></td>
Adam Vartaniana52aa9f2017-03-20 11:32:38 +0000163 * </tr>
164 * <tr>
Adam Vartanian11796722018-02-02 14:09:14 +0000165 * <td><span style="white-space: nowrap">GCM</span></td>
166 * <td><span style="white-space: nowrap">NoPadding</span></td>
167 * <td><span style="white-space: nowrap">26+</span></td>
168 * <td></td>
Adam Vartaniana52aa9f2017-03-20 11:32:38 +0000169 * </tr>
170 * <tr>
Adam Vartanian11796722018-02-02 14:09:14 +0000171 * <td rowspan="2"><span style="white-space: nowrap">AES_256</span></td>
172 * <td><span style="white-space: nowrap">CBC</span><br><span style="white-space: nowrap">ECB</span></td>
173 * <td><span style="white-space: nowrap">NoPadding</span><br><span style="white-space: nowrap">PKCS5Padding</span></td>
174 * <td><span style="white-space: nowrap">26+</span></td>
175 * <td></td>
Adam Vartaniana52aa9f2017-03-20 11:32:38 +0000176 * </tr>
177 * <tr>
Adam Vartanian11796722018-02-02 14:09:14 +0000178 * <td><span style="white-space: nowrap">GCM</span></td>
179 * <td><span style="white-space: nowrap">NoPadding</span></td>
180 * <td><span style="white-space: nowrap">26+</span></td>
181 * <td></td>
Adam Vartaniana52aa9f2017-03-20 11:32:38 +0000182 * </tr>
183 * <tr>
Adam Vartanian11796722018-02-02 14:09:14 +0000184 * <td rowspan="2"><span style="white-space: nowrap">ARC4</span></td>
185 * <td><span style="white-space: nowrap">ECB</span></td>
186 * <td><span style="white-space: nowrap">NoPadding</span></td>
187 * <td><span style="white-space: nowrap">10+</span></td>
188 * <td></td>
Adam Vartaniana52aa9f2017-03-20 11:32:38 +0000189 * </tr>
190 * <tr>
Adam Vartanian11796722018-02-02 14:09:14 +0000191 * <td><span style="white-space: nowrap">NONE</span></td>
192 * <td><span style="white-space: nowrap">NoPadding</span></td>
193 * <td><span style="white-space: nowrap">28+</span></td>
194 * <td></td>
Adam Vartanian6b6741f2018-01-03 14:44:12 +0000195 * </tr>
196 * <tr>
Adam Vartanian11796722018-02-02 14:09:14 +0000197 * <td><span style="white-space: nowrap">BLOWFISH</span></td>
198 * <td><span style="white-space: nowrap">CBC</span><br><span style="white-space: nowrap">CFB</span><br><span style="white-space: nowrap">CTR</span><br><span style="white-space: nowrap">CTS</span><br><span style="white-space: nowrap">ECB</span><br><span style="white-space: nowrap">OFB</span></td>
199 * <td><span style="white-space: nowrap">ISO10126Padding</span><br><span style="white-space: nowrap">NoPadding</span><br><span style="white-space: nowrap">PKCS5Padding</span></td>
200 * <td><span style="white-space: nowrap">10+</span></td>
201 * <td></td>
Adam Vartaniana52aa9f2017-03-20 11:32:38 +0000202 * </tr>
203 * <tr>
Adam Vartanian11796722018-02-02 14:09:14 +0000204 * <td><span style="white-space: nowrap">ChaCha20</span></td>
205 * <td><span style="white-space: nowrap">NONE</span><br><span style="white-space: nowrap">Poly1305</span></td>
206 * <td><span style="white-space: nowrap">NoPadding</span></td>
207 * <td><span style="white-space: nowrap">28+</span></td>
208 * <td>ChaCha with 20 rounds, 96-bit nonce, and 32-bit counter as described in RFC 7539.</td>
Adam Vartanian6b6741f2018-01-03 14:44:12 +0000209 * </tr>
210 * <tr>
Adam Vartanian11796722018-02-02 14:09:14 +0000211 * <td><span style="white-space: nowrap">DES</span></td>
212 * <td><span style="white-space: nowrap">CBC</span><br><span style="white-space: nowrap">CFB</span><br><span style="white-space: nowrap">CTR</span><br><span style="white-space: nowrap">CTS</span><br><span style="white-space: nowrap">ECB</span><br><span style="white-space: nowrap">OFB</span></td>
213 * <td><span style="white-space: nowrap">ISO10126Padding</span><br><span style="white-space: nowrap">NoPadding</span><br><span style="white-space: nowrap">PKCS5Padding</span></td>
214 * <td><span style="white-space: nowrap">1+</span></td>
215 * <td></td>
Adam Vartaniana52aa9f2017-03-20 11:32:38 +0000216 * </tr>
217 * <tr>
Adam Vartanian11796722018-02-02 14:09:14 +0000218 * <td><span style="white-space: nowrap">DESede</span></td>
219 * <td><span style="white-space: nowrap">CBC</span><br><span style="white-space: nowrap">CFB</span><br><span style="white-space: nowrap">CTR</span><br><span style="white-space: nowrap">CTS</span><br><span style="white-space: nowrap">ECB</span><br><span style="white-space: nowrap">OFB</span></td>
220 * <td><span style="white-space: nowrap">ISO10126Padding</span><br><span style="white-space: nowrap">NoPadding</span><br><span style="white-space: nowrap">PKCS5Padding</span></td>
221 * <td><span style="white-space: nowrap">1+</span></td>
222 * <td></td>
Adam Vartaniana52aa9f2017-03-20 11:32:38 +0000223 * </tr>
224 * <tr>
Adam Vartanian11796722018-02-02 14:09:14 +0000225 * <td rowspan="3"><span style="white-space: nowrap">RSA</span></td>
226 * <td rowspan="3"><span style="white-space: nowrap">ECB</span><br><span style="white-space: nowrap">NONE</span></td>
227 * <td><span style="white-space: nowrap">NoPadding</span><br><span style="white-space: nowrap">OAEPPadding</span><br><span style="white-space: nowrap">PKCS1Padding</span></td>
228 * <td><span style="white-space: nowrap">1+</span></td>
229 * <td></td>
Adam Vartaniana52aa9f2017-03-20 11:32:38 +0000230 * </tr>
231 * <tr>
Adam Vartanian11796722018-02-02 14:09:14 +0000232 * <td><span style="white-space: nowrap">OAEPwithSHA-1andMGF1Padding</span><br><span style="white-space: nowrap">OAEPwithSHA-256andMGF1Padding</span></td>
233 * <td><span style="white-space: nowrap">10+</span></td>
234 * <td></td>
Adam Vartaniana52aa9f2017-03-20 11:32:38 +0000235 * </tr>
236 * <tr>
Adam Vartanian11796722018-02-02 14:09:14 +0000237 * <td><span style="white-space: nowrap">OAEPwithSHA-224andMGF1Padding</span><br><span style="white-space: nowrap">OAEPwithSHA-384andMGF1Padding</span><br><span style="white-space: nowrap">OAEPwithSHA-512andMGF1Padding</span></td>
238 * <td><span style="white-space: nowrap">23+</span></td>
239 * <td></td>
Adam Vartaniana52aa9f2017-03-20 11:32:38 +0000240 * </tr>
241 * </tbody>
Przemyslaw Szczepaniak444325b2016-05-18 13:09:39 +0100242 * </table>
243 *
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000244 * These transformations are described in the
Tobias Thierer6bd07db2019-04-03 18:06:18 +0100245 * <a href="{@docRoot}/../technotes/guides/security/StandardNames.html#Cipher">
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000246 * Cipher section</a> of the
247 * Java Cryptography Architecture Standard Algorithm Name Documentation.
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000248 *
249 * @author Jan Luehe
250 * @see KeyGenerator
251 * @see SecretKey
252 * @since 1.4
253 */
254
255public class Cipher {
256
Adam Vartanian11bd3492017-10-20 16:18:34 +0100257 // Android-note: Android reimplements provider selection.
258 //
259 // Android uses different provider/impl selection code than upstream does. Provider
260 // selection permeates much of this class, so this class is forked significantly
261 // from the upstream version. Not every change is marked, and any changes to upstream code
262 // should be evaluated to see if they should be merged.
263 //
264 // The changes are chiefly in construction (constructors, getInstance, and createCipher) and
265 // initialization (init and chooseProvider). Most of the actual implementation is in the
266 // classes and methods at the bottom of this file.
267
268
Tobias Thierer9eca2692017-04-12 18:16:06 +0100269 // Android-removed: this debugging mechanism is not used in Android.
270 /*
Adam Vartanian96635862017-05-25 14:39:26 +0100271 private static final Debug debug =
272 Debug.getInstance("jca", "Cipher");
273
Sergio Giro17982542016-08-03 19:21:52 +0100274 private static final Debug pdebug =
275 Debug.getInstance("provider", "Provider");
276 private static final boolean skipDebug =
277 Debug.isOn("engine=") && !Debug.isOn("cipher");
278 */
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000279
280 /**
281 * Constant used to initialize cipher to encryption mode.
282 */
283 public static final int ENCRYPT_MODE = 1;
284
285 /**
286 * Constant used to initialize cipher to decryption mode.
287 */
288 public static final int DECRYPT_MODE = 2;
289
290 /**
291 * Constant used to initialize cipher to key-wrapping mode.
292 */
293 public static final int WRAP_MODE = 3;
294
295 /**
296 * Constant used to initialize cipher to key-unwrapping mode.
297 */
298 public static final int UNWRAP_MODE = 4;
299
300 /**
301 * Constant used to indicate the to-be-unwrapped key is a "public key".
302 */
303 public static final int PUBLIC_KEY = 1;
304
305 /**
306 * Constant used to indicate the to-be-unwrapped key is a "private key".
307 */
308 public static final int PRIVATE_KEY = 2;
309
310 /**
311 * Constant used to indicate the to-be-unwrapped key is a "secret key".
312 */
313 public static final int SECRET_KEY = 3;
314
315 // The provider
316 private Provider provider;
317
318 // The provider implementation (delegate)
319 private CipherSpi spi;
320
321 // The transformation
Adam Vartanian11bd3492017-10-20 16:18:34 +0100322 // Android-changed: Made final.
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +0000323 final private String transformation;
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000324
Adam Vartanian11bd3492017-10-20 16:18:34 +0100325 // Android-added: Added tokenizedTransformation.
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +0000326 // The tokenized version of transformation
327 final private String[] tokenizedTransformation;
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000328
Adam Vartanian11bd3492017-10-20 16:18:34 +0100329 // Android-removed: Removed cryptoPerm.
330 /*
331 // Crypto permission representing the maximum allowable cryptographic
332 // strength that this Cipher object can be used for. (The cryptographic
333 // strength is a function of the keysize and algorithm parameters encoded
334 // in the crypto permission.)
335 private CryptoPermission cryptoPerm;
336 */
337
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000338 // The exemption mechanism that needs to be enforced
339 private ExemptionMechanism exmech;
340
341 // Flag which indicates whether or not this cipher has been initialized
342 private boolean initialized = false;
343
344 // The operation mode - store the operation mode after the
345 // cipher has been initialized.
346 private int opmode = 0;
347
348 // The OID for the KeyUsage extension in an X.509 v3 certificate
349 private static final String KEY_USAGE_EXTENSION_OID = "2.5.29.15";
350
Adam Vartanian11bd3492017-10-20 16:18:34 +0100351 // BEGIN Android-changed: Reimplement provider selection.
352 // See note at top of class.
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +0000353 private final SpiAndProviderUpdater spiAndProviderUpdater;
Adam Vartanian11bd3492017-10-20 16:18:34 +0100354 /*
355 // next SPI to try in provider selection
356 // null once provider is selected
357 private CipherSpi firstSpi;
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000358
Adam Vartanian11bd3492017-10-20 16:18:34 +0100359 // next service to try in provider selection
360 // null once provider is selected
361 private Service firstService;
362
363 // remaining services to try in provider selection
364 // null once provider is selected
365 private Iterator<Service> serviceIterator;
366
367 // list of transform Strings to lookup in the provider
368 private List<Transform> transforms;
369
370 private final Object lock;
371 */
372 // END Android-changed: Reimplement provider selection.
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000373
374 /**
375 * Creates a Cipher object.
376 *
377 * @param cipherSpi the delegate
378 * @param provider the provider
379 * @param transformation the transformation
380 */
381 protected Cipher(CipherSpi cipherSpi,
382 Provider provider,
383 String transformation) {
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +0000384 if (cipherSpi == null) {
385 throw new NullPointerException("cipherSpi == null");
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000386 }
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +0000387 if (!(cipherSpi instanceof NullCipherSpi) && provider == null) {
388 throw new NullPointerException("provider == null");
389 }
390
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000391 this.spi = cipherSpi;
392 this.provider = provider;
393 this.transformation = transformation;
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +0000394 this.tokenizedTransformation = null;
395
396 this.spiAndProviderUpdater =
397 new SpiAndProviderUpdater(provider, cipherSpi);
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000398 }
399
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +0000400 private Cipher(CipherSpi cipherSpi,
401 Provider provider,
402 String transformation,
403 String[] tokenizedTransformation) {
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000404 this.spi = cipherSpi;
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +0000405 this.provider = provider;
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000406 this.transformation = transformation;
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +0000407 this.tokenizedTransformation = tokenizedTransformation;
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000408
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +0000409 this.spiAndProviderUpdater =
410 new SpiAndProviderUpdater(provider, cipherSpi);
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000411 }
412
413 private static String[] tokenizeTransformation(String transformation)
414 throws NoSuchAlgorithmException {
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +0000415 if (transformation == null || transformation.isEmpty()) {
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000416 throw new NoSuchAlgorithmException("No transformation given");
417 }
418 /*
419 * array containing the components of a Cipher transformation:
420 *
421 * index 0: algorithm component (e.g., DES)
422 * index 1: feedback component (e.g., CFB)
423 * index 2: padding component (e.g., PKCS5Padding)
424 */
425 String[] parts = new String[3];
426 int count = 0;
427 StringTokenizer parser = new StringTokenizer(transformation, "/");
428 try {
429 while (parser.hasMoreTokens() && count < 3) {
430 parts[count++] = parser.nextToken().trim();
431 }
432 if (count == 0 || count == 2 || parser.hasMoreTokens()) {
433 throw new NoSuchAlgorithmException("Invalid transformation"
434 + " format:" +
435 transformation);
436 }
437 } catch (NoSuchElementException e) {
438 throw new NoSuchAlgorithmException("Invalid transformation " +
439 "format:" + transformation);
440 }
441 if ((parts[0] == null) || (parts[0].length() == 0)) {
442 throw new NoSuchAlgorithmException("Invalid transformation:" +
443 "algorithm not specified-"
444 + transformation);
445 }
446 return parts;
447 }
448
Adam Vartanian11bd3492017-10-20 16:18:34 +0100449 // BEGIN Android-removed: Reimplement provider selection.
450 // See note at top of class.
451 /*
452 // Provider attribute name for supported chaining mode
453 private final static String ATTR_MODE = "SupportedModes";
454 // Provider attribute name for supported padding names
455 private final static String ATTR_PAD = "SupportedPaddings";
456
457 // constants indicating whether the provider supports
458 // a given mode or padding
459 private final static int S_NO = 0; // does not support
460 private final static int S_MAYBE = 1; // unable to determine
461 private final static int S_YES = 2; // does support
462
463 /**
464 * Nested class to deal with modes and paddings.
465 *
466 private static class Transform {
467 // transform string to lookup in the provider
468 final String transform;
469 // the mode/padding suffix in upper case. for example, if the algorithm
470 // to lookup is "DES/CBC/PKCS5Padding" suffix is "/CBC/PKCS5PADDING"
471 // if loopup is "DES", suffix is the empty string
472 // needed because aliases prevent straight transform.equals()
473 final String suffix;
474 // value to pass to setMode() or null if no such call required
475 final String mode;
476 // value to pass to setPadding() or null if no such call required
477 final String pad;
478 Transform(String alg, String suffix, String mode, String pad) {
479 this.transform = alg + suffix;
480 this.suffix = suffix.toUpperCase(Locale.ENGLISH);
481 this.mode = mode;
482 this.pad = pad;
483 }
484 // set mode and padding for the given SPI
485 void setModePadding(CipherSpi spi) throws NoSuchAlgorithmException,
486 NoSuchPaddingException {
487 if (mode != null) {
488 spi.engineSetMode(mode);
489 }
490 if (pad != null) {
491 spi.engineSetPadding(pad);
492 }
493 }
494 // check whether the given services supports the mode and
495 // padding described by this Transform
496 int supportsModePadding(Service s) {
497 int smode = supportsMode(s);
498 if (smode == S_NO) {
499 return smode;
500 }
501 int spad = supportsPadding(s);
502 // our constants are defined so that Math.min() is a tri-valued AND
503 return Math.min(smode, spad);
504 }
505
506 // separate methods for mode and padding
507 // called directly by Cipher only to throw the correct exception
508 int supportsMode(Service s) {
509 return supports(s, ATTR_MODE, mode);
510 }
511 int supportsPadding(Service s) {
512 return supports(s, ATTR_PAD, pad);
513 }
514
515 private static int supports(Service s, String attrName, String value) {
516 if (value == null) {
517 return S_YES;
518 }
519 String regexp = s.getAttribute(attrName);
520 if (regexp == null) {
521 return S_MAYBE;
522 }
523 return matches(regexp, value) ? S_YES : S_NO;
524 }
525
526 // ConcurrentMap<String,Pattern> for previously compiled patterns
527 private final static ConcurrentMap<String, Pattern> patternCache =
528 new ConcurrentHashMap<String, Pattern>();
529
530 private static boolean matches(String regexp, String str) {
531 Pattern pattern = patternCache.get(regexp);
532 if (pattern == null) {
533 pattern = Pattern.compile(regexp);
534 patternCache.putIfAbsent(regexp, pattern);
535 }
536 return pattern.matcher(str.toUpperCase(Locale.ENGLISH)).matches();
537 }
538
539 }
540
541 private static List<Transform> getTransforms(String transformation)
542 throws NoSuchAlgorithmException {
543 String[] parts = tokenizeTransformation(transformation);
544
545 String alg = parts[0];
546 String mode = parts[1];
547 String pad = parts[2];
548 if ((mode != null) && (mode.length() == 0)) {
549 mode = null;
550 }
551 if ((pad != null) && (pad.length() == 0)) {
552 pad = null;
553 }
554
555 if ((mode == null) && (pad == null)) {
556 // DES
557 Transform tr = new Transform(alg, "", null, null);
558 return Collections.singletonList(tr);
559 } else { // if ((mode != null) && (pad != null)) {
560 // DES/CBC/PKCS5Padding
561 List<Transform> list = new ArrayList<>(4);
562 list.add(new Transform(alg, "/" + mode + "/" + pad, null, null));
563 list.add(new Transform(alg, "/" + mode, null, pad));
564 list.add(new Transform(alg, "//" + pad, mode, null));
565 list.add(new Transform(alg, "", mode, pad));
566 return list;
567 }
568 }
569
570 // get the transform matching the specified service
571 private static Transform getTransform(Service s,
572 List<Transform> transforms) {
573 String alg = s.getAlgorithm().toUpperCase(Locale.ENGLISH);
574 for (Transform tr : transforms) {
575 if (alg.endsWith(tr.suffix)) {
576 return tr;
577 }
578 }
579 return null;
580 }
581 */
582 // END Android-removed: Reimplement provider selection.
583
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000584 /**
585 * Returns a <code>Cipher</code> object that implements the specified
586 * transformation.
587 *
588 * <p> This method traverses the list of registered security Providers,
589 * starting with the most preferred Provider.
590 * A new Cipher object encapsulating the
591 * CipherSpi implementation from the first
592 * Provider that supports the specified algorithm is returned.
593 *
594 * <p> Note that the list of registered providers may be retrieved via
595 * the {@link Security#getProviders() Security.getProviders()} method.
596 *
597 * @param transformation the name of the transformation, e.g.,
598 * <i>DES/CBC/PKCS5Padding</i>.
599 * See the Cipher section in the <a href=
Tobias Thierer6bd07db2019-04-03 18:06:18 +0100600 * "{@docRoot}/../technotes/guides/security/StandardNames.html#Cipher">
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000601 * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
602 * for information about standard transformation names.
603 *
604 * @return a cipher that implements the requested transformation.
605 *
606 * @exception NoSuchAlgorithmException if <code>transformation</code>
607 * is null, empty, in an invalid format,
608 * or if no Provider supports a CipherSpi implementation for the
609 * specified algorithm.
610 *
611 * @exception NoSuchPaddingException if <code>transformation</code>
612 * contains a padding scheme that is not available.
613 *
614 * @see java.security.Provider
615 */
616 public static final Cipher getInstance(String transformation)
617 throws NoSuchAlgorithmException, NoSuchPaddingException
618 {
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +0000619 return createCipher(transformation, null);
Piotr Jastrzebskic2597fc2015-03-30 14:47:39 +0100620 }
621
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000622 /**
623 * Returns a <code>Cipher</code> object that implements the specified
624 * transformation.
625 *
626 * <p> A new Cipher object encapsulating the
627 * CipherSpi implementation from the specified provider
628 * is returned. The specified provider must be registered
629 * in the security provider list.
630 *
631 * <p> Note that the list of registered providers may be retrieved via
632 * the {@link Security#getProviders() Security.getProviders()} method.
633 *
634 * @param transformation the name of the transformation,
635 * e.g., <i>DES/CBC/PKCS5Padding</i>.
636 * See the Cipher section in the <a href=
Tobias Thierer6bd07db2019-04-03 18:06:18 +0100637 * "{@docRoot}/../technotes/guides/security/StandardNames.html#Cipher">
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000638 * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
639 * for information about standard transformation names.
640 *
641 * @param provider the name of the provider.
642 *
643 * @return a cipher that implements the requested transformation.
644 *
645 * @exception NoSuchAlgorithmException if <code>transformation</code>
646 * is null, empty, in an invalid format,
647 * or if a CipherSpi implementation for the specified algorithm
648 * is not available from the specified provider.
649 *
650 * @exception NoSuchProviderException if the specified provider is not
651 * registered in the security provider list.
652 *
653 * @exception NoSuchPaddingException if <code>transformation</code>
654 * contains a padding scheme that is not available.
655 *
656 * @exception IllegalArgumentException if the <code>provider</code>
657 * is null or empty.
658 *
659 * @see java.security.Provider
660 */
661 public static final Cipher getInstance(String transformation,
662 String provider)
663 throws NoSuchAlgorithmException, NoSuchProviderException,
664 NoSuchPaddingException
665 {
666 if ((provider == null) || (provider.length() == 0)) {
667 throw new IllegalArgumentException("Missing provider");
668 }
669 Provider p = Security.getProvider(provider);
670 if (p == null) {
671 throw new NoSuchProviderException("No such provider: " +
672 provider);
673 }
Adam Vartanian11bd3492017-10-20 16:18:34 +0100674 return getInstance(transformation, p);
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000675 }
676
677 /**
678 * Returns a <code>Cipher</code> object that implements the specified
679 * transformation.
680 *
681 * <p> A new Cipher object encapsulating the
682 * CipherSpi implementation from the specified Provider
683 * object is returned. Note that the specified Provider object
684 * does not have to be registered in the provider list.
685 *
686 * @param transformation the name of the transformation,
687 * e.g., <i>DES/CBC/PKCS5Padding</i>.
688 * See the Cipher section in the <a href=
Tobias Thierer6bd07db2019-04-03 18:06:18 +0100689 * "{@docRoot}/../technotes/guides/security/StandardNames.html#Cipher">
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000690 * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
691 * for information about standard transformation names.
692 *
693 * @param provider the provider.
694 *
695 * @return a cipher that implements the requested transformation.
696 *
697 * @exception NoSuchAlgorithmException if <code>transformation</code>
698 * is null, empty, in an invalid format,
699 * or if a CipherSpi implementation for the specified algorithm
700 * is not available from the specified Provider object.
701 *
702 * @exception NoSuchPaddingException if <code>transformation</code>
703 * contains a padding scheme that is not available.
704 *
705 * @exception IllegalArgumentException if the <code>provider</code>
706 * is null.
707 *
708 * @see java.security.Provider
709 */
710 public static final Cipher getInstance(String transformation,
711 Provider provider)
712 throws NoSuchAlgorithmException, NoSuchPaddingException
713 {
714 if (provider == null) {
715 throw new IllegalArgumentException("Missing provider");
716 }
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +0000717 return createCipher(transformation, provider);
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000718 }
719
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +0000720 static final Cipher createCipher(String transformation, Provider provider)
721 throws NoSuchAlgorithmException, NoSuchPaddingException {
Adam Vartanian14cf0e02017-10-24 12:34:43 +0100722 Providers.checkBouncyCastleDeprecation(provider, "Cipher", transformation);
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +0000723 String[] tokenizedTransformation = tokenizeTransformation(transformation);
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000724
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +0000725 CipherSpiAndProvider cipherSpiAndProvider = null;
726 try {
727 cipherSpiAndProvider =
728 tryCombinations(null /*params*/, provider, tokenizedTransformation);
729 } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
730 // Shouldn't happen.
731 throw new IllegalStateException("Key/Algorithm excepton despite not passing one", e);
732 }
733
734 if (cipherSpiAndProvider == null) {
735 if (provider == null) {
736 throw new NoSuchAlgorithmException("No provider found for " + transformation);
737 } else {
738 throw new NoSuchAlgorithmException("Provider " + provider.getName()
739 + " does not provide " + transformation);
740 }
741 }
742
743 // exceptions and stuff
744 return new Cipher(null, provider, transformation, tokenizedTransformation);
745 }
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000746
747 /**
748 * Choose the Spi from the first provider available. Used if
749 * delayed provider selection is not possible because init()
750 * is not the first method called.
751 */
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +0000752 void updateProviderIfNeeded() {
753 try {
754 spiAndProviderUpdater.updateAndGetSpiAndProvider(null, spi, provider);
755 } catch (Exception lastException) {
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000756 ProviderException e = new ProviderException
757 ("Could not construct CipherSpi instance");
758 if (lastException != null) {
759 e.initCause(lastException);
760 }
761 throw e;
762 }
763 }
764
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +0000765 private void chooseProvider(InitType initType, int opmode, Key key,
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000766 AlgorithmParameterSpec paramSpec,
767 AlgorithmParameters params, SecureRandom random)
768 throws InvalidKeyException, InvalidAlgorithmParameterException {
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +0000769
770 try {
771 final InitParams initParams = new InitParams(initType, opmode, key, random,
772 paramSpec, params);
773 spiAndProviderUpdater.updateAndGetSpiAndProvider(initParams, spi, provider);
774 } catch (Exception lastException) {
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000775 // no working provider found, fail
776 if (lastException instanceof InvalidKeyException) {
777 throw (InvalidKeyException)lastException;
778 }
779 if (lastException instanceof InvalidAlgorithmParameterException) {
780 throw (InvalidAlgorithmParameterException)lastException;
781 }
782 if (lastException instanceof RuntimeException) {
783 throw (RuntimeException)lastException;
784 }
785 String kName = (key != null) ? key.getClass().getName() : "(null)";
786 throw new InvalidKeyException
787 ("No installed provider supports this key: "
788 + kName, lastException);
789 }
790 }
791
792 /**
793 * Returns the provider of this <code>Cipher</code> object.
794 *
795 * @return the provider of this <code>Cipher</code> object
796 */
797 public final Provider getProvider() {
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +0000798 updateProviderIfNeeded();
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000799 return this.provider;
800 }
801
802 /**
803 * Returns the algorithm name of this <code>Cipher</code> object.
804 *
805 * <p>This is the same name that was specified in one of the
806 * <code>getInstance</code> calls that created this <code>Cipher</code>
807 * object..
808 *
809 * @return the algorithm name of this <code>Cipher</code> object.
810 */
811 public final String getAlgorithm() {
812 return this.transformation;
813 }
814
815 /**
816 * Returns the block size (in bytes).
817 *
818 * @return the block size (in bytes), or 0 if the underlying algorithm is
819 * not a block cipher
820 */
821 public final int getBlockSize() {
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +0000822 updateProviderIfNeeded();
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000823 return spi.engineGetBlockSize();
824 }
825
826 /**
827 * Returns the length in bytes that an output buffer would need to be in
828 * order to hold the result of the next <code>update</code> or
829 * <code>doFinal</code> operation, given the input length
830 * <code>inputLen</code> (in bytes).
831 *
832 * <p>This call takes into account any unprocessed (buffered) data from a
833 * previous <code>update</code> call, padding, and AEAD tagging.
834 *
835 * <p>The actual output length of the next <code>update</code> or
836 * <code>doFinal</code> call may be smaller than the length returned by
837 * this method.
838 *
839 * @param inputLen the input length (in bytes)
840 *
841 * @return the required output buffer size (in bytes)
842 *
843 * @exception IllegalStateException if this cipher is in a wrong state
844 * (e.g., has not yet been initialized)
845 */
846 public final int getOutputSize(int inputLen) {
847
848 if (!initialized && !(this instanceof NullCipher)) {
849 throw new IllegalStateException("Cipher not initialized");
850 }
851 if (inputLen < 0) {
852 throw new IllegalArgumentException("Input size must be equal " +
853 "to or greater than zero");
854 }
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +0000855 updateProviderIfNeeded();
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000856 return spi.engineGetOutputSize(inputLen);
857 }
858
859 /**
860 * Returns the initialization vector (IV) in a new buffer.
861 *
862 * <p>This is useful in the case where a random IV was created,
863 * or in the context of password-based encryption or
864 * decryption, where the IV is derived from a user-supplied password.
865 *
866 * @return the initialization vector in a new buffer, or null if the
867 * underlying algorithm does not use an IV, or if the IV has not yet
868 * been set.
869 */
870 public final byte[] getIV() {
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +0000871 updateProviderIfNeeded();
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000872 return spi.engineGetIV();
873 }
874
875 /**
876 * Returns the parameters used with this cipher.
877 *
878 * <p>The returned parameters may be the same that were used to initialize
879 * this cipher, or may contain a combination of default and random
880 * parameter values used by the underlying cipher implementation if this
881 * cipher requires algorithm parameters but was not initialized with any.
882 *
883 * @return the parameters used with this cipher, or null if this cipher
884 * does not use any parameters.
885 */
886 public final AlgorithmParameters getParameters() {
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +0000887 updateProviderIfNeeded();
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000888 return spi.engineGetParameters();
889 }
890
891 /**
892 * Returns the exemption mechanism object used with this cipher.
893 *
894 * @return the exemption mechanism object used with this cipher, or
895 * null if this cipher does not use any exemption mechanism.
896 */
897 public final ExemptionMechanism getExemptionMechanism() {
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +0000898 updateProviderIfNeeded();
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +0000899 return exmech;
900 }
901
Adam Vartanian11bd3492017-10-20 16:18:34 +0100902 // BEGIN Android-removed: Eliminate crypto permission checking.
903 // Android doesn't implement SecurityManager permissions.
904 /*
905 //
906 // Crypto permission check code below
907 //
908 private void checkCryptoPerm(CipherSpi checkSpi, Key key)
909 throws InvalidKeyException {
910 if (cryptoPerm == CryptoAllPermission.INSTANCE) {
911 return;
912 }
913 // Check if key size and default parameters are within legal limits
914 AlgorithmParameterSpec params;
915 try {
916 params = getAlgorithmParameterSpec(checkSpi.engineGetParameters());
917 } catch (InvalidParameterSpecException ipse) {
918 throw new InvalidKeyException
919 ("Unsupported default algorithm parameters");
920 }
921 if (!passCryptoPermCheck(checkSpi, key, params)) {
922 throw new InvalidKeyException(
923 "Illegal key size or default parameters");
924 }
925 }
926
927 private void checkCryptoPerm(CipherSpi checkSpi, Key key,
928 AlgorithmParameterSpec params) throws InvalidKeyException,
929 InvalidAlgorithmParameterException {
930 if (cryptoPerm == CryptoAllPermission.INSTANCE) {
931 return;
932 }
933 // Determine keysize and check if it is within legal limits
934 if (!passCryptoPermCheck(checkSpi, key, null)) {
935 throw new InvalidKeyException("Illegal key size");
936 }
937 if ((params != null) && (!passCryptoPermCheck(checkSpi, key, params))) {
938 throw new InvalidAlgorithmParameterException("Illegal parameters");
939 }
940 }
941
942 private void checkCryptoPerm(CipherSpi checkSpi, Key key,
943 AlgorithmParameters params)
944 throws InvalidKeyException, InvalidAlgorithmParameterException {
945 if (cryptoPerm == CryptoAllPermission.INSTANCE) {
946 return;
947 }
948 // Convert the specified parameters into specs and then delegate.
949 AlgorithmParameterSpec pSpec;
950 try {
951 pSpec = getAlgorithmParameterSpec(params);
952 } catch (InvalidParameterSpecException ipse) {
953 throw new InvalidAlgorithmParameterException
954 ("Failed to retrieve algorithm parameter specification");
955 }
956 checkCryptoPerm(checkSpi, key, pSpec);
957 }
958
959 private boolean passCryptoPermCheck(CipherSpi checkSpi, Key key,
960 AlgorithmParameterSpec params)
961 throws InvalidKeyException {
962 String em = cryptoPerm.getExemptionMechanism();
963 int keySize = checkSpi.engineGetKeySize(key);
964 // Use the "algorithm" component of the cipher
965 // transformation so that the perm check would
966 // work when the key has the "aliased" algo.
967 String algComponent;
968 int index = transformation.indexOf('/');
969 if (index != -1) {
970 algComponent = transformation.substring(0, index);
971 } else {
972 algComponent = transformation;
973 }
974 CryptoPermission checkPerm =
975 new CryptoPermission(algComponent, keySize, params, em);
976
977 if (!cryptoPerm.implies(checkPerm)) {
978 if (debug != null) {
979 debug.println("Crypto Permission check failed");
980 debug.println("granted: " + cryptoPerm);
981 debug.println("requesting: " + checkPerm);
982 }
983 return false;
984 }
985 if (exmech == null) {
986 return true;
987 }
988 try {
989 if (!exmech.isCryptoAllowed(key)) {
990 if (debug != null) {
991 debug.println(exmech.getName() + " isn't enforced");
992 }
993 return false;
994 }
995 } catch (ExemptionMechanismException eme) {
996 if (debug != null) {
997 debug.println("Cannot determine whether "+
998 exmech.getName() + " has been enforced");
999 eme.printStackTrace();
1000 }
1001 return false;
1002 }
1003 return true;
1004 }
1005 */
1006 // END Android-removed: Eliminate crypto permission checking.
1007
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001008 // check if opmode is one of the defined constants
1009 // throw InvalidParameterExeption if not
1010 private static void checkOpmode(int opmode) {
1011 if ((opmode < ENCRYPT_MODE) || (opmode > UNWRAP_MODE)) {
1012 throw new InvalidParameterException("Invalid operation mode");
1013 }
1014 }
1015
Sergio Giro17982542016-08-03 19:21:52 +01001016 private static String getOpmodeString(int opmode) {
1017 switch (opmode) {
1018 case ENCRYPT_MODE:
1019 return "encryption";
1020 case DECRYPT_MODE:
1021 return "decryption";
1022 case WRAP_MODE:
1023 return "key wrapping";
1024 case UNWRAP_MODE:
1025 return "key unwrapping";
1026 default:
1027 return "";
1028 }
1029 }
1030
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001031 /**
1032 * Initializes this cipher with a key.
1033 *
1034 * <p>The cipher is initialized for one of the following four operations:
1035 * encryption, decryption, key wrapping or key unwrapping, depending
1036 * on the value of <code>opmode</code>.
1037 *
1038 * <p>If this cipher requires any algorithm parameters that cannot be
1039 * derived from the given <code>key</code>, the underlying cipher
1040 * implementation is supposed to generate the required parameters itself
1041 * (using provider-specific default or random values) if it is being
1042 * initialized for encryption or key wrapping, and raise an
1043 * <code>InvalidKeyException</code> if it is being
1044 * initialized for decryption or key unwrapping.
1045 * The generated parameters can be retrieved using
1046 * {@link #getParameters() getParameters} or
1047 * {@link #getIV() getIV} (if the parameter is an IV).
1048 *
1049 * <p>If this cipher requires algorithm parameters that cannot be
1050 * derived from the input parameters, and there are no reasonable
1051 * provider-specific default values, initialization will
1052 * necessarily fail.
1053 *
1054 * <p>If this cipher (including its underlying feedback or padding scheme)
1055 * requires any random bytes (e.g., for parameter generation), it will get
Sergio Giro17982542016-08-03 19:21:52 +01001056 * them using the {@link java.security.SecureRandom}
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001057 * implementation of the highest-priority
1058 * installed provider as the source of randomness.
1059 * (If none of the installed providers supply an implementation of
1060 * SecureRandom, a system-provided source of randomness will be used.)
1061 *
1062 * <p>Note that when a Cipher object is initialized, it loses all
1063 * previously-acquired state. In other words, initializing a Cipher is
1064 * equivalent to creating a new instance of that Cipher and initializing
1065 * it.
1066 *
1067 * @param opmode the operation mode of this cipher (this is one of
1068 * the following:
1069 * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,
1070 * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
1071 * @param key the key
1072 *
1073 * @exception InvalidKeyException if the given key is inappropriate for
1074 * initializing this cipher, or requires
1075 * algorithm parameters that cannot be
1076 * determined from the given key, or if the given key has a keysize that
1077 * exceeds the maximum allowable keysize (as determined from the
1078 * configured jurisdiction policy files).
Sergio Giro17982542016-08-03 19:21:52 +01001079 * @throws UnsupportedOperationException if (@code opmode} is
1080 * {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented
1081 * by the underlying {@code CipherSpi}.
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001082 */
1083 public final void init(int opmode, Key key) throws InvalidKeyException {
1084 init(opmode, key, JceSecurity.RANDOM);
1085 }
1086
1087 /**
1088 * Initializes this cipher with a key and a source of randomness.
1089 *
1090 * <p>The cipher is initialized for one of the following four operations:
1091 * encryption, decryption, key wrapping or key unwrapping, depending
1092 * on the value of <code>opmode</code>.
1093 *
1094 * <p>If this cipher requires any algorithm parameters that cannot be
1095 * derived from the given <code>key</code>, the underlying cipher
1096 * implementation is supposed to generate the required parameters itself
1097 * (using provider-specific default or random values) if it is being
1098 * initialized for encryption or key wrapping, and raise an
1099 * <code>InvalidKeyException</code> if it is being
1100 * initialized for decryption or key unwrapping.
1101 * The generated parameters can be retrieved using
1102 * {@link #getParameters() getParameters} or
1103 * {@link #getIV() getIV} (if the parameter is an IV).
1104 *
1105 * <p>If this cipher requires algorithm parameters that cannot be
1106 * derived from the input parameters, and there are no reasonable
1107 * provider-specific default values, initialization will
1108 * necessarily fail.
1109 *
1110 * <p>If this cipher (including its underlying feedback or padding scheme)
1111 * requires any random bytes (e.g., for parameter generation), it will get
1112 * them from <code>random</code>.
1113 *
1114 * <p>Note that when a Cipher object is initialized, it loses all
1115 * previously-acquired state. In other words, initializing a Cipher is
1116 * equivalent to creating a new instance of that Cipher and initializing
1117 * it.
1118 *
1119 * @param opmode the operation mode of this cipher (this is one of the
1120 * following:
1121 * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,
1122 * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
1123 * @param key the encryption key
1124 * @param random the source of randomness
1125 *
1126 * @exception InvalidKeyException if the given key is inappropriate for
1127 * initializing this cipher, or requires
1128 * algorithm parameters that cannot be
1129 * determined from the given key, or if the given key has a keysize that
1130 * exceeds the maximum allowable keysize (as determined from the
1131 * configured jurisdiction policy files).
Sergio Giro17982542016-08-03 19:21:52 +01001132 * @throws UnsupportedOperationException if (@code opmode} is
1133 * {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented
1134 * by the underlying {@code CipherSpi}.
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001135 */
1136 public final void init(int opmode, Key key, SecureRandom random)
1137 throws InvalidKeyException
1138 {
1139 initialized = false;
1140 checkOpmode(opmode);
1141
Sergio Girodbb107c2016-06-06 18:41:07 +01001142 try {
1143 chooseProvider(InitType.KEY, opmode, key, null, null, random);
1144 } catch (InvalidAlgorithmParameterException e) {
1145 // should never occur
1146 throw new InvalidKeyException(e);
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001147 }
1148
1149 initialized = true;
1150 this.opmode = opmode;
Adam Vartanian11bd3492017-10-20 16:18:34 +01001151
Tobias Thierer9eca2692017-04-12 18:16:06 +01001152 // Android-removed: this debugging mechanism is not used in Android.
1153 /*
Sergio Giro17982542016-08-03 19:21:52 +01001154 if (!skipDebug && pdebug != null) {
1155 pdebug.println("Cipher." + transformation + " " +
1156 getOpmodeString(opmode) + " algorithm from: " +
1157 this.provider.getName());
1158 }
1159 */
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001160 }
1161
1162 /**
1163 * Initializes this cipher with a key and a set of algorithm
1164 * parameters.
1165 *
1166 * <p>The cipher is initialized for one of the following four operations:
1167 * encryption, decryption, key wrapping or key unwrapping, depending
1168 * on the value of <code>opmode</code>.
1169 *
1170 * <p>If this cipher requires any algorithm parameters and
1171 * <code>params</code> is null, the underlying cipher implementation is
1172 * supposed to generate the required parameters itself (using
1173 * provider-specific default or random values) if it is being
1174 * initialized for encryption or key wrapping, and raise an
1175 * <code>InvalidAlgorithmParameterException</code> if it is being
1176 * initialized for decryption or key unwrapping.
1177 * The generated parameters can be retrieved using
1178 * {@link #getParameters() getParameters} or
1179 * {@link #getIV() getIV} (if the parameter is an IV).
1180 *
1181 * <p>If this cipher requires algorithm parameters that cannot be
1182 * derived from the input parameters, and there are no reasonable
1183 * provider-specific default values, initialization will
1184 * necessarily fail.
1185 *
1186 * <p>If this cipher (including its underlying feedback or padding scheme)
1187 * requires any random bytes (e.g., for parameter generation), it will get
Sergio Giro17982542016-08-03 19:21:52 +01001188 * them using the {@link java.security.SecureRandom}
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001189 * implementation of the highest-priority
1190 * installed provider as the source of randomness.
1191 * (If none of the installed providers supply an implementation of
1192 * SecureRandom, a system-provided source of randomness will be used.)
1193 *
1194 * <p>Note that when a Cipher object is initialized, it loses all
1195 * previously-acquired state. In other words, initializing a Cipher is
1196 * equivalent to creating a new instance of that Cipher and initializing
1197 * it.
1198 *
1199 * @param opmode the operation mode of this cipher (this is one of the
1200 * following:
1201 * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,
1202 * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
1203 * @param key the encryption key
1204 * @param params the algorithm parameters
1205 *
1206 * @exception InvalidKeyException if the given key is inappropriate for
1207 * initializing this cipher, or its keysize exceeds the maximum allowable
1208 * keysize (as determined from the configured jurisdiction policy files).
1209 * @exception InvalidAlgorithmParameterException if the given algorithm
1210 * parameters are inappropriate for this cipher,
1211 * or this cipher requires
1212 * algorithm parameters and <code>params</code> is null, or the given
1213 * algorithm parameters imply a cryptographic strength that would exceed
1214 * the legal limits (as determined from the configured jurisdiction
1215 * policy files).
Sergio Giro17982542016-08-03 19:21:52 +01001216 * @throws UnsupportedOperationException if (@code opmode} is
1217 * {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented
1218 * by the underlying {@code CipherSpi}.
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001219 */
1220 public final void init(int opmode, Key key, AlgorithmParameterSpec params)
1221 throws InvalidKeyException, InvalidAlgorithmParameterException
1222 {
1223 init(opmode, key, params, JceSecurity.RANDOM);
1224 }
1225
1226 /**
1227 * Initializes this cipher with a key, a set of algorithm
1228 * parameters, and a source of randomness.
1229 *
1230 * <p>The cipher is initialized for one of the following four operations:
1231 * encryption, decryption, key wrapping or key unwrapping, depending
1232 * on the value of <code>opmode</code>.
1233 *
1234 * <p>If this cipher requires any algorithm parameters and
1235 * <code>params</code> is null, the underlying cipher implementation is
1236 * supposed to generate the required parameters itself (using
1237 * provider-specific default or random values) if it is being
1238 * initialized for encryption or key wrapping, and raise an
1239 * <code>InvalidAlgorithmParameterException</code> if it is being
1240 * initialized for decryption or key unwrapping.
1241 * The generated parameters can be retrieved using
1242 * {@link #getParameters() getParameters} or
1243 * {@link #getIV() getIV} (if the parameter is an IV).
1244 *
1245 * <p>If this cipher requires algorithm parameters that cannot be
1246 * derived from the input parameters, and there are no reasonable
1247 * provider-specific default values, initialization will
1248 * necessarily fail.
1249 *
1250 * <p>If this cipher (including its underlying feedback or padding scheme)
1251 * requires any random bytes (e.g., for parameter generation), it will get
1252 * them from <code>random</code>.
1253 *
1254 * <p>Note that when a Cipher object is initialized, it loses all
1255 * previously-acquired state. In other words, initializing a Cipher is
1256 * equivalent to creating a new instance of that Cipher and initializing
1257 * it.
1258 *
1259 * @param opmode the operation mode of this cipher (this is one of the
1260 * following:
1261 * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,
1262 * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
1263 * @param key the encryption key
1264 * @param params the algorithm parameters
1265 * @param random the source of randomness
1266 *
1267 * @exception InvalidKeyException if the given key is inappropriate for
1268 * initializing this cipher, or its keysize exceeds the maximum allowable
1269 * keysize (as determined from the configured jurisdiction policy files).
1270 * @exception InvalidAlgorithmParameterException if the given algorithm
1271 * parameters are inappropriate for this cipher,
1272 * or this cipher requires
1273 * algorithm parameters and <code>params</code> is null, or the given
1274 * algorithm parameters imply a cryptographic strength that would exceed
1275 * the legal limits (as determined from the configured jurisdiction
1276 * policy files).
Sergio Giro17982542016-08-03 19:21:52 +01001277 * @throws UnsupportedOperationException if (@code opmode} is
1278 * {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented
1279 * by the underlying {@code CipherSpi}.
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001280 */
1281 public final void init(int opmode, Key key, AlgorithmParameterSpec params,
1282 SecureRandom random)
1283 throws InvalidKeyException, InvalidAlgorithmParameterException
1284 {
1285 initialized = false;
1286 checkOpmode(opmode);
1287
Sergio Girodbb107c2016-06-06 18:41:07 +01001288 chooseProvider(InitType.ALGORITHM_PARAM_SPEC, opmode, key, params, null, random);
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001289
1290 initialized = true;
1291 this.opmode = opmode;
Sergio Giro17982542016-08-03 19:21:52 +01001292
Tobias Thierer9eca2692017-04-12 18:16:06 +01001293 // Android-removed: this debugging mechanism is not used in Android.
1294 /*
Sergio Giro17982542016-08-03 19:21:52 +01001295 if (!skipDebug && pdebug != null) {
1296 pdebug.println("Cipher." + transformation + " " +
1297 getOpmodeString(opmode) + " algorithm from: " +
1298 this.provider.getName());
1299 }
1300 */
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001301 }
1302
1303 /**
1304 * Initializes this cipher with a key and a set of algorithm
1305 * parameters.
1306 *
1307 * <p>The cipher is initialized for one of the following four operations:
1308 * encryption, decryption, key wrapping or key unwrapping, depending
1309 * on the value of <code>opmode</code>.
1310 *
1311 * <p>If this cipher requires any algorithm parameters and
1312 * <code>params</code> is null, the underlying cipher implementation is
1313 * supposed to generate the required parameters itself (using
1314 * provider-specific default or random values) if it is being
1315 * initialized for encryption or key wrapping, and raise an
1316 * <code>InvalidAlgorithmParameterException</code> if it is being
1317 * initialized for decryption or key unwrapping.
1318 * The generated parameters can be retrieved using
1319 * {@link #getParameters() getParameters} or
1320 * {@link #getIV() getIV} (if the parameter is an IV).
1321 *
1322 * <p>If this cipher requires algorithm parameters that cannot be
1323 * derived from the input parameters, and there are no reasonable
1324 * provider-specific default values, initialization will
1325 * necessarily fail.
1326 *
1327 * <p>If this cipher (including its underlying feedback or padding scheme)
1328 * requires any random bytes (e.g., for parameter generation), it will get
Sergio Giro17982542016-08-03 19:21:52 +01001329 * them using the {@link java.security.SecureRandom}
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001330 * implementation of the highest-priority
1331 * installed provider as the source of randomness.
1332 * (If none of the installed providers supply an implementation of
1333 * SecureRandom, a system-provided source of randomness will be used.)
1334 *
1335 * <p>Note that when a Cipher object is initialized, it loses all
1336 * previously-acquired state. In other words, initializing a Cipher is
1337 * equivalent to creating a new instance of that Cipher and initializing
1338 * it.
1339 *
1340 * @param opmode the operation mode of this cipher (this is one of the
1341 * following: <code>ENCRYPT_MODE</code>,
1342 * <code>DECRYPT_MODE</code>, <code>WRAP_MODE</code>
1343 * or <code>UNWRAP_MODE</code>)
1344 * @param key the encryption key
1345 * @param params the algorithm parameters
1346 *
1347 * @exception InvalidKeyException if the given key is inappropriate for
1348 * initializing this cipher, or its keysize exceeds the maximum allowable
1349 * keysize (as determined from the configured jurisdiction policy files).
1350 * @exception InvalidAlgorithmParameterException if the given algorithm
1351 * parameters are inappropriate for this cipher,
1352 * or this cipher requires
1353 * algorithm parameters and <code>params</code> is null, or the given
1354 * algorithm parameters imply a cryptographic strength that would exceed
1355 * the legal limits (as determined from the configured jurisdiction
1356 * policy files).
Sergio Giro17982542016-08-03 19:21:52 +01001357 * @throws UnsupportedOperationException if (@code opmode} is
1358 * {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented
1359 * by the underlying {@code CipherSpi}.
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001360 */
1361 public final void init(int opmode, Key key, AlgorithmParameters params)
1362 throws InvalidKeyException, InvalidAlgorithmParameterException
1363 {
1364 init(opmode, key, params, JceSecurity.RANDOM);
1365 }
1366
1367 /**
1368 * Initializes this cipher with a key, a set of algorithm
1369 * parameters, and a source of randomness.
1370 *
1371 * <p>The cipher is initialized for one of the following four operations:
1372 * encryption, decryption, key wrapping or key unwrapping, depending
1373 * on the value of <code>opmode</code>.
1374 *
1375 * <p>If this cipher requires any algorithm parameters and
1376 * <code>params</code> is null, the underlying cipher implementation is
1377 * supposed to generate the required parameters itself (using
1378 * provider-specific default or random values) if it is being
1379 * initialized for encryption or key wrapping, and raise an
1380 * <code>InvalidAlgorithmParameterException</code> if it is being
1381 * initialized for decryption or key unwrapping.
1382 * The generated parameters can be retrieved using
1383 * {@link #getParameters() getParameters} or
1384 * {@link #getIV() getIV} (if the parameter is an IV).
1385 *
1386 * <p>If this cipher requires algorithm parameters that cannot be
1387 * derived from the input parameters, and there are no reasonable
1388 * provider-specific default values, initialization will
1389 * necessarily fail.
1390 *
1391 * <p>If this cipher (including its underlying feedback or padding scheme)
1392 * requires any random bytes (e.g., for parameter generation), it will get
1393 * them from <code>random</code>.
1394 *
1395 * <p>Note that when a Cipher object is initialized, it loses all
1396 * previously-acquired state. In other words, initializing a Cipher is
1397 * equivalent to creating a new instance of that Cipher and initializing
1398 * it.
1399 *
1400 * @param opmode the operation mode of this cipher (this is one of the
1401 * following: <code>ENCRYPT_MODE</code>,
1402 * <code>DECRYPT_MODE</code>, <code>WRAP_MODE</code>
1403 * or <code>UNWRAP_MODE</code>)
1404 * @param key the encryption key
1405 * @param params the algorithm parameters
1406 * @param random the source of randomness
1407 *
1408 * @exception InvalidKeyException if the given key is inappropriate for
1409 * initializing this cipher, or its keysize exceeds the maximum allowable
1410 * keysize (as determined from the configured jurisdiction policy files).
1411 * @exception InvalidAlgorithmParameterException if the given algorithm
1412 * parameters are inappropriate for this cipher,
1413 * or this cipher requires
1414 * algorithm parameters and <code>params</code> is null, or the given
1415 * algorithm parameters imply a cryptographic strength that would exceed
1416 * the legal limits (as determined from the configured jurisdiction
1417 * policy files).
Sergio Giro17982542016-08-03 19:21:52 +01001418 * @throws UnsupportedOperationException if (@code opmode} is
1419 * {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented
1420 * by the underlying {@code CipherSpi}.
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001421 */
1422 public final void init(int opmode, Key key, AlgorithmParameters params,
1423 SecureRandom random)
1424 throws InvalidKeyException, InvalidAlgorithmParameterException
1425 {
1426 initialized = false;
1427 checkOpmode(opmode);
1428
Sergio Girodbb107c2016-06-06 18:41:07 +01001429 chooseProvider(InitType.ALGORITHM_PARAMS, opmode, key, null, params, random);
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001430
1431 initialized = true;
1432 this.opmode = opmode;
Sergio Giro17982542016-08-03 19:21:52 +01001433
Tobias Thierer9eca2692017-04-12 18:16:06 +01001434 // Android-removed: this debugging mechanism is not used in Android.
1435 /*
Sergio Giro17982542016-08-03 19:21:52 +01001436 if (!skipDebug && pdebug != null) {
1437 pdebug.println("Cipher." + transformation + " " +
1438 getOpmodeString(opmode) + " algorithm from: " +
1439 this.provider.getName());
1440 }
1441 */
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001442 }
1443
1444 /**
1445 * Initializes this cipher with the public key from the given certificate.
1446 * <p> The cipher is initialized for one of the following four operations:
1447 * encryption, decryption, key wrapping or key unwrapping, depending
1448 * on the value of <code>opmode</code>.
1449 *
1450 * <p>If the certificate is of type X.509 and has a <i>key usage</i>
1451 * extension field marked as critical, and the value of the <i>key usage</i>
1452 * extension field implies that the public key in
1453 * the certificate and its corresponding private key are not
1454 * supposed to be used for the operation represented by the value
1455 * of <code>opmode</code>,
1456 * an <code>InvalidKeyException</code>
1457 * is thrown.
1458 *
1459 * <p> If this cipher requires any algorithm parameters that cannot be
1460 * derived from the public key in the given certificate, the underlying
1461 * cipher
1462 * implementation is supposed to generate the required parameters itself
1463 * (using provider-specific default or random values) if it is being
1464 * initialized for encryption or key wrapping, and raise an <code>
1465 * InvalidKeyException</code> if it is being initialized for decryption or
1466 * key unwrapping.
1467 * The generated parameters can be retrieved using
1468 * {@link #getParameters() getParameters} or
1469 * {@link #getIV() getIV} (if the parameter is an IV).
1470 *
1471 * <p>If this cipher requires algorithm parameters that cannot be
1472 * derived from the input parameters, and there are no reasonable
1473 * provider-specific default values, initialization will
1474 * necessarily fail.
1475 *
1476 * <p>If this cipher (including its underlying feedback or padding scheme)
1477 * requires any random bytes (e.g., for parameter generation), it will get
1478 * them using the
1479 * <code>SecureRandom</code>
1480 * implementation of the highest-priority
1481 * installed provider as the source of randomness.
1482 * (If none of the installed providers supply an implementation of
1483 * SecureRandom, a system-provided source of randomness will be used.)
1484 *
1485 * <p>Note that when a Cipher object is initialized, it loses all
1486 * previously-acquired state. In other words, initializing a Cipher is
1487 * equivalent to creating a new instance of that Cipher and initializing
1488 * it.
1489 *
1490 * @param opmode the operation mode of this cipher (this is one of the
1491 * following:
1492 * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,
1493 * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
1494 * @param certificate the certificate
1495 *
1496 * @exception InvalidKeyException if the public key in the given
1497 * certificate is inappropriate for initializing this cipher, or this
1498 * cipher requires algorithm parameters that cannot be determined from the
1499 * public key in the given certificate, or the keysize of the public key
1500 * in the given certificate has a keysize that exceeds the maximum
1501 * allowable keysize (as determined by the configured jurisdiction policy
1502 * files).
Sergio Giro17982542016-08-03 19:21:52 +01001503 * @throws UnsupportedOperationException if (@code opmode} is
1504 * {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented
1505 * by the underlying {@code CipherSpi}.
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001506 */
1507 public final void init(int opmode, Certificate certificate)
1508 throws InvalidKeyException
1509 {
1510 init(opmode, certificate, JceSecurity.RANDOM);
1511 }
1512
1513 /**
1514 * Initializes this cipher with the public key from the given certificate
1515 * and
1516 * a source of randomness.
1517 *
1518 * <p>The cipher is initialized for one of the following four operations:
1519 * encryption, decryption, key wrapping
1520 * or key unwrapping, depending on
1521 * the value of <code>opmode</code>.
1522 *
1523 * <p>If the certificate is of type X.509 and has a <i>key usage</i>
1524 * extension field marked as critical, and the value of the <i>key usage</i>
1525 * extension field implies that the public key in
1526 * the certificate and its corresponding private key are not
1527 * supposed to be used for the operation represented by the value of
1528 * <code>opmode</code>,
1529 * an <code>InvalidKeyException</code>
1530 * is thrown.
1531 *
1532 * <p>If this cipher requires any algorithm parameters that cannot be
1533 * derived from the public key in the given <code>certificate</code>,
1534 * the underlying cipher
1535 * implementation is supposed to generate the required parameters itself
1536 * (using provider-specific default or random values) if it is being
1537 * initialized for encryption or key wrapping, and raise an
1538 * <code>InvalidKeyException</code> if it is being
1539 * initialized for decryption or key unwrapping.
1540 * The generated parameters can be retrieved using
1541 * {@link #getParameters() getParameters} or
1542 * {@link #getIV() getIV} (if the parameter is an IV).
1543 *
1544 * <p>If this cipher requires algorithm parameters that cannot be
1545 * derived from the input parameters, and there are no reasonable
1546 * provider-specific default values, initialization will
1547 * necessarily fail.
1548 *
1549 * <p>If this cipher (including its underlying feedback or padding scheme)
1550 * requires any random bytes (e.g., for parameter generation), it will get
1551 * them from <code>random</code>.
1552 *
1553 * <p>Note that when a Cipher object is initialized, it loses all
1554 * previously-acquired state. In other words, initializing a Cipher is
1555 * equivalent to creating a new instance of that Cipher and initializing
1556 * it.
1557 *
1558 * @param opmode the operation mode of this cipher (this is one of the
1559 * following:
1560 * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,
1561 * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
1562 * @param certificate the certificate
1563 * @param random the source of randomness
1564 *
1565 * @exception InvalidKeyException if the public key in the given
1566 * certificate is inappropriate for initializing this cipher, or this
1567 * cipher
1568 * requires algorithm parameters that cannot be determined from the
1569 * public key in the given certificate, or the keysize of the public key
1570 * in the given certificate has a keysize that exceeds the maximum
1571 * allowable keysize (as determined by the configured jurisdiction policy
1572 * files).
Sergio Giro17982542016-08-03 19:21:52 +01001573 * @throws UnsupportedOperationException if (@code opmode} is
1574 * {@code WRAP_MODE} or {@code UNWRAP_MODE} but the mode is not implemented
1575 * by the underlying {@code CipherSpi}.
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001576 */
1577 public final void init(int opmode, Certificate certificate,
1578 SecureRandom random)
Adam Vartanian11bd3492017-10-20 16:18:34 +01001579 throws InvalidKeyException
1580 {
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001581 initialized = false;
1582 checkOpmode(opmode);
1583
1584 // Check key usage if the certificate is of
1585 // type X.509.
1586 if (certificate instanceof java.security.cert.X509Certificate) {
1587 // Check whether the cert has a key usage extension
1588 // marked as a critical extension.
Adam Vartanian11bd3492017-10-20 16:18:34 +01001589 X509Certificate cert = (X509Certificate)certificate;
Sergio Giro17982542016-08-03 19:21:52 +01001590 Set<String> critSet = cert.getCriticalExtensionOIDs();
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001591
1592 if (critSet != null && !critSet.isEmpty()
Adam Vartanian11bd3492017-10-20 16:18:34 +01001593 && critSet.contains(KEY_USAGE_EXTENSION_OID)) {
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001594 boolean[] keyUsageInfo = cert.getKeyUsage();
1595 // keyUsageInfo[2] is for keyEncipherment;
1596 // keyUsageInfo[3] is for dataEncipherment.
1597 if ((keyUsageInfo != null) &&
Adam Vartanian11bd3492017-10-20 16:18:34 +01001598 (((opmode == Cipher.ENCRYPT_MODE) &&
1599 (keyUsageInfo.length > 3) &&
1600 (keyUsageInfo[3] == false)) ||
1601 ((opmode == Cipher.WRAP_MODE) &&
1602 (keyUsageInfo.length > 2) &&
1603 (keyUsageInfo[2] == false)))) {
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001604 throw new InvalidKeyException("Wrong key usage");
1605 }
1606 }
1607 }
1608
1609 PublicKey publicKey =
Adam Vartanian11bd3492017-10-20 16:18:34 +01001610 (certificate==null? null:certificate.getPublicKey());
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001611
Sergio Girodbb107c2016-06-06 18:41:07 +01001612 try {
1613 chooseProvider(InitType.KEY, opmode, (Key) publicKey, null, null, random);
1614 } catch (InvalidAlgorithmParameterException e) {
1615 // should never occur
1616 throw new InvalidKeyException(e);
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001617 }
1618
1619 initialized = true;
1620 this.opmode = opmode;
Sergio Giro17982542016-08-03 19:21:52 +01001621
Tobias Thierer9eca2692017-04-12 18:16:06 +01001622 // Android-removed: this debugging mechanism is not used in Android.
1623 /*
Sergio Giro17982542016-08-03 19:21:52 +01001624 if (!skipDebug && pdebug != null) {
1625 pdebug.println("Cipher." + transformation + " " +
1626 getOpmodeString(opmode) + " algorithm from: " +
1627 this.provider.getName());
1628 }
1629 */
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001630 }
1631
1632 /**
1633 * Ensures that Cipher is in a valid state for update() and doFinal()
1634 * calls - should be initialized and in ENCRYPT_MODE or DECRYPT_MODE.
1635 * @throws IllegalStateException if Cipher object is not in valid state.
1636 */
1637 private void checkCipherState() {
1638 if (!(this instanceof NullCipher)) {
1639 if (!initialized) {
1640 throw new IllegalStateException("Cipher not initialized");
1641 }
1642 if ((opmode != Cipher.ENCRYPT_MODE) &&
1643 (opmode != Cipher.DECRYPT_MODE)) {
1644 throw new IllegalStateException("Cipher not initialized " +
1645 "for encryption/decryption");
1646 }
1647 }
1648 }
1649
1650 /**
1651 * Continues a multiple-part encryption or decryption operation
1652 * (depending on how this cipher was initialized), processing another data
1653 * part.
1654 *
1655 * <p>The bytes in the <code>input</code> buffer are processed, and the
1656 * result is stored in a new buffer.
1657 *
1658 * <p>If <code>input</code> has a length of zero, this method returns
1659 * <code>null</code>.
1660 *
1661 * @param input the input buffer
1662 *
1663 * @return the new buffer with the result, or null if the underlying
1664 * cipher is a block cipher and the input data is too short to result in a
1665 * new block.
1666 *
1667 * @exception IllegalStateException if this cipher is in a wrong state
1668 * (e.g., has not been initialized)
1669 */
1670 public final byte[] update(byte[] input) {
1671 checkCipherState();
1672
1673 // Input sanity check
1674 if (input == null) {
1675 throw new IllegalArgumentException("Null input buffer");
1676 }
1677
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +00001678 updateProviderIfNeeded();
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001679 if (input.length == 0) {
1680 return null;
1681 }
1682 return spi.engineUpdate(input, 0, input.length);
1683 }
1684
1685 /**
1686 * Continues a multiple-part encryption or decryption operation
1687 * (depending on how this cipher was initialized), processing another data
1688 * part.
1689 *
1690 * <p>The first <code>inputLen</code> bytes in the <code>input</code>
1691 * buffer, starting at <code>inputOffset</code> inclusive, are processed,
1692 * and the result is stored in a new buffer.
1693 *
1694 * <p>If <code>inputLen</code> is zero, this method returns
1695 * <code>null</code>.
1696 *
1697 * @param input the input buffer
1698 * @param inputOffset the offset in <code>input</code> where the input
1699 * starts
1700 * @param inputLen the input length
1701 *
1702 * @return the new buffer with the result, or null if the underlying
1703 * cipher is a block cipher and the input data is too short to result in a
1704 * new block.
1705 *
1706 * @exception IllegalStateException if this cipher is in a wrong state
1707 * (e.g., has not been initialized)
1708 */
1709 public final byte[] update(byte[] input, int inputOffset, int inputLen) {
1710 checkCipherState();
1711
1712 // Input sanity check
1713 if (input == null || inputOffset < 0
1714 || inputLen > (input.length - inputOffset) || inputLen < 0) {
1715 throw new IllegalArgumentException("Bad arguments");
1716 }
1717
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +00001718 updateProviderIfNeeded();
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001719 if (inputLen == 0) {
1720 return null;
1721 }
1722 return spi.engineUpdate(input, inputOffset, inputLen);
1723 }
1724
1725 /**
1726 * Continues a multiple-part encryption or decryption operation
1727 * (depending on how this cipher was initialized), processing another data
1728 * part.
1729 *
1730 * <p>The first <code>inputLen</code> bytes in the <code>input</code>
1731 * buffer, starting at <code>inputOffset</code> inclusive, are processed,
1732 * and the result is stored in the <code>output</code> buffer.
1733 *
1734 * <p>If the <code>output</code> buffer is too small to hold the result,
1735 * a <code>ShortBufferException</code> is thrown. In this case, repeat this
1736 * call with a larger output buffer. Use
1737 * {@link #getOutputSize(int) getOutputSize} to determine how big
1738 * the output buffer should be.
1739 *
1740 * <p>If <code>inputLen</code> is zero, this method returns
1741 * a length of zero.
1742 *
1743 * <p>Note: this method should be copy-safe, which means the
1744 * <code>input</code> and <code>output</code> buffers can reference
1745 * the same byte array and no unprocessed input data is overwritten
1746 * when the result is copied into the output buffer.
1747 *
1748 * @param input the input buffer
1749 * @param inputOffset the offset in <code>input</code> where the input
1750 * starts
1751 * @param inputLen the input length
1752 * @param output the buffer for the result
1753 *
1754 * @return the number of bytes stored in <code>output</code>
1755 *
1756 * @exception IllegalStateException if this cipher is in a wrong state
1757 * (e.g., has not been initialized)
1758 * @exception ShortBufferException if the given output buffer is too small
1759 * to hold the result
1760 */
1761 public final int update(byte[] input, int inputOffset, int inputLen,
1762 byte[] output)
1763 throws ShortBufferException {
1764 checkCipherState();
1765
1766 // Input sanity check
1767 if (input == null || inputOffset < 0
1768 || inputLen > (input.length - inputOffset) || inputLen < 0) {
1769 throw new IllegalArgumentException("Bad arguments");
1770 }
1771
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +00001772 updateProviderIfNeeded();
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001773 if (inputLen == 0) {
1774 return 0;
1775 }
1776 return spi.engineUpdate(input, inputOffset, inputLen,
1777 output, 0);
1778 }
1779
1780 /**
1781 * Continues a multiple-part encryption or decryption operation
1782 * (depending on how this cipher was initialized), processing another data
1783 * part.
1784 *
1785 * <p>The first <code>inputLen</code> bytes in the <code>input</code>
1786 * buffer, starting at <code>inputOffset</code> inclusive, are processed,
1787 * and the result is stored in the <code>output</code> buffer, starting at
1788 * <code>outputOffset</code> inclusive.
1789 *
1790 * <p>If the <code>output</code> buffer is too small to hold the result,
1791 * a <code>ShortBufferException</code> is thrown. In this case, repeat this
1792 * call with a larger output buffer. Use
1793 * {@link #getOutputSize(int) getOutputSize} to determine how big
1794 * the output buffer should be.
1795 *
1796 * <p>If <code>inputLen</code> is zero, this method returns
1797 * a length of zero.
1798 *
1799 * <p>Note: this method should be copy-safe, which means the
1800 * <code>input</code> and <code>output</code> buffers can reference
1801 * the same byte array and no unprocessed input data is overwritten
1802 * when the result is copied into the output buffer.
1803 *
1804 * @param input the input buffer
1805 * @param inputOffset the offset in <code>input</code> where the input
1806 * starts
1807 * @param inputLen the input length
1808 * @param output the buffer for the result
1809 * @param outputOffset the offset in <code>output</code> where the result
1810 * is stored
1811 *
1812 * @return the number of bytes stored in <code>output</code>
1813 *
1814 * @exception IllegalStateException if this cipher is in a wrong state
1815 * (e.g., has not been initialized)
1816 * @exception ShortBufferException if the given output buffer is too small
1817 * to hold the result
1818 */
1819 public final int update(byte[] input, int inputOffset, int inputLen,
1820 byte[] output, int outputOffset)
1821 throws ShortBufferException {
1822 checkCipherState();
1823
1824 // Input sanity check
1825 if (input == null || inputOffset < 0
1826 || inputLen > (input.length - inputOffset) || inputLen < 0
1827 || outputOffset < 0) {
1828 throw new IllegalArgumentException("Bad arguments");
1829 }
1830
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +00001831 updateProviderIfNeeded();
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001832 if (inputLen == 0) {
1833 return 0;
1834 }
1835 return spi.engineUpdate(input, inputOffset, inputLen,
1836 output, outputOffset);
1837 }
1838
1839 /**
1840 * Continues a multiple-part encryption or decryption operation
1841 * (depending on how this cipher was initialized), processing another data
1842 * part.
1843 *
1844 * <p>All <code>input.remaining()</code> bytes starting at
1845 * <code>input.position()</code> are processed. The result is stored
1846 * in the output buffer.
1847 * Upon return, the input buffer's position will be equal
1848 * to its limit; its limit will not have changed. The output buffer's
1849 * position will have advanced by n, where n is the value returned
1850 * by this method; the output buffer's limit will not have changed.
1851 *
1852 * <p>If <code>output.remaining()</code> bytes are insufficient to
1853 * hold the result, a <code>ShortBufferException</code> is thrown.
1854 * In this case, repeat this call with a larger output buffer. Use
1855 * {@link #getOutputSize(int) getOutputSize} to determine how big
1856 * the output buffer should be.
1857 *
1858 * <p>Note: this method should be copy-safe, which means the
1859 * <code>input</code> and <code>output</code> buffers can reference
1860 * the same block of memory and no unprocessed input data is overwritten
1861 * when the result is copied into the output buffer.
1862 *
1863 * @param input the input ByteBuffer
1864 * @param output the output ByteByffer
1865 *
1866 * @return the number of bytes stored in <code>output</code>
1867 *
1868 * @exception IllegalStateException if this cipher is in a wrong state
1869 * (e.g., has not been initialized)
1870 * @exception IllegalArgumentException if input and output are the
1871 * same object
1872 * @exception ReadOnlyBufferException if the output buffer is read-only
1873 * @exception ShortBufferException if there is insufficient space in the
1874 * output buffer
1875 * @since 1.5
1876 */
1877 public final int update(ByteBuffer input, ByteBuffer output)
1878 throws ShortBufferException {
1879 checkCipherState();
1880
1881 if ((input == null) || (output == null)) {
1882 throw new IllegalArgumentException("Buffers must not be null");
1883 }
1884 if (input == output) {
1885 throw new IllegalArgumentException("Input and output buffers must "
1886 + "not be the same object, consider using buffer.duplicate()");
1887 }
1888 if (output.isReadOnly()) {
1889 throw new ReadOnlyBufferException();
1890 }
1891
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +00001892 updateProviderIfNeeded();
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001893 return spi.engineUpdate(input, output);
1894 }
1895
1896 /**
1897 * Finishes a multiple-part encryption or decryption operation, depending
1898 * on how this cipher was initialized.
1899 *
1900 * <p>Input data that may have been buffered during a previous
1901 * <code>update</code> operation is processed, with padding (if requested)
1902 * being applied.
1903 * If an AEAD mode such as GCM/CCM is being used, the authentication
1904 * tag is appended in the case of encryption, or verified in the
1905 * case of decryption.
1906 * The result is stored in a new buffer.
1907 *
1908 * <p>Upon finishing, this method resets this cipher object to the state
1909 * it was in when previously initialized via a call to <code>init</code>.
1910 * That is, the object is reset and available to encrypt or decrypt
1911 * (depending on the operation mode that was specified in the call to
1912 * <code>init</code>) more data.
1913 *
1914 * <p>Note: if any exception is thrown, this cipher object may need to
1915 * be reset before it can be used again.
1916 *
1917 * @return the new buffer with the result
1918 *
1919 * @exception IllegalStateException if this cipher is in a wrong state
1920 * (e.g., has not been initialized)
1921 * @exception IllegalBlockSizeException if this cipher is a block cipher,
1922 * no padding has been requested (only in encryption mode), and the total
1923 * input length of the data processed by this cipher is not a multiple of
1924 * block size; or if this encryption algorithm is unable to
1925 * process the input data provided.
1926 * @exception BadPaddingException if this cipher is in decryption mode,
1927 * and (un)padding has been requested, but the decrypted data is not
1928 * bounded by the appropriate padding bytes
1929 * @exception AEADBadTagException if this cipher is decrypting in an
1930 * AEAD mode (such as GCM/CCM), and the received authentication tag
1931 * does not match the calculated value
1932 */
1933 public final byte[] doFinal()
1934 throws IllegalBlockSizeException, BadPaddingException {
1935 checkCipherState();
1936
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +00001937 updateProviderIfNeeded();
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00001938 return spi.engineDoFinal(null, 0, 0);
1939 }
1940
1941 /**
1942 * Finishes a multiple-part encryption or decryption operation, depending
1943 * on how this cipher was initialized.
1944 *
1945 * <p>Input data that may have been buffered during a previous
1946 * <code>update</code> operation is processed, with padding (if requested)
1947 * being applied.
1948 * If an AEAD mode such as GCM/CCM is being used, the authentication
1949 * tag is appended in the case of encryption, or verified in the
1950 * case of decryption.
1951 * The result is stored in the <code>output</code> buffer, starting at
1952 * <code>outputOffset</code> inclusive.
1953 *
1954 * <p>If the <code>output</code> buffer is too small to hold the result,
1955 * a <code>ShortBufferException</code> is thrown. In this case, repeat this
1956 * call with a larger output buffer. Use
1957 * {@link #getOutputSize(int) getOutputSize} to determine how big
1958 * the output buffer should be.
1959 *
1960 * <p>Upon finishing, this method resets this cipher object to the state
1961 * it was in when previously initialized via a call to <code>init</code>.
1962 * That is, the object is reset and available to encrypt or decrypt
1963 * (depending on the operation mode that was specified in the call to
1964 * <code>init</code>) more data.
1965 *
1966 * <p>Note: if any exception is thrown, this cipher object may need to
1967 * be reset before it can be used again.
1968 *
1969 * @param output the buffer for the result
1970 * @param outputOffset the offset in <code>output</code> where the result
1971 * is stored
1972 *
1973 * @return the number of bytes stored in <code>output</code>
1974 *
1975 * @exception IllegalStateException if this cipher is in a wrong state
1976 * (e.g., has not been initialized)
1977 * @exception IllegalBlockSizeException if this cipher is a block cipher,
1978 * no padding has been requested (only in encryption mode), and the total
1979 * input length of the data processed by this cipher is not a multiple of
1980 * block size; or if this encryption algorithm is unable to
1981 * process the input data provided.
1982 * @exception ShortBufferException if the given output buffer is too small
1983 * to hold the result
1984 * @exception BadPaddingException if this cipher is in decryption mode,
1985 * and (un)padding has been requested, but the decrypted data is not
1986 * bounded by the appropriate padding bytes
1987 * @exception AEADBadTagException if this cipher is decrypting in an
1988 * AEAD mode (such as GCM/CCM), and the received authentication tag
1989 * does not match the calculated value
1990 */
1991 public final int doFinal(byte[] output, int outputOffset)
1992 throws IllegalBlockSizeException, ShortBufferException,
1993 BadPaddingException {
1994 checkCipherState();
1995
1996 // Input sanity check
1997 if ((output == null) || (outputOffset < 0)) {
1998 throw new IllegalArgumentException("Bad arguments");
1999 }
2000
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +00002001 updateProviderIfNeeded();
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00002002 return spi.engineDoFinal(null, 0, 0, output, outputOffset);
2003 }
2004
2005 /**
2006 * Encrypts or decrypts data in a single-part operation, or finishes a
2007 * multiple-part operation. The data is encrypted or decrypted,
2008 * depending on how this cipher was initialized.
2009 *
2010 * <p>The bytes in the <code>input</code> buffer, and any input bytes that
2011 * may have been buffered during a previous <code>update</code> operation,
2012 * are processed, with padding (if requested) being applied.
2013 * If an AEAD mode such as GCM/CCM is being used, the authentication
2014 * tag is appended in the case of encryption, or verified in the
2015 * case of decryption.
2016 * The result is stored in a new buffer.
2017 *
2018 * <p>Upon finishing, this method resets this cipher object to the state
2019 * it was in when previously initialized via a call to <code>init</code>.
2020 * That is, the object is reset and available to encrypt or decrypt
2021 * (depending on the operation mode that was specified in the call to
2022 * <code>init</code>) more data.
2023 *
2024 * <p>Note: if any exception is thrown, this cipher object may need to
2025 * be reset before it can be used again.
2026 *
2027 * @param input the input buffer
2028 *
2029 * @return the new buffer with the result
2030 *
2031 * @exception IllegalStateException if this cipher is in a wrong state
2032 * (e.g., has not been initialized)
2033 * @exception IllegalBlockSizeException if this cipher is a block cipher,
2034 * no padding has been requested (only in encryption mode), and the total
2035 * input length of the data processed by this cipher is not a multiple of
2036 * block size; or if this encryption algorithm is unable to
2037 * process the input data provided.
2038 * @exception BadPaddingException if this cipher is in decryption mode,
2039 * and (un)padding has been requested, but the decrypted data is not
2040 * bounded by the appropriate padding bytes
2041 * @exception AEADBadTagException if this cipher is decrypting in an
2042 * AEAD mode (such as GCM/CCM), and the received authentication tag
2043 * does not match the calculated value
2044 */
2045 public final byte[] doFinal(byte[] input)
2046 throws IllegalBlockSizeException, BadPaddingException {
2047 checkCipherState();
2048
2049 // Input sanity check
2050 if (input == null) {
2051 throw new IllegalArgumentException("Null input buffer");
2052 }
2053
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +00002054 updateProviderIfNeeded();
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00002055 return spi.engineDoFinal(input, 0, input.length);
2056 }
2057
2058 /**
2059 * Encrypts or decrypts data in a single-part operation, or finishes a
2060 * multiple-part operation. The data is encrypted or decrypted,
2061 * depending on how this cipher was initialized.
2062 *
2063 * <p>The first <code>inputLen</code> bytes in the <code>input</code>
2064 * buffer, starting at <code>inputOffset</code> inclusive, and any input
2065 * bytes that may have been buffered during a previous <code>update</code>
2066 * operation, are processed, with padding (if requested) being applied.
2067 * If an AEAD mode such as GCM/CCM is being used, the authentication
2068 * tag is appended in the case of encryption, or verified in the
2069 * case of decryption.
2070 * The result is stored in a new buffer.
2071 *
2072 * <p>Upon finishing, this method resets this cipher object to the state
2073 * it was in when previously initialized via a call to <code>init</code>.
2074 * That is, the object is reset and available to encrypt or decrypt
2075 * (depending on the operation mode that was specified in the call to
2076 * <code>init</code>) more data.
2077 *
2078 * <p>Note: if any exception is thrown, this cipher object may need to
2079 * be reset before it can be used again.
2080 *
2081 * @param input the input buffer
2082 * @param inputOffset the offset in <code>input</code> where the input
2083 * starts
2084 * @param inputLen the input length
2085 *
2086 * @return the new buffer with the result
2087 *
2088 * @exception IllegalStateException if this cipher is in a wrong state
2089 * (e.g., has not been initialized)
2090 * @exception IllegalBlockSizeException if this cipher is a block cipher,
2091 * no padding has been requested (only in encryption mode), and the total
2092 * input length of the data processed by this cipher is not a multiple of
2093 * block size; or if this encryption algorithm is unable to
2094 * process the input data provided.
2095 * @exception BadPaddingException if this cipher is in decryption mode,
2096 * and (un)padding has been requested, but the decrypted data is not
2097 * bounded by the appropriate padding bytes
2098 * @exception AEADBadTagException if this cipher is decrypting in an
2099 * AEAD mode (such as GCM/CCM), and the received authentication tag
2100 * does not match the calculated value
2101 */
2102 public final byte[] doFinal(byte[] input, int inputOffset, int inputLen)
2103 throws IllegalBlockSizeException, BadPaddingException {
2104 checkCipherState();
2105
2106 // Input sanity check
2107 if (input == null || inputOffset < 0
2108 || inputLen > (input.length - inputOffset) || inputLen < 0) {
2109 throw new IllegalArgumentException("Bad arguments");
2110 }
2111
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +00002112 updateProviderIfNeeded();
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00002113 return spi.engineDoFinal(input, inputOffset, inputLen);
2114 }
2115
2116 /**
2117 * Encrypts or decrypts data in a single-part operation, or finishes a
2118 * multiple-part operation. The data is encrypted or decrypted,
2119 * depending on how this cipher was initialized.
2120 *
2121 * <p>The first <code>inputLen</code> bytes in the <code>input</code>
2122 * buffer, starting at <code>inputOffset</code> inclusive, and any input
2123 * bytes that may have been buffered during a previous <code>update</code>
2124 * operation, are processed, with padding (if requested) being applied.
2125 * If an AEAD mode such as GCM/CCM is being used, the authentication
2126 * tag is appended in the case of encryption, or verified in the
2127 * case of decryption.
2128 * The result is stored in the <code>output</code> buffer.
2129 *
2130 * <p>If the <code>output</code> buffer is too small to hold the result,
2131 * a <code>ShortBufferException</code> is thrown. In this case, repeat this
2132 * call with a larger output buffer. Use
2133 * {@link #getOutputSize(int) getOutputSize} to determine how big
2134 * the output buffer should be.
2135 *
2136 * <p>Upon finishing, this method resets this cipher object to the state
2137 * it was in when previously initialized via a call to <code>init</code>.
2138 * That is, the object is reset and available to encrypt or decrypt
2139 * (depending on the operation mode that was specified in the call to
2140 * <code>init</code>) more data.
2141 *
2142 * <p>Note: if any exception is thrown, this cipher object may need to
2143 * be reset before it can be used again.
2144 *
2145 * <p>Note: this method should be copy-safe, which means the
2146 * <code>input</code> and <code>output</code> buffers can reference
2147 * the same byte array and no unprocessed input data is overwritten
2148 * when the result is copied into the output buffer.
2149 *
2150 * @param input the input buffer
2151 * @param inputOffset the offset in <code>input</code> where the input
2152 * starts
2153 * @param inputLen the input length
2154 * @param output the buffer for the result
2155 *
2156 * @return the number of bytes stored in <code>output</code>
2157 *
2158 * @exception IllegalStateException if this cipher is in a wrong state
2159 * (e.g., has not been initialized)
2160 * @exception IllegalBlockSizeException if this cipher is a block cipher,
2161 * no padding has been requested (only in encryption mode), and the total
2162 * input length of the data processed by this cipher is not a multiple of
2163 * block size; or if this encryption algorithm is unable to
2164 * process the input data provided.
2165 * @exception ShortBufferException if the given output buffer is too small
2166 * to hold the result
2167 * @exception BadPaddingException if this cipher is in decryption mode,
2168 * and (un)padding has been requested, but the decrypted data is not
2169 * bounded by the appropriate padding bytes
2170 * @exception AEADBadTagException if this cipher is decrypting in an
2171 * AEAD mode (such as GCM/CCM), and the received authentication tag
2172 * does not match the calculated value
2173 */
2174 public final int doFinal(byte[] input, int inputOffset, int inputLen,
2175 byte[] output)
2176 throws ShortBufferException, IllegalBlockSizeException,
2177 BadPaddingException {
2178 checkCipherState();
2179
2180 // Input sanity check
2181 if (input == null || inputOffset < 0
2182 || inputLen > (input.length - inputOffset) || inputLen < 0) {
2183 throw new IllegalArgumentException("Bad arguments");
2184 }
2185
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +00002186 updateProviderIfNeeded();
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00002187 return spi.engineDoFinal(input, inputOffset, inputLen,
2188 output, 0);
2189 }
2190
2191 /**
2192 * Encrypts or decrypts data in a single-part operation, or finishes a
2193 * multiple-part operation. The data is encrypted or decrypted,
2194 * depending on how this cipher was initialized.
2195 *
2196 * <p>The first <code>inputLen</code> bytes in the <code>input</code>
2197 * buffer, starting at <code>inputOffset</code> inclusive, and any input
2198 * bytes that may have been buffered during a previous
2199 * <code>update</code> operation, are processed, with padding
2200 * (if requested) being applied.
2201 * If an AEAD mode such as GCM/CCM is being used, the authentication
2202 * tag is appended in the case of encryption, or verified in the
2203 * case of decryption.
2204 * The result is stored in the <code>output</code> buffer, starting at
2205 * <code>outputOffset</code> inclusive.
2206 *
2207 * <p>If the <code>output</code> buffer is too small to hold the result,
2208 * a <code>ShortBufferException</code> is thrown. In this case, repeat this
2209 * call with a larger output buffer. Use
2210 * {@link #getOutputSize(int) getOutputSize} to determine how big
2211 * the output buffer should be.
2212 *
2213 * <p>Upon finishing, this method resets this cipher object to the state
2214 * it was in when previously initialized via a call to <code>init</code>.
2215 * That is, the object is reset and available to encrypt or decrypt
2216 * (depending on the operation mode that was specified in the call to
2217 * <code>init</code>) more data.
2218 *
2219 * <p>Note: if any exception is thrown, this cipher object may need to
2220 * be reset before it can be used again.
2221 *
2222 * <p>Note: this method should be copy-safe, which means the
2223 * <code>input</code> and <code>output</code> buffers can reference
2224 * the same byte array and no unprocessed input data is overwritten
2225 * when the result is copied into the output buffer.
2226 *
2227 * @param input the input buffer
2228 * @param inputOffset the offset in <code>input</code> where the input
2229 * starts
2230 * @param inputLen the input length
2231 * @param output the buffer for the result
2232 * @param outputOffset the offset in <code>output</code> where the result
2233 * is stored
2234 *
2235 * @return the number of bytes stored in <code>output</code>
2236 *
2237 * @exception IllegalStateException if this cipher is in a wrong state
2238 * (e.g., has not been initialized)
2239 * @exception IllegalBlockSizeException if this cipher is a block cipher,
2240 * no padding has been requested (only in encryption mode), and the total
2241 * input length of the data processed by this cipher is not a multiple of
2242 * block size; or if this encryption algorithm is unable to
2243 * process the input data provided.
2244 * @exception ShortBufferException if the given output buffer is too small
2245 * to hold the result
2246 * @exception BadPaddingException if this cipher is in decryption mode,
2247 * and (un)padding has been requested, but the decrypted data is not
2248 * bounded by the appropriate padding bytes
2249 * @exception AEADBadTagException if this cipher is decrypting in an
2250 * AEAD mode (such as GCM/CCM), and the received authentication tag
2251 * does not match the calculated value
2252 */
2253 public final int doFinal(byte[] input, int inputOffset, int inputLen,
2254 byte[] output, int outputOffset)
2255 throws ShortBufferException, IllegalBlockSizeException,
2256 BadPaddingException {
2257 checkCipherState();
2258
2259 // Input sanity check
2260 if (input == null || inputOffset < 0
2261 || inputLen > (input.length - inputOffset) || inputLen < 0
2262 || outputOffset < 0) {
2263 throw new IllegalArgumentException("Bad arguments");
2264 }
2265
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +00002266 updateProviderIfNeeded();
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00002267 return spi.engineDoFinal(input, inputOffset, inputLen,
2268 output, outputOffset);
2269 }
2270
2271 /**
2272 * Encrypts or decrypts data in a single-part operation, or finishes a
2273 * multiple-part operation. The data is encrypted or decrypted,
2274 * depending on how this cipher was initialized.
2275 *
2276 * <p>All <code>input.remaining()</code> bytes starting at
2277 * <code>input.position()</code> are processed.
2278 * If an AEAD mode such as GCM/CCM is being used, the authentication
2279 * tag is appended in the case of encryption, or verified in the
2280 * case of decryption.
2281 * The result is stored in the output buffer.
2282 * Upon return, the input buffer's position will be equal
2283 * to its limit; its limit will not have changed. The output buffer's
2284 * position will have advanced by n, where n is the value returned
2285 * by this method; the output buffer's limit will not have changed.
2286 *
2287 * <p>If <code>output.remaining()</code> bytes are insufficient to
2288 * hold the result, a <code>ShortBufferException</code> is thrown.
2289 * In this case, repeat this call with a larger output buffer. Use
2290 * {@link #getOutputSize(int) getOutputSize} to determine how big
2291 * the output buffer should be.
2292 *
2293 * <p>Upon finishing, this method resets this cipher object to the state
2294 * it was in when previously initialized via a call to <code>init</code>.
2295 * That is, the object is reset and available to encrypt or decrypt
2296 * (depending on the operation mode that was specified in the call to
2297 * <code>init</code>) more data.
2298 *
2299 * <p>Note: if any exception is thrown, this cipher object may need to
2300 * be reset before it can be used again.
2301 *
2302 * <p>Note: this method should be copy-safe, which means the
2303 * <code>input</code> and <code>output</code> buffers can reference
2304 * the same byte array and no unprocessed input data is overwritten
2305 * when the result is copied into the output buffer.
2306 *
2307 * @param input the input ByteBuffer
2308 * @param output the output ByteBuffer
2309 *
2310 * @return the number of bytes stored in <code>output</code>
2311 *
2312 * @exception IllegalStateException if this cipher is in a wrong state
2313 * (e.g., has not been initialized)
2314 * @exception IllegalArgumentException if input and output are the
2315 * same object
2316 * @exception ReadOnlyBufferException if the output buffer is read-only
2317 * @exception IllegalBlockSizeException if this cipher is a block cipher,
2318 * no padding has been requested (only in encryption mode), and the total
2319 * input length of the data processed by this cipher is not a multiple of
2320 * block size; or if this encryption algorithm is unable to
2321 * process the input data provided.
2322 * @exception ShortBufferException if there is insufficient space in the
2323 * output buffer
2324 * @exception BadPaddingException if this cipher is in decryption mode,
2325 * and (un)padding has been requested, but the decrypted data is not
2326 * bounded by the appropriate padding bytes
2327 * @exception AEADBadTagException if this cipher is decrypting in an
2328 * AEAD mode (such as GCM/CCM), and the received authentication tag
2329 * does not match the calculated value
2330 *
2331 * @since 1.5
2332 */
2333 public final int doFinal(ByteBuffer input, ByteBuffer output)
2334 throws ShortBufferException, IllegalBlockSizeException,
2335 BadPaddingException {
2336 checkCipherState();
2337
2338 if ((input == null) || (output == null)) {
2339 throw new IllegalArgumentException("Buffers must not be null");
2340 }
2341 if (input == output) {
2342 throw new IllegalArgumentException("Input and output buffers must "
2343 + "not be the same object, consider using buffer.duplicate()");
2344 }
2345 if (output.isReadOnly()) {
2346 throw new ReadOnlyBufferException();
2347 }
2348
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +00002349 updateProviderIfNeeded();
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00002350 return spi.engineDoFinal(input, output);
2351 }
2352
2353 /**
2354 * Wrap a key.
2355 *
2356 * @param key the key to be wrapped.
2357 *
2358 * @return the wrapped key.
2359 *
2360 * @exception IllegalStateException if this cipher is in a wrong
2361 * state (e.g., has not been initialized).
2362 *
2363 * @exception IllegalBlockSizeException if this cipher is a block
2364 * cipher, no padding has been requested, and the length of the
2365 * encoding of the key to be wrapped is not a
2366 * multiple of the block size.
2367 *
2368 * @exception InvalidKeyException if it is impossible or unsafe to
2369 * wrap the key with this cipher (e.g., a hardware protected key is
2370 * being passed to a software-only cipher).
Sergio Giro17982542016-08-03 19:21:52 +01002371 *
2372 * @throws UnsupportedOperationException if the corresponding method in the
2373 * {@code CipherSpi} is not supported.
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00002374 */
2375 public final byte[] wrap(Key key)
2376 throws IllegalBlockSizeException, InvalidKeyException {
2377 if (!(this instanceof NullCipher)) {
2378 if (!initialized) {
2379 throw new IllegalStateException("Cipher not initialized");
2380 }
2381 if (opmode != Cipher.WRAP_MODE) {
2382 throw new IllegalStateException("Cipher not initialized " +
2383 "for wrapping keys");
2384 }
2385 }
2386
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +00002387 updateProviderIfNeeded();
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00002388 return spi.engineWrap(key);
2389 }
2390
2391 /**
2392 * Unwrap a previously wrapped key.
2393 *
2394 * @param wrappedKey the key to be unwrapped.
2395 *
2396 * @param wrappedKeyAlgorithm the algorithm associated with the wrapped
2397 * key.
2398 *
2399 * @param wrappedKeyType the type of the wrapped key. This must be one of
2400 * <code>SECRET_KEY</code>, <code>PRIVATE_KEY</code>, or
2401 * <code>PUBLIC_KEY</code>.
2402 *
2403 * @return the unwrapped key.
2404 *
2405 * @exception IllegalStateException if this cipher is in a wrong state
2406 * (e.g., has not been initialized).
2407 *
2408 * @exception NoSuchAlgorithmException if no installed providers
2409 * can create keys of type <code>wrappedKeyType</code> for the
2410 * <code>wrappedKeyAlgorithm</code>.
2411 *
2412 * @exception InvalidKeyException if <code>wrappedKey</code> does not
2413 * represent a wrapped key of type <code>wrappedKeyType</code> for
2414 * the <code>wrappedKeyAlgorithm</code>.
Sergio Giro17982542016-08-03 19:21:52 +01002415 *
2416 * @throws UnsupportedOperationException if the corresponding method in the
2417 * {@code CipherSpi} is not supported.
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00002418 */
2419 public final Key unwrap(byte[] wrappedKey,
2420 String wrappedKeyAlgorithm,
2421 int wrappedKeyType)
2422 throws InvalidKeyException, NoSuchAlgorithmException {
2423
2424 if (!(this instanceof NullCipher)) {
2425 if (!initialized) {
2426 throw new IllegalStateException("Cipher not initialized");
2427 }
2428 if (opmode != Cipher.UNWRAP_MODE) {
2429 throw new IllegalStateException("Cipher not initialized " +
2430 "for unwrapping keys");
2431 }
2432 }
2433 if ((wrappedKeyType != SECRET_KEY) &&
2434 (wrappedKeyType != PRIVATE_KEY) &&
2435 (wrappedKeyType != PUBLIC_KEY)) {
2436 throw new InvalidParameterException("Invalid key type");
2437 }
2438
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +00002439 updateProviderIfNeeded();
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00002440 return spi.engineUnwrap(wrappedKey,
2441 wrappedKeyAlgorithm,
2442 wrappedKeyType);
2443 }
2444
2445 private AlgorithmParameterSpec getAlgorithmParameterSpec(
2446 AlgorithmParameters params)
2447 throws InvalidParameterSpecException {
2448 if (params == null) {
2449 return null;
2450 }
2451
2452 String alg = params.getAlgorithm().toUpperCase(Locale.ENGLISH);
2453
2454 if (alg.equalsIgnoreCase("RC2")) {
2455 return params.getParameterSpec(RC2ParameterSpec.class);
2456 }
2457
2458 if (alg.equalsIgnoreCase("RC5")) {
2459 return params.getParameterSpec(RC5ParameterSpec.class);
2460 }
2461
2462 if (alg.startsWith("PBE")) {
2463 return params.getParameterSpec(PBEParameterSpec.class);
2464 }
2465
2466 if (alg.startsWith("DES")) {
2467 return params.getParameterSpec(IvParameterSpec.class);
2468 }
2469 return null;
2470 }
2471
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00002472 /**
2473 * Returns the maximum key length for the specified transformation
2474 * according to the installed JCE jurisdiction policy files. If
2475 * JCE unlimited strength jurisdiction policy files are installed,
2476 * Integer.MAX_VALUE will be returned.
2477 * For more information on default key size in JCE jurisdiction
2478 * policy files, please see Appendix E in the
2479 * <a href=
Tobias Thierer6bd07db2019-04-03 18:06:18 +01002480 * "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppC">
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00002481 * Java Cryptography Architecture Reference Guide</a>.
2482 *
2483 * @param transformation the cipher transformation.
2484 * @return the maximum key length in bits or Integer.MAX_VALUE.
2485 * @exception NullPointerException if <code>transformation</code> is null.
2486 * @exception NoSuchAlgorithmException if <code>transformation</code>
2487 * is not a valid transformation, i.e. in the form of "algorithm" or
2488 * "algorithm/mode/padding".
2489 * @since 1.5
2490 */
2491 public static final int getMaxAllowedKeyLength(String transformation)
2492 throws NoSuchAlgorithmException {
Tobias Thierer9eca2692017-04-12 18:16:06 +01002493 // Android-changed: Remove references to CryptoPermission.
2494 // Throw early if transformation == null or isn't valid.
Piotr Jastrzebskifa68edd2015-04-10 14:14:00 +01002495 //
2496 // CryptoPermission cp = getConfiguredPermission(transformation);
2497 // return cp.getMaxAllowedKeyLength();
2498 if (transformation == null) {
2499 throw new NullPointerException("transformation == null");
2500 }
2501 // Throws NoSuchAlgorithmException if necessary.
2502 tokenizeTransformation(transformation);
Piotr Jastrzebski9af80462015-02-24 15:48:00 +00002503 return Integer.MAX_VALUE;
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00002504 }
2505
2506 /**
2507 * Returns an AlgorithmParameterSpec object which contains
2508 * the maximum cipher parameter value according to the
2509 * jurisdiction policy file. If JCE unlimited strength jurisdiction
2510 * policy files are installed or there is no maximum limit on the
2511 * parameters for the specified transformation in the policy file,
2512 * null will be returned.
2513 *
2514 * @param transformation the cipher transformation.
2515 * @return an AlgorithmParameterSpec which holds the maximum
2516 * value or null.
2517 * @exception NullPointerException if <code>transformation</code>
2518 * is null.
2519 * @exception NoSuchAlgorithmException if <code>transformation</code>
2520 * is not a valid transformation, i.e. in the form of "algorithm" or
2521 * "algorithm/mode/padding".
2522 * @since 1.5
2523 */
2524 public static final AlgorithmParameterSpec getMaxAllowedParameterSpec(
2525 String transformation) throws NoSuchAlgorithmException {
Tobias Thierer9eca2692017-04-12 18:16:06 +01002526 // Android-changed: Remove references to CryptoPermission.
2527 // Throw early if transformation == null or isn't valid.
Piotr Jastrzebskifa68edd2015-04-10 14:14:00 +01002528 //
2529 // CryptoPermission cp = getConfiguredPermission(transformation);
2530 // return cp.getAlgorithmParameterSpec();
2531 if (transformation == null) {
2532 throw new NullPointerException("transformation == null");
2533 }
2534 // Throws NoSuchAlgorithmException if necessary.
2535 tokenizeTransformation(transformation);
Piotr Jastrzebski9af80462015-02-24 15:48:00 +00002536 return null;
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00002537 }
2538
2539 /**
2540 * Continues a multi-part update of the Additional Authentication
2541 * Data (AAD).
2542 * <p>
2543 * Calls to this method provide AAD to the cipher when operating in
2544 * modes such as AEAD (GCM/CCM). If this cipher is operating in
2545 * either GCM or CCM mode, all AAD must be supplied before beginning
2546 * operations on the ciphertext (via the {@code update} and {@code
2547 * doFinal} methods).
2548 *
2549 * @param src the buffer containing the Additional Authentication Data
2550 *
2551 * @throws IllegalArgumentException if the {@code src}
2552 * byte array is null
2553 * @throws IllegalStateException if this cipher is in a wrong state
2554 * (e.g., has not been initialized), does not accept AAD, or if
2555 * operating in either GCM or CCM mode and one of the {@code update}
2556 * methods has already been called for the active
2557 * encryption/decryption operation
2558 * @throws UnsupportedOperationException if the corresponding method
2559 * in the {@code CipherSpi} has not been overridden by an
2560 * implementation
2561 *
2562 * @since 1.7
2563 */
2564 public final void updateAAD(byte[] src) {
2565 if (src == null) {
2566 throw new IllegalArgumentException("src buffer is null");
2567 }
2568
2569 updateAAD(src, 0, src.length);
2570 }
2571
2572 /**
2573 * Continues a multi-part update of the Additional Authentication
2574 * Data (AAD), using a subset of the provided buffer.
2575 * <p>
2576 * Calls to this method provide AAD to the cipher when operating in
2577 * modes such as AEAD (GCM/CCM). If this cipher is operating in
2578 * either GCM or CCM mode, all AAD must be supplied before beginning
2579 * operations on the ciphertext (via the {@code update} and {@code
2580 * doFinal} methods).
2581 *
2582 * @param src the buffer containing the AAD
2583 * @param offset the offset in {@code src} where the AAD input starts
2584 * @param len the number of AAD bytes
2585 *
2586 * @throws IllegalArgumentException if the {@code src}
2587 * byte array is null, or the {@code offset} or {@code length}
2588 * is less than 0, or the sum of the {@code offset} and
2589 * {@code len} is greater than the length of the
2590 * {@code src} byte array
2591 * @throws IllegalStateException if this cipher is in a wrong state
2592 * (e.g., has not been initialized), does not accept AAD, or if
2593 * operating in either GCM or CCM mode and one of the {@code update}
2594 * methods has already been called for the active
2595 * encryption/decryption operation
2596 * @throws UnsupportedOperationException if the corresponding method
2597 * in the {@code CipherSpi} has not been overridden by an
2598 * implementation
2599 *
2600 * @since 1.7
2601 */
2602 public final void updateAAD(byte[] src, int offset, int len) {
2603 checkCipherState();
2604
2605 // Input sanity check
2606 if ((src == null) || (offset < 0) || (len < 0)
2607 || ((len + offset) > src.length)) {
2608 throw new IllegalArgumentException("Bad arguments");
2609 }
2610
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +00002611 updateProviderIfNeeded();
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00002612 if (len == 0) {
2613 return;
2614 }
2615 spi.engineUpdateAAD(src, offset, len);
2616 }
2617
2618 /**
2619 * Continues a multi-part update of the Additional Authentication
2620 * Data (AAD).
2621 * <p>
2622 * Calls to this method provide AAD to the cipher when operating in
2623 * modes such as AEAD (GCM/CCM). If this cipher is operating in
2624 * either GCM or CCM mode, all AAD must be supplied before beginning
2625 * operations on the ciphertext (via the {@code update} and {@code
2626 * doFinal} methods).
2627 * <p>
2628 * All {@code src.remaining()} bytes starting at
2629 * {@code src.position()} are processed.
2630 * Upon return, the input buffer's position will be equal
2631 * to its limit; its limit will not have changed.
2632 *
2633 * @param src the buffer containing the AAD
2634 *
2635 * @throws IllegalArgumentException if the {@code src ByteBuffer}
2636 * is null
2637 * @throws IllegalStateException if this cipher is in a wrong state
2638 * (e.g., has not been initialized), does not accept AAD, or if
2639 * operating in either GCM or CCM mode and one of the {@code update}
2640 * methods has already been called for the active
2641 * encryption/decryption operation
2642 * @throws UnsupportedOperationException if the corresponding method
2643 * in the {@code CipherSpi} has not been overridden by an
2644 * implementation
2645 *
2646 * @since 1.7
2647 */
2648 public final void updateAAD(ByteBuffer src) {
2649 checkCipherState();
2650
2651 // Input sanity check
2652 if (src == null) {
2653 throw new IllegalArgumentException("src ByteBuffer is null");
2654 }
2655
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +00002656 updateProviderIfNeeded();
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00002657 if (src.remaining() == 0) {
2658 return;
2659 }
2660 spi.engineUpdateAAD(src);
2661 }
Przemyslaw Szczepaniak68571892015-09-28 16:24:00 +01002662
Adam Vartanian11bd3492017-10-20 16:18:34 +01002663 // BEGIN Android-added: Bulk of the new provider implementation.
2664 // See note at top of class.
Przemyslaw Szczepaniak68571892015-09-28 16:24:00 +01002665 /**
2666 * Returns the {@code CipherSpi} backing this {@code Cipher} or {@code null} if no
2667 * {@code CipherSpi} is backing this {@code Cipher}.
2668 *
2669 * @hide
2670 */
2671 public CipherSpi getCurrentSpi() {
2672 return spi;
2673 }
Przemyslaw Szczepaniak9f3f2502016-01-21 15:20:15 +00002674
2675 /** The attribute used for supported paddings. */
2676 private static final String ATTRIBUTE_PADDINGS = "SupportedPaddings";
2677
2678 /** The attribute used for supported modes. */
2679 private static final String ATTRIBUTE_MODES = "SupportedModes";
2680
2681 /**
2682 * If the attribute listed exists, check that it matches the regular
2683 * expression.
2684 */
2685 static boolean matchAttribute(Provider.Service service, String attr, String value) {
2686 if (value == null) {
2687 return true;
2688 }
2689 final String pattern = service.getAttribute(attr);
2690 if (pattern == null) {
2691 return true;
2692 }
2693 final String valueUc = value.toUpperCase(Locale.US);
2694 return valueUc.matches(pattern.toUpperCase(Locale.US));
2695 }
2696
2697 /** Items that need to be set on the Cipher instance. */
2698 enum NeedToSet {
2699 NONE, MODE, PADDING, BOTH,
2700 }
2701
2702 /**
2703 * Expresses the various types of transforms that may be used during
2704 * initialization.
2705 */
2706 static class Transform {
2707 private final String name;
2708 private final NeedToSet needToSet;
2709
2710 public Transform(String name, NeedToSet needToSet) {
2711 this.name = name;
2712 this.needToSet = needToSet;
2713 }
2714 }
2715
2716 /**
2717 * Keeps track of the possible arguments to {@code Cipher#init(...)}.
2718 */
2719 static class InitParams {
2720 final InitType initType;
2721 final int opmode;
2722 final Key key;
2723 final SecureRandom random;
2724 final AlgorithmParameterSpec spec;
2725 final AlgorithmParameters params;
2726
2727 InitParams(InitType initType, int opmode, Key key, SecureRandom random,
2728 AlgorithmParameterSpec spec, AlgorithmParameters params) {
2729 this.initType = initType;
2730 this.opmode = opmode;
2731 this.key = key;
2732 this.random = random;
2733 this.spec = spec;
2734 this.params = params;
2735 }
2736 }
2737
2738 /**
2739 * Used to keep track of which underlying {@code CipherSpi#engineInit(...)}
2740 * variant to call when testing suitability.
2741 */
2742 static enum InitType {
2743 KEY, ALGORITHM_PARAMS, ALGORITHM_PARAM_SPEC,
2744 }
2745
2746 class SpiAndProviderUpdater {
2747 /**
2748 * Lock held while the SPI is initializing.
2749 */
2750 private final Object initSpiLock = new Object();
2751
2752 /**
2753 * The provider specified when instance created.
2754 */
2755 private final Provider specifiedProvider;
2756
2757 /**
2758 * The SPI implementation.
2759 */
2760 private final CipherSpi specifiedSpi;
2761
2762 SpiAndProviderUpdater(Provider specifiedProvider, CipherSpi specifiedSpi) {
2763 this.specifiedProvider = specifiedProvider;
2764 this.specifiedSpi = specifiedSpi;
2765 }
2766
2767 void setCipherSpiImplAndProvider(CipherSpi cipherSpi, Provider provider) {
2768 Cipher.this.spi = cipherSpi;
2769 Cipher.this.provider = provider;
2770 }
2771
2772 /**
2773 * Makes sure a CipherSpi that matches this type is selected. If
2774 * {@code key != null} then it assumes that a suitable provider exists for
2775 * this instance (used by {@link Cipher#init}. If the {@code initParams} is passed
2776 * in, then the {@code CipherSpi} returned will be initialized.
2777 *
2778 * @throws InvalidKeyException if the specified key cannot be used to
2779 * initialize this cipher.
2780 */
2781 CipherSpiAndProvider updateAndGetSpiAndProvider(
2782 InitParams initParams,
2783 CipherSpi spiImpl,
2784 Provider provider)
2785 throws InvalidKeyException, InvalidAlgorithmParameterException {
2786 if (specifiedSpi != null) {
2787 return new CipherSpiAndProvider(specifiedSpi, provider);
2788 }
2789 synchronized (initSpiLock) {
2790 // This is not only a matter of performance. Many methods like update, doFinal, etc.
2791 // call {@code #getSpi()} (ie, {@code #getSpi(null /* params */)}) and without this
2792 // shortcut they would override an spi that was chosen using the key.
2793 if (spiImpl != null && initParams == null) {
2794 return new CipherSpiAndProvider(spiImpl, provider);
2795 }
2796 final CipherSpiAndProvider sap = tryCombinations(
2797 initParams, specifiedProvider, tokenizedTransformation);
2798 if (sap == null) {
2799 throw new ProviderException("No provider found for "
2800 + Arrays.toString(tokenizedTransformation));
2801 }
2802 setCipherSpiImplAndProvider(sap.cipherSpi, sap.provider);
2803 return new CipherSpiAndProvider(sap.cipherSpi, sap.provider);
2804 }
2805 }
2806
2807 /**
2808 * Convenience call when the Key is not available.
2809 */
2810 CipherSpiAndProvider updateAndGetSpiAndProvider(CipherSpi spiImpl, Provider provider) {
2811 try {
2812 return updateAndGetSpiAndProvider(null, spiImpl, provider);
2813 } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
2814 throw new ProviderException("Exception thrown when params == null", e);
2815 }
2816 }
2817
2818 CipherSpi getCurrentSpi(CipherSpi spiImpl) {
2819 if (specifiedSpi != null) {
2820 return specifiedSpi;
2821 }
2822
2823 synchronized (initSpiLock) {
2824 return spiImpl;
2825 }
2826 }
2827 }
2828
2829 /**
2830 * Tries to find the correct {@code Cipher} transform to use. Returns a
2831 * {@link org.apache.harmony.security.fortress.Engine.SpiAndProvider}, throws the first exception that was
2832 * encountered during attempted initialization, or {@code null} if there are
2833 * no providers that support the {@code initParams}.
2834 * <p>
2835 * {@code tokenizedTransformation} must be in the format returned by
2836 * {@link Cipher#checkTransformation(String)}. The combinations of mode strings
2837 * tried are as follows:
2838 * <ul>
2839 * <li><code>[cipher]/[mode]/[padding]</code>
2840 * <li><code>[cipher]/[mode]</code>
2841 * <li><code>[cipher]//[padding]</code>
2842 * <li><code>[cipher]</code>
2843 * </ul>
2844 * {@code services} is a list of cipher services. Needs to be non-null only if
2845 * {@code provider != null}
2846 */
2847 static CipherSpiAndProvider tryCombinations(InitParams initParams, Provider provider,
2848 String[] tokenizedTransformation)
2849 throws InvalidKeyException,
2850 InvalidAlgorithmParameterException {
2851 // Enumerate all the transforms we need to try
2852 ArrayList<Transform> transforms = new ArrayList<Transform>();
2853 if (tokenizedTransformation[1] != null && tokenizedTransformation[2] != null) {
2854 transforms.add(new Transform(tokenizedTransformation[0] + "/" + tokenizedTransformation[1] + "/"
2855 + tokenizedTransformation[2], NeedToSet.NONE));
2856 }
2857 if (tokenizedTransformation[1] != null) {
2858 transforms.add(new Transform(tokenizedTransformation[0] + "/" + tokenizedTransformation[1],
2859 NeedToSet.PADDING));
2860 }
2861 if (tokenizedTransformation[2] != null) {
2862 transforms.add(new Transform(tokenizedTransformation[0] + "//" + tokenizedTransformation[2],
2863 NeedToSet.MODE));
2864 }
2865 transforms.add(new Transform(tokenizedTransformation[0], NeedToSet.BOTH));
2866
2867 // Try each of the transforms and keep track of the first exception
2868 // encountered.
2869 Exception cause = null;
2870
2871 if (provider != null) {
2872 for (Transform transform : transforms) {
2873 Provider.Service service = provider.getService("Cipher", transform.name);
2874 if (service == null) {
2875 continue;
2876 }
2877 return tryTransformWithProvider(initParams, tokenizedTransformation, transform.needToSet,
2878 service);
2879 }
2880 } else {
2881 for (Provider prov : Security.getProviders()) {
2882 for (Transform transform : transforms) {
2883 Provider.Service service = prov.getService("Cipher", transform.name);
2884 if (service == null) {
2885 continue;
2886 }
2887
2888 if (initParams == null || initParams.key == null
2889 || service.supportsParameter(initParams.key)) {
2890 try {
2891 CipherSpiAndProvider sap = tryTransformWithProvider(initParams,
2892 tokenizedTransformation, transform.needToSet, service);
2893 if (sap != null) {
2894 return sap;
2895 }
2896 } catch (Exception e) {
2897 if (cause == null) {
2898 cause = e;
2899 }
2900 }
2901 }
2902 }
2903 }
2904 }
2905 if (cause instanceof InvalidKeyException) {
2906 throw (InvalidKeyException) cause;
2907 } else if (cause instanceof InvalidAlgorithmParameterException) {
2908 throw (InvalidAlgorithmParameterException) cause;
2909 } else if (cause instanceof RuntimeException) {
2910 throw (RuntimeException) cause;
2911 } else if (cause != null) {
2912 throw new InvalidKeyException("No provider can be initialized with given key", cause);
2913 } else if (initParams == null || initParams.key == null) {
2914 return null;
2915 } else {
2916 // Since the key is not null, a suitable provider exists,
2917 // and it is an InvalidKeyException.
2918 throw new InvalidKeyException(
2919 "No provider offers " + Arrays.toString(tokenizedTransformation) + " for "
2920 + initParams.key.getAlgorithm() + " key of class "
2921 + initParams.key.getClass().getName() + " and export format "
2922 + initParams.key.getFormat());
2923 }
2924 }
2925
2926 static class CipherSpiAndProvider {
2927 CipherSpi cipherSpi;
2928 Provider provider;
2929
2930 CipherSpiAndProvider(CipherSpi cipherSpi, Provider provider) {
2931 this.cipherSpi = cipherSpi;
2932 this.provider = provider;
2933 }
2934 }
2935
2936 /**
2937 * Tries to initialize the {@code Cipher} from a given {@code service}. If
2938 * initialization is successful, the initialized {@code spi} is returned. If
2939 * the {@code service} cannot be initialized with the specified
2940 * {@code initParams}, then it's expected to throw
2941 * {@code InvalidKeyException} or {@code InvalidAlgorithmParameterException}
2942 * as a hint to the caller that it should continue searching for a
2943 * {@code Service} that will work.
2944 */
2945 static CipherSpiAndProvider tryTransformWithProvider(InitParams initParams,
2946 String[] tokenizedTransformation, NeedToSet type, Provider.Service service)
2947 throws InvalidKeyException, InvalidAlgorithmParameterException {
2948 try {
2949 /*
2950 * Check to see if the Cipher even supports the attributes before
2951 * trying to instantiate it.
2952 */
2953 if (!matchAttribute(service, ATTRIBUTE_MODES, tokenizedTransformation[1])
2954 || !matchAttribute(service, ATTRIBUTE_PADDINGS, tokenizedTransformation[2])) {
2955 return null;
2956 }
2957
2958 CipherSpiAndProvider sap = new CipherSpiAndProvider(
2959 (CipherSpi) service.newInstance(null), service.getProvider());
2960 if (sap.cipherSpi == null || sap.provider == null) {
2961 return null;
2962 }
2963 CipherSpi spi = sap.cipherSpi;
2964 if (((type == NeedToSet.MODE) || (type == NeedToSet.BOTH))
2965 && (tokenizedTransformation[1] != null)) {
2966 spi.engineSetMode(tokenizedTransformation[1]);
2967 }
2968 if (((type == NeedToSet.PADDING) || (type == NeedToSet.BOTH))
2969 && (tokenizedTransformation[2] != null)) {
2970 spi.engineSetPadding(tokenizedTransformation[2]);
2971 }
2972
2973 if (initParams != null) {
2974 switch (initParams.initType) {
2975 case ALGORITHM_PARAMS:
2976 spi.engineInit(initParams.opmode, initParams.key, initParams.params,
2977 initParams.random);
2978 break;
2979 case ALGORITHM_PARAM_SPEC:
2980 spi.engineInit(initParams.opmode, initParams.key, initParams.spec,
2981 initParams.random);
2982 break;
2983 case KEY:
2984 spi.engineInit(initParams.opmode, initParams.key, initParams.random);
2985 break;
2986 default:
2987 throw new AssertionError("This should never be reached");
2988 }
2989 }
2990 return new CipherSpiAndProvider(spi, sap.provider);
2991 } catch (NoSuchAlgorithmException ignored) {
2992 } catch (NoSuchPaddingException ignored) {
2993 }
2994 return null;
2995 }
Adam Vartanian11bd3492017-10-20 16:18:34 +01002996 // END Android-added: Bulk of the new provider implementation.
Piotr Jastrzebski51b1b692015-02-16 15:01:09 +00002997}