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