/*--------------------------------------------------------------------------*/
/* Copyright 2021 NXP                                                       */
/*                                                                          */
/* NXP Confidential. This software is owned or controlled by NXP and may    */
/* only be used strictly in accordance with the applicable license terms.   */
/* By expressly accepting such terms or by downloading, installing,         */
/* activating and/or otherwise using the software, you are agreeing that    */
/* you have read, and that you agree to comply with and are bound by, such  */
/* license terms. If you do not agree to be bound by the applicable license */
/* terms, then you may not retain, install, activate or otherwise use the   */
/* software.                                                                */
/*--------------------------------------------------------------------------*/

/**
 * @file  mcuxClKey_example.c
 * @brief Example for the mcuxClKey component
 *
 * @example mcuxClKey_example.c
 * @brief   Example for the mcuxClKey component
 */

#include <mcuxClKey.h>
#include <mcuxClSession.h>
#include <mcuxCsslFlowProtection.h> // Code flow protection
#include <stdbool.h>  // bool type for the example's return code


/* Example AES-128 key. */
static uint8_t aes128_key[MCUXCLKEY_SIZE_128] = {
                                    0x7c, 0x0b, 0x7d, 0xb9,
                                    0x81, 0x1f, 0x10, 0xd0,
                                    0x0e, 0x47, 0x6c, 0x7a,
                                    0x0d, 0x92, 0xf6, 0xe0
};


/** Performs an example initialization and cleanup of the mcuxClKey component.
 * @retval true  The example code completed successfully
 * @retval false The example code failed */
bool mcuxClKey_example(void)
{
    /**************************************************************************/
    /* Preparation                                                            */
    /**************************************************************************/

    /* Key buffer for the key in memory. */
    uint32_t key_buffer[MCUXCLKEY_SIZE_128 / sizeof(uint32_t)];

    mcuxClSession_Descriptor_t session;

    MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClSession_init(&session,
                                                                     NULL,
                                                                     NULL,
                                                                     NULL,
                                                                     NULL));

    if((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClSession_init) != token) || (MCUXCLSESSION_STATUS_OK != result))
        return false;
    MCUX_CSSL_FP_FUNCTION_CALL_END();


    /**************************************************************************/
    /* Key setup                                                              */
    /**************************************************************************/

    /* Create and initialize mcuxClKey_Descriptor_t structure. */
    mcuxClKey_Descriptor_t key = {0};

    MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClKey_init(&session,
                                                                 (mcuxClKey_Handle_t) &key,
                                                                 &mcuxKey_keyType_Aes128,
                                                                 &mcuxClKey_protection_none,
                                                                 aes128_key,
                                                                 NULL, /* no srcAuxData */
                                                                 0u));

    if((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClKey_init) != token) || (MCUXCLKEY_STATUS_OK != result))
        return false;
    MCUX_CSSL_FP_FUNCTION_CALL_END();


    /* Set key properties. */
    mcuxClCss_KeyProp_t key_properties;

    key_properties.word.value = 0u;
    key_properties.bits.ksize = MCUXCLCSS_KEYPROPERTY_KEY_SIZE_128;
    key_properties.bits.kactv = MCUXCLCSS_KEYPROPERTY_ACTIVE_TRUE;

    MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClKey_setKeyproperties((mcuxClKey_Handle_t) &key,
                                                                             key_properties));

    if((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClKey_setKeyproperties) != token) || (MCUXCLKEY_STATUS_OK != result))
        return false;
    MCUX_CSSL_FP_FUNCTION_CALL_END();


    /* Load key to memory. */
    MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClKey_loadMemory(&session,
                                                                       (mcuxClKey_Handle_t) &key,
                                                                       key_buffer));

    if((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClKey_loadMemory) != token) || (MCUXCLKEY_STATUS_OK != result))
        return false;
    MCUX_CSSL_FP_FUNCTION_CALL_END();

    /**************************************************************************/
    /* The key could now be used for a cryptographic operation.               */
    /**************************************************************************/


    /**************************************************************************/
    /* Cleanup                                                                */
    /**************************************************************************/

    /* Flush the key. */
    MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(result, token, mcuxClKey_flush(&session,
                                                                 (mcuxClKey_Handle_t) &key));

    if((MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClKey_flush) != token) || (MCUXCLKEY_STATUS_OK != result))
        return false;
    MCUX_CSSL_FP_FUNCTION_CALL_END();


    MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(cleanup_result, cleanup_token, mcuxClSession_cleanup(
                /* mcuxClSession_Handle_t           pSession: */           &session));

    if(MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClSession_cleanup) != cleanup_token || MCUXCLSESSION_STATUS_OK != cleanup_result)
    {
        return false;
    }

    MCUX_CSSL_FP_FUNCTION_CALL_END();

    MCUX_CSSL_FP_FUNCTION_CALL_BEGIN(destroy_result, destroy_token, mcuxClSession_destroy(
                /* mcuxClSession_Handle_t           pSession: */           &session));

    if(MCUX_CSSL_FP_FUNCTION_CALLED(mcuxClSession_destroy) != destroy_token || MCUXCLSESSION_STATUS_OK != destroy_result)
    {
        return false;
    }

    MCUX_CSSL_FP_FUNCTION_CALL_END();

    return true;
}
