Save This Page
Home » openjdk-7 » javax » crypto » [javadoc | source]
    1   /*
    2    * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   
   26   package javax.crypto;
   27   
   28   import java.util.StringTokenizer;
   29   import java.util.NoSuchElementException;
   30   import java.security.AlgorithmParameters;
   31   import java.security.Provider;
   32   import java.security.Key;
   33   import java.security.SecureRandom;
   34   import java.security.NoSuchAlgorithmException;
   35   import java.security.NoSuchProviderException;
   36   import java.security.InvalidKeyException;
   37   import java.security.InvalidAlgorithmParameterException;
   38   import java.security.ProviderException;
   39   import java.security.spec.AlgorithmParameterSpec;
   40   
   41   import java.nio.ByteBuffer;
   42   
   43   /**
   44    * This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
   45    * for the <code>Cipher</code> class.
   46    * All the abstract methods in this class must be implemented by each
   47    * cryptographic service provider who wishes to supply the implementation
   48    * of a particular cipher algorithm.
   49    *
   50    * <p>In order to create an instance of <code>Cipher</code>, which
   51    * encapsulates an instance of this <code>CipherSpi</code> class, an
   52    * application calls one of the
   53    * {@link Cipher#getInstance(java.lang.String) getInstance}
   54    * factory methods of the
   55    * {@link Cipher Cipher} engine class and specifies the requested
   56    * <i>transformation</i>.
   57    * Optionally, the application may also specify the name of a provider.
   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    * <p>A provider may supply a separate class for each combination
   82    * of <i>algorithm/mode/padding</i>, or may decide to provide more generic
   83    * classes representing sub-transformations corresponding to
   84    * <i>algorithm</i> or <i>algorithm/mode</i> or <i>algorithm//padding</i>
   85    * (note the double slashes),
   86    * in which case the requested mode and/or padding are set automatically by
   87    * the <code>getInstance</code> methods of <code>Cipher</code>, which invoke
   88    * the {@link #engineSetMode(java.lang.String) engineSetMode} and
   89    * {@link #engineSetPadding(java.lang.String) engineSetPadding}
   90    * methods of the provider's subclass of <code>CipherSpi</code>.
   91    *
   92    * <p>A <code>Cipher</code> property in a provider master class may have one of
   93    * the following formats:
   94    *
   95    * <ul>
   96    *
   97    * <li>
   98    * <pre>
   99    *     // provider's subclass of "CipherSpi" implements "algName" with
  100    *     // pluggable mode and padding
  101    *     <code>Cipher.</code><i>algName</i>
  102    * </pre>
  103    *
  104    * <li>
  105    * <pre>
  106    *     // provider's subclass of "CipherSpi" implements "algName" in the
  107    *     // specified "mode", with pluggable padding
  108    *     <code>Cipher.</code><i>algName/mode</i>
  109    * </pre>
  110    *
  111    * <li>
  112    * <pre>
  113    *     // provider's subclass of "CipherSpi" implements "algName" with the
  114    *     // specified "padding", with pluggable mode
  115    *     <code>Cipher.</code><i>algName//padding</i>
  116    * </pre>
  117    *
  118    * <li>
  119    * <pre>
  120    *     // provider's subclass of "CipherSpi" implements "algName" with the
  121    *     // specified "mode" and "padding"
  122    *     <code>Cipher.</code><i>algName/mode/padding</i>
  123    * </pre>
  124    *
  125    * </ul>
  126    *
  127    * <p>For example, a provider may supply a subclass of <code>CipherSpi</code>
  128    * that implements <i>DES/ECB/PKCS5Padding</i>, one that implements
  129    * <i>DES/CBC/PKCS5Padding</i>, one that implements
  130    * <i>DES/CFB/PKCS5Padding</i>, and yet another one that implements
  131    * <i>DES/OFB/PKCS5Padding</i>. That provider would have the following
  132    * <code>Cipher</code> properties in its master class:<p>
  133    *
  134    * <ul>
  135    *
  136    * <li>
  137    * <pre>
  138    *     <code>Cipher.</code><i>DES/ECB/PKCS5Padding</i>
  139    * </pre>
  140    *
  141    * <li>
  142    * <pre>
  143    *     <code>Cipher.</code><i>DES/CBC/PKCS5Padding</i>
  144    * </pre>
  145    *
  146    * <li>
  147    * <pre>
  148    *     <code>Cipher.</code><i>DES/CFB/PKCS5Padding</i>
  149    * </pre>
  150    *
  151    * <li>
  152    * <pre>
  153    *     <code>Cipher.</code><i>DES/OFB/PKCS5Padding</i>
  154    * </pre>
  155    *
  156    * </ul>
  157    *
  158    * <p>Another provider may implement a class for each of the above modes
  159    * (i.e., one class for <i>ECB</i>, one for <i>CBC</i>, one for <i>CFB</i>,
  160    * and one for <i>OFB</i>), one class for <i>PKCS5Padding</i>,
  161    * and a generic <i>DES</i> class that subclasses from <code>CipherSpi</code>.
  162    * That provider would have the following
  163    * <code>Cipher</code> properties in its master class:<p>
  164    *
  165    * <ul>
  166    *
  167    * <li>
  168    * <pre>
  169    *     <code>Cipher.</code><i>DES</i>
  170    * </pre>
  171    *
  172    * </ul>
  173    *
  174    * <p>The <code>getInstance</code> factory method of the <code>Cipher</code>
  175    * engine class follows these rules in order to instantiate a provider's
  176    * implementation of <code>CipherSpi</code> for a
  177    * transformation of the form "<i>algorithm</i>":
  178    *
  179    * <ol>
  180    * <li>
  181    * Check if the provider has registered a subclass of <code>CipherSpi</code>
  182    * for the specified "<i>algorithm</i>".
  183    * <p>If the answer is YES, instantiate this
  184    * class, for whose mode and padding scheme default values (as supplied by
  185    * the provider) are used.
  186    * <p>If the answer is NO, throw a <code>NoSuchAlgorithmException</code>
  187    * exception.
  188    * </ol>
  189    *
  190    * <p>The <code>getInstance</code> factory method of the <code>Cipher</code>
  191    * engine class follows these rules in order to instantiate a provider's
  192    * implementation of <code>CipherSpi</code> for a
  193    * transformation of the form "<i>algorithm/mode/padding</i>":
  194    *
  195    * <ol>
  196    * <li>
  197    * Check if the provider has registered a subclass of <code>CipherSpi</code>
  198    * for the specified "<i>algorithm/mode/padding</i>" transformation.
  199    * <p>If the answer is YES, instantiate it.
  200    * <p>If the answer is NO, go to the next step.<p>
  201    * <li>
  202    * Check if the provider has registered a subclass of <code>CipherSpi</code>
  203    * for the sub-transformation "<i>algorithm/mode</i>".
  204    * <p>If the answer is YES, instantiate it, and call
  205    * <code>engineSetPadding(<i>padding</i>)</code> on the new instance.
  206    * <p>If the answer is NO, go to the next step.<p>
  207    * <li>
  208    * Check if the provider has registered a subclass of <code>CipherSpi</code>
  209    * for the sub-transformation "<i>algorithm//padding</i>" (note the double
  210    * slashes).
  211    * <p>If the answer is YES, instantiate it, and call
  212    * <code>engineSetMode(<i>mode</i>)</code> on the new instance.
  213    * <p>If the answer is NO, go to the next step.<p>
  214    * <li>
  215    * Check if the provider has registered a subclass of <code>CipherSpi</code>
  216    * for the sub-transformation "<i>algorithm</i>".
  217    * <p>If the answer is YES, instantiate it, and call
  218    * <code>engineSetMode(<i>mode</i>)</code> and
  219    * <code>engineSetPadding(<i>padding</i>)</code> on the new instance.
  220    * <p>If the answer is NO, throw a <code>NoSuchAlgorithmException</code>
  221    * exception.
  222    * </ol>
  223    *
  224    * @author Jan Luehe
  225    * @see KeyGenerator
  226    * @see SecretKey
  227    * @since 1.4
  228    */
  229   
  230   public abstract class CipherSpi {
  231   
  232       /**
  233        * Sets the mode of this cipher.
  234        *
  235        * @param mode the cipher mode
  236        *
  237        * @exception NoSuchAlgorithmException if the requested cipher mode does
  238        * not exist
  239        */
  240       protected abstract void engineSetMode(String mode)
  241           throws NoSuchAlgorithmException;
  242   
  243       /**
  244        * Sets the padding mechanism of this cipher.
  245        *
  246        * @param padding the padding mechanism
  247        *
  248        * @exception NoSuchPaddingException if the requested padding mechanism
  249        * does not exist
  250        */
  251       protected abstract void engineSetPadding(String padding)
  252           throws NoSuchPaddingException;
  253   
  254       /**
  255        * Returns the block size (in bytes).
  256        *
  257        * @return the block size (in bytes), or 0 if the underlying algorithm is
  258        * not a block cipher
  259        */
  260       protected abstract int engineGetBlockSize();
  261   
  262       /**
  263        * Returns the length in bytes that an output buffer would
  264        * need to be in order to hold the result of the next <code>update</code>
  265        * or <code>doFinal</code> operation, given the input length
  266        * <code>inputLen</code> (in bytes).
  267        *
  268        * <p>This call takes into account any unprocessed (buffered) data from a
  269        * previous <code>update</code> call, padding, and AEAD tagging.
  270        *
  271        * <p>The actual output length of the next <code>update</code> or
  272        * <code>doFinal</code> call may be smaller than the length returned by
  273        * this method.
  274        *
  275        * @param inputLen the input length (in bytes)
  276        *
  277        * @return the required output buffer size (in bytes)
  278        */
  279       protected abstract int engineGetOutputSize(int inputLen);
  280   
  281       /**
  282        * Returns the initialization vector (IV) in a new buffer.
  283        *
  284        * <p> This is useful in the context of password-based encryption or
  285        * decryption, where the IV is derived from a user-provided passphrase.
  286        *
  287        * @return the initialization vector in a new buffer, or null if the
  288        * underlying algorithm does not use an IV, or if the IV has not yet
  289        * been set.
  290        */
  291       protected abstract byte[] engineGetIV();
  292   
  293       /**
  294        * Returns the parameters used with this cipher.
  295        *
  296        * <p>The returned parameters may be the same that were used to initialize
  297        * this cipher, or may contain a combination of default and random
  298        * parameter values used by the underlying cipher implementation if this
  299        * cipher requires algorithm parameters but was not initialized with any.
  300        *
  301        * @return the parameters used with this cipher, or null if this cipher
  302        * does not use any parameters.
  303        */
  304       protected abstract AlgorithmParameters engineGetParameters();
  305   
  306       /**
  307        * Initializes this cipher with a key and a source
  308        * of randomness.
  309        *
  310        * <p>The cipher is initialized for one of the following four operations:
  311        * encryption, decryption, key wrapping or key unwrapping, depending on
  312        * the value of <code>opmode</code>.
  313        *
  314        * <p>If this cipher requires any algorithm parameters that cannot be
  315        * derived from the given <code>key</code>, the underlying cipher
  316        * implementation is supposed to generate the required parameters itself
  317        * (using provider-specific default or random values) if it is being
  318        * initialized for encryption or key wrapping, and raise an
  319        * <code>InvalidKeyException</code> if it is being
  320        * initialized for decryption or key unwrapping.
  321        * The generated parameters can be retrieved using
  322        * {@link #engineGetParameters() engineGetParameters} or
  323        * {@link #engineGetIV() engineGetIV} (if the parameter is an IV).
  324        *
  325        * <p>If this cipher requires algorithm parameters that cannot be
  326        * derived from the input parameters, and there are no reasonable
  327        * provider-specific default values, initialization will
  328        * necessarily fail.
  329        *
  330        * <p>If this cipher (including its underlying feedback or padding scheme)
  331        * requires any random bytes (e.g., for parameter generation), it will get
  332        * them from <code>random</code>.
  333        *
  334        * <p>Note that when a Cipher object is initialized, it loses all
  335        * previously-acquired state. In other words, initializing a Cipher is
  336        * equivalent to creating a new instance of that Cipher and initializing
  337        * it.
  338        *
  339        * @param opmode the operation mode of this cipher (this is one of
  340        * the following:
  341        * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,
  342        * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
  343        * @param key the encryption key
  344        * @param random the source of randomness
  345        *
  346        * @exception InvalidKeyException if the given key is inappropriate for
  347        * initializing this cipher, or requires
  348        * algorithm parameters that cannot be
  349        * determined from the given key.
  350        */
  351       protected abstract void engineInit(int opmode, Key key,
  352                                          SecureRandom random)
  353           throws InvalidKeyException;
  354   
  355       /**
  356        * Initializes this cipher with a key, a set of
  357        * algorithm parameters, and a source of randomness.
  358        *
  359        * <p>The cipher is initialized for one of the following four operations:
  360        * encryption, decryption, key wrapping or key unwrapping, depending on
  361        * the value of <code>opmode</code>.
  362        *
  363        * <p>If this cipher requires any algorithm parameters and
  364        * <code>params</code> is null, the underlying cipher implementation is
  365        * supposed to generate the required parameters itself (using
  366        * provider-specific default or random values) if it is being
  367        * initialized for encryption or key wrapping, and raise an
  368        * <code>InvalidAlgorithmParameterException</code> if it is being
  369        * initialized for decryption or key unwrapping.
  370        * The generated parameters can be retrieved using
  371        * {@link #engineGetParameters() engineGetParameters} or
  372        * {@link #engineGetIV() engineGetIV} (if the parameter is an IV).
  373        *
  374        * <p>If this cipher requires algorithm parameters that cannot be
  375        * derived from the input parameters, and there are no reasonable
  376        * provider-specific default values, initialization will
  377        * necessarily fail.
  378        *
  379        * <p>If this cipher (including its underlying feedback or padding scheme)
  380        * requires any random bytes (e.g., for parameter generation), it will get
  381        * them from <code>random</code>.
  382        *
  383        * <p>Note that when a Cipher object is initialized, it loses all
  384        * previously-acquired state. In other words, initializing a Cipher is
  385        * equivalent to creating a new instance of that Cipher and initializing
  386        * it.
  387        *
  388        * @param opmode the operation mode of this cipher (this is one of
  389        * the following:
  390        * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,
  391        * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
  392        * @param key the encryption key
  393        * @param params the algorithm parameters
  394        * @param random the source of randomness
  395        *
  396        * @exception InvalidKeyException if the given key is inappropriate for
  397        * initializing this cipher
  398        * @exception InvalidAlgorithmParameterException if the given algorithm
  399        * parameters are inappropriate for this cipher,
  400        * or if this cipher requires
  401        * algorithm parameters and <code>params</code> is null.
  402        */
  403       protected abstract void engineInit(int opmode, Key key,
  404                                          AlgorithmParameterSpec params,
  405                                          SecureRandom random)
  406           throws InvalidKeyException, InvalidAlgorithmParameterException;
  407   
  408       /**
  409        * Initializes this cipher with a key, a set of
  410        * algorithm parameters, and a source of randomness.
  411        *
  412        * <p>The cipher is initialized for one of the following four operations:
  413        * encryption, decryption, key wrapping or key unwrapping, depending on
  414        * the value of <code>opmode</code>.
  415        *
  416        * <p>If this cipher requires any algorithm parameters and
  417        * <code>params</code> is null, the underlying cipher implementation is
  418        * supposed to generate the required parameters itself (using
  419        * provider-specific default or random values) if it is being
  420        * initialized for encryption or key wrapping, and raise an
  421        * <code>InvalidAlgorithmParameterException</code> if it is being
  422        * initialized for decryption or key unwrapping.
  423        * The generated parameters can be retrieved using
  424        * {@link #engineGetParameters() engineGetParameters} or
  425        * {@link #engineGetIV() engineGetIV} (if the parameter is an IV).
  426        *
  427        * <p>If this cipher requires algorithm parameters that cannot be
  428        * derived from the input parameters, and there are no reasonable
  429        * provider-specific default values, initialization will
  430        * necessarily fail.
  431        *
  432        * <p>If this cipher (including its underlying feedback or padding scheme)
  433        * requires any random bytes (e.g., for parameter generation), it will get
  434        * them from <code>random</code>.
  435        *
  436        * <p>Note that when a Cipher object is initialized, it loses all
  437        * previously-acquired state. In other words, initializing a Cipher is
  438        * equivalent to creating a new instance of that Cipher and initializing
  439        * it.
  440        *
  441        * @param opmode the operation mode of this cipher (this is one of
  442        * the following:
  443        * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,
  444        * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
  445        * @param key the encryption key
  446        * @param params the algorithm parameters
  447        * @param random the source of randomness
  448        *
  449        * @exception InvalidKeyException if the given key is inappropriate for
  450        * initializing this cipher
  451        * @exception InvalidAlgorithmParameterException if the given algorithm
  452        * parameters are inappropriate for this cipher,
  453        * or if this cipher requires
  454        * algorithm parameters and <code>params</code> is null.
  455        */
  456       protected abstract void engineInit(int opmode, Key key,
  457                                          AlgorithmParameters params,
  458                                          SecureRandom random)
  459           throws InvalidKeyException, InvalidAlgorithmParameterException;
  460   
  461       /**
  462        * Continues a multiple-part encryption or decryption operation
  463        * (depending on how this cipher was initialized), processing another data
  464        * part.
  465        *
  466        * <p>The first <code>inputLen</code> bytes in the <code>input</code>
  467        * buffer, starting at <code>inputOffset</code> inclusive, are processed,
  468        * and the result is stored in a new buffer.
  469        *
  470        * @param input the input buffer
  471        * @param inputOffset the offset in <code>input</code> where the input
  472        * starts
  473        * @param inputLen the input length
  474        *
  475        * @return the new buffer with the result, or null if the underlying
  476        * cipher is a block cipher and the input data is too short to result in a
  477        * new block.
  478        */
  479       protected abstract byte[] engineUpdate(byte[] input, int inputOffset,
  480                                              int inputLen);
  481   
  482       /**
  483        * Continues a multiple-part encryption or decryption operation
  484        * (depending on how this cipher was initialized), processing another data
  485        * part.
  486        *
  487        * <p>The first <code>inputLen</code> bytes in the <code>input</code>
  488        * buffer, starting at <code>inputOffset</code> inclusive, are processed,
  489        * and the result is stored in the <code>output</code> buffer, starting at
  490        * <code>outputOffset</code> inclusive.
  491        *
  492        * <p>If the <code>output</code> buffer is too small to hold the result,
  493        * a <code>ShortBufferException</code> is thrown.
  494        *
  495        * @param input the input buffer
  496        * @param inputOffset the offset in <code>input</code> where the input
  497        * starts
  498        * @param inputLen the input length
  499        * @param output the buffer for the result
  500        * @param outputOffset the offset in <code>output</code> where the result
  501        * is stored
  502        *
  503        * @return the number of bytes stored in <code>output</code>
  504        *
  505        * @exception ShortBufferException if the given output buffer is too small
  506        * to hold the result
  507        */
  508       protected abstract int engineUpdate(byte[] input, int inputOffset,
  509                                           int inputLen, byte[] output,
  510                                           int outputOffset)
  511           throws ShortBufferException;
  512   
  513       /**
  514        * Continues a multiple-part encryption or decryption operation
  515        * (depending on how this cipher was initialized), processing another data
  516        * part.
  517        *
  518        * <p>All <code>input.remaining()</code> bytes starting at
  519        * <code>input.position()</code> are processed. The result is stored
  520        * in the output buffer.
  521        * Upon return, the input buffer's position will be equal
  522        * to its limit; its limit will not have changed. The output buffer's
  523        * position will have advanced by n, where n is the value returned
  524        * by this method; the output buffer's limit will not have changed.
  525        *
  526        * <p>If <code>output.remaining()</code> bytes are insufficient to
  527        * hold the result, a <code>ShortBufferException</code> is thrown.
  528        *
  529        * <p>Subclasses should consider overriding this method if they can
  530        * process ByteBuffers more efficiently than byte arrays.
  531        *
  532        * @param input the input ByteBuffer
  533        * @param output the output ByteByffer
  534        *
  535        * @return the number of bytes stored in <code>output</code>
  536        *
  537        * @exception ShortBufferException if there is insufficient space in the
  538        * output buffer
  539        *
  540        * @throws NullPointerException if either parameter is <CODE>null</CODE>
  541        * @since 1.5
  542        */
  543       protected int engineUpdate(ByteBuffer input, ByteBuffer output)
  544               throws ShortBufferException {
  545           try {
  546               return bufferCrypt(input, output, true);
  547           } catch (IllegalBlockSizeException e) {
  548               // never thrown for engineUpdate()
  549               throw new ProviderException("Internal error in update()");
  550           } catch (BadPaddingException e) {
  551               // never thrown for engineUpdate()
  552               throw new ProviderException("Internal error in update()");
  553           }
  554       }
  555   
  556       /**
  557        * Encrypts or decrypts data in a single-part operation,
  558        * or finishes a multiple-part operation.
  559        * The data is encrypted or decrypted, depending on how this cipher was
  560        * initialized.
  561        *
  562        * <p>The first <code>inputLen</code> bytes in the <code>input</code>
  563        * buffer, starting at <code>inputOffset</code> inclusive, and any input
  564        * bytes that may have been buffered during a previous <code>update</code>
  565        * operation, are processed, with padding (if requested) being applied.
  566        * If an AEAD mode such as GCM/CCM is being used, the authentication
  567        * tag is appended in the case of encryption, or verified in the
  568        * case of decryption.
  569        * The result is stored in a new buffer.
  570        *
  571        * <p>Upon finishing, this method resets this cipher object to the state
  572        * it was in when previously initialized via a call to
  573        * <code>engineInit</code>.
  574        * That is, the object is reset and available to encrypt or decrypt
  575        * (depending on the operation mode that was specified in the call to
  576        * <code>engineInit</code>) more data.
  577        *
  578        * <p>Note: if any exception is thrown, this cipher object may need to
  579        * be reset before it can be used again.
  580        *
  581        * @param input the input buffer
  582        * @param inputOffset the offset in <code>input</code> where the input
  583        * starts
  584        * @param inputLen the input length
  585        *
  586        * @return the new buffer with the result
  587        *
  588        * @exception IllegalBlockSizeException if this cipher is a block cipher,
  589        * no padding has been requested (only in encryption mode), and the total
  590        * input length of the data processed by this cipher is not a multiple of
  591        * block size; or if this encryption algorithm is unable to
  592        * process the input data provided.
  593        * @exception BadPaddingException if this cipher is in decryption mode,
  594        * and (un)padding has been requested, but the decrypted data is not
  595        * bounded by the appropriate padding bytes
  596        * @exception AEADBadTagException if this cipher is decrypting in an
  597        * AEAD mode (such as GCM/CCM), and the received authentication tag
  598        * does not match the calculated value
  599        */
  600       protected abstract byte[] engineDoFinal(byte[] input, int inputOffset,
  601                                               int inputLen)
  602           throws IllegalBlockSizeException, BadPaddingException;
  603   
  604       /**
  605        * Encrypts or decrypts data in a single-part operation,
  606        * or finishes a multiple-part operation.
  607        * The data is encrypted or decrypted, depending on how this cipher was
  608        * initialized.
  609        *
  610        * <p>The first <code>inputLen</code> bytes in the <code>input</code>
  611        * buffer, starting at <code>inputOffset</code> inclusive, and any input
  612        * bytes that may have been buffered during a previous <code>update</code>
  613        * operation, are processed, with padding (if requested) being applied.
  614        * If an AEAD mode such as GCM/CCM is being used, the authentication
  615        * tag is appended in the case of encryption, or verified in the
  616        * case of decryption.
  617        * The result is stored in the <code>output</code> buffer, starting at
  618        * <code>outputOffset</code> inclusive.
  619        *
  620        * <p>If the <code>output</code> buffer is too small to hold the result,
  621        * a <code>ShortBufferException</code> is thrown.
  622        *
  623        * <p>Upon finishing, this method resets this cipher object to the state
  624        * it was in when previously initialized via a call to
  625        * <code>engineInit</code>.
  626        * That is, the object is reset and available to encrypt or decrypt
  627        * (depending on the operation mode that was specified in the call to
  628        * <code>engineInit</code>) more data.
  629        *
  630        * <p>Note: if any exception is thrown, this cipher object may need to
  631        * be reset before it can be used again.
  632        *
  633        * @param input the input buffer
  634        * @param inputOffset the offset in <code>input</code> where the input
  635        * starts
  636        * @param inputLen the input length
  637        * @param output the buffer for the result
  638        * @param outputOffset the offset in <code>output</code> where the result
  639        * is stored
  640        *
  641        * @return the number of bytes stored in <code>output</code>
  642        *
  643        * @exception IllegalBlockSizeException if this cipher is a block cipher,
  644        * no padding has been requested (only in encryption mode), and the total
  645        * input length of the data processed by this cipher is not a multiple of
  646        * block size; or if this encryption algorithm is unable to
  647        * process the input data provided.
  648        * @exception ShortBufferException if the given output buffer is too small
  649        * to hold the result
  650        * @exception BadPaddingException if this cipher is in decryption mode,
  651        * and (un)padding has been requested, but the decrypted data is not
  652        * bounded by the appropriate padding bytes
  653        * @exception AEADBadTagException if this cipher is decrypting in an
  654        * AEAD mode (such as GCM/CCM), and the received authentication tag
  655        * does not match the calculated value
  656        */
  657       protected abstract int engineDoFinal(byte[] input, int inputOffset,
  658                                            int inputLen, byte[] output,
  659                                            int outputOffset)
  660           throws ShortBufferException, IllegalBlockSizeException,
  661                  BadPaddingException;
  662   
  663       /**
  664        * Encrypts or decrypts data in a single-part operation,
  665        * or finishes a multiple-part operation.
  666        * The data is encrypted or decrypted, depending on how this cipher was
  667        * initialized.
  668        *
  669        * <p>All <code>input.remaining()</code> bytes starting at
  670        * <code>input.position()</code> are processed.
  671        * If an AEAD mode such as GCM/CCM is being used, the authentication
  672        * tag is appended in the case of encryption, or verified in the
  673        * case of decryption.
  674        * The result is stored in the output buffer.
  675        * Upon return, the input buffer's position will be equal
  676        * to its limit; its limit will not have changed. The output buffer's
  677        * position will have advanced by n, where n is the value returned
  678        * by this method; the output buffer's limit will not have changed.
  679        *
  680        * <p>If <code>output.remaining()</code> bytes are insufficient to
  681        * hold the result, a <code>ShortBufferException</code> is thrown.
  682        *
  683        * <p>Upon finishing, this method resets this cipher object to the state
  684        * it was in when previously initialized via a call to
  685        * <code>engineInit</code>.
  686        * That is, the object is reset and available to encrypt or decrypt
  687        * (depending on the operation mode that was specified in the call to
  688        * <code>engineInit</code>) more data.
  689        *
  690        * <p>Note: if any exception is thrown, this cipher object may need to
  691        * be reset before it can be used again.
  692        *
  693        * <p>Subclasses should consider overriding this method if they can
  694        * process ByteBuffers more efficiently than byte arrays.
  695        *
  696        * @param input the input ByteBuffer
  697        * @param output the output ByteByffer
  698        *
  699        * @return the number of bytes stored in <code>output</code>
  700        *
  701        * @exception IllegalBlockSizeException if this cipher is a block cipher,
  702        * no padding has been requested (only in encryption mode), and the total
  703        * input length of the data processed by this cipher is not a multiple of
  704        * block size; or if this encryption algorithm is unable to
  705        * process the input data provided.
  706        * @exception ShortBufferException if there is insufficient space in the
  707        * output buffer
  708        * @exception BadPaddingException if this cipher is in decryption mode,
  709        * and (un)padding has been requested, but the decrypted data is not
  710        * bounded by the appropriate padding bytes
  711        * @exception AEADBadTagException if this cipher is decrypting in an
  712        * AEAD mode (such as GCM/CCM), and the received authentication tag
  713        * does not match the calculated value
  714        *
  715        * @throws NullPointerException if either parameter is <CODE>null</CODE>
  716        * @since 1.5
  717        */
  718       protected int engineDoFinal(ByteBuffer input, ByteBuffer output)
  719               throws ShortBufferException, IllegalBlockSizeException,
  720               BadPaddingException {
  721           return bufferCrypt(input, output, false);
  722       }
  723   
  724       // copied from sun.security.jca.JCAUtil
  725       // will be changed to reference that method once that code has been
  726       // integrated and promoted
  727       static int getTempArraySize(int totalSize) {
  728           return Math.min(4096, totalSize);
  729       }
  730   
  731       /**
  732        * Implementation for encryption using ByteBuffers. Used for both
  733        * engineUpdate() and engineDoFinal().
  734        */
  735       private int bufferCrypt(ByteBuffer input, ByteBuffer output,
  736               boolean isUpdate) throws ShortBufferException,
  737               IllegalBlockSizeException, BadPaddingException {
  738           if ((input == null) || (output == null)) {
  739               throw new NullPointerException
  740                   ("Input and output buffers must not be null");
  741           }
  742           int inPos = input.position();
  743           int inLimit = input.limit();
  744           int inLen = inLimit - inPos;
  745           if (isUpdate && (inLen == 0)) {
  746               return 0;
  747           }
  748           int outLenNeeded = engineGetOutputSize(inLen);
  749           if (output.remaining() < outLenNeeded) {
  750               throw new ShortBufferException("Need at least " + outLenNeeded
  751                   + " bytes of space in output buffer");
  752           }
  753   
  754           boolean a1 = input.hasArray();
  755           boolean a2 = output.hasArray();
  756   
  757           if (a1 && a2) {
  758               byte[] inArray = input.array();
  759               int inOfs = input.arrayOffset() + inPos;
  760               byte[] outArray = output.array();
  761               int outPos = output.position();
  762               int outOfs = output.arrayOffset() + outPos;
  763               int n;
  764               if (isUpdate) {
  765                   n = engineUpdate(inArray, inOfs, inLen, outArray, outOfs);
  766               } else {
  767                   n = engineDoFinal(inArray, inOfs, inLen, outArray, outOfs);
  768               }
  769               input.position(inLimit);
  770               output.position(outPos + n);
  771               return n;
  772           } else if (!a1 && a2) {
  773               int outPos = output.position();
  774               byte[] outArray = output.array();
  775               int outOfs = output.arrayOffset() + outPos;
  776               byte[] inArray = new byte[getTempArraySize(inLen)];
  777               int total = 0;
  778               while (inLen > 0) {
  779                   int chunk = Math.min(inLen, inArray.length);
  780                   input.get(inArray, 0, chunk);
  781                   int n;
  782                   if (isUpdate || (inLen != chunk)) {
  783                       n = engineUpdate(inArray, 0, chunk, outArray, outOfs);
  784                   } else {
  785                       n = engineDoFinal(inArray, 0, chunk, outArray, outOfs);
  786                   }
  787                   total += n;
  788                   outOfs += n;
  789                   inLen -= chunk;
  790               }
  791               output.position(outPos + total);
  792               return total;
  793           } else { // output is not backed by an accessible byte[]
  794               byte[] inArray;
  795               int inOfs;
  796               if (a1) {
  797                   inArray = input.array();
  798                   inOfs = input.arrayOffset() + inPos;
  799               } else {
  800                   inArray = new byte[getTempArraySize(inLen)];
  801                   inOfs = 0;
  802               }
  803               byte[] outArray = new byte[getTempArraySize(outLenNeeded)];
  804               int outSize = outArray.length;
  805               int total = 0;
  806               boolean resized = false;
  807               while (inLen > 0) {
  808                   int chunk = Math.min(inLen, outSize);
  809                   if ((a1 == false) && (resized == false)) {
  810                       input.get(inArray, 0, chunk);
  811                       inOfs = 0;
  812                   }
  813                   try {
  814                       int n;
  815                       if (isUpdate || (inLen != chunk)) {
  816                           n = engineUpdate(inArray, inOfs, chunk, outArray, 0);
  817                       } else {
  818                           n = engineDoFinal(inArray, inOfs, chunk, outArray, 0);
  819                       }
  820                       resized = false;
  821                       inOfs += chunk;
  822                       inLen -= chunk;
  823                       output.put(outArray, 0, n);
  824                       total += n;
  825                   } catch (ShortBufferException e) {
  826                       if (resized) {
  827                           // we just resized the output buffer, but it still
  828                           // did not work. Bug in the provider, abort
  829                           throw (ProviderException)new ProviderException
  830                               ("Could not determine buffer size").initCause(e);
  831                       }
  832                       // output buffer is too small, realloc and try again
  833                       resized = true;
  834                       int newOut = engineGetOutputSize(chunk);
  835                       outArray = new byte[newOut];
  836                   }
  837               }
  838               input.position(inLimit);
  839               return total;
  840           }
  841       }
  842   
  843       /**
  844        * Wrap a key.
  845        *
  846        * <p>This concrete method has been added to this previously-defined
  847        * abstract class. (For backwards compatibility, it cannot be abstract.)
  848        * It may be overridden by a provider to wrap a key.
  849        * Such an override is expected to throw an IllegalBlockSizeException or
  850        * InvalidKeyException (under the specified circumstances),
  851        * if the given key cannot be wrapped.
  852        * If this method is not overridden, it always throws an
  853        * UnsupportedOperationException.
  854        *
  855        * @param key the key to be wrapped.
  856        *
  857        * @return the wrapped key.
  858        *
  859        * @exception IllegalBlockSizeException if this cipher is a block cipher,
  860        * no padding has been requested, and the length of the encoding of the
  861        * key to be wrapped is not a multiple of the block size.
  862        *
  863        * @exception InvalidKeyException if it is impossible or unsafe to
  864        * wrap the key with this cipher (e.g., a hardware protected key is
  865        * being passed to a software-only cipher).
  866        */
  867       protected byte[] engineWrap(Key key)
  868           throws IllegalBlockSizeException, InvalidKeyException
  869       {
  870           throw new UnsupportedOperationException();
  871       }
  872   
  873       /**
  874        * Unwrap a previously wrapped key.
  875        *
  876        * <p>This concrete method has been added to this previously-defined
  877        * abstract class. (For backwards compatibility, it cannot be abstract.)
  878        * It may be overridden by a provider to unwrap a previously wrapped key.
  879        * Such an override is expected to throw an InvalidKeyException if
  880        * the given wrapped key cannot be unwrapped.
  881        * If this method is not overridden, it always throws an
  882        * UnsupportedOperationException.
  883        *
  884        * @param wrappedKey the key to be unwrapped.
  885        *
  886        * @param wrappedKeyAlgorithm the algorithm associated with the wrapped
  887        * key.
  888        *
  889        * @param wrappedKeyType the type of the wrapped key. This is one of
  890        * <code>SECRET_KEY</code>, <code>PRIVATE_KEY</code>, or
  891        * <code>PUBLIC_KEY</code>.
  892        *
  893        * @return the unwrapped key.
  894        *
  895        * @exception NoSuchAlgorithmException if no installed providers
  896        * can create keys of type <code>wrappedKeyType</code> for the
  897        * <code>wrappedKeyAlgorithm</code>.
  898        *
  899        * @exception InvalidKeyException if <code>wrappedKey</code> does not
  900        * represent a wrapped key of type <code>wrappedKeyType</code> for
  901        * the <code>wrappedKeyAlgorithm</code>.
  902        */
  903       protected Key engineUnwrap(byte[] wrappedKey,
  904                                  String wrappedKeyAlgorithm,
  905                                  int wrappedKeyType)
  906           throws InvalidKeyException, NoSuchAlgorithmException
  907       {
  908           throw new UnsupportedOperationException();
  909       }
  910   
  911       /**
  912        * Returns the key size of the given key object in bits.
  913        * <p>This concrete method has been added to this previously-defined
  914        * abstract class. It throws an <code>UnsupportedOperationException</code>
  915        * if it is not overridden by the provider.
  916        *
  917        * @param key the key object.
  918        *
  919        * @return the key size of the given key object.
  920        *
  921        * @exception InvalidKeyException if <code>key</code> is invalid.
  922        */
  923       protected int engineGetKeySize(Key key)
  924           throws InvalidKeyException
  925       {
  926           throw new UnsupportedOperationException();
  927       }
  928   
  929       /**
  930        * Continues a multi-part update of the Additional Authentication
  931        * Data (AAD), using a subset of the provided buffer.
  932        * <p>
  933        * Calls to this method provide AAD to the cipher when operating in
  934        * modes such as AEAD (GCM/CCM).  If this cipher is operating in
  935        * either GCM or CCM mode, all AAD must be supplied before beginning
  936        * operations on the ciphertext (via the {@code update} and {@code
  937        * doFinal} methods).
  938        *
  939        * @param src the buffer containing the AAD
  940        * @param offset the offset in {@code src} where the AAD input starts
  941        * @param len the number of AAD bytes
  942        *
  943        * @throws IllegalStateException if this cipher is in a wrong state
  944        * (e.g., has not been initialized), does not accept AAD, or if
  945        * operating in either GCM or CCM mode and one of the {@code update}
  946        * methods has already been called for the active
  947        * encryption/decryption operation
  948        * @throws UnsupportedOperationException if this method
  949        * has not been overridden by an implementation
  950        *
  951        * @since 1.7
  952        */
  953       protected void engineUpdateAAD(byte[] src, int offset, int len) {
  954           throw new UnsupportedOperationException(
  955               "The underlying Cipher implementation "
  956               +  "does not support this method");
  957       }
  958   
  959       /**
  960        * Continues a multi-part update of the Additional Authentication
  961        * Data (AAD).
  962        * <p>
  963        * Calls to this method provide AAD to the cipher when operating in
  964        * modes such as AEAD (GCM/CCM).  If this cipher is operating in
  965        * either GCM or CCM mode, all AAD must be supplied before beginning
  966        * operations on the ciphertext (via the {@code update} and {@code
  967        * doFinal} methods).
  968        * <p>
  969        * All {@code src.remaining()} bytes starting at
  970        * {@code src.position()} are processed.
  971        * Upon return, the input buffer's position will be equal
  972        * to its limit; its limit will not have changed.
  973        *
  974        * @param src the buffer containing the AAD
  975        *
  976        * @throws IllegalStateException if this cipher is in a wrong state
  977        * (e.g., has not been initialized), does not accept AAD, or if
  978        * operating in either GCM or CCM mode and one of the {@code update}
  979        * methods has already been called for the active
  980        * encryption/decryption operation
  981        * @throws UnsupportedOperationException if this method
  982        * has not been overridden by an implementation
  983        *
  984        * @since 1.7
  985        */
  986       protected void engineUpdateAAD(ByteBuffer src) {
  987           throw new UnsupportedOperationException(
  988               "The underlying Cipher implementation "
  989               +  "does not support this method");
  990       }
  991   }

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