/*
 * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package javax.crypto;

import java.nio.ByteBuffer;
import java.security.*;
import java.security.spec.AlgorithmParameterSpec;

/**
 * This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
 * for the {@code Cipher} class.
 * All the abstract methods in this class must be implemented by each
 * cryptographic service provider who wishes to supply the implementation
 * of a particular cipher algorithm.
 *
 * <p>In order to create an instance of {@code Cipher}, which
 * encapsulates an instance of this {@code CipherSpi} class, an
 * application calls one of the
 * {@link Cipher#getInstance(java.lang.String) getInstance}
 * factory methods of the
 * {@link Cipher Cipher} engine class and specifies the requested
 * <i>transformation</i>.
 * Optionally, the application may also specify the name of a provider.
 *
 * <p>A <i>transformation</i> is a string that describes the operation (or
 * set of operations) to be performed on the given input, to produce some
 * output. A transformation always includes the name of a cryptographic
 * algorithm (e.g., <i>AES</i>), and may be followed by a feedback mode and
 * padding scheme.
 *
 * <p> A transformation is of the form:
 *
 * <ul>
 * <li>"<i>algorithm/mode/padding</i>" or
 *
 * <li>"<i>algorithm</i>"
 * </ul>
 *
 * <P> (in the latter case,
 * provider-specific default values for the mode and padding scheme are used).
 * For example, the following is a valid transformation:
 *
 * <pre>
 *     Cipher c = Cipher.getInstance("<i>AES/CBC/PKCS5Padding</i>");
 * </pre>
 *
 * <p>A provider may supply a separate class for each combination
 * of <i>algorithm/mode/padding</i>, or may decide to provide more generic
 * classes representing sub-transformations corresponding to
 * <i>algorithm</i> or <i>algorithm/mode</i> or <i>algorithm//padding</i>
 * (note the double slashes),
 * in which case the requested mode and/or padding are set automatically by
 * the {@code getInstance} methods of {@code Cipher}, which invoke
 * the {@link #engineSetMode(java.lang.String) engineSetMode} and
 * {@link #engineSetPadding(java.lang.String) engineSetPadding}
 * methods of the provider's subclass of {@code CipherSpi}.
 *
 * <p>A {@code Cipher} property in a provider master class may have one of
 * the following formats:
 *
 * <ul>
 *
 * <li>
 * <pre>
 *     // provider's subclass of "CipherSpi" implements "algName" with
 *     // pluggable mode and padding
 *     {@code Cipher.}<i>algName</i>
 * </pre>
 *
 * <li>
 * <pre>
 *     // provider's subclass of "CipherSpi" implements "algName" in the
 *     // specified "mode", with pluggable padding
 *     {@code Cipher.}<i>algName/mode</i>
 * </pre>
 *
 * <li>
 * <pre>
 *     // provider's subclass of "CipherSpi" implements "algName" with the
 *     // specified "padding", with pluggable mode
 *     {@code Cipher.}<i>algName//padding</i>
 * </pre>
 *
 * <li>
 * <pre>
 *     // provider's subclass of "CipherSpi" implements "algName" with the
 *     // specified "mode" and "padding"
 *     {@code Cipher.}<i>algName/mode/padding</i>
 * </pre>
 *
 * </ul>
 *
 * <p>For example, a provider may supply a subclass of {@code CipherSpi}
 * that implements <i>AES/ECB/PKCS5Padding</i>, one that implements
 * <i>AES/CBC/PKCS5Padding</i>, one that implements
 * <i>AES/CFB/PKCS5Padding</i>, and yet another one that implements
 * <i>AES/OFB/PKCS5Padding</i>. That provider would have the following
 * {@code Cipher} properties in its master class:
 *
 * <ul>
 *
 * <li>
 * <pre>
 *     {@code Cipher.}<i>AES/ECB/PKCS5Padding</i>
 * </pre>
 *
 * <li>
 * <pre>
 *     {@code Cipher.}<i>AES/CBC/PKCS5Padding</i>
 * </pre>
 *
 * <li>
 * <pre>
 *     {@code Cipher.}<i>AES/CFB/PKCS5Padding</i>
 * </pre>
 *
 * <li>
 * <pre>
 *     {@code Cipher.}<i>AES/OFB/PKCS5Padding</i>
 * </pre>
 *
 * </ul>
 *
 * <p>Another provider may implement a class for each of the above modes
 * (i.e., one class for <i>ECB</i>, one for <i>CBC</i>, one for <i>CFB</i>,
 * and one for <i>OFB</i>), one class for <i>PKCS5Padding</i>,
 * and a generic <i>AES</i> class that subclasses from {@code CipherSpi}.
 * That provider would have the following
 * {@code Cipher} properties in its master class:
 *
 * <ul>
 *
 * <li>
 * <pre>
 *     {@code Cipher.}<i>AES</i>
 * </pre>
 *
 * </ul>
 *
 * <p>The {@code getInstance} factory method of the {@code Cipher}
 * engine class follows these rules in order to instantiate a provider's
 * implementation of {@code CipherSpi} for a
 * transformation of the form "<i>algorithm</i>":
 *
 * <ol>
 * <li>
 * Check if the provider has registered a subclass of {@code CipherSpi}
 * for the specified "<i>algorithm</i>".
 * <p>If the answer is YES, instantiate this
 * class, for whose mode and padding scheme default values (as supplied by
 * the provider) are used.
 * <p>If the answer is NO, throw a {@code NoSuchAlgorithmException}
 * exception.
 * </ol>
 *
 * <p>The {@code getInstance} factory method of the {@code Cipher}
 * engine class follows these rules in order to instantiate a provider's
 * implementation of {@code CipherSpi} for a
 * transformation of the form "<i>algorithm/mode/padding</i>":
 *
 * <ol>
 * <li>
 * Check if the provider has registered a subclass of {@code CipherSpi}
 * for the specified "<i>algorithm/mode/padding</i>" transformation.
 * <p>If the answer is YES, instantiate it.
 * <p>If the answer is NO, go to the next step.
 * <li>
 * Check if the provider has registered a subclass of {@code CipherSpi}
 * for the sub-transformation "<i>algorithm/mode</i>".
 * <p>If the answer is YES, instantiate it, and call
 * {@code engineSetPadding(<i>padding</i>)} on the new instance.
 * <p>If the answer is NO, go to the next step.
 * <li>
 * Check if the provider has registered a subclass of {@code CipherSpi}
 * for the sub-transformation "<i>algorithm//padding</i>" (note the double
 * slashes).
 * <p>If the answer is YES, instantiate it, and call
 * {@code engineSetMode(<i>mode</i>)} on the new instance.
 * <p>If the answer is NO, go to the next step.
 * <li>
 * Check if the provider has registered a subclass of {@code CipherSpi}
 * for the sub-transformation "<i>algorithm</i>".
 * <p>If the answer is YES, instantiate it, and call
 * {@code engineSetMode(<i>mode</i>)} and
 * {@code engineSetPadding(<i>padding</i>)} on the new instance.
 * <p>If the answer is NO, throw a {@code NoSuchAlgorithmException}
 * exception.
 * </ol>
 *
 * @author Jan Luehe
 * @see KeyGenerator
 * @see SecretKey
 * @since 1.4
 */

