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

/* ************************************************************************** */
/* Includes                                                                   */
/* ************************************************************************** */

#include <ex_sss.h>
#include <ex_sss_auth.h>
#include <ex_sss_boot.h>
#include <nxEnsure.h>
#include <nxLog_App.h>
#include <se05x_APDU_apis.h>
#include <se05x_tlv.h>

/* ************************************************************************** */
/* Local Defines                                                              */
/* ************************************************************************** */

#define EC_KEY_BIT_LEN 256
#define ATTESTATION_KEY_ID 0xAFFE5F
#define OBJECT_TO_ATTEST 0xF5EFFA

#if (SSS_HAVE_SE05X_AUTH_USERID) || (SSS_HAVE_SE05X_AUTH_USERID_PLATFSCP03) //UserID Session
#define EX_LOCAL_OBJ_AUTH_ID EX_SSS_AUTH_SE05X_UserID_AUTH_ID
#elif (SSS_HAVE_SE05X_AUTH_NONE) || (SSS_HAVE_SE05X_AUTH_PLATFSCP03) //No auth
#define EX_LOCAL_OBJ_AUTH_ID EX_SSS_AUTH_SE05X_NONE_AUTH_ID
#elif (SSS_HAVE_SE05X_AUTH_AESKEY) || (SSS_HAVE_SE05X_AUTH_AESKEY_PLATFSCP03) //AESKey
#define EX_LOCAL_OBJ_AUTH_ID EX_SSS_AUTH_SE05X_APPLETSCP_AUTH_ID
#elif (SSS_HAVE_SE05X_AUTH_ECKEY) || (SSS_HAVE_SE05X_AUTH_ECKEY_PLATFSCP03) //ECKey session
#define EX_LOCAL_OBJ_AUTH_ID EX_SSS_AUTH_SE05X_ECKEY_ECDSA_AUTH_ID
#endif
/* ************************************************************************** */
/* Structures and Typedefs                                                    */
/* ************************************************************************** */

/* ************************************************************************** */
/* Global Variables                                                           */
/* ************************************************************************** */

static ex_sss_boot_ctx_t gex_sss_get_timestamp_boot_ctx;
#define EX_SSS_BOOT_PCONTEXT (&gex_sss_get_timestamp_boot_ctx)
#define EX_SSS_BOOT_DO_ERASE 1
#define EX_SSS_BOOT_EXPOSE_ARGC_ARGV 0

#include <ex_sss_main_inc.h>

/* ************************************************************************** */
/* Static function declarations                                               */
/* ************************************************************************** */

/* ************************************************************************** */
/* Private Functions                                                          */
/* ************************************************************************** */

static sss_status_t create_attestation_key(ex_sss_boot_ctx_t *pCtx, uint32_t keyId, size_t keyBitLen);
static sss_status_t create_host_public_key(
    ex_sss_boot_ctx_t *pCtx, uint32_t keyId, size_t keyBitLen, sss_object_t *verification_object);
static sss_status_t create_binary_object_to_attest(ex_sss_boot_ctx_t *pCtx, uint32_t keyId);
static sss_status_t attest_binary_object(ex_sss_boot_ctx_t *pCtx,
    uint32_t attestation_key_id,
    uint32_t object_key_id,
    sss_object_t *verification_object,
    SE05x_TimeStamp_t *timestamp);
static int compare_array(uint8_t *array1, uint8_t *array2, size_t bytes_to_compare);
static void clean_attestation_objects(ex_sss_boot_ctx_t *pCtx, uint32_t attestation_key_id, uint32_t keyid_to_attest);

/* ************************************************************************** */
/* Public Functions                                                           */
/* ************************************************************************** */

