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