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