/*
 * Copyright (C) 2017 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.net;

import android.annotation.StringDef;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;

import com.android.internal.util.HexDump;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;

/**
 * IpSecAlgorithm specifies a single algorithm that can be applied to an IpSec Transform. Refer to
 * RFC 4301.
 */
public final class IpSecAlgorithm implements Parcelable {
    /**
     * AES-CBC Encryption/Ciphering Algorithm.
     *
     * <p>Valid lengths for this key are {128, 192, 256}.
     */
    public static final String CRYPT_AES_CBC = "cbc(aes)";

    /**
     * MD5 HMAC Authentication/Integrity Algorithm. This algorithm is not recommended for use in new
     * applications and is provided for legacy compatibility with 3gpp infrastructure.
     *
     * <p>Valid truncation lengths are multiples of 8 bits from 96 to (default) 128.
     */
    public static final String AUTH_HMAC_MD5 = "hmac(md5)";

    /**
     * SHA1 HMAC Authentication/Integrity Algorithm. This algorithm is not recommended for use in
     * new applications and is provided for legacy compatibility with 3gpp infrastructure.
     *
     * <p>Valid truncation lengths are multiples of 8 bits from 96 to (default) 160.
     */
    public static final String AUTH_HMAC_SHA1 = "hmac(sha1)";

    /**
     * SHA256 HMAC Authentication/Integrity Algorithm.
     *
     * <p>Valid truncation lengths are multiples of 8 bits from 96 to (default) 256.
     */
    public static final String AUTH_HMAC_SHA256 = "hmac(sha256)";

    /**
     * SHA384 HMAC Authentication/Integrity Algorithm.
     *
     * <p>Valid truncation lengths are multiples of 8 bits from 192 to (default) 384.
     */
    public static final String AUTH_HMAC_SHA384 = "hmac(sha384)";

    /**
     * SHA512 HMAC Authentication/Integrity Algorithm
     *
     * <p>Valid truncation lengths are multiples of 8 bits from 256 to (default) 512.
     */
    public static final String AUTH_HMAC_SHA512 = "hmac(sha512)";

    /**
     * AES-GCM Authentication/Integrity + Encryption/Ciphering Algorithm.
     *
     * <p>Valid lengths for this key are {128, 192, 256}.
     *
     * <p>Valid ICV (truncation) lengths are {64, 96, 128}.
     */
    public static final String AUTH_CRYPT_AES_GCM = "rfc4106(gcm(aes))";

    /** @hide */
    @StringDef({
        CRYPT_AES_CBC,
        AUTH_HMAC_MD5,
        AUTH_HMAC_SHA1,
        AUTH_HMAC_SHA256,
        AUTH_HMAC_SHA512,
        AUTH_CRYPT_AES_GCM
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface AlgorithmName {}

    private final String mName;
    private final byte[] mKey;
    private final int mTruncLenBits;

    /**
     * Specify a IpSecAlgorithm of one of the supported types including the truncation length of the
     * algorithm
     *
     * @param algorithm type for IpSec.
     * @param key non-null Key padded to a multiple of 8 bits.
     */
    public IpSecAlgorithm(String algorithm, byte[] key) {
        this(algorithm, key, key.length * 8);
    }

    /**
     * Specify a IpSecAlgorithm of one of the supported types including the truncation length of the
     * algorithm
     *
     * @param algoName precise name of the algorithm to be used.
     * @param key non-null Key padded to a multiple of 8 bits.
     * @param truncLenBits the number of bits of output hash to use; only meaningful for
     *     Authentication or Authenticated Encryption (equivalent to ICV length).
     */
    public IpSecAlgorithm(@AlgorithmName String algoName, byte[] key, int truncLenBits) {
        if (!isTruncationLengthValid(algoName, truncLenBits)) {
            throw new IllegalArgumentException("Unknown algorithm or invalid length");
        }
        mName = algoName;
        mKey = key.clone();
        mTruncLenBits = Math.min(truncLenBits, key.length * 8);
    }

    /** Retrieve the algorithm name */
    public String getName() {
        return mName;
    }

    /** Retrieve the key for this algorithm */
    public byte[] getKey() {
        return mKey.clone();
    }

    /**
     * Retrieve the truncation length, in bits, for the key in this algo. By default this will be
     * the length in bits of the key.
     */
    public int getTruncationLengthBits() {
        return mTruncLenBits;
    }

    /* Parcelable Implementation */
    public int describeContents() {
        return 0;
    }

    /** Write to parcel */
    public void writeToParcel(Parcel out, int flags) {
        out.writeString(mName);
        out.writeByteArray(mKey);
        out.writeInt(mTruncLenBits);
    }

    /** Parcelable Creator */
    public static final Parcelable.Creator<IpSecAlgorithm> CREATOR =
            new Parcelable.Creator<IpSecAlgorithm>() {
                public IpSecAlgorithm createFromParcel(Parcel in) {
                    return new IpSecAlgorithm(in);
                }

                public IpSecAlgorithm[] newArray(int size) {
                    return new IpSecAlgorithm[size];
                }
            };

    private IpSecAlgorithm(Parcel in) {
        mName = in.readString();
        mKey = in.createByteArray();
        mTruncLenBits = in.readInt();
    }

    private static boolean isTruncationLengthValid(String algo, int truncLenBits) {
        switch (algo) {
            case CRYPT_AES_CBC:
                return (truncLenBits == 128 || truncLenBits == 192 || truncLenBits == 256);
            case AUTH_HMAC_MD5:
                return (truncLenBits >= 96 && truncLenBits <= 128);
            case AUTH_HMAC_SHA1:
                return (truncLenBits >= 96 && truncLenBits <= 160);
            case AUTH_HMAC_SHA256:
                return (truncLenBits >= 96 && truncLenBits <= 256);
            case AUTH_HMAC_SHA384:
                return (truncLenBits >= 192 && truncLenBits <= 384);
            case AUTH_HMAC_SHA512:
                return (truncLenBits >= 256 && truncLenBits <= 512);
            case AUTH_CRYPT_AES_GCM:
                return (truncLenBits == 64 || truncLenBits == 96 || truncLenBits == 128);
            default:
                return false;
        }
    }

    @Override
    public String toString() {
        return new StringBuilder()
                .append("{mName=")
                .append(mName)
                .append(", mKey=")
                .append(Build.IS_DEBUGGABLE ? HexDump.toHexString(mKey) : "<hidden>")
                .append(", mTruncLenBits=")
                .append(mTruncLenBits)
                .append("}")
                .toString();
    }

    /** package */
    static boolean equals(IpSecAlgorithm lhs, IpSecAlgorithm rhs) {
        if (lhs == null || rhs == null) return (lhs == rhs);
        return (lhs.mName.equals(rhs.mName)
                && Arrays.equals(lhs.mKey, rhs.mKey)
                && lhs.mTruncLenBits == rhs.mTruncLenBits);
    }
};