sss_status_t ex_sss_entry(ex_sss_boot_ctx_t *pCtx)
{
    sss_status_t status           = kStatus_SSS_Fail;
    smStatus_t sm_status          = SM_NOT_OK;
    uint32_t attestation_key_id   = ATTESTATION_KEY_ID;
    uint32_t keyid_to_attest      = OBJECT_TO_ATTEST;
    sss_se05x_session_t *pSession = (sss_se05x_session_t *)&pCtx->session;
    pSe05xSession_t s_ctx         = &pSession->s_ctx;
    SE05x_TimeStamp_t timestamp = {0}, new_timestamp = {0};
    int result = -1;
    /* verification context */
    sss_object_t verification_object;

    sm_status = Se05x_API_GetTimestamp(s_ctx, &timestamp);
    ENSURE_OR_GO_CLEANUP(sm_status == SM_OK);
    status = kStatus_SSS_Success;
    LOG_AU8_I(timestamp.ts, sizeof(timestamp.ts));

    /* Generate Random Attestation key
     * We use NIST-P 256 in this example
     */
    status = create_attestation_key(pCtx, attestation_key_id, EC_KEY_BIT_LEN);
    ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);

    status = create_host_public_key(pCtx, attestation_key_id, EC_KEY_BIT_LEN, &verification_object);
    ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);

    /* Import any object into the SE which will be
     * read with attestation. In this example, we are
     * importing a binary objecct
     */
    status = create_binary_object_to_attest(pCtx, keyid_to_attest);
    ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);

    status = attest_binary_object(pCtx, attestation_key_id, keyid_to_attest, &verification_object, &new_timestamp);
    ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);
    LOG_AU8_I(new_timestamp.ts, sizeof(new_timestamp.ts));

    result = compare_array(timestamp.ts, new_timestamp.ts, sizeof(timestamp.ts));
    status = ((result == 1) || (result == -1)) ? kStatus_SSS_Fail : kStatus_SSS_Success;

cleanup:
    clean_attestation_objects(pCtx, attestation_key_id, keyid_to_attest);
    sss_key_object_free(&verification_object);
    if (kStatus_SSS_Success == status) {
        LOG_I("se05x_TimeStamp Example Success !!!...");
    }
    else {
        LOG_E("se05x_TimeStamp Example Failed !!!...");
    }
    return status;
}

static sss_status_t create_attestation_key(ex_sss_boot_ctx_t *pCtx, uint32_t keyId, size_t keyBitLen)
{
    sss_status_t status          = kStatus_SSS_Fail;
    size_t keylen                = keyBitLen / 8;
    sss_object_t key_attst       = {0};
    sss_cipher_type_t cipherType = kSSS_CipherType_EC_NIST_P;
    sss_policy_u key_pol;
    sss_policy_u common;
    sss_policy_t policy_for_ec_key;

    status = sss_key_object_init(&key_attst, &pCtx->ks);
    ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);

    /* Generate asymmetric key */
    status = sss_key_object_allocate_handle(
        &key_attst, keyId, kSSS_KeyPart_Pair, cipherType, keylen, kKeyObject_Mode_Persistent);
    ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);

    key_pol = (sss_policy_u){.type = KPolicy_Asym_Key,
        .auth_obj_id               = EX_LOCAL_OBJ_AUTH_ID,
        .policy                    = {.asymmkey = {
                       .can_Sign          = 1,
                       .can_Verify        = 1,
                       .can_Encrypt       = 1,
                       .can_Decrypt       = 1,
                       .can_KD            = 1,
                       .can_Wrap          = 1,
                       .can_Write         = 1,
                       .can_Gen           = 1,
                       .can_Import_Export = 1,
                       .can_KA            = 1,
                       .can_Read          = 1,
                       .can_Attest        = 1,
                   }}};

    common            = (sss_policy_u){.type = KPolicy_Common,
        .auth_obj_id              = EX_LOCAL_OBJ_AUTH_ID,
        .policy                   = {.common = {
                       .can_Delete = 1,
                   }}};
    policy_for_ec_key = (sss_policy_t){.nPolicies = 2, .policies = {&key_pol, &common}};

    status = sss_key_store_generate_key(&pCtx->ks, &key_attst, keyBitLen, &policy_for_ec_key);

cleanup:
    return status;
}

static sss_status_t create_host_public_key(
    ex_sss_boot_ctx_t *pCtx, uint32_t keyId, size_t keyBitLen, sss_object_t *verification_object)
{
    sss_status_t status          = kStatus_SSS_Fail;
    sss_object_t attestation_key = {0};
    uint8_t public_key[100]      = {0};
    size_t public_key_len        = sizeof(public_key);

    status = sss_key_object_init(&attestation_key, &pCtx->ks);
    ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);

    status = sss_key_object_get_handle(&attestation_key, keyId);
    ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);

    status = sss_key_store_get_key(&pCtx->ks, &attestation_key, public_key, &public_key_len, &keyBitLen);
    ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);

    status = sss_key_object_init(verification_object, &pCtx->host_ks);
    ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);

    status = sss_key_object_allocate_handle(verification_object,
        __LINE__,
        kSSS_KeyPart_Public,
        attestation_key.cipherType,
        public_key_len,
        kKeyObject_Mode_Persistent);
    ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);

    status = sss_key_store_set_key(&pCtx->host_ks, verification_object, public_key, public_key_len, keyBitLen, NULL, 0);

