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