/*
 * Copyright (C) 2019 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 com.android.internal.net.ipsec.ike.crypto;

import android.net.IpSecAlgorithm;
import android.net.ipsec.ike.SaProposal;

import com.android.internal.net.ipsec.ike.message.IkeSaPayload.EncryptionTransform;

import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;

/**
 * IkeCipher contains common information of normal and combined mode encryption algorithms.
 *
 * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3.2">RFC 7296, Internet Key Exchange
 *     Protocol Version 2 (IKEv2)</a>
 */
public abstract class IkeCipher extends IkeCrypto {
    private static final int KEY_LEN_3DES = 24;

    private static final int IV_LEN_3DES = 8;
    private static final int IV_LEN_AES_CBC = 16;
    private static final int IV_LEN_AES_GCM = 8;

    private final boolean mIsAead;
    private final int mIvLen;

    protected final Cipher mCipher;

    protected IkeCipher(
            int algorithmId,
            int keyLength,
            int ivLength,
            String algorithmName,
            boolean isAead,
            Provider provider) {
        super(algorithmId, keyLength, algorithmName);
        mIvLen = ivLength;
        mIsAead = isAead;

        try {
            mCipher = Cipher.getInstance(getAlgorithmName(), provider);
        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
            throw new IllegalArgumentException("Failed to construct " + getTypeString(), e);
        }
    }

    /**
     * Contruct an instance of IkeCipher.
     *
     * @param encryptionTransform the valid negotiated EncryptionTransform.
     * @param provider the security provider.
     * @return an instance of IkeCipher.
     */
    public static IkeCipher create(EncryptionTransform encryptionTransform, Provider provider) {
        int algorithmId = encryptionTransform.id;

        // Use specifiedKeyLength for algorithms with variable key length. Since
        // specifiedKeyLength are encoded in bits, it needs to be converted to bytes.
        switch (algorithmId) {
            case SaProposal.ENCRYPTION_ALGORITHM_3DES:
                return new IkeNormalModeCipher(
                        algorithmId, KEY_LEN_3DES, IV_LEN_3DES, "DESede/CBC/NoPadding", provider);
            case SaProposal.ENCRYPTION_ALGORITHM_AES_CBC:
                return new IkeNormalModeCipher(
                        algorithmId,
                        encryptionTransform.getSpecifiedKeyLength() / 8,
                        IV_LEN_AES_CBC,
                        "AES/CBC/NoPadding",
                        provider);
            case SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8:
                // Fall through
            case SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12:
                // Fall through
            case SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16:
                // Fall through
                return new IkeCombinedModeCipher(
                        algorithmId,
                        encryptionTransform.getSpecifiedKeyLength() / 8,
                        IV_LEN_AES_GCM,
                        "AES/GCM/NoPadding",
                        provider);
            default:
                throw new IllegalArgumentException(
                        "Unrecognized Encryption Algorithm ID: " + algorithmId);
        }
    }

    /**
     * Check if this encryption algorithm is a combined-mode/AEAD algorithm.
     *
     * @return if this encryption algorithm is a combined-mode/AEAD algorithm.
     */
    public boolean isAead() {
        return mIsAead;
    }

    /**
     * Get the block size (in bytes).
     *
     * @return the block size (in bytes).
     */
    public int getBlockSize() {
        // Currently all supported encryption algorithms are block ciphers. So the return value will
        // not be zero.
        return mCipher.getBlockSize();
    }

    /**
     * Get initialization vector (IV) length.
     *
     * @return the IV length.
     */
    public int getIvLen() {
        return mIvLen;
    }

    /**
     * Generate initialization vector (IV).
     *
     * @return the initialization vector (IV).
     */
    public byte[] generateIv() {
        byte[] iv = new byte[getIvLen()];
        new SecureRandom().nextBytes(iv);
        return iv;
    }

    protected void validateKeyLenOrThrow(byte[] key) {
        if (key.length != getKeyLength()) {
            throw new IllegalArgumentException(
                    "Expected key with length of : "
                            + getKeyLength()
                            + " Received key with length of : "
                            + key.length);
        }
    }

    /**
     * Build IpSecAlgorithm from this IkeCipher.
     *
     * <p>Build IpSecAlgorithm that represents the same encryption algorithm with this IkeCipher
     * instance with provided encryption key.
     *
     * @param key the encryption key in byte array.
     * @return the IpSecAlgorithm.
     */
    public abstract IpSecAlgorithm buildIpSecAlgorithmWithKey(byte[] key);

    /**
     * Returns algorithm type as a String.
     *
     * @return the algorithm type as a String.
     */
    @Override
    public String getTypeString() {
        return "Encryption Algorithm";
    }
}