cleanup:
    return status;
}

static sss_status_t create_binary_object_to_attest(ex_sss_boot_ctx_t *pCtx, uint32_t keyId)
{
    sss_status_t status           = kStatus_SSS_Fail;
    sss_object_t object_to_attest = {0};
    sss_key_part_t key_part       = kSSS_KeyPart_Default;
    sss_cipher_type_t cipherType  = kSSS_CipherType_Binary;
    uint8_t data[]                = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09};
    size_t dataLen                = sizeof(data);
    sss_policy_u obj_pol;
    sss_policy_u common;
    sss_policy_t policy_for_bin_obj;

    status = sss_key_object_init(&object_to_attest, &pCtx->ks);
    ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);

    /* Generate asymmetric key */
    status = sss_key_object_allocate_handle(
        &object_to_attest, keyId, key_part, cipherType, dataLen, kKeyObject_Mode_Persistent);
    ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);

    obj_pol            = (sss_policy_u){.type = KPolicy_File,
        .auth_obj_id               = EX_LOCAL_OBJ_AUTH_ID,
        .policy                    = {.file = {
                       .can_Write = 1,
                       .can_Read  = 1,
                   }}};
    common             = (sss_policy_u){.type = KPolicy_Common,
        .auth_obj_id              = EX_LOCAL_OBJ_AUTH_ID,
        .policy                   = {.common = {
                       .can_Delete = 1,
                   }}};
    policy_for_bin_obj = (sss_policy_t){.nPolicies = 2, .policies = {&obj_pol, &common}};

    status = sss_key_store_set_key(
        &pCtx->ks, &object_to_attest, data, dataLen, dataLen, &policy_for_bin_obj, sizeof(policy_for_bin_obj));

cleanup:
    return status;
}