public abstract class CipherSpi {

    /**
     * Constructor for subclasses to call.
     */
    public CipherSpi() {}

    /**
     * Sets the mode of this cipher.
     *
     * @param mode the cipher mode
     *
     * @throws NoSuchAlgorithmException if the requested cipher mode
     * does not exist
     */
    protected abstract void engineSetMode(String mode)
        throws NoSuchAlgorithmException;

    /**
     * Sets the padding mechanism of this cipher.
     *
     * @param padding the padding mechanism
     *
     * @throws NoSuchPaddingException if the requested padding mechanism
     * does not exist
     */
    protected abstract void engineSetPadding(String padding)
        throws NoSuchPaddingException;

    /**
     * Returns the block size (in bytes).
     *
     * @return the block size (in bytes), or 0 if the algorithm is
     * not a block cipher
     */
    protected abstract int engineGetBlockSize();

    /**
     * Returns the length in bytes that an output buffer would
     * need to be in order to hold the result of the next {@code update}
     * or {@code doFinal} operation, given the input length
     * {@code inputLen} (in bytes).
     *
     * <p>This call takes into account any unprocessed (buffered) data from a
     * previous {@code update} call, padding, and AEAD tagging.
     *
     * <p>The actual output length of the next {@code update} or
     * {@code doFinal} call may be smaller than the length returned by
     * this method.
     *
     * @param inputLen the input length (in bytes)
     *
     * @return the required output buffer size (in bytes)
     */
    protected abstract int engineGetOutputSize(int inputLen);

    /**
     * Returns the initialization vector (IV) in a new buffer.
     *
     * <p> This is useful in the context of password-based encryption or
     * decryption, where the IV is derived from a user-provided passphrase.
     *
     * @return the initialization vector in a new buffer, or {@code null} if the
     * algorithm does not use an IV, or if the IV has not yet
     * been set
     */
    protected abstract byte[] engineGetIV();

    /**
     * Returns the parameters used with this cipher.
     *
     * <p>The returned parameters may be the same that were used to initialize
     * this cipher, or may contain additional default or random parameter
     * values used by the underlying cipher implementation. If the required
     * parameters were not supplied and can be generated by the cipher, the
     * generated parameters are returned. Otherwise, {@code null} is returned.
     *
     * @return the parameters used with this cipher, or {@code null}
     */
    protected abstract AlgorithmParameters engineGetParameters();

    /**
     * Initializes this {@code CipherSpi} object with a key and a source
     * of randomness.
     *
     * <p>The {@code CipherSpi} object is initialized for one of the
     * following four operations:
     * encryption, decryption, key wrapping or key unwrapping, depending on
     * the value of {@code opmode}.
     *
     * <p>If this cipher requires any algorithm parameters that cannot be
     * derived from the given {@code key}, the underlying cipher
     * implementation is supposed to generate the required parameters itself
     * (using provider-specific default or random values) if it is being
     * initialized for encryption or key wrapping, and raise an
     * {@code InvalidKeyException} if it is being
     * initialized for decryption or key unwrapping.
     * The generated parameters can be retrieved using
     * {@link #engineGetParameters() engineGetParameters} or
     * {@link #engineGetIV() engineGetIV} (if the parameter is an IV).
     *
     * <p>If this cipher requires algorithm parameters that cannot be
     * derived from the input parameters, and there are no reasonable
     * provider-specific default values, initialization will
     * necessarily fail.
     *
     * <p>If this cipher (including its feedback or padding scheme)
     * requires any random bytes (e.g., for parameter generation), it will get
     * them from {@code random}.
     *
     * <p>Note that when a {@code CipherSpi} object is initialized, it loses all
     * previously-acquired state. In other words, initializing a
     * {@code CipherSpi} object is equivalent to creating a new instance
     * of that {@code CipherSpi} object and initializing it.
     *
     * @param opmode the operation mode of this {@code CipherSpi} object
     * (this is one of the following:
     * {@code ENCRYPT_MODE}, {@code DECRYPT_MODE},
     * {@code WRAP_MODE} or {@code UNWRAP_MODE})
     * @param key the encryption key
     * @param random the source of randomness
     *
     * @throws InvalidKeyException if the given key is inappropriate for
     * initializing this cipher, or requires
     * algorithm parameters that cannot be
     * determined from the given key
     * @throws UnsupportedOperationException if {@code opmode} is
     * {@code WRAP_MODE} or {@code UNWRAP_MODE} is not implemented
     * by the cipher
     */
    protected abstract void engineInit(int opmode, Key key,
                                       SecureRandom random)
        throws InvalidKeyException;

    /**
     * Initializes this {@code CipherSpi} object with a key, a set of
     * algorithm parameters, and a source of randomness.
     *
     * <p>The {@code CipherSpi} object is initialized for one of the
     * following four operations:
     * encryption, decryption, key wrapping or key unwrapping, depending on
     * the value of {@code opmode}.
     *
     * <p>If this cipher requires any algorithm parameters and
     * {@code params} is {@code null}, the underlying cipher implementation
     * is supposed to generate the required parameters itself (using
     * provider-specific default or random values) if it is being
     * initialized for encryption or key wrapping, and raise an
     * {@code InvalidAlgorithmParameterException} if it is being
     * initialized for decryption or key unwrapping.
     * The generated parameters can be retrieved using
     * {@link #engineGetParameters() engineGetParameters} or
     * {@link #engineGetIV() engineGetIV} (if the parameter is an IV).
     *
     * <p>If this cipher requires algorithm parameters that cannot be
     * derived from the input parameters, and there are no reasonable
     * provider-specific default values, initialization will
     * necessarily fail.
     *
     * <p>If this cipher (including its feedback or padding scheme)
     * requires any random bytes (e.g., for parameter generation), it will get
     * them from {@code random}.
     *
     * <p>Note that when a {@code CipherSpi} object is initialized, it loses all
     * previously-acquired state. In other words, initializing a
     * {@code CipherSpi} object is equivalent to creating a new instance of that
     * {@code CipherSpi} object and initializing it.
     *
     * @param opmode the operation mode of this {@code CipherSpi} object
     * (this is one of the following:
     * {@code ENCRYPT_MODE}, {@code DECRYPT_MODE},
     * {@code WRAP_MODE}, or {@code UNWRAP_MODE})
     * @param key the encryption key
     * @param params the algorithm parameters
     * @param random the source of randomness
     *
     * @throws InvalidKeyException if the given key is inappropriate for
     * initializing this cipher
     * @throws InvalidAlgorithmParameterException if the given algorithm
     * parameters are inappropriate for this cipher,
     * or if this cipher requires
     * algorithm parameters and {@code params} is {@code null}
     * @throws UnsupportedOperationException if {@code opmode} is
     * {@code WRAP_MODE} or {@code UNWRAP_MODE} is not implemented
     * by the cipher
     */
    protected abstract void engineInit(int opmode, Key key,
                                       AlgorithmParameterSpec params,
                                       SecureRandom random)
        throws InvalidKeyException, InvalidAlgorithmParameterException;

    /**
     * Initializes this {@code CipherSpi} object with a key, a set of
     * algorithm parameters, and a source of randomness.
     *
     * <p>The {@code CipherSpi} object is initialized for one of the
     * following four operations:
     * encryption, decryption, key wrapping or key unwrapping, depending on
     * the value of {@code opmode}.
     *
     * <p>If this cipher requires any algorithm parameters and
     * {@code params} is {@code null}, the underlying cipher implementation is
     * supposed to generate the required parameters itself (using
     * provider-specific default or random values) if it is being
     * initialized for encryption or key wrapping, and raise an
     * {@code InvalidAlgorithmParameterException} if it is being
     * initialized for decryption or key unwrapping.
     * The generated parameters can be retrieved using
     * {@link #engineGetParameters() engineGetParameters} or
     * {@link #engineGetIV() engineGetIV} (if the parameter is an IV).
     *
     * <p>If this cipher requires algorithm parameters that cannot be
     * derived from the input parameters, and there are no reasonable
     * provider-specific default values, initialization will
     * necessarily fail.
     *
     * <p>If this cipher (including its feedback or padding scheme)
     * requires any random bytes (e.g., for parameter generation), it will get
     * them from {@code random}.
     *
     * <p>Note that when a {@code CipherSpi} object is initialized, it loses all
     * previously-acquired state. In other words, initializing a
     * {@code CipherSpi} object is equivalent to creating a new instance of that
     * {@code CipherSpi} object and initializing it.
     *
     * @param opmode the operation mode of this {@code CipherSpi} object
     * (this is one of the following:
     * {@code ENCRYPT_MODE}, {@code DECRYPT_MODE},
     * {@code WRAP_MODE}, or {@code UNWRAP_MODE})
     * @param key the encryption key
     * @param params the algorithm parameters
     * @param random the source of randomness
     *
     * @throws InvalidKeyException if the given key is inappropriate for
     * initializing this cipher
     * @throws InvalidAlgorithmParameterException if the given algorithm
     * parameters are inappropriate for this cipher,
     * or if this cipher requires
     * algorithm parameters and {@code params} is null
     * @throws UnsupportedOperationException if {@code opmode} is
     * {@code WRAP_MODE} or {@code UNWRAP_MODE} is not implemented
     * by the cipher
     */
    protected abstract void engineInit(int opmode, Key key,
                                       AlgorithmParameters params,
                                       SecureRandom random)
        throws InvalidKeyException, InvalidAlgorithmParameterException;

    /**
     * Continues a multiple-part encryption or decryption operation
     * (depending on how this {@code CipherSpi} object was initialized),
     * processing another data part.
     *
     * <p>The first {@code inputLen} bytes in the {@code input}
     * buffer, starting at {@code inputOffset} inclusive, are processed,
     * and the result is stored in a new buffer.
     *
     * @param input the input buffer
     * @param inputOffset the offset in {@code input} where the input starts
     * @param inputLen the input length
     *
     * @return the new buffer with the result, or {@code null} if the
     * cipher is a block cipher and the input data is too short to result in a
     * new block
     */
    protected abstract byte[] engineUpdate(byte[] input, int inputOffset,
                                           int inputLen);

    /**
     * Continues a multiple-part encryption or decryption operation
     * (depending on how this {@code CipherSpi} object was initialized),
     * processing another data part.
     *
     * <p>The first {@code inputLen} bytes in the {@code input}
     * buffer, starting at {@code inputOffset} inclusive, are processed,
     * and the result is stored in the {@code output} buffer, starting at
     * {@code outputOffset} inclusive.
     *
     * <p>If the {@code output} buffer is too small to hold the result,
     * a {@code ShortBufferException} is thrown.
     *
     * @param input the input buffer
     * @param inputOffset the offset in {@code input} where the input
     * starts
     * @param inputLen the input length
     * @param output the buffer for the result
     * @param outputOffset the offset in {@code output} where the result
     * is stored
     *
     * @return the number of bytes stored in {@code output}
     *
     * @throws ShortBufferException if the given output buffer is too small
     * to hold the result
     */
    protected abstract int engineUpdate(byte[] input, int inputOffset,
                                        int inputLen, byte[] output,
                                        int outputOffset)
        throws ShortBufferException;

    /**
     * Continues a multiple-part encryption or decryption operation
     * (depending on how this {@code CipherSpi} object was initialized),
     * processing another data part.
     *
     * <p>All {@code input.remaining()} bytes starting at
     * {@code input.position()} are processed. The result is stored
     * in the output buffer.
     * Upon return, the input buffer's position will be equal
     * to its limit; its limit will not have changed. The output buffer's
     * position will have advanced by n, where n is the value returned
     * by this method; the output buffer's limit will not have changed.
     *
     * <p>If {@code output.remaining()} bytes are insufficient to
     * hold the result, a {@code ShortBufferException} is thrown.
     *
     * <p>Subclasses should consider overriding this method if they can
     * process ByteBuffers more efficiently than byte arrays.
     *
     * @param input the input ByteBuffer
     * @param output the output ByteBuffer
     *
     * @return the number of bytes stored in {@code output}
     *
     * @throws ShortBufferException if there is insufficient space in the
     * output buffer
     *
     * @throws NullPointerException if either parameter is {@code null}
     * @since 1.5
     */
    protected int engineUpdate(ByteBuffer input, ByteBuffer output)
            throws ShortBufferException {
        try {
            return bufferCrypt(input, output, true);
        } catch (IllegalBlockSizeException | BadPaddingException e) {
            // never thrown for engineUpdate()
            throw new ProviderException("Internal error in update()");
        }
    }

    /**
     * Encrypts or decrypts data in a single-part operation,
     * or finishes a multiple-part operation.
     * The data is encrypted or decrypted, depending on how this
     * {@code CipherSpi} object was initialized.
     *
     * <p>The first {@code inputLen} bytes in the {@code input}
     * buffer, starting at {@code inputOffset} inclusive, and any input
     * bytes that may have been buffered during a previous {@code update}
     * operation, are processed, with padding (if requested) being applied.
     * If an AEAD mode (such as GCM or CCM) is being used, the authentication
     * tag is appended in the case of encryption, or verified in the
     * case of decryption.
     * The result is stored in a new buffer.
     *
     * <p>Upon finishing, this method resets this {@code CipherSpi} object
     * to the state it was in when previously initialized via a call to
     * {@code engineInit}.
     * That is, the object is reset and available to encrypt or decrypt
     * (depending on the operation mode that was specified in the call to
     * {@code engineInit}) more data.
     *
     * <p>Note: if any exception is thrown, this {@code CipherSpi} object
     * may need to be reset before it can be used again.
     *
     * @param input the input buffer
     * @param inputOffset the offset in {@code input} where the input starts
     * @param inputLen the input length
     *
     * @return the new buffer with the result
     *
     * @throws IllegalBlockSizeException if this cipher is a block cipher,
     * no padding has been requested (only in encryption mode), and the total
     * input length of the data processed by this cipher is not a multiple of
     * block size; or if this encryption algorithm is unable to
     * process the input data provided
     * @throws BadPaddingException if this {@code CipherSpi} object is in
     * decryption mode, and (un)padding has been requested, but the decrypted
     * data is not bounded by the appropriate padding bytes
     * @throws AEADBadTagException if this {@code CipherSpi} object is
     * decrypting in an AEAD mode (such as GCM or CCM), and the received
     * authentication tag does not match the calculated value
     */
    protected abstract byte[] engineDoFinal(byte[] input, int inputOffset,
                                            int inputLen)
        throws IllegalBlockSizeException, BadPaddingException;

    /**
     * Encrypts or decrypts data in a single-part operation,
     * or finishes a multiple-part operation.
     * The data is encrypted or decrypted, depending on how this
     * {@code CipherSpi} object was initialized.
     *
     * <p>The first {@code inputLen} bytes in the {@code input}
     * buffer, starting at {@code inputOffset} inclusive, and any input
     * bytes that may have been buffered during a previous {@code update}
     * operation, are processed, with padding (if requested) being applied.
     * If an AEAD mode such as GCM or CCM is being used, the authentication
     * tag is appended in the case of encryption, or verified in the
     * case of decryption.
     * The result is stored in the {@code output} buffer, starting at
     * {@code outputOffset} inclusive.
     *
     * <p>If the {@code output} buffer is too small to hold the result,
     * a {@code ShortBufferException} is thrown.
     *
     * <p>Upon finishing, this method resets this {@code CipherSpi} object
     * to the state it was in when previously initialized via a call to
     * {@code engineInit}.
     * That is, the object is reset and available to encrypt or decrypt
     * (depending on the operation mode that was specified in the call to
     * {@code engineInit}) more data.
     *
     * <p>Note: if any exception is thrown, this {@code CipherSpi} object
     * may need to be reset before it can be used again.
     *
     * @param input the input buffer
     * @param inputOffset the offset in {@code input} where the input
     * starts
     * @param inputLen the input length
     * @param output the buffer for the result
     * @param outputOffset the offset in {@code output} where the result
     * is stored
     *
     * @return the number of bytes stored in {@code output}
     *
     * @throws IllegalBlockSizeException if this cipher is a block cipher,
     * no padding has been requested (only in encryption mode), and the total
     * input length of the data processed by this cipher is not a multiple of
     * block size; or if this encryption algorithm is unable to
     * process the input data provided
     * @throws ShortBufferException if the given output buffer is too small
     * to hold the result
     * @throws BadPaddingException if this {@code CipherSpi} object is in
     * decryption mode,
     * and (un)padding has been requested, but the decrypted data is not
     * bounded by the appropriate padding bytes
     * @throws AEADBadTagException if this {@code CipherSpi} object is
     * decrypting in an AEAD mode (such as GCM or CCM), and the received
     * authentication tag does not match the calculated value
     */
    protected abstract int engineDoFinal(byte[] input, int inputOffset,
                                         int inputLen, byte[] output,
                                         int outputOffset)
        throws ShortBufferException, IllegalBlockSizeException,
               BadPaddingException;

    /**
     * Encrypts or decrypts data in a single-part operation,
     * or finishes a multiple-part operation.
     * The data is encrypted or decrypted, depending on how this
     * {@code CipherSpi} object was initialized.
     *
     * <p>All {@code input.remaining()} bytes starting at
     * {@code input.position()} are processed.
     * If an AEAD mode such as GCM or CCM is being used, the authentication
     * tag is appended in the case of encryption, or verified in the
     * case of decryption.
     * The result is stored in the output buffer.
     * Upon return, the input buffer's position will be equal
     * to its limit; its limit will not have changed. The output buffer's
     * position will have advanced by n, where n is the value returned
     * by this method; the output buffer's limit will not have changed.
     *
     * <p>If {@code output.remaining()} bytes are insufficient to
     * hold the result, a {@code ShortBufferException} is thrown.
     *
     * <p>Upon finishing, this method resets this {@code CipherSpi} object
     * to the state it was in when previously initialized via a call to
     * {@code engineInit}.
     * That is, the object is reset and available to encrypt or decrypt
     * (depending on the operation mode that was specified in the call to
     * {@code engineInit} more data.
     *
     * <p>Note: if any exception is thrown, this {@code CipherSpi} object
     * may need to be reset before it can be used again.
     *
     * <p>Subclasses should consider overriding this method if they can
     * process ByteBuffers more efficiently than byte arrays.
     *
     * @param input the input ByteBuffer
     * @param output the output ByteBuffer
     *
     * @return the number of bytes stored in {@code output}
     *
     * @throws IllegalBlockSizeException if this cipher is a block cipher,
     * no padding has been requested (only in encryption mode), and the total
     * input length of the data processed by this cipher is not a multiple of
     * block size; or if this encryption algorithm is unable to
     * process the input data provided
     * @throws ShortBufferException if there is insufficient space in the
     * output buffer
     * @throws BadPaddingException if this {@code CipherSpi} object is in
     * decryption mode, and (un)padding has been requested, but the decrypted
     * data is not bounded by the appropriate padding bytes
     * @throws AEADBadTagException if this {@code CipherSpi} object is
     * decrypting in an AEAD mode (such as GCM or CCM), and the received
     * authentication tag does not match the calculated value
     *
     * @throws NullPointerException if either parameter is {@code null}
     * @since 1.5
     */
    protected int engineDoFinal(ByteBuffer input, ByteBuffer output)
            throws ShortBufferException, IllegalBlockSizeException,
            BadPaddingException {
        return bufferCrypt(input, output, false);
    }

    // copied from sun.security.jca.JCAUtil
    // will be changed to reference that method once that code has been
    // integrated and promoted
    static int getTempArraySize(int totalSize) {
        return Math.min(4096, totalSize);
    }

    /**
     * Implementation for encryption using ByteBuffers. Used for both
     * engineUpdate() and engineDoFinal().
     */
    private int bufferCrypt(ByteBuffer input, ByteBuffer output,
            boolean isUpdate) throws ShortBufferException,
            IllegalBlockSizeException, BadPaddingException {
        if ((input == null) || (output == null)) {
            throw new NullPointerException
                ("Input and output buffers must not be null");
        }
        int inPos = input.position();
        int inLimit = input.limit();
        int inLen = inLimit - inPos;
        if (isUpdate && (inLen == 0)) {
            return 0;
        }
        int outLenNeeded = engineGetOutputSize(inLen);

        if (output.remaining() < outLenNeeded) {
            throw new ShortBufferException("Need at least " + outLenNeeded
                + " bytes of space in output buffer");
        }

        // detecting input and output buffer overlap may be tricky
        // we can only write directly into output buffer when we
        // are 100% sure it's safe to do so

        boolean a1 = input.hasArray();
        boolean a2 = output.hasArray();
        int total = 0;

        if (a1) { // input has an accessible byte[]
            byte[] inArray = input.array();
            int inOfs = input.arrayOffset() + inPos;

            byte[] outArray;
            if (a2) { // output has an accessible byte[]
                outArray = output.array();
                int outPos = output.position();
                int outOfs = output.arrayOffset() + outPos;

                // check array address and offsets and use temp output buffer
                // if output offset is larger than input offset and
                // falls within the range of input data
                boolean useTempOut = false;
                if (inArray == outArray &&
                    ((inOfs < outOfs) && (outOfs < inOfs + inLen))) {
                    useTempOut = true;
                    outArray = new byte[outLenNeeded];
                    outOfs = 0;
                }
                if (isUpdate) {
                    total = engineUpdate(inArray, inOfs, inLen, outArray, outOfs);
                } else {
                    total = engineDoFinal(inArray, inOfs, inLen, outArray, outOfs);
                }
                if (useTempOut) {
                    output.put(outArray, outOfs, total);
                } else {
                    // adjust output position manually
                    output.position(outPos + total);
                }
            } else { // output does not have an accessible byte[]
                if (isUpdate) {
                    outArray = engineUpdate(inArray, inOfs, inLen);
                } else {
                    outArray = engineDoFinal(inArray, inOfs, inLen);
                }
                if (outArray != null && outArray.length != 0) {
                    output.put(outArray);
                    total = outArray.length;
                }
            }
            // adjust input position manually
            input.position(inLimit);
        } else { // input does not have an accessible byte[]
            // have to assume the worst, since we have no way of determine
            // if input and output overlaps or not
            byte[] tempOut = new byte[outLenNeeded];
            int outOfs = 0;

            byte[] tempIn = new byte[getTempArraySize(inLen)];
            do {
                int chunk = Math.min(inLen, tempIn.length);
                if (chunk > 0) {
                    input.get(tempIn, 0, chunk);
                }
                int n;
                if (isUpdate || (inLen > chunk)) {
                    n = engineUpdate(tempIn, 0, chunk, tempOut, outOfs);
                } else {
                    n = engineDoFinal(tempIn, 0, chunk, tempOut, outOfs);
                }
                outOfs += n;
                total += n;
                inLen -= chunk;
            } while (inLen > 0);
            if (total > 0) {
                output.put(tempOut, 0, total);
            }
        }

        return total;
    }

    /**
     * Wrap a key.
     *
     * <p>This concrete method has been added to this previously-defined
     * abstract class. (For backwards compatibility, it cannot be abstract.)
     * It may be overridden by a provider to wrap a key.
     * Such an override is expected to throw an
     * {@code IllegalBlockSizeException} or {@code InvalidKeyException}
     * (under the specified circumstances), if the given key cannot be wrapped.
     * If this method is not overridden, it always throws an
     * {@code UnsupportedOperationException}.
     *
     * @param key the key to be wrapped
     *
     * @return the wrapped key
     *
     * @throws IllegalBlockSizeException if this cipher is a block cipher,
     * no padding has been requested, and the length of the encoding of the
     * key to be wrapped is not a multiple of the block size
     *
     * @throws InvalidKeyException if it is impossible or unsafe to
     * wrap the key with this cipher (e.g., a hardware protected key is
     * being passed to a software-only cipher)
     *
     * @throws UnsupportedOperationException if this method is not supported
     */
    protected byte[] engineWrap(Key key)
        throws IllegalBlockSizeException, InvalidKeyException
    {
        throw new UnsupportedOperationException();
    }

    /**
     * Unwrap a previously wrapped key.
     *
     * <p>This concrete method has been added to this previously-defined
     * abstract class. (For backwards compatibility, it cannot be abstract.)
     * It may be overridden by a provider to unwrap a previously wrapped key.
     * Such an override is expected to throw an {@code InvalidKeyException} if
     * the given wrapped key cannot be unwrapped.
     * If this method is not overridden, it always throws an
     * {@code UnsupportedOperationException}.
     *
     * @param wrappedKey the key to be unwrapped
     *
     * @param wrappedKeyAlgorithm the algorithm associated with the wrapped
     * key
     *
     * @param wrappedKeyType the type of the wrapped key. This is one of
     * {@code SECRET_KEY}, {@code PRIVATE_KEY}, or {@code PUBLIC_KEY}.
     *
     * @return the unwrapped key
     *
     * @throws NoSuchAlgorithmException if no installed providers
     * can create keys of type {@code wrappedKeyType} for the
     * {@code wrappedKeyAlgorithm}
     *
     * @throws InvalidKeyException if {@code wrappedKey} does not
     * represent a wrapped key of type {@code wrappedKeyType} for
     * the {@code wrappedKeyAlgorithm}
     *
     * @throws UnsupportedOperationException if this method is not supported
     */
    protected Key engineUnwrap(byte[] wrappedKey,
                               String wrappedKeyAlgorithm,
                               int wrappedKeyType)
        throws InvalidKeyException, NoSuchAlgorithmException
    {
        throw new UnsupportedOperationException();
    }

    /**
     * Returns the key size of the given key object in bits.
     * <p>This concrete method has been added to this previously-defined
     * abstract class. It throws an {@code UnsupportedOperationException}
     * if it is not overridden by the provider.
     *
     * @param key the key object
     *
     * @return the key size of the given key object
     *
     * @throws InvalidKeyException if {@code key} is invalid
     */
    protected int engineGetKeySize(Key key)
        throws InvalidKeyException
    {
        throw new UnsupportedOperationException();
    }

    /**
     * Continues a multipart update of the Additional Authentication
     * Data (AAD), using a subset of the provided buffer.
     * <p>
     * Calls to this method provide AAD to the cipher when operating in
     * modes such as AEAD (GCM or CCM).  If this cipher is operating in
     * either GCM or CCM mode, all AAD must be supplied before beginning
     * operations on the ciphertext (via the {@code update} and
     * {@code doFinal} methods).
     *
     * @param src the buffer containing the AAD
     * @param offset the offset in {@code src} where the AAD input starts
     * @param len the number of AAD bytes
     *
     * @throws IllegalStateException if this {@code CipherSpi} object is in
     * a wrong state (e.g., has not been initialized), does not accept AAD,
     * or if operating in either GCM or CCM mode and one of the
     * {@code update} methods has already been called for the active
     * encryption/decryption operation
     * @throws UnsupportedOperationException if this method
     * has not been overridden by an implementation
     *
     * @since 1.7
     */
    protected void engineUpdateAAD(byte[] src, int offset, int len) {
        throw new UnsupportedOperationException(
            "The underlying Cipher implementation "
            +  "does not support this method");
    }

    /**
     * Continues a multipart update of the Additional Authentication
     * Data (AAD).
     * <p>
     * Calls to this method provide AAD to the cipher when operating in
     * modes such as AEAD (GCM or CCM).  If this cipher is operating in
     * either GCM or CCM mode, all AAD must be supplied before beginning
     * operations on the ciphertext (via the {@code update} and
     * {@code doFinal} methods).
     * <p>
     * All {@code src.remaining()} bytes starting at
     * {@code src.position()} are processed.
     * Upon return, the input buffer's position will be equal
     * to its limit; its limit will not have changed.
     *
     * @param src the buffer containing the AAD
     *
     * @throws IllegalStateException if this {@code CipherSpi} object is in
     * a wrong state (e.g., has not been initialized), does not accept AAD,
     * or if operating in either GCM or CCM mode and one of the
     * {@code update} methods has already been called for the active
     * encryption/decryption operation
     * @throws UnsupportedOperationException if this method
     * has not been overridden by an implementation
     *
     * @since 1.7
     */
    protected void engineUpdateAAD(ByteBuffer src) {
        throw new UnsupportedOperationException(
            "The underlying Cipher implementation "
            +  "does not support this method");
    }
}
