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