static sss_status_t attest_binary_object(ex_sss_boot_ctx_t *pCtx,
    uint32_t attestation_key_id,
    uint32_t object_key_id,
    sss_object_t *verification_object,
    SE05x_TimeStamp_t *timestamp)
{
    sss_status_t status                      = kStatus_SSS_Fail;
    uint8_t attested_object_data[2500]       = {0};
    size_t attestedObjByteLen                = sizeof(attested_object_data);
    size_t objBitLen                         = attestedObjByteLen * 8;
    sss_algorithm_t algorithm                = kAlgorithm_SSS_ECDSA_SHA256;
    sss_object_t sss_attestation_object      = {0};
    sss_object_t sss_object_to_attest        = {0};
    sss_se05x_attst_comp_data_t comp_data[2] = {0};
    sss_se05x_attst_data_t att_data          = {.valid_number = 2};
    /* Random data from the host to check if SE
     * answers to current attestation request and
     * not an older response is used */

    /* clang-format off */
    uint8_t freshness[16] = {
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
        0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
    /* clang-format on */

    /* Variables for verification */
    uint8_t plainData[2600] = {0};
    size_t plainDataLen     = sizeof(plainData);
    uint8_t digest[64]      = {0};
    size_t digestLen        = sizeof(digest);
    sss_digest_t digest_ctx;
    sss_algorithm_t digest_algorithm = kAlgorithm_SSS_SHA256;
    sss_asymmetric_t verify_ctx;

    /* Initialize Attesttation Object */
    status = sss_key_object_init(&sss_attestation_object, &pCtx->ks);
    ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);

    status = sss_key_object_get_handle(&sss_attestation_object, attestation_key_id);
    ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);

    /* Initialize object to attest */
    status = sss_key_object_init(&sss_object_to_attest, &pCtx->ks);
    ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);

    status = sss_key_object_get_handle(&sss_object_to_attest, object_key_id);
    ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);
    /* Prepare/init attestation data structure */

    memcpy(&att_data.data, &comp_data[0], sizeof(comp_data));
    att_data.data[0].attributeLen = sizeof(att_data.data[0].attribute);
    att_data.data[0].outrandomLen = sizeof(att_data.data[0].outrandom);
    att_data.data[0].chipIdLen    = sizeof(att_data.data[0].attribute);
    att_data.data[0].signatureLen = sizeof(att_data.data[0].signature);
    att_data.data[1].attributeLen = sizeof(att_data.data[1].attribute);
    att_data.data[1].outrandomLen = sizeof(att_data.data[1].outrandom);
    att_data.data[1].chipIdLen    = sizeof(att_data.data[1].attribute);
    att_data.data[1].signatureLen = sizeof(att_data.data[1].signature);

    /* Execute attested read
     * We use attestation object to attest (sign) all read data + object attributes
     * Returns object attributes and signature in att_data
     */

    status = sss_se05x_key_store_get_key_attst((sss_se05x_key_store_t *)&pCtx->ks,
        (sss_se05x_object_t *)&sss_object_to_attest,
        attested_object_data,
        &attestedObjByteLen,
        &objBitLen,
        (sss_se05x_object_t *)&sss_attestation_object,
        algorithm,
        freshness,
        sizeof(freshness),
        &att_data);
    ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);

    /* Perform verification operation here on the following data
     *      (key + offset) +
     *      att_data->data[0].attribute +
     *      att_data->data[0].timestamp +
     *      att_data->data[0].outrandom +
     *      att_data->data[0].chipId
     * with signature
     *      att_data->data[0].signature
     *
     * We perform signature verification on host.
     * First we digest the data then pass it to verify API
     */

    plainDataLen = attestedObjByteLen + att_data.data[0].attributeLen + att_data.data[0].timeStampLen +
                   att_data.data[0].outrandomLen + att_data.data[0].chipIdLen;
    if (plainDataLen > sizeof(plainData)) {
        LOG_E("Insufficient Buffer");
        status = kStatus_SSS_Fail;
        goto cleanup;
    }
    memcpy(plainData, attested_object_data, attestedObjByteLen);
    memcpy(plainData + attestedObjByteLen, att_data.data[0].attribute, att_data.data[0].attributeLen);
    memcpy(plainData + attestedObjByteLen + att_data.data[0].attributeLen,
        &(att_data.data[0].timeStamp),
        att_data.data[0].timeStampLen);
    memcpy(plainData + attestedObjByteLen + att_data.data[0].attributeLen + att_data.data[0].timeStampLen,
        att_data.data[0].outrandom,
        att_data.data[0].outrandomLen);
    memcpy(plainData + attestedObjByteLen + att_data.data[0].attributeLen + att_data.data[0].timeStampLen +
               att_data.data[0].outrandomLen,
        att_data.data[0].chipId,
        att_data.data[0].chipIdLen);

    status = sss_digest_context_init(&digest_ctx, &pCtx->host_session, digest_algorithm, kMode_SSS_Digest);
    ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);

    status = sss_digest_one_go(&digest_ctx, plainData, plainDataLen, digest, &digestLen);
    ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);

    sss_digest_context_free(&digest_ctx);

    /* Verify signature */
    sss_asymmetric_context_init(&verify_ctx, &pCtx->host_session, verification_object, algorithm, kMode_SSS_Verify);

    status = sss_asymmetric_verify_digest(
        &verify_ctx, digest, digestLen, att_data.data[0].signature, att_data.data[0].signatureLen);

    sss_asymmetric_context_free(&verify_ctx);

    ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success);

    memcpy(timestamp, &(att_data.data[0].timeStamp), att_data.data[0].timeStampLen);

cleanup:
    return status;
}

static void clean_attestation_objects(ex_sss_boot_ctx_t *pCtx, uint32_t attestation_key_id, uint32_t keyid_to_attest)
{
    sss_status_t status           = kStatus_SSS_Fail;
    sss_object_t object_to_delete = {0};
    status                        = sss_key_object_init(&object_to_delete, &pCtx->ks);
    ENSURE_OR_GO_EXIT(status == kStatus_SSS_Success);
    /* Delete attestation object */
    status = sss_key_object_get_handle(&object_to_delete, attestation_key_id);
    ENSURE_OR_GO_EXIT(status == kStatus_SSS_Success);
    status = sss_key_store_erase_key(&pCtx->ks, &object_to_delete);
    ENSURE_OR_GO_EXIT(status == kStatus_SSS_Success);
    /* Delete object to attest */
    status = sss_key_object_get_handle(&object_to_delete, keyid_to_attest);
    ENSURE_OR_GO_EXIT(status == kStatus_SSS_Success);
    status = sss_key_store_erase_key(&pCtx->ks, &object_to_delete);

exit:
    return;
}

static int compare_array(uint8_t *array1, uint8_t *array2, size_t bytes_to_compare)
{
    size_t i         = 0;
    int compareValue = 0;
    for (i = 0; i < bytes_to_compare; i++) {
        if (array1[i] > array2[i]) {
            compareValue = 1;
            break;
        }
        else if (array1[i] < array2[i]) {
            compareValue = 2;
            break;
        }
    }
    return compareValue;
}
