/*
 * Copyright (C) 2021 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.libraries.entitlement.eapaka;

import static com.android.libraries.entitlement.ServiceEntitlementException.ERROR_ICC_AUTHENTICATION_NOT_AVAILABLE;
import static com.android.libraries.entitlement.eapaka.EapAkaChallenge.SUBTYPE_AKA_CHALLENGE;
import static com.android.libraries.entitlement.eapaka.EapAkaChallenge.TYPE_EAP_AKA;

import android.content.Context;
import android.telephony.TelephonyManager;
import android.util.Base64;
import android.util.Log;

import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;

import com.android.libraries.entitlement.ServiceEntitlementException;
import com.android.libraries.entitlement.utils.BytesConverter;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

/**
 * Generates the response of EAP-AKA challenge. Refer to RFC 4187 Section 8.1 Message
 * Format/RFC 3748 Session 4 EAP Packet Format.
 */
public class EapAkaResponse {
    private static final String TAG = "ServiceEntitlement";

    private static final byte CODE_RESPONSE = 0x02;
    private static final byte SUBTYPE_SYNC_FAILURE = 0x04;
    private static final byte ATTRIBUTE_RES = 0x03;
    private static final byte ATTRIBUTE_AUTS = 0x04;
    private static final byte ATTRIBUTE_MAC = 0x0B;
    private static final String ALGORITHM_HMAC_SHA1 = "HmacSHA1";
    private static final int SHA1_OUTPUT_LENGTH = 20;
    private static final int MAC_LENGTH = 16;

    // RFC 4187 Section 9.4 EAP-Response/AKA-Challenge
    private String mResponse;
    // RFC 4187 Section 9.6 EAP-Response/AKA-Synchronization-Failure
    private String mSynchronizationFailureResponse;

    private EapAkaResponse() {}

    /** Returns EAP-Response/AKA-Challenge, if authentication success. Otherwise {@code null}. */
    @Nullable
    public String response() {
        return mResponse;
    }

    /**
     * Returns EAP-Response/AKA-Synchronization-Failure, if synchronization failure detected.
     * Otherwise {@code null}.
     */
    @Nullable
    public String synchronizationFailureResponse() {
        return mSynchronizationFailureResponse;
    }

    /**
     * Returns EAP-AKA challenge response message which generated with SIM EAP-AKA authentication
     * with network provided EAP-AKA challenge request message.
     */
    public static EapAkaResponse respondToEapAkaChallenge(
            Context context, int simSubscriptionId, EapAkaChallenge eapAkaChallenge)
            throws ServiceEntitlementException {
        TelephonyManager telephonyManager =
                context.getSystemService(TelephonyManager.class)
                        .createForSubscriptionId(simSubscriptionId);

        // process EAP-AKA authentication with SIM
        String response =
                telephonyManager.getIccAuthentication(
                        TelephonyManager.APPTYPE_USIM,
                        TelephonyManager.AUTHTYPE_EAP_AKA,
                        eapAkaChallenge.getSimAuthenticationRequest());
        if (response == null) {
            throw new ServiceEntitlementException(
                    ERROR_ICC_AUTHENTICATION_NOT_AVAILABLE, "EAP-AKA response is null!");
        }

        EapAkaSecurityContext securityContext = EapAkaSecurityContext.from(response);
        EapAkaResponse result = new EapAkaResponse();

        if (securityContext.getRes() != null
                && securityContext.getIk() != null
                && securityContext.getCk() != null) { // Success authentication

            // generate master key - refer to RFC 4187, section 7. Key Generation
            MasterKey mk =
                    MasterKey.create(
                            EapAkaApi.getImsiEap(telephonyManager.getSimOperator(),
                                    telephonyManager.getSubscriberId()),
                            securityContext.getIk(),
                            securityContext.getCk());
            // K_aut is the key used to calculate MAC
            if (mk.getAut() == null) {
                throw new ServiceEntitlementException(
                        ERROR_ICC_AUTHENTICATION_NOT_AVAILABLE, "Can't generate K_Aut!");
            }

            // generate EAP-AKA challenge response message
            byte[] challengeResponse =
                    generateEapAkaChallengeResponse(
                            securityContext.getRes(), eapAkaChallenge.getIdentifier(), mk.getAut());
            if (challengeResponse == null) {
                throw new ServiceEntitlementException(
                        ERROR_ICC_AUTHENTICATION_NOT_AVAILABLE,
                        "Failed to generate EAP-AKA Challenge Response data!");
            }
            // base64 encoding
            result.mResponse = Base64.encodeToString(challengeResponse, Base64.NO_WRAP).trim();

        } else if (securityContext.getAuts() != null) {

            byte[] syncFailure =
                    generateEapAkaSynchronizationFailureResponse(
                            securityContext.getAuts(), eapAkaChallenge.getIdentifier());
            result.mSynchronizationFailureResponse =
                    Base64.encodeToString(syncFailure, Base64.NO_WRAP).trim();

        } else {
            throw new ServiceEntitlementException(
                ERROR_ICC_AUTHENTICATION_NOT_AVAILABLE,
                "Invalid SIM EAP-AKA authentication response!");
        }

        return result;
    }

    /**
     * Returns EAP-Response/AKA-Challenge message, or {@code null} if failed to generate.
     * Refer to RFC 4187 section 9.4 EAP-Response/AKA-Challenge.
     */
    @VisibleForTesting
    @Nullable
    static byte[] generateEapAkaChallengeResponse(
            @Nullable byte[] res, byte identifier, @Nullable byte[] aut) {
        if (res == null || aut == null) {
            return null;
        }

        byte[] message = createEapAkaChallengeResponse(res, identifier);

        // use K_aut as key to calculate mac
        byte[] mac = calculateMac(aut, message);
        if (mac == null) {
            return null;
        }

        // fill MAC value to the message
        // The value start index is 8 + AT_RES (4 + res.length) + header of AT_MAC (4)
        int index = 8 + 4 + res.length + 4;
        System.arraycopy(mac, 0, message, index, mac.length);

        return message;
    }

    /**
     * Returns EAP-Response/AKA-Synchronization-Failure, or {@code null} if failed to generate.
     * Refer to RFC 4187 section 9.6 EAP-Response/AKA-Synchronization-Failure.
     */
    @VisibleForTesting
    @Nullable
    static byte[] generateEapAkaSynchronizationFailureResponse(
            @Nullable byte[] auts, byte identifier) {
        // size = 8 (header) + 2 (attribute & length) + AUTS
        byte[] message = new byte[10 + auts.length];

        // set up header
        message[0] = CODE_RESPONSE;
        // identifier: same as request
        message[1] = identifier;
        // length: include entire EAP-AKA message
        byte[] lengthBytes = BytesConverter.convertIntegerTo4Bytes(message.length);
        message[2] = lengthBytes[2];
        message[3] = lengthBytes[3];
        message[4] = TYPE_EAP_AKA;
        message[5] = SUBTYPE_SYNC_FAILURE;
        // reserved: 2 bytes
        message[6] = 0x00;
        message[7] = 0x00;

        // set up AT_AUTS. RFC 4187, Section 10.9 AT_AUTS
        message[8] = ATTRIBUTE_AUTS;
        // length (in 4-bytes): 4, because AUTS is 14 bytes, plus the attribute (1 byte) and
        // the length (1 byte).
        message[9] = 0x04;
        System.arraycopy(auts, 0, message, 10, auts.length);
        return message;
    }

    // AT_MAC/AT_RES are must included in response message
    //
    // Reference RFC 4187 Section 8.1 Message Format
    //           RFC 4187 Section 9.4 EAP-Response/AKA-Challenge
    //           RFC 3748 Section 4.1 Request and Response
    private static byte[] createEapAkaChallengeResponse(byte[] res, byte identifier) {
        // size = 8 (header) + resHeader (4) + res.length + AT_MAC (20 bytes)
        byte[] message = new byte[32 + res.length];

        // set up header
        message[0] = CODE_RESPONSE;
        // identifier: same as request
        message[1] = identifier;
        // length: include entire EAP-AKA message
        byte[] lengthBytes = BytesConverter.convertIntegerTo4Bytes(message.length);
        message[2] = lengthBytes[2];
        message[3] = lengthBytes[3];
        message[4] = TYPE_EAP_AKA;
        message[5] = SUBTYPE_AKA_CHALLENGE;
        // reserved: 2 bytes
        message[6] = 0x00;
        message[7] = 0x00;

        int index = 8;

        // set up AT_RES, RFC 4187, Section 10.8 AT_RES
        message[index++] = ATTRIBUTE_RES;
        // Length (in 4-bytes):
        // The length of the RES should already be a multiple of 4 bytes.
        // Add 4 to the attribute length to account for the attribute (1 byte), the length (1 byte),
        // and the length of the RES in bits (2 bytes).
        int resLength = (res.length + 4) / 4;
        message[index++] = (byte) (resLength & 0xff);
        // The value field of this attribute begins with the 2-byte RES Length, which identifies
        // the exact length of the RES in bits.
        byte[] resBitLength = BytesConverter.convertIntegerTo4Bytes(res.length * 8);
        message[index++] = resBitLength[2];
        message[index++] = resBitLength[3];
        System.arraycopy(res, 0, message, index, res.length);
        index += res.length;

        // set up AT_MAC, RFC 4187, Section 10.15 AT_MAC
        message[index++] = ATTRIBUTE_MAC;
        // length (in 4-bytes): 5, because MAC is 16 bytes, plus the attribute (1 byte),
        // the length (1 byte), and reserved bytes (2 bytes).
        message[index++] = 0x05;
        // With two bytes reserved
        message[index++] = 0x00;
        message[index++] = 0x00;

        // The MAC is calculated over the whole EAP packet and concatenated with optional
        // message-specific data, with the exception that the value field of the
        // MAC attribute is set to zero when calculating the MAC.
        Arrays.fill(message, index, index + 16, (byte) 0x00);

        return message;
    }

    // See RFC 4187, 10.15 AT_MAC, snippet as below, the key must be k_aut
    //
    // The MAC algorithm is HMAC-SHA1-128 [RFC2104] keyed hash value.  (The
    // HMAC-SHA1-128 value is obtained from the 20-byte HMAC-SHA1 value by
    // truncating the output to 16 bytes.  Hence, the length of the MAC is
    // 16 bytes.)  The derivation of the authentication key (K_aut) used in
    // the calculation of the MAC is specified in Section 7.
    @Nullable
    private static byte[] calculateMac(byte[] key, byte[] message) {
        try {
            Mac mac = Mac.getInstance(ALGORITHM_HMAC_SHA1);
            SecretKeySpec secret = new SecretKeySpec(key, ALGORITHM_HMAC_SHA1);
            mac.init(secret);
            byte[] output = mac.doFinal(message);

            if (output == null || output.length != SHA1_OUTPUT_LENGTH) {
                Log.e(TAG, "Invalid result! length should be 20, but " + output.length);
                return null;
            }

            byte[] macValue = new byte[MAC_LENGTH];
            System.arraycopy(output, 0, macValue, 0, MAC_LENGTH);
            return macValue;
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            Log.e(TAG, "calculateMac failed!", e);
        }

        return null;
    }
}
