Home » openjdk-7 » javax » crypto » [javadoc | source]

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

Home » openjdk-7 » javax » crypto » [javadoc | source]