Home | History | Annotate | Download | only in crypto
      1 /*
      2  * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
      3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      4  *
      5  * This code is free software; you can redistribute it and/or modify it
      6  * under the terms of the GNU General Public License version 2 only, as
      7  * published by the Free Software Foundation.  Oracle designates this
      8  * particular file as subject to the "Classpath" exception as provided
      9  * by Oracle in the LICENSE file that accompanied this code.
     10  *
     11  * This code is distributed in the hope that it will be useful, but WITHOUT
     12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     14  * version 2 for more details (a copy is included in the LICENSE file that
     15  * accompanied this code).
     16  *
     17  * You should have received a copy of the GNU General Public License version
     18  * 2 along with this work; if not, write to the Free Software Foundation,
     19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     20  *
     21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     22  * or visit www.oracle.com if you need additional information or have any
     23  * questions.
     24  */
     25 
     26 package javax.crypto;
     27 
     28 import java.util.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:
     66  *
     67  * <ul>
     68  * <li>"<i>algorithm/mode/padding</i>" or
     69  *
     70  * <li>"<i>algorithm</i>"
     71  * </ul>
     72  *
     73  * <P> (in the latter case,
     74  * provider-specific default values for the mode and padding scheme are used).
     75  * For example, the following is a valid transformation:
     76  *
     77  * <pre>
     78  *     Cipher c = Cipher.getInstance("<i>DES/CBC/PKCS5Padding</i>");
     79  * </pre>
     80  *
     81  * <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:
    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:
    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.
    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.
    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.
    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      * @throws UnsupportedOperationException if {@code opmode} is
    351      * {@code WRAP_MODE} or {@code UNWRAP_MODE} is not implemented
    352      * by the cipher.
    353      */
    354     protected abstract void engineInit(int opmode, Key key,
    355                                        SecureRandom random)
    356         throws InvalidKeyException;
    357 
    358     /**
    359      * Initializes this cipher with a key, a set of
    360      * algorithm parameters, and a source of randomness.
    361      *
    362      * <p>The cipher is initialized for one of the following four operations:
    363      * encryption, decryption, key wrapping or key unwrapping, depending on
    364      * the value of <code>opmode</code>.
    365      *
    366      * <p>If this cipher requires any algorithm parameters and
    367      * <code>params</code> is null, the underlying cipher implementation is
    368      * supposed to generate the required parameters itself (using
    369      * provider-specific default or random values) if it is being
    370      * initialized for encryption or key wrapping, and raise an
    371      * <code>InvalidAlgorithmParameterException</code> if it is being
    372      * initialized for decryption or key unwrapping.
    373      * The generated parameters can be retrieved using
    374      * {@link #engineGetParameters() engineGetParameters} or
    375      * {@link #engineGetIV() engineGetIV} (if the parameter is an IV).
    376      *
    377      * <p>If this cipher requires algorithm parameters that cannot be
    378      * derived from the input parameters, and there are no reasonable
    379      * provider-specific default values, initialization will
    380      * necessarily fail.
    381      *
    382      * <p>If this cipher (including its underlying feedback or padding scheme)
    383      * requires any random bytes (e.g., for parameter generation), it will get
    384      * them from <code>random</code>.
    385      *
    386      * <p>Note that when a Cipher object is initialized, it loses all
    387      * previously-acquired state. In other words, initializing a Cipher is
    388      * equivalent to creating a new instance of that Cipher and initializing
    389      * it.
    390      *
    391      * @param opmode the operation mode of this cipher (this is one of
    392      * the following:
    393      * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,
    394      * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
    395      * @param key the encryption key
    396      * @param params the algorithm parameters
    397      * @param random the source of randomness
    398      *
    399      * @exception InvalidKeyException if the given key is inappropriate for
    400      * initializing this cipher
    401      * @exception InvalidAlgorithmParameterException if the given algorithm
    402      * parameters are inappropriate for this cipher,
    403      * or if this cipher requires
    404      * algorithm parameters and <code>params</code> is null.
    405      * @throws UnsupportedOperationException if {@code opmode} is
    406      * {@code WRAP_MODE} or {@code UNWRAP_MODE} is not implemented
    407      * by the cipher.
    408      */
    409     protected abstract void engineInit(int opmode, Key key,
    410                                        AlgorithmParameterSpec params,
    411                                        SecureRandom random)
    412         throws InvalidKeyException, InvalidAlgorithmParameterException;
    413 
    414     /**
    415      * Initializes this cipher with a key, a set of
    416      * algorithm parameters, and a source of randomness.
    417      *
    418      * <p>The cipher is initialized for one of the following four operations:
    419      * encryption, decryption, key wrapping or key unwrapping, depending on
    420      * the value of <code>opmode</code>.
    421      *
    422      * <p>If this cipher requires any algorithm parameters and
    423      * <code>params</code> is null, the underlying cipher implementation is
    424      * supposed to generate the required parameters itself (using
    425      * provider-specific default or random values) if it is being
    426      * initialized for encryption or key wrapping, and raise an
    427      * <code>InvalidAlgorithmParameterException</code> if it is being
    428      * initialized for decryption or key unwrapping.
    429      * The generated parameters can be retrieved using
    430      * {@link #engineGetParameters() engineGetParameters} or
    431      * {@link #engineGetIV() engineGetIV} (if the parameter is an IV).
    432      *
    433      * <p>If this cipher requires algorithm parameters that cannot be
    434      * derived from the input parameters, and there are no reasonable
    435      * provider-specific default values, initialization will
    436      * necessarily fail.
    437      *
    438      * <p>If this cipher (including its underlying feedback or padding scheme)
    439      * requires any random bytes (e.g., for parameter generation), it will get
    440      * them from <code>random</code>.
    441      *
    442      * <p>Note that when a Cipher object is initialized, it loses all
    443      * previously-acquired state. In other words, initializing a Cipher is
    444      * equivalent to creating a new instance of that Cipher and initializing
    445      * it.
    446      *
    447      * @param opmode the operation mode of this cipher (this is one of
    448      * the following:
    449      * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,
    450      * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
    451      * @param key the encryption key
    452      * @param params the algorithm parameters
    453      * @param random the source of randomness
    454      *
    455      * @exception InvalidKeyException if the given key is inappropriate for
    456      * initializing this cipher
    457      * @exception InvalidAlgorithmParameterException if the given algorithm
    458      * parameters are inappropriate for this cipher,
    459      * or if this cipher requires
    460      * algorithm parameters and <code>params</code> is null.
    461      * @throws UnsupportedOperationException if {@code opmode} is
    462      * {@code WRAP_MODE} or {@code UNWRAP_MODE} is not implemented
    463      * by the cipher.
    464      */
    465     protected abstract void engineInit(int opmode, Key key,
    466                                        AlgorithmParameters params,
    467                                        SecureRandom random)
    468         throws InvalidKeyException, InvalidAlgorithmParameterException;
    469 
    470     /**
    471      * Continues a multiple-part encryption or decryption operation
    472      * (depending on how this cipher was initialized), processing another data
    473      * part.
    474      *
    475      * <p>The first <code>inputLen</code> bytes in the <code>input</code>
    476      * buffer, starting at <code>inputOffset</code> inclusive, are processed,
    477      * and the result is stored in a new buffer.
    478      *
    479      * @param input the input buffer
    480      * @param inputOffset the offset in <code>input</code> where the input
    481      * starts
    482      * @param inputLen the input length
    483      *
    484      * @return the new buffer with the result, or null if the underlying
    485      * cipher is a block cipher and the input data is too short to result in a
    486      * new block.
    487      */
    488     protected abstract byte[] engineUpdate(byte[] input, int inputOffset,
    489                                            int inputLen);
    490 
    491     /**
    492      * Continues a multiple-part encryption or decryption operation
    493      * (depending on how this cipher was initialized), processing another data
    494      * part.
    495      *
    496      * <p>The first <code>inputLen</code> bytes in the <code>input</code>
    497      * buffer, starting at <code>inputOffset</code> inclusive, are processed,
    498      * and the result is stored in the <code>output</code> buffer, starting at
    499      * <code>outputOffset</code> inclusive.
    500      *
    501      * <p>If the <code>output</code> buffer is too small to hold the result,
    502      * a <code>ShortBufferException</code> is thrown.
    503      *
    504      * @param input the input buffer
    505      * @param inputOffset the offset in <code>input</code> where the input
    506      * starts
    507      * @param inputLen the input length
    508      * @param output the buffer for the result
    509      * @param outputOffset the offset in <code>output</code> where the result
    510      * is stored
    511      *
    512      * @return the number of bytes stored in <code>output</code>
    513      *
    514      * @exception ShortBufferException if the given output buffer is too small
    515      * to hold the result
    516      */
    517     protected abstract int engineUpdate(byte[] input, int inputOffset,
    518                                         int inputLen, byte[] output,
    519                                         int outputOffset)
    520         throws ShortBufferException;
    521 
    522     /**
    523      * Continues a multiple-part encryption or decryption operation
    524      * (depending on how this cipher was initialized), processing another data
    525      * part.
    526      *
    527      * <p>All <code>input.remaining()</code> bytes starting at
    528      * <code>input.position()</code> are processed. The result is stored
    529      * in the output buffer.
    530      * Upon return, the input buffer's position will be equal
    531      * to its limit; its limit will not have changed. The output buffer's
    532      * position will have advanced by n, where n is the value returned
    533      * by this method; the output buffer's limit will not have changed.
    534      *
    535      * <p>If <code>output.remaining()</code> bytes are insufficient to
    536      * hold the result, a <code>ShortBufferException</code> is thrown.
    537      *
    538      * <p>Subclasses should consider overriding this method if they can
    539      * process ByteBuffers more efficiently than byte arrays.
    540      *
    541      * @param input the input ByteBuffer
    542      * @param output the output ByteByffer
    543      *
    544      * @return the number of bytes stored in <code>output</code>
    545      *
    546      * @exception ShortBufferException if there is insufficient space in the
    547      * output buffer
    548      *
    549      * @throws NullPointerException if either parameter is <CODE>null</CODE>
    550      * @since 1.5
    551      */
    552     protected int engineUpdate(ByteBuffer input, ByteBuffer output)
    553             throws ShortBufferException {
    554         try {
    555             return bufferCrypt(input, output, true);
    556         } catch (IllegalBlockSizeException e) {
    557             // never thrown for engineUpdate()
    558             throw new ProviderException("Internal error in update()");
    559         } catch (BadPaddingException e) {
    560             // never thrown for engineUpdate()
    561             throw new ProviderException("Internal error in update()");
    562         }
    563     }
    564 
    565     /**
    566      * Encrypts or decrypts data in a single-part operation,
    567      * or finishes a multiple-part operation.
    568      * The data is encrypted or decrypted, depending on how this cipher was
    569      * initialized.
    570      *
    571      * <p>The first <code>inputLen</code> bytes in the <code>input</code>
    572      * buffer, starting at <code>inputOffset</code> inclusive, and any input
    573      * bytes that may have been buffered during a previous <code>update</code>
    574      * operation, are processed, with padding (if requested) being applied.
    575      * If an AEAD mode such as GCM/CCM is being used, the authentication
    576      * tag is appended in the case of encryption, or verified in the
    577      * case of decryption.
    578      * The result is stored in a new buffer.
    579      *
    580      * <p>Upon finishing, this method resets this cipher object to the state
    581      * it was in when previously initialized via a call to
    582      * <code>engineInit</code>.
    583      * That is, the object is reset and available to encrypt or decrypt
    584      * (depending on the operation mode that was specified in the call to
    585      * <code>engineInit</code>) more data.
    586      *
    587      * <p>Note: if any exception is thrown, this cipher object may need to
    588      * be reset before it can be used again.
    589      *
    590      * @param input the input buffer
    591      * @param inputOffset the offset in <code>input</code> where the input
    592      * starts
    593      * @param inputLen the input length
    594      *
    595      * @return the new buffer with the result
    596      *
    597      * @exception IllegalBlockSizeException if this cipher is a block cipher,
    598      * no padding has been requested (only in encryption mode), and the total
    599      * input length of the data processed by this cipher is not a multiple of
    600      * block size; or if this encryption algorithm is unable to
    601      * process the input data provided.
    602      * @exception BadPaddingException if this cipher is in decryption mode,
    603      * and (un)padding has been requested, but the decrypted data is not
    604      * bounded by the appropriate padding bytes
    605      * @exception AEADBadTagException if this cipher is decrypting in an
    606      * AEAD mode (such as GCM/CCM), and the received authentication tag
    607      * does not match the calculated value
    608      */
    609     protected abstract byte[] engineDoFinal(byte[] input, int inputOffset,
    610                                             int inputLen)
    611         throws IllegalBlockSizeException, BadPaddingException;
    612 
    613     /**
    614      * Encrypts or decrypts data in a single-part operation,
    615      * or finishes a multiple-part operation.
    616      * The data is encrypted or decrypted, depending on how this cipher was
    617      * initialized.
    618      *
    619      * <p>The first <code>inputLen</code> bytes in the <code>input</code>
    620      * buffer, starting at <code>inputOffset</code> inclusive, and any input
    621      * bytes that may have been buffered during a previous <code>update</code>
    622      * operation, are processed, with padding (if requested) being applied.
    623      * If an AEAD mode such as GCM/CCM is being used, the authentication
    624      * tag is appended in the case of encryption, or verified in the
    625      * case of decryption.
    626      * The result is stored in the <code>output</code> buffer, starting at
    627      * <code>outputOffset</code> inclusive.
    628      *
    629      * <p>If the <code>output</code> buffer is too small to hold the result,
    630      * a <code>ShortBufferException</code> is thrown.
    631      *
    632      * <p>Upon finishing, this method resets this cipher object to the state
    633      * it was in when previously initialized via a call to
    634      * <code>engineInit</code>.
    635      * That is, the object is reset and available to encrypt or decrypt
    636      * (depending on the operation mode that was specified in the call to
    637      * <code>engineInit</code>) more data.
    638      *
    639      * <p>Note: if any exception is thrown, this cipher object may need to
    640      * be reset before it can be used again.
    641      *
    642      * @param input the input buffer
    643      * @param inputOffset the offset in <code>input</code> where the input
    644      * starts
    645      * @param inputLen the input length
    646      * @param output the buffer for the result
    647      * @param outputOffset the offset in <code>output</code> where the result
    648      * is stored
    649      *
    650      * @return the number of bytes stored in <code>output</code>
    651      *
    652      * @exception IllegalBlockSizeException if this cipher is a block cipher,
    653      * no padding has been requested (only in encryption mode), and the total
    654      * input length of the data processed by this cipher is not a multiple of
    655      * block size; or if this encryption algorithm is unable to
    656      * process the input data provided.
    657      * @exception ShortBufferException if the given output buffer is too small
    658      * to hold the result
    659      * @exception BadPaddingException if this cipher is in decryption mode,
    660      * and (un)padding has been requested, but the decrypted data is not
    661      * bounded by the appropriate padding bytes
    662      * @exception AEADBadTagException if this cipher is decrypting in an
    663      * AEAD mode (such as GCM/CCM), and the received authentication tag
    664      * does not match the calculated value
    665      */
    666     protected abstract int engineDoFinal(byte[] input, int inputOffset,
    667                                          int inputLen, byte[] output,
    668                                          int outputOffset)
    669         throws ShortBufferException, IllegalBlockSizeException,
    670                BadPaddingException;
    671 
    672     /**
    673      * Encrypts or decrypts data in a single-part operation,
    674      * or finishes a multiple-part operation.
    675      * The data is encrypted or decrypted, depending on how this cipher was
    676      * initialized.
    677      *
    678      * <p>All <code>input.remaining()</code> bytes starting at
    679      * <code>input.position()</code> are processed.
    680      * If an AEAD mode such as GCM/CCM is being used, the authentication
    681      * tag is appended in the case of encryption, or verified in the
    682      * case of decryption.
    683      * The result is stored in the output buffer.
    684      * Upon return, the input buffer's position will be equal
    685      * to its limit; its limit will not have changed. The output buffer's
    686      * position will have advanced by n, where n is the value returned
    687      * by this method; the output buffer's limit will not have changed.
    688      *
    689      * <p>If <code>output.remaining()</code> bytes are insufficient to
    690      * hold the result, a <code>ShortBufferException</code> is thrown.
    691      *
    692      * <p>Upon finishing, this method resets this cipher object to the state
    693      * it was in when previously initialized via a call to
    694      * <code>engineInit</code>.
    695      * That is, the object is reset and available to encrypt or decrypt
    696      * (depending on the operation mode that was specified in the call to
    697      * <code>engineInit</code>) more data.
    698      *
    699      * <p>Note: if any exception is thrown, this cipher object may need to
    700      * be reset before it can be used again.
    701      *
    702      * <p>Subclasses should consider overriding this method if they can
    703      * process ByteBuffers more efficiently than byte arrays.
    704      *
    705      * @param input the input ByteBuffer
    706      * @param output the output ByteByffer
    707      *
    708      * @return the number of bytes stored in <code>output</code>
    709      *
    710      * @exception IllegalBlockSizeException if this cipher is a block cipher,
    711      * no padding has been requested (only in encryption mode), and the total
    712      * input length of the data processed by this cipher is not a multiple of
    713      * block size; or if this encryption algorithm is unable to
    714      * process the input data provided.
    715      * @exception ShortBufferException if there is insufficient space in the
    716      * output buffer
    717      * @exception BadPaddingException if this cipher is in decryption mode,
    718      * and (un)padding has been requested, but the decrypted data is not
    719      * bounded by the appropriate padding bytes
    720      * @exception AEADBadTagException if this cipher is decrypting in an
    721      * AEAD mode (such as GCM/CCM), and the received authentication tag
    722      * does not match the calculated value
    723      *
    724      * @throws NullPointerException if either parameter is <CODE>null</CODE>
    725      * @since 1.5
    726      */
    727     protected int engineDoFinal(ByteBuffer input, ByteBuffer output)
    728             throws ShortBufferException, IllegalBlockSizeException,
    729             BadPaddingException {
    730         return bufferCrypt(input, output, false);
    731     }
    732 
    733     // copied from sun.security.jca.JCAUtil
    734     // will be changed to reference that method once that code has been
    735     // integrated and promoted
    736     static int getTempArraySize(int totalSize) {
    737         return Math.min(4096, totalSize);
    738     }
    739 
    740     /**
    741      * Implementation for encryption using ByteBuffers. Used for both
    742      * engineUpdate() and engineDoFinal().
    743      */
    744     private int bufferCrypt(ByteBuffer input, ByteBuffer output,
    745             boolean isUpdate) throws ShortBufferException,
    746             IllegalBlockSizeException, BadPaddingException {
    747         if ((input == null) || (output == null)) {
    748             throw new NullPointerException
    749                 ("Input and output buffers must not be null");
    750         }
    751         int inPos = input.position();
    752         int inLimit = input.limit();
    753         int inLen = inLimit - inPos;
    754         if (isUpdate && (inLen == 0)) {
    755             return 0;
    756         }
    757         int outLenNeeded = engineGetOutputSize(inLen);
    758         if (output.remaining() < outLenNeeded) {
    759             throw new ShortBufferException("Need at least " + outLenNeeded
    760                 + " bytes of space in output buffer");
    761         }
    762 
    763         boolean a1 = input.hasArray();
    764         boolean a2 = output.hasArray();
    765 
    766         if (a1 && a2) {
    767             byte[] inArray = input.array();
    768             int inOfs = input.arrayOffset() + inPos;
    769             byte[] outArray = output.array();
    770             int outPos = output.position();
    771             int outOfs = output.arrayOffset() + outPos;
    772             int n;
    773             if (isUpdate) {
    774                 n = engineUpdate(inArray, inOfs, inLen, outArray, outOfs);
    775             } else {
    776                 n = engineDoFinal(inArray, inOfs, inLen, outArray, outOfs);
    777             }
    778             input.position(inLimit);
    779             output.position(outPos + n);
    780             return n;
    781         } else if (!a1 && a2) {
    782             int outPos = output.position();
    783             byte[] outArray = output.array();
    784             int outOfs = output.arrayOffset() + outPos;
    785             byte[] inArray = new byte[getTempArraySize(inLen)];
    786             int total = 0;
    787             do {
    788                 int chunk = Math.min(inLen, inArray.length);
    789                 if (chunk > 0) {
    790                     input.get(inArray, 0, chunk);
    791                 }
    792                 int n;
    793                 if (isUpdate || (inLen != chunk)) {
    794                     n = engineUpdate(inArray, 0, chunk, outArray, outOfs);
    795                 } else {
    796                     n = engineDoFinal(inArray, 0, chunk, outArray, outOfs);
    797                 }
    798                 total += n;
    799                 outOfs += n;
    800                 inLen -= chunk;
    801             } while (inLen > 0);
    802             output.position(outPos + total);
    803             return total;
    804         } else { // output is not backed by an accessible byte[]
    805             byte[] inArray;
    806             int inOfs;
    807             if (a1) {
    808                 inArray = input.array();
    809                 inOfs = input.arrayOffset() + inPos;
    810             } else {
    811                 inArray = new byte[getTempArraySize(inLen)];
    812                 inOfs = 0;
    813             }
    814             byte[] outArray = new byte[getTempArraySize(outLenNeeded)];
    815             int outSize = outArray.length;
    816             int total = 0;
    817             boolean resized = false;
    818             do {
    819                 int chunk =
    820                     Math.min(inLen, (outSize == 0? inArray.length : outSize));
    821                 if (!a1 && !resized && chunk > 0) {
    822                     input.get(inArray, 0, chunk);
    823                     inOfs = 0;
    824                 }
    825                 try {
    826                     int n;
    827                     if (isUpdate || (inLen != chunk)) {
    828                         n = engineUpdate(inArray, inOfs, chunk, outArray, 0);
    829                     } else {
    830                         n = engineDoFinal(inArray, inOfs, chunk, outArray, 0);
    831                     }
    832                     resized = false;
    833                     inOfs += chunk;
    834                     inLen -= chunk;
    835                     if (n > 0) {
    836                         output.put(outArray, 0, n);
    837                         total += n;
    838                     }
    839                 } catch (ShortBufferException e) {
    840                     if (resized) {
    841                         // we just resized the output buffer, but it still
    842                         // did not work. Bug in the provider, abort
    843                         throw (ProviderException)new ProviderException
    844                             ("Could not determine buffer size").initCause(e);
    845                     }
    846                     // output buffer is too small, realloc and try again
    847                     resized = true;
    848                     outSize = engineGetOutputSize(chunk);
    849                     outArray = new byte[outSize];
    850                 }
    851             } while (inLen > 0);
    852             if (a1) {
    853                 input.position(inLimit);
    854             }
    855             return total;
    856         }
    857     }
    858 
    859     /**
    860      * Wrap a key.
    861      *
    862      * <p>This concrete method has been added to this previously-defined
    863      * abstract class. (For backwards compatibility, it cannot be abstract.)
    864      * It may be overridden by a provider to wrap a key.
    865      * Such an override is expected to throw an IllegalBlockSizeException or
    866      * InvalidKeyException (under the specified circumstances),
    867      * if the given key cannot be wrapped.
    868      * If this method is not overridden, it always throws an
    869      * UnsupportedOperationException.
    870      *
    871      * @param key the key to be wrapped.
    872      *
    873      * @return the wrapped key.
    874      *
    875      * @exception IllegalBlockSizeException if this cipher is a block cipher,
    876      * no padding has been requested, and the length of the encoding of the
    877      * key to be wrapped is not a multiple of the block size.
    878      *
    879      * @exception InvalidKeyException if it is impossible or unsafe to
    880      * wrap the key with this cipher (e.g., a hardware protected key is
    881      * being passed to a software-only cipher).
    882      *
    883      * @throws UnsupportedOperationException if this method is not supported.
    884      */
    885     protected byte[] engineWrap(Key key)
    886         throws IllegalBlockSizeException, InvalidKeyException
    887     {
    888         throw new UnsupportedOperationException();
    889     }
    890 
    891     /**
    892      * Unwrap a previously wrapped key.
    893      *
    894      * <p>This concrete method has been added to this previously-defined
    895      * abstract class. (For backwards compatibility, it cannot be abstract.)
    896      * It may be overridden by a provider to unwrap a previously wrapped key.
    897      * Such an override is expected to throw an InvalidKeyException if
    898      * the given wrapped key cannot be unwrapped.
    899      * If this method is not overridden, it always throws an
    900      * UnsupportedOperationException.
    901      *
    902      * @param wrappedKey the key to be unwrapped.
    903      *
    904      * @param wrappedKeyAlgorithm the algorithm associated with the wrapped
    905      * key.
    906      *
    907      * @param wrappedKeyType the type of the wrapped key. This is one of
    908      * <code>SECRET_KEY</code>, <code>PRIVATE_KEY</code>, or
    909      * <code>PUBLIC_KEY</code>.
    910      *
    911      * @return the unwrapped key.
    912      *
    913      * @exception NoSuchAlgorithmException if no installed providers
    914      * can create keys of type <code>wrappedKeyType</code> for the
    915      * <code>wrappedKeyAlgorithm</code>.
    916      *
    917      * @exception InvalidKeyException if <code>wrappedKey</code> does not
    918      * represent a wrapped key of type <code>wrappedKeyType</code> for
    919      * the <code>wrappedKeyAlgorithm</code>.
    920      *
    921      * @throws UnsupportedOperationException if this method is not supported.
    922      */
    923     protected Key engineUnwrap(byte[] wrappedKey,
    924                                String wrappedKeyAlgorithm,
    925                                int wrappedKeyType)
    926         throws InvalidKeyException, NoSuchAlgorithmException
    927     {
    928         throw new UnsupportedOperationException();
    929     }
    930 
    931     /**
    932      * Returns the key size of the given key object in bits.
    933      * <p>This concrete method has been added to this previously-defined
    934      * abstract class. It throws an <code>UnsupportedOperationException</code>
    935      * if it is not overridden by the provider.
    936      *
    937      * @param key the key object.
    938      *
    939      * @return the key size of the given key object.
    940      *
    941      * @exception InvalidKeyException if <code>key</code> is invalid.
    942      */
    943     protected int engineGetKeySize(Key key)
    944         throws InvalidKeyException
    945     {
    946         throw new UnsupportedOperationException();
    947     }
    948 
    949     /**
    950      * Continues a multi-part update of the Additional Authentication
    951      * Data (AAD), using a subset of the provided buffer.
    952      * <p>
    953      * Calls to this method provide AAD to the cipher when operating in
    954      * modes such as AEAD (GCM/CCM).  If this cipher is operating in
    955      * either GCM or CCM mode, all AAD must be supplied before beginning
    956      * operations on the ciphertext (via the {@code update} and {@code
    957      * doFinal} methods).
    958      *
    959      * @param src the buffer containing the AAD
    960      * @param offset the offset in {@code src} where the AAD input starts
    961      * @param len the number of AAD bytes
    962      *
    963      * @throws IllegalStateException if this cipher is in a wrong state
    964      * (e.g., has not been initialized), does not accept AAD, or if
    965      * operating in either GCM or CCM mode and one of the {@code update}
    966      * methods has already been called for the active
    967      * encryption/decryption operation
    968      * @throws UnsupportedOperationException if this method
    969      * has not been overridden by an implementation
    970      *
    971      * @since 1.7
    972      */
    973     protected void engineUpdateAAD(byte[] src, int offset, int len) {
    974         throw new UnsupportedOperationException(
    975             "The underlying Cipher implementation "
    976             +  "does not support this method");
    977     }
    978 
    979     /**
    980      * Continues a multi-part update of the Additional Authentication
    981      * Data (AAD).
    982      * <p>
    983      * Calls to this method provide AAD to the cipher when operating in
    984      * modes such as AEAD (GCM/CCM).  If this cipher is operating in
    985      * either GCM or CCM mode, all AAD must be supplied before beginning
    986      * operations on the ciphertext (via the {@code update} and {@code
    987      * doFinal} methods).
    988      * <p>
    989      * All {@code src.remaining()} bytes starting at
    990      * {@code src.position()} are processed.
    991      * Upon return, the input buffer's position will be equal
    992      * to its limit; its limit will not have changed.
    993      *
    994      * @param src the buffer containing the AAD
    995      *
    996      * @throws IllegalStateException if this cipher is in a wrong state
    997      * (e.g., has not been initialized), does not accept AAD, or if
    998      * operating in either GCM or CCM mode and one of the {@code update}
    999      * methods has already been called for the active
   1000      * encryption/decryption operation
   1001      * @throws UnsupportedOperationException if this method
   1002      * has not been overridden by an implementation
   1003      *
   1004      * @since 1.7
   1005      */
   1006     protected void engineUpdateAAD(ByteBuffer src) {
   1007         throw new UnsupportedOperationException(
   1008             "The underlying Cipher implementation "
   1009             +  "does not support this method");
   1010     }
   1011 }
   1012