/*
*
* Copyright 2018-2020 NXP
* SPDX-License-Identifier: Apache-2.0
*/

/** @file */

#include <fsl_sss_se05x_apis.h>
#include <nxLog_sss.h>
#include <string.h>

#if SSS_HAVE_APPLET_SE05X_IOT
#include <fsl_sss_se05x_policy.h>

/*Update header bit of policy based on the access rights sets in the policy
 Input:policy object of type sss_policy_sym_key_u
 Output:pbuffer pointing to policy header offset*/
static void sss_se05x_update_header_sym_key_policy(sss_policy_sym_key_u key_pol, uint8_t *pbuffer);

/*Update header bit of policy based on the access rights sets in the policy
 Input:policy object of type sss_policy_asym_key_u
 Output:pbuffer pointing to policy header offset*/
static void sss_se05x_update_header_asym_key_policy(sss_policy_asym_key_u key_pol, uint8_t *pbuffer);

/*Update header bit of policy based on the access rights sets in the policy
Input:policy object of type sss_policy_common_u
Output:pbuffer pointing to policy header offset*/
static void sss_se05x_update_header_common_policy(sss_policy_common_u common_pol, uint8_t *pbuffer);

/*Update header bit of policy based on the access rights sets in the policy
Input:policy object of type sss_policy_userid_u
Output:pbuffer pointing to policy header offset*/
static void sss_se05x_update_header_pin_policy(sss_policy_userid_u pin_pol, uint8_t *pbuffer);

/*Update header bit of policy based on the access rights sets in the policy
Input:policy object of type sss_policy_file_u
Output:pbuffer pointing to policy header offset*/
static void sss_se05x_update_header_file_policy(sss_policy_file_u file_pol, uint8_t *pbuffer);

/*Update header bit of policy based on the access rights sets in the policy
Input:policy object of type sss_policy_counter_u
Output:pbuffer pointing to policy header offset*/
static void sss_se05x_update_header_counter_policy(sss_policy_counter_u counter_pol, uint8_t *pbuffer);

/*Update header bit of policy based on the access rights sets in the policy
Input:policy object of type sss_policy_pcr_u
Output:pbuffer pointing to policy header offset
*/
static void sss_se05x_update_header_pcr_policy(sss_policy_pcr_u pcr_pol, uint8_t *pbuffer);

/*Update header bit of policy based on the access rights sets in the policy
Input:policy object of type sss_policy_common_pcr_value_u
Output:pbuffer pointing to policy header offset
*/
static void sss_se05x_update_header_pcr_value_policy(sss_policy_common_pcr_value_u pcr_value_pol, uint8_t *pbuffer);

static void sss_se05x_update_ext_pcr_value_policy(
    sss_policy_common_pcr_value_u pcr_value_pol, uint8_t *pbuffer, uint32_t *ext_offset);

/*
finds indices of all same auth Ids in a group of polices and returns the count
of same auth ids with in a group of Ids, it laso copies indices in to an array passed by user
Input: authId to be searched
        policies: array of all policies with diversified auth ids
Output: pindices " array contains index of all input authid
retuns :count of same auth ids with in a group of Ids
*/
static int sss_se05x_find_authId_instances(uint32_t authId, uint8_t *pindices, sss_policy_t *policies);
static void sss_se05x_copy_uint32_to_u8_array(uint32_t u32, uint8_t *pbuffer);
static void sss_se05x_copy_uint16_to_u8_array(uint16_t u16, uint8_t *pbuffer);

static void sss_se05x_update_header_sym_key_policy(sss_policy_sym_key_u key_pol, uint8_t *pbuffer)
{
    uint32_t header = 0;
    if (key_pol.can_Sign) {
        header |= POLICY_OBJ_ALLOW_SIGN;
    }
    if (key_pol.can_Verify) {
        header |= POLICY_OBJ_ALLOW_VERIFY;
    }
    if (key_pol.can_Encrypt) {
        header |= POLICY_OBJ_ALLOW_ENC;
    }
    if (key_pol.can_Decrypt) {
        header |= POLICY_OBJ_ALLOW_DEC;
    }
    if (key_pol.can_KD) {
        header |= POLICY_OBJ_ALLOW_KDF;
    }
    if (key_pol.can_Wrap) {
        header |= POLICY_OBJ_ALLOW_WRAP;
    }
    if (key_pol.can_Write) {
        header |= POLICY_OBJ_ALLOW_WRITE;
    }
    if (key_pol.can_Gen) {
        header |= POLICY_OBJ_ALLOW_GEN;
    }
    if (key_pol.can_Desfire_Auth) {
        header |= POLICY_OBJ_ALLOW_DESFIRE_AUTHENTICATION;
    }
    if (key_pol.can_Desfire_Dump) {
        header |= POLICY_OBJ_ALLOW_DESFIRE_DUMP_SESSION_KEYS;
    }
    if (key_pol.can_Import_Export) {
        header |= POLICY_OBJ_ALLOW_IMPORT_EXPORT;
    }
#if SSS_HAVE_SE05X_VER_GTE_06_00
    if (key_pol.forbid_Derived_Output) {
        header |= POLICY_OBJ_FORBID_DERIVED_OUTPUT;
    }
#endif
#if SSS_HAVE_SE05X_VER_GTE_06_00
    if (key_pol.allow_kdf_ext_rnd) {
        header |= POLICY_OBJ_ALLOW_KDF_EXT_RANDOM;
    }
#endif
    sss_se05x_copy_uint32_to_u8_array(header, pbuffer);
}

static void sss_se05x_update_header_asym_key_policy(sss_policy_asym_key_u key_pol, uint8_t *pbuffer)
{
    uint32_t header = 0;
    if (key_pol.can_Sign) {
        header |= POLICY_OBJ_ALLOW_SIGN;
    }
    if (key_pol.can_Verify) {
        header |= POLICY_OBJ_ALLOW_VERIFY;
    }
    if (key_pol.can_Encrypt) {
        header |= POLICY_OBJ_ALLOW_ENC;
    }
    if (key_pol.can_Decrypt) {
        header |= POLICY_OBJ_ALLOW_DEC;
    }
    if (key_pol.can_KD) {
        header |= POLICY_OBJ_ALLOW_KDF;
    }
    if (key_pol.can_Wrap) {
        header |= POLICY_OBJ_ALLOW_WRAP;
    }
    if (key_pol.can_Write) {
        header |= POLICY_OBJ_ALLOW_WRITE;
    }
    if (key_pol.can_Gen) {
        header |= POLICY_OBJ_ALLOW_GEN;
    }
    if (key_pol.can_Import_Export) {
        header |= POLICY_OBJ_ALLOW_IMPORT_EXPORT;
    }
    if (key_pol.can_KA) {
        header |= POLICY_OBJ_ALLOW_KA;
    }
    if (key_pol.can_Read) {
        header |= POLICY_OBJ_ALLOW_READ;
    }
    if (key_pol.can_Attest) {
        header |= POLICY_OBJ_ALLOW_ATTESTATION;
    }
#if SSS_HAVE_SE05X_VER_GTE_06_00
    if (key_pol.forbid_Derived_Output) {
        header |= POLICY_OBJ_FORBID_DERIVED_OUTPUT;
    }
#endif
    sss_se05x_copy_uint32_to_u8_array(header, pbuffer);
}

static void sss_se05x_update_header_common_policy(sss_policy_common_u common_pol, uint8_t *pbuffer)
{
    uint32_t header = 0;
    if (common_pol.can_Delete) {
        header |= POLICY_OBJ_ALLOW_DELETE;
    }
    if (common_pol.forbid_All) {
        header |= POLICY_OBJ_FORBID_ALL;
    }
    if (common_pol.req_Sm) {
        header |= POLICY_OBJ_REQUIRE_SM;
    }
    sss_se05x_copy_uint32_to_u8_array(header, pbuffer);
}

static void sss_se05x_update_header_pin_policy(sss_policy_userid_u pin_pol, uint8_t *pbuffer)
{
    uint32_t header = 0;
    if (pin_pol.can_Write) {
        header |= POLICY_OBJ_ALLOW_WRITE;
    }
    sss_se05x_copy_uint32_to_u8_array(header, pbuffer);
}

static void sss_se05x_update_header_file_policy(sss_policy_file_u file_pol, uint8_t *pbuffer)
{
    uint32_t header = 0;
    if (file_pol.can_Read) {
        header |= POLICY_OBJ_ALLOW_READ;
    }
    if (file_pol.can_Write) {
        header |= POLICY_OBJ_ALLOW_WRITE;
    }
    sss_se05x_copy_uint32_to_u8_array(header, pbuffer);
}

static void sss_se05x_update_header_counter_policy(sss_policy_counter_u counter_pol, uint8_t *pbuffer)
{
    uint32_t header = 0;
    if (counter_pol.can_Read) {
        header |= POLICY_OBJ_ALLOW_READ;
    }
    if (counter_pol.can_Write) {
        header |= POLICY_OBJ_ALLOW_WRITE;
    }
    sss_se05x_copy_uint32_to_u8_array(header, pbuffer);
}

static void sss_se05x_update_header_pcr_policy(sss_policy_pcr_u pcr_pol, uint8_t *pbuffer)
{
    uint32_t header = 0;
    if (pcr_pol.can_Read) {
        header |= POLICY_OBJ_ALLOW_READ;
    }
    if (pcr_pol.can_Write) {
        header |= POLICY_OBJ_ALLOW_WRITE;
    }
    sss_se05x_copy_uint32_to_u8_array(header, pbuffer);
}

static void sss_se05x_update_header_pcr_value_policy(sss_policy_common_pcr_value_u pcr_pol, uint8_t *pbuffer)
{
    uint32_t header = 0;
    header |= POLICY_OBJ_REQUIRE_PCR_VALUE;
    sss_se05x_copy_uint32_to_u8_array(header, pbuffer);
}

static void sss_se05x_update_ext_pcr_value_policy(
    sss_policy_common_pcr_value_u pcr_pol, uint8_t *pbuffer, uint32_t *ext_offset)
{
    /*copy 4 bytes PCR Object ID*/
    sss_se05x_copy_uint32_to_u8_array(pcr_pol.pcrObjId, pbuffer + *ext_offset);
    *ext_offset += sizeof(pcr_pol.pcrObjId);
    /*copy 32 bytes PCR value*/
    memcpy(pbuffer + *ext_offset, pcr_pol.pcrExpectedValue, sizeof(pcr_pol.pcrExpectedValue));
    *ext_offset += sizeof(pcr_pol.pcrExpectedValue);
}

static void sss_se05x_copy_uint32_to_u8_array(uint32_t u32, uint8_t *pbuffer)
{
    pbuffer[0] |= (uint8_t)((u32 >> 3 * 8) & 0xFF);
    pbuffer[1] |= (uint8_t)((u32 >> 2 * 8) & 0xFF);
    pbuffer[2] |= (uint8_t)((u32 >> 1 * 8) & 0xFF);
    pbuffer[3] |= (uint8_t)((u32 >> 0 * 8) & 0xFF);
}

static void sss_se05x_copy_uint16_to_u8_array(uint16_t u16, uint8_t *pbuffer)
{
    pbuffer[0] |= (uint8_t)((u16 >> 8) & 0xFF);
    pbuffer[1] |= (uint8_t)((u16)&0xFF);
}
static int sss_se05x_find_authId_instances(uint32_t authId, uint8_t *pindices, sss_policy_t *policies)
{
    int count = 0;
    for (uint32_t i = 0; i <= policies->nPolicies - 1; i++) {
        if (policies->policies[i] != NULL && policies->policies[i]->auth_obj_id == authId) {
            *pindices++ = i;
            count++;
        }
    }
    return count;
}

sss_status_t sss_se05x_create_object_policy_buffer(sss_policy_t *policies, uint8_t *pbuff, size_t *buf_len)
{
    uint8_t temp_buffer[MAX_OBJ_POLICY_SIZE] = {0};
    uint8_t indexArray[MAX_OBJ_POLICY_TYPES] = {0};
    uint8_t auth_id_count                    = 0;
    uint8_t policiesCopied                   = 0;
    uint32_t ext_offset                      = 0;
    uint32_t offset                          = 0;

    if ((policies == NULL) || (pbuff == NULL) || (buf_len == NULL))
        return kStatus_SSS_InvalidArgument;

    if (policies->nPolicies > SSS_POLICY_COUNT_MAX) {
        return kStatus_SSS_InvalidArgument;
    }

    *buf_len = 0;
    /*Reinitialize policy buffer for every Secure object*/
    memset(pbuff, 0x00, MAX_POLICY_BUFFER_SIZE);
    for (uint32_t i = 0; i < policies->nPolicies && policiesCopied < policies->nPolicies; i++) {
        if (policies->policies[i] != NULL) {
            auth_id_count =
                sss_se05x_find_authId_instances(policies->policies[i]->auth_obj_id, &indexArray[0], policies);
            /*length is initialized with default length
                        will be updated when extensions are copied*/
            temp_buffer[OBJ_POLICY_LENGTH_OFFSET] = DEFAULT_OBJECT_POLICY_SIZE;
            /* Copy Auth Id*/
            sss_se05x_copy_uint32_to_u8_array(
                policies->policies[i]->auth_obj_id, &temp_buffer[OBJ_POLICY_AUTHID_OFFSET]);
            for (int j = 0; j < auth_id_count; j++) {
                /* Update AR Header as per object type*/
                switch (policies->policies[indexArray[j]]->type) {
                case KPolicy_Sym_Key:
                    sss_se05x_update_header_sym_key_policy(
                        (policies->policies[indexArray[j]])->policy.symmkey, &temp_buffer[OBJ_POLICY_HEADER_OFFSET]);
                    break;
                case KPolicy_Asym_Key:
                    sss_se05x_update_header_asym_key_policy(
                        (policies->policies[indexArray[j]])->policy.asymmkey, &temp_buffer[OBJ_POLICY_HEADER_OFFSET]);
                    break;
                case KPolicy_Common:
                    sss_se05x_update_header_common_policy(
                        (policies->policies[indexArray[j]])->policy.common, &temp_buffer[OBJ_POLICY_HEADER_OFFSET]);
                    break;
                case KPolicy_Common_PCR_Value:
                    sss_se05x_update_header_pcr_value_policy(
                        (policies->policies[indexArray[j]])->policy.common_pcr_value,
                        &temp_buffer[OBJ_POLICY_HEADER_OFFSET]);
                    sss_se05x_update_ext_pcr_value_policy((policies->policies[indexArray[j]])->policy.common_pcr_value,
                        &temp_buffer[OBJ_POLICY_EXT_OFFSET],
                        &ext_offset);
                    temp_buffer[OBJ_POLICY_LENGTH_OFFSET] += OBJ_POLICY_PCR_DATA_SIZE;
                    break;
                case KPolicy_File:
                    sss_se05x_update_header_file_policy(
                        (policies->policies[indexArray[j]])->policy.file, &temp_buffer[OBJ_POLICY_HEADER_OFFSET]);
                    break;
                case KPolicy_Counter:
                    sss_se05x_update_header_counter_policy(
                        (policies->policies[indexArray[j]])->policy.counter, &temp_buffer[OBJ_POLICY_HEADER_OFFSET]);
                    break;
                case KPolicy_PCR:
                    sss_se05x_update_header_pcr_policy(
                        (policies->policies[indexArray[j]])->policy.pcr, &temp_buffer[OBJ_POLICY_HEADER_OFFSET]);
                    break;
                case KPolicy_UserID:
                    sss_se05x_update_header_pin_policy(
                        (policies->policies[indexArray[j]])->policy.pin, &temp_buffer[OBJ_POLICY_HEADER_OFFSET]);
                    break;
                default:
                    break;
                }
                policies->policies[indexArray[j]] = NULL;
            }
            memcpy(pbuff + offset, temp_buffer, (temp_buffer[0] + 1));
            *buf_len += (temp_buffer[0] + 1);
            policiesCopied = policiesCopied + auth_id_count;
            offset += (temp_buffer[0] + 1);
            /* reinitialize temp buffer for a new policy*/
            memset(&temp_buffer[0], 0x00, sizeof(temp_buffer));
            ext_offset = 0;
        }
    }

    return kStatus_SSS_Success;
}

sss_status_t sss_se05x_create_session_policy_buffer(
    sss_policy_session_u *session_policy, uint8_t *session_pol_buff, size_t *buf_len)
{
    uint16_t session_header = 0;
    /*Reinitialize policy buffer for every Secure object*/
    memset(session_pol_buff, 0x00, MAX_POLICY_BUFFER_SIZE);

    if ((session_policy == NULL) || (session_pol_buff == NULL) || (buf_len == NULL))
        return kStatus_SSS_InvalidArgument;

    *buf_len = DEFAULT_SESSION_POLICY_SIZE;

    /*set default length*/
    session_pol_buff[SESSION_POLICY_LENGTH_OFFSET] = DEFAULT_SESSION_POLICY_SIZE;
    if (session_policy->has_MaxOperationsInSession) {
        session_header |= POLICY_SESSION_MAX_APDU;
        sss_se05x_copy_uint16_to_u8_array(session_header, &session_pol_buff[SESSION_POLICY_AR_HEADER_OFFSET]);
        sss_se05x_copy_uint16_to_u8_array(session_policy->maxOperationsInSession, &session_pol_buff[*buf_len]);
        *buf_len += sizeof(session_policy->maxOperationsInSession);
    }
    if (session_policy->has_MaxDurationOfSession_sec) {
        session_header |= POLICY_SESSION_MAX_TIME;
        sss_se05x_copy_uint16_to_u8_array(session_header, &session_pol_buff[SESSION_POLICY_AR_HEADER_OFFSET]);
        sss_se05x_copy_uint16_to_u8_array(session_policy->maxDurationOfSession_sec, &session_pol_buff[*buf_len]);
        *buf_len += sizeof(session_policy->maxDurationOfSession_sec);
    }
    if (session_policy->allowRefresh) {
        session_header |= POLICY_SESSION_ALLOW_REFRESH;
        sss_se05x_copy_uint16_to_u8_array(session_header, &session_pol_buff[SESSION_POLICY_AR_HEADER_OFFSET]);
    }
    session_pol_buff[0] = (uint8_t)(*buf_len - 1); //Exclude Length of Policy field.
    return kStatus_SSS_Success;
}
#endif /* SSS_HAVE_APPLET_SE05X_IOT */
