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