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