/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.security.keystore;

import android.annotation.CallSuper;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.IBinder;
import android.security.KeyStore;
import android.security.KeyStoreException;
import android.security.keymaster.KeymasterArguments;
import android.security.keymaster.KeymasterDefs;
import android.security.keymaster.OperationResult;

import libcore.util.EmptyArray;

import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import java.security.AlgorithmParameters;
import java.security.GeneralSecurityException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.InvalidParameterException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.ProviderException;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.AEADBadTagException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.CipherSpi;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.ShortBufferException;
import javax.crypto.spec.SecretKeySpec;

/**
 * Base class for {@link CipherSpi} implementations of Android KeyStore backed ciphers.
 *
 * @hide
 */
abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStoreCryptoOperation {
    private final KeyStore mKeyStore;

    // Fields below are populated by Cipher.init and KeyStore.begin and should be preserved after
    // doFinal finishes.
    private boolean mEncrypting;
    private int mKeymasterPurposeOverride = -1;
    private AndroidKeyStoreKey mKey;
    private SecureRandom mRng;

    /**
     * Token referencing this operation inside keystore service. It is initialized by
     * {@code engineInit} and is invalidated when {@code engineDoFinal} succeeds and on some error
     * conditions in between.
     */
    private IBinder mOperationToken;
    private long mOperationHandle;
    private KeyStoreCryptoOperationStreamer mMainDataStreamer;
    private KeyStoreCryptoOperationStreamer mAdditionalAuthenticationDataStreamer;
    private boolean mAdditionalAuthenticationDataStreamerClosed;

    /**
     * Encountered exception which could not be immediately thrown because it was encountered inside
     * a method that does not throw checked exception. This exception will be thrown from
     * {@code engineDoFinal}. Once such an exception is encountered, {@code engineUpdate} and
     * {@code engineDoFinal} start ignoring input data.
     */
    private Exception mCachedException;

    AndroidKeyStoreCipherSpiBase() {
        mKeyStore = KeyStore.getInstance();
    }

    @Override
    protected final void engineInit(int opmode, Key key, SecureRandom random)
            throws InvalidKeyException {
        resetAll();

        boolean success = false;
        try {
            init(opmode, key, random);
            initAlgorithmSpecificParameters();
            try {
                ensureKeystoreOperationInitialized();
            } catch (InvalidAlgorithmParameterException e) {
                throw new InvalidKeyException(e);
            }
            success = true;
        } finally {
            if (!success) {
                resetAll();
            }
        }
    }

    @Override
    protected final void engineInit(int opmode, Key key, AlgorithmParameters params,
            SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
        resetAll();

        boolean success = false;
        try {
            init(opmode, key, random);
            initAlgorithmSpecificParameters(params);
            ensureKeystoreOperationInitialized();
            success = true;
        } finally {
            if (!success) {
                resetAll();
            }
        }
    }

    @Override
    protected final void engineInit(int opmode, Key key, AlgorithmParameterSpec params,
            SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
        resetAll();

        boolean success = false;
        try {
            init(opmode, key, random);
            initAlgorithmSpecificParameters(params);
            ensureKeystoreOperationInitialized();
            success = true;
        } finally {
            if (!success) {
                resetAll();
            }
        }
    }

    private void init(int opmode, Key key, SecureRandom random) throws InvalidKeyException {
        switch (opmode) {
            case Cipher.ENCRYPT_MODE:
            case Cipher.WRAP_MODE:
                mEncrypting = true;
                break;
            case Cipher.DECRYPT_MODE:
            case Cipher.UNWRAP_MODE:
                mEncrypting = false;
                break;
            default:
                throw new InvalidParameterException("Unsupported opmode: " + opmode);
        }
        initKey(opmode, key);
        if (mKey == null) {
            throw new ProviderException("initKey did not initialize the key");
        }
        mRng = random;
    }

    /**
     * Resets this cipher to its pristine pre-init state. This must be equivalent to obtaining a new
     * cipher instance.
     *
     * <p>Subclasses storing additional state should override this method, reset the additional
     * state, and then chain to superclass.
     */
    @CallSuper
    protected void resetAll() {
        IBinder operationToken = mOperationToken;
        if (operationToken != null) {
            mKeyStore.abort(operationToken);
        }
        mEncrypting = false;
        mKeymasterPurposeOverride = -1;
        mKey = null;
        mRng = null;
        mOperationToken = null;
        mOperationHandle = 0;
        mMainDataStreamer = null;
        mAdditionalAuthenticationDataStreamer = null;
        mAdditionalAuthenticationDataStreamerClosed = false;
        mCachedException = null;
    }

    /**
     * Resets this cipher while preserving the initialized state. This must be equivalent to
     * rolling back the cipher's state to just after the most recent {@code engineInit} completed
     * successfully.
     *
     * <p>Subclasses storing additional post-init state should override this method, reset the
     * additional state, and then chain to superclass.
     */
    @CallSuper
    protected void resetWhilePreservingInitState() {
        IBinder operationToken = mOperationToken;
        if (operationToken != null) {
            mKeyStore.abort(operationToken);
        }
        mOperationToken = null;
        mOperationHandle = 0;
        mMainDataStreamer = null;
        mAdditionalAuthenticationDataStreamer = null;
        mAdditionalAuthenticationDataStreamerClosed = false;
        mCachedException = null;
    }

    private void ensureKeystoreOperationInitialized() throws InvalidKeyException,
            InvalidAlgorithmParameterException {
        if (mMainDataStreamer != null) {
            return;
        }
        if (mCachedException != null) {
            return;
        }
        if (mKey == null) {
            throw new IllegalStateException("Not initialized");
        }

        KeymasterArguments keymasterInputArgs = new KeymasterArguments();
        addAlgorithmSpecificParametersToBegin(keymasterInputArgs);
        byte[] additionalEntropy = KeyStoreCryptoOperationUtils.getRandomBytesToMixIntoKeystoreRng(
                mRng, getAdditionalEntropyAmountForBegin());

        int purpose;
        if (mKeymasterPurposeOverride != -1) {
            purpose = mKeymasterPurposeOverride;
        } else {
            purpose = mEncrypting
                    ? KeymasterDefs.KM_PURPOSE_ENCRYPT : KeymasterDefs.KM_PURPOSE_DECRYPT;
        }
        OperationResult opResult = mKeyStore.begin(
                mKey.getAlias(),
                purpose,
                true, // permit aborting this operation if keystore runs out of resources
                keymasterInputArgs,
                additionalEntropy,
                mKey.getUid());
        if (opResult == null) {
            throw new KeyStoreConnectException();
        }

        // Store operation token and handle regardless of the error code returned by KeyStore to
        // ensure that the operation gets aborted immediately if the code below throws an exception.
        mOperationToken = opResult.token;
        mOperationHandle = opResult.operationHandle;

        // If necessary, throw an exception due to KeyStore operation having failed.
        GeneralSecurityException e = KeyStoreCryptoOperationUtils.getExceptionForCipherInit(
                mKeyStore, mKey, opResult.resultCode);
        if (e != null) {
            if (e instanceof InvalidKeyException) {
                throw (InvalidKeyException) e;
            } else if (e instanceof InvalidAlgorithmParameterException) {
                throw (InvalidAlgorithmParameterException) e;
            } else {
                throw new ProviderException("Unexpected exception type", e);
            }
        }

        if (mOperationToken == null) {
            throw new ProviderException("Keystore returned null operation token");
        }
        if (mOperationHandle == 0) {
            throw new ProviderException("Keystore returned invalid operation handle");
        }

        loadAlgorithmSpecificParametersFromBeginResult(opResult.outParams);
        mMainDataStreamer = createMainDataStreamer(mKeyStore, opResult.token);
        mAdditionalAuthenticationDataStreamer =
                createAdditionalAuthenticationDataStreamer(mKeyStore, opResult.token);
        mAdditionalAuthenticationDataStreamerClosed = false;
    }

    /**
     * Creates a streamer which sends plaintext/ciphertext into the provided KeyStore and receives
     * the corresponding ciphertext/plaintext from the KeyStore.
     *
     * <p>This implementation returns a working streamer.
     */
    @NonNull
    protected KeyStoreCryptoOperationStreamer createMainDataStreamer(
            KeyStore keyStore, IBinder operationToken) {
        return new KeyStoreCryptoOperationChunkedStreamer(
                new KeyStoreCryptoOperationChunkedStreamer.MainDataStream(
                        keyStore, operationToken));
    }

    /**
     * Creates a streamer which sends Additional Authentication Data (AAD) into the KeyStore.
     *
     * <p>This implementation returns {@code null}.
     *
     * @return stream or {@code null} if AAD is not supported by this cipher.
     */
    @Nullable
    protected KeyStoreCryptoOperationStreamer createAdditionalAuthenticationDataStreamer(
            @SuppressWarnings("unused") KeyStore keyStore,
            @SuppressWarnings("unused") IBinder operationToken) {
        return null;
    }

    @Override
    protected final byte[] engineUpdate(byte[] input, int inputOffset, int inputLen) {
        if (mCachedException != null) {
            return null;
        }
        try {
            ensureKeystoreOperationInitialized();
        } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
            mCachedException = e;
            return null;
        }

        if (inputLen == 0) {
            return null;
        }

        byte[] output;
        try {
            flushAAD();
            output = mMainDataStreamer.update(input, inputOffset, inputLen);
        } catch (KeyStoreException e) {
            mCachedException = e;
            return null;
        }

        if (output.length == 0) {
            return null;
        }

        return output;
    }

    private void flushAAD() throws KeyStoreException {
        if ((mAdditionalAuthenticationDataStreamer != null)
                && (!mAdditionalAuthenticationDataStreamerClosed)) {
            byte[] output;
            try {
                output = mAdditionalAuthenticationDataStreamer.doFinal(
                        EmptyArray.BYTE, 0, 0,
                        null, // no signature
                        null // no additional entropy needed flushing AAD
                        );
            } finally {
                mAdditionalAuthenticationDataStreamerClosed = true;
            }
            if ((output != null) && (output.length > 0)) {
                throw new ProviderException(
                        "AAD update unexpectedly returned data: " + output.length + " bytes");
            }
        }
    }

    @Override
    protected final int engineUpdate(byte[] input, int inputOffset, int inputLen, byte[] output,
            int outputOffset) throws ShortBufferException {
        byte[] outputCopy = engineUpdate(input, inputOffset, inputLen);
        if (outputCopy == null) {
            return 0;
        }
        int outputAvailable = output.length - outputOffset;
        if (outputCopy.length > outputAvailable) {
            throw new ShortBufferException("Output buffer too short. Produced: "
                    + outputCopy.length + ", available: " + outputAvailable);
        }
        System.arraycopy(outputCopy, 0, output, outputOffset, outputCopy.length);
        return outputCopy.length;
    }

    @Override
    protected final int engineUpdate(ByteBuffer input, ByteBuffer output)
            throws ShortBufferException {
        if (input == null) {
            throw new NullPointerException("input == null");
        }
        if (output == null) {
            throw new NullPointerException("output == null");
        }

        int inputSize = input.remaining();
        byte[] outputArray;
        if (input.hasArray()) {
            outputArray =
                    engineUpdate(
                            input.array(), input.arrayOffset() + input.position(), inputSize);
            input.position(input.position() + inputSize);
        } else {
            byte[] inputArray = new byte[inputSize];
            input.get(inputArray);
            outputArray = engineUpdate(inputArray, 0, inputSize);
        }

        int outputSize = (outputArray != null) ? outputArray.length : 0;
        if (outputSize > 0) {
            int outputBufferAvailable = output.remaining();
            try {
                output.put(outputArray);
            } catch (BufferOverflowException e) {
                throw new ShortBufferException(
                        "Output buffer too small. Produced: " + outputSize + ", available: "
                                + outputBufferAvailable);
            }
        }
        return outputSize;
    }

    @Override
    protected final void engineUpdateAAD(byte[] input, int inputOffset, int inputLen) {
        if (mCachedException != null) {
            return;
        }

        try {
            ensureKeystoreOperationInitialized();
        } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
            mCachedException = e;
            return;
        }

        if (mAdditionalAuthenticationDataStreamerClosed) {
            throw new IllegalStateException(
                    "AAD can only be provided before Cipher.update is invoked");
        }

        if (mAdditionalAuthenticationDataStreamer == null) {
            throw new IllegalStateException("This cipher does not support AAD");
        }

        byte[] output;
        try {
            output = mAdditionalAuthenticationDataStreamer.update(input, inputOffset, inputLen);
        } catch (KeyStoreException e) {
            mCachedException = e;
            return;
        }

        if ((output != null) && (output.length > 0)) {
            throw new ProviderException("AAD update unexpectedly produced output: "
                    + output.length + " bytes");
        }
    }

    @Override
    protected final void engineUpdateAAD(ByteBuffer src) {
        if (src == null) {
            throw new IllegalArgumentException("src == null");
        }
        if (!src.hasRemaining()) {
            return;
        }

        byte[] input;
        int inputOffset;
        int inputLen;
        if (src.hasArray()) {
            input = src.array();
            inputOffset = src.arrayOffset() + src.position();
            inputLen = src.remaining();
            src.position(src.limit());
        } else {
            input = new byte[src.remaining()];
            inputOffset = 0;
            inputLen = input.length;
            src.get(input);
        }
        engineUpdateAAD(input, inputOffset, inputLen);
    }

    @Override
    protected final byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen)
            throws IllegalBlockSizeException, BadPaddingException {
        if (mCachedException != null) {
            throw (IllegalBlockSizeException)
                    new IllegalBlockSizeException().initCause(mCachedException);
        }

        try {
            ensureKeystoreOperationInitialized();
        } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
            throw (IllegalBlockSizeException) new IllegalBlockSizeException().initCause(e);
        }

        byte[] output;
        try {
            flushAAD();
            byte[] additionalEntropy =
                    KeyStoreCryptoOperationUtils.getRandomBytesToMixIntoKeystoreRng(
                            mRng, getAdditionalEntropyAmountForFinish());
            output = mMainDataStreamer.doFinal(
                    input, inputOffset, inputLen,
                    null, // no signature involved
                    additionalEntropy);
        } catch (KeyStoreException e) {
            switch (e.getErrorCode()) {
                case KeymasterDefs.KM_ERROR_INVALID_INPUT_LENGTH:
                    throw (IllegalBlockSizeException) new IllegalBlockSizeException().initCause(e);
                case KeymasterDefs.KM_ERROR_INVALID_ARGUMENT:
                    throw (BadPaddingException) new BadPaddingException().initCause(e);
                case KeymasterDefs.KM_ERROR_VERIFICATION_FAILED:
                    throw (AEADBadTagException) new AEADBadTagException().initCause(e);
                default:
                    throw (IllegalBlockSizeException) new IllegalBlockSizeException().initCause(e);
            }
        }

        resetWhilePreservingInitState();
        return output;
    }

    @Override
    protected final int engineDoFinal(byte[] input, int inputOffset, int inputLen, byte[] output,
            int outputOffset) throws ShortBufferException, IllegalBlockSizeException,
            BadPaddingException {
        byte[] outputCopy = engineDoFinal(input, inputOffset, inputLen);
        if (outputCopy == null) {
            return 0;
        }
        int outputAvailable = output.length - outputOffset;
        if (outputCopy.length > outputAvailable) {
            throw new ShortBufferException("Output buffer too short. Produced: "
                    + outputCopy.length + ", available: " + outputAvailable);
        }
        System.arraycopy(outputCopy, 0, output, outputOffset, outputCopy.length);
        return outputCopy.length;
    }

    @Override
    protected final int engineDoFinal(ByteBuffer input, ByteBuffer output)
            throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
        if (input == null) {
            throw new NullPointerException("input == null");
        }
        if (output == null) {
            throw new NullPointerException("output == null");
        }

        int inputSize = input.remaining();
        byte[] outputArray;
        if (input.hasArray()) {
            outputArray =
                    engineDoFinal(
                            input.array(), input.arrayOffset() + input.position(), inputSize);
            input.position(input.position() + inputSize);
        } else {
            byte[] inputArray = new byte[inputSize];
            input.get(inputArray);
            outputArray = engineDoFinal(inputArray, 0, inputSize);
        }

        int outputSize = (outputArray != null) ? outputArray.length : 0;
        if (outputSize > 0) {
            int outputBufferAvailable = output.remaining();
            try {
                output.put(outputArray);
            } catch (BufferOverflowException e) {
                throw new ShortBufferException(
                        "Output buffer too small. Produced: " + outputSize + ", available: "
                                + outputBufferAvailable);
            }
        }
        return outputSize;
    }

    @Override
    protected final byte[] engineWrap(Key key)
            throws IllegalBlockSizeException, InvalidKeyException {
        if (mKey == null) {
            throw new IllegalStateException("Not initilized");
        }

        if (!isEncrypting()) {
            throw new IllegalStateException(
                    "Cipher must be initialized in Cipher.WRAP_MODE to wrap keys");
        }

        if (key == null) {
            throw new NullPointerException("key == null");
        }
        byte[] encoded = null;
        if (key instanceof SecretKey) {
            if ("RAW".equalsIgnoreCase(key.getFormat())) {
                encoded = key.getEncoded();
            }
            if (encoded == null) {
                try {
                    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(key.getAlgorithm());
                    SecretKeySpec spec =
                            (SecretKeySpec) keyFactory.getKeySpec(
                                    (SecretKey) key, SecretKeySpec.class);
                    encoded = spec.getEncoded();
                } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
                    throw new InvalidKeyException(
                            "Failed to wrap key because it does not export its key material",
                            e);
                }
            }
        } else if (key instanceof PrivateKey) {
            if ("PKCS8".equalsIgnoreCase(key.getFormat())) {
                encoded = key.getEncoded();
            }
            if (encoded == null) {
                try {
                    KeyFactory keyFactory = KeyFactory.getInstance(key.getAlgorithm());
                    PKCS8EncodedKeySpec spec =
                            keyFactory.getKeySpec(key, PKCS8EncodedKeySpec.class);
                    encoded = spec.getEncoded();
                } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
                    throw new InvalidKeyException(
                            "Failed to wrap key because it does not export its key material",
                            e);
                }
            }
        } else if (key instanceof PublicKey) {
            if ("X.509".equalsIgnoreCase(key.getFormat())) {
                encoded = key.getEncoded();
            }
            if (encoded == null) {
                try {
                    KeyFactory keyFactory = KeyFactory.getInstance(key.getAlgorithm());
                    X509EncodedKeySpec spec =
                            keyFactory.getKeySpec(key, X509EncodedKeySpec.class);
                    encoded = spec.getEncoded();
                } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
                    throw new InvalidKeyException(
                            "Failed to wrap key because it does not export its key material",
                            e);
                }
            }
        } else {
            throw new InvalidKeyException("Unsupported key type: " + key.getClass().getName());
        }

        if (encoded == null) {
            throw new InvalidKeyException(
                    "Failed to wrap key because it does not export its key material");
        }

        try {
            return engineDoFinal(encoded, 0, encoded.length);
        } catch (BadPaddingException e) {
            throw (IllegalBlockSizeException) new IllegalBlockSizeException().initCause(e);
        }
    }

    @Override
    protected final Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm,
            int wrappedKeyType) throws InvalidKeyException, NoSuchAlgorithmException {
        if (mKey == null) {
            throw new IllegalStateException("Not initilized");
        }

        if (isEncrypting()) {
            throw new IllegalStateException(
                    "Cipher must be initialized in Cipher.WRAP_MODE to wrap keys");
        }

        if (wrappedKey == null) {
            throw new NullPointerException("wrappedKey == null");
        }

        byte[] encoded;
        try {
            encoded = engineDoFinal(wrappedKey, 0, wrappedKey.length);
        } catch (IllegalBlockSizeException | BadPaddingException e) {
            throw new InvalidKeyException("Failed to unwrap key", e);
        }

        switch (wrappedKeyType) {
            case Cipher.SECRET_KEY:
            {
                return new SecretKeySpec(encoded, wrappedKeyAlgorithm);
                // break;
            }
            case Cipher.PRIVATE_KEY:
            {
                KeyFactory keyFactory = KeyFactory.getInstance(wrappedKeyAlgorithm);
                try {
                    return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encoded));
                } catch (InvalidKeySpecException e) {
                    throw new InvalidKeyException(
                            "Failed to create private key from its PKCS#8 encoded form", e);
                }
                // break;
            }
            case Cipher.PUBLIC_KEY:
            {
                KeyFactory keyFactory = KeyFactory.getInstance(wrappedKeyAlgorithm);
                try {
                    return keyFactory.generatePublic(new X509EncodedKeySpec(encoded));
                } catch (InvalidKeySpecException e) {
                    throw new InvalidKeyException(
                            "Failed to create public key from its X.509 encoded form", e);
                }
                // break;
            }
            default:
                throw new InvalidParameterException(
                        "Unsupported wrappedKeyType: " + wrappedKeyType);
        }
    }

    @Override
    protected final void engineSetMode(String mode) throws NoSuchAlgorithmException {
        // This should never be invoked because all algorithms registered with the AndroidKeyStore
        // provide explicitly specify block mode.
        throw new UnsupportedOperationException();
    }

    @Override
    protected final void engineSetPadding(String arg0) throws NoSuchPaddingException {
        // This should never be invoked because all algorithms registered with the AndroidKeyStore
        // provide explicitly specify padding mode.
        throw new UnsupportedOperationException();
    }

    @Override
    protected final int engineGetKeySize(Key key) throws InvalidKeyException {
        throw new UnsupportedOperationException();
    }

    @CallSuper
    @Override
    public void finalize() throws Throwable {
        try {
            IBinder operationToken = mOperationToken;
            if (operationToken != null) {
                mKeyStore.abort(operationToken);
            }
        } finally {
            super.finalize();
        }
    }

    @Override
    public final long getOperationHandle() {
        return mOperationHandle;
    }

    protected final void setKey(@NonNull AndroidKeyStoreKey key) {
        mKey = key;
    }

    /**
     * Overrides the default purpose/type of the crypto operation.
     */
    protected final void setKeymasterPurposeOverride(int keymasterPurpose) {
        mKeymasterPurposeOverride = keymasterPurpose;
    }

    protected final int getKeymasterPurposeOverride() {
        return mKeymasterPurposeOverride;
    }

    /**
     * Returns {@code true} if this cipher is initialized for encryption, {@code false} if this
     * cipher is initialized for decryption.
     */
    protected final boolean isEncrypting() {
        return mEncrypting;
    }

    @NonNull
    protected final KeyStore getKeyStore() {
        return mKeyStore;
    }

    protected final long getConsumedInputSizeBytes() {
        if (mMainDataStreamer == null) {
            throw new IllegalStateException("Not initialized");
        }
        return mMainDataStreamer.getConsumedInputSizeBytes();
    }

    protected final long getProducedOutputSizeBytes() {
        if (mMainDataStreamer == null) {
            throw new IllegalStateException("Not initialized");
        }
        return mMainDataStreamer.getProducedOutputSizeBytes();
    }

    static String opmodeToString(int opmode) {
        switch (opmode) {
            case Cipher.ENCRYPT_MODE:
                return "ENCRYPT_MODE";
            case Cipher.DECRYPT_MODE:
                return "DECRYPT_MODE";
            case Cipher.WRAP_MODE:
                return "WRAP_MODE";
            case Cipher.UNWRAP_MODE:
                return "UNWRAP_MODE";
            default:
                return String.valueOf(opmode);
        }
    }

    // The methods below need to be implemented by subclasses.

    /**
     * Initializes this cipher with the provided key.
     *
     * @throws InvalidKeyException if the {@code key} is not suitable for this cipher in the
     *         specified {@code opmode}.
     *
     * @see #setKey(AndroidKeyStoreKey)
     */
    protected abstract void initKey(int opmode, @Nullable Key key) throws InvalidKeyException;

    /**
     * Returns algorithm-specific parameters used by this cipher or {@code null} if no
     * algorithm-specific parameters are used.
     */
    @Nullable
    @Override
    protected abstract AlgorithmParameters engineGetParameters();

    /**
     * Invoked by {@code engineInit} to initialize algorithm-specific parameters when no additional
     * initialization parameters were provided.
     *
     * @throws InvalidKeyException if this cipher cannot be configured based purely on the provided
     *         key and needs additional parameters to be provided to {@code Cipher.init}.
     */
    protected abstract void initAlgorithmSpecificParameters() throws InvalidKeyException;

    /**
     * Invoked by {@code engineInit} to initialize algorithm-specific parameters when additional
     * parameters were provided.
     *
     * @param params additional algorithm parameters or {@code null} if not specified.
     *
     * @throws InvalidAlgorithmParameterException if there is insufficient information to configure
     *         this cipher or if the provided parameters are not suitable for this cipher.
     */
    protected abstract void initAlgorithmSpecificParameters(
            @Nullable AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException;

    /**
     * Invoked by {@code engineInit} to initialize algorithm-specific parameters when additional
     * parameters were provided.
     *
     * @param params additional algorithm parameters or {@code null} if not specified.
     *
     * @throws InvalidAlgorithmParameterException if there is insufficient information to configure
     *         this cipher or if the provided parameters are not suitable for this cipher.
     */
    protected abstract void initAlgorithmSpecificParameters(@Nullable AlgorithmParameters params)
            throws InvalidAlgorithmParameterException;

    /**
     * Returns the amount of additional entropy (in bytes) to be provided to the KeyStore's
     * {@code begin} operation. This amount of entropy is typically what's consumed to generate
     * random parameters, such as IV.
     *
     * <p>For decryption, the return value should be {@code 0} because decryption should not be
     * consuming any entropy. For encryption, the value combined with
     * {@link #getAdditionalEntropyAmountForFinish()} should match (or exceed) the amount of Shannon
     * entropy of the ciphertext produced by this cipher assuming the key, the plaintext, and all
     * explicitly provided parameters to {@code Cipher.init} are known. For example, for AES CBC
     * encryption with an explicitly provided IV the return value should be {@code 0}, whereas for
     * the case where IV is generated by the KeyStore's {@code begin} operation it should be
     * {@code 16}.
     */
    protected abstract int getAdditionalEntropyAmountForBegin();

    /**
     * Returns the amount of additional entropy (in bytes) to be provided to the KeyStore's
     * {@code finish} operation. This amount of entropy is typically what's consumed by encryption
     * padding scheme.
     *
     * <p>For decryption, the return value should be {@code 0} because decryption should not be
     * consuming any entropy. For encryption, the value combined with
     * {@link #getAdditionalEntropyAmountForBegin()} should match (or exceed) the amount of Shannon
     * entropy of the ciphertext produced by this cipher assuming the key, the plaintext, and all
     * explicitly provided parameters to {@code Cipher.init} are known. For example, for RSA with
     * OAEP the return value should be the size of the OAEP hash output. For RSA with PKCS#1 padding
     * the return value should be the size of the padding string or could be raised (for simplicity)
     * to the size of the modulus.
     */
    protected abstract int getAdditionalEntropyAmountForFinish();

    /**
     * Invoked to add algorithm-specific parameters for the KeyStore's {@code begin} operation.
     *
     * @param keymasterArgs keystore/keymaster arguments to be populated with algorithm-specific
     *        parameters.
     */
    protected abstract void addAlgorithmSpecificParametersToBegin(
            @NonNull KeymasterArguments keymasterArgs);

    /**
     * Invoked to obtain algorithm-specific parameters from the result of the KeyStore's
     * {@code begin} operation.
     *
     * <p>Some parameters, such as IV, are not required to be provided to {@code Cipher.init}. Such
     * parameters, if not provided, must be generated by KeyStore and returned to the user of
     * {@code Cipher} and potentially reused after {@code doFinal}.
     *
     * @param keymasterArgs keystore/keymaster arguments returned by KeyStore {@code begin}
     *        operation.
     */
    protected abstract void loadAlgorithmSpecificParametersFromBeginResult(
            @NonNull KeymasterArguments keymasterArgs);
}
