/**
*   @file    Crypto_ASRExtension.c
*   @version 1.0.0
*
*   @brief   AUTOSAR Crypto - Autosar Extension Functions.
*   @details Autosar extension functions used for accessing CSE services.
*
*   @addtogroup Crypto
*   @{
*/
/*==================================================================================================
*   Project              : AUTOSAR 4.3 MCAL
*   Platform             : PA
*   Peripheral           : Crypto
*   Dependencies         : none
*
*   Autosar Version      : 4.3.1
*   Autosar Revision     : ASR_REL_4_3_REV_0001
*   Autosar Conf.Variant :
*   SW Version           : 1.0.0
*   Build Version        : MPC5777C_MCAL_1_0_0_RTM_ASR_REL_4_3_REV_0001_20190315
*
*   (c) Copyright 2006-2016 Freescale Semiconductor, Inc. 
*       Copyright 2017-2019 NXP
*   All Rights Reserved.
==================================================================================================*/
/*==================================================================================================
==================================================================================================*/

#ifdef __cplusplus
extern "C"{
#endif

/**
* @page misra_violations MISRA-C:2012 violations
*
* @section Crypto_ASRExtension_h_REF_1
* Violates MISRA 2012 Advisory Rule 8.7, Functions and objects should not be defined with external linkage if
* they are referenced in only one translation unit.
* These functions represent the API of the driver. External linkage is needed to "export" the API.
*
* @section [global]
*          Violates MISRA 2012 Required Rule 5.1, External identifiers shall be distinct.
*          The used compilers use more than 31 chars for identifiers.
*
* @section [global]
*          Violates MISRA 2012 Required Rule 5.2, Identifiers declared in the same scope and name space shall be distinct.
*          The used compilers use more than 31 chars for identifiers.
*
* @section [global]
*          Violates MISRA 2012 Required Rule 5.4, Macro identifiers shall be distinct.
*          The used compilers use more than 31 chars for identifiers.
*
* @section [global]
*          Violates MISRA 2012 Required Rule 5.5, Identifiers shall be distinct from macro names.
*          The used compilers use more than 31 chars for identifiers.
*/
/*==================================================================================================
*                                        INCLUDE FILES
* 1) system and project includes
* 2) needed interfaces from external units
* 3) internal and external interfaces from this unit
==================================================================================================*/
#include "Crypto_ASRExtension.h"
#include "Crypto.h"
#include "Crypto_Ipw.h"
#include "Det.h"

/*==================================================================================================
*                              SOURCE FILE VERSION INFORMATION
==================================================================================================*/
#define CRYPTO_ASREXTENSION_VENDOR_ID_C                       43
#define CRYPTO_ASREXTENSION_AR_RELEASE_MAJOR_VERSION_C        4
#define CRYPTO_ASREXTENSION_AR_RELEASE_MINOR_VERSION_C        3
#define CRYPTO_ASREXTENSION_AR_RELEASE_REVISION_VERSION_C     1
#define CRYPTO_ASREXTENSION_SW_MAJOR_VERSION_C                1
#define CRYPTO_ASREXTENSION_SW_MINOR_VERSION_C                0
#define CRYPTO_ASREXTENSION_SW_PATCH_VERSION_C                0

/*==================================================================================================
*                                     FILE VERSION CHECKS
==================================================================================================*/
/* Check if Crypto_ASRExtension source file and Crypto ASRExtensions header file are of the same vendor */
#if (CRYPTO_ASREXTENSION_VENDOR_ID_C != CRYPTO_ASREXTENSION_VENDOR_ID)
    #error "Crypto_ASRExtension.c and Crypto_ASRExtension.h have different vendor ids"
#endif

/* Check if Crypto_ASRExtension source file and Crypto ASRExtensions header file are of the same Autosar version */
#if ((CRYPTO_ASREXTENSION_AR_RELEASE_MAJOR_VERSION_C    != CRYPTO_ASREXTENSION_AR_RELEASE_MAJOR_VERSION) || \
     (CRYPTO_ASREXTENSION_AR_RELEASE_MINOR_VERSION_C    != CRYPTO_ASREXTENSION_AR_RELEASE_MINOR_VERSION) || \
     (CRYPTO_ASREXTENSION_AR_RELEASE_REVISION_VERSION_C != CRYPTO_ASREXTENSION_AR_RELEASE_REVISION_VERSION) \
    )
    #error "AutoSar Version Numbers of Crypto_ASRExtension.c and Crypto_ASRExtension.h are different"
#endif

/* Check if Crypto_ASRExtension source file and Crypto ASRExtensions header file are of the same Software version */
#if ((CRYPTO_ASREXTENSION_SW_MAJOR_VERSION_C != CRYPTO_ASREXTENSION_SW_MAJOR_VERSION) || \
     (CRYPTO_ASREXTENSION_SW_MINOR_VERSION_C != CRYPTO_ASREXTENSION_SW_MINOR_VERSION) || \
     (CRYPTO_ASREXTENSION_SW_PATCH_VERSION_C != CRYPTO_ASREXTENSION_SW_PATCH_VERSION)    \
    )
    #error "Software Version Numbers of Crypto_ASRExtension.c and Crypto_ASRExtension.h are different"
#endif

/* Check if Crypto_ASRExtension source file and Crypto header file are of the same vendor */
#if (CRYPTO_ASREXTENSION_VENDOR_ID_C != CRYPTO_VENDOR_ID)
    #error "Crypto_ASRExtension.c and Crypto.h have different vendor ids"
#endif

/* Check if Crypto_ASRExtension source file and Crypto header file are of the same Autosar version */
#if ((CRYPTO_ASREXTENSION_AR_RELEASE_MAJOR_VERSION_C    != CRYPTO_AR_RELEASE_MAJOR_VERSION) || \
     (CRYPTO_ASREXTENSION_AR_RELEASE_MINOR_VERSION_C    != CRYPTO_AR_RELEASE_MINOR_VERSION) || \
     (CRYPTO_ASREXTENSION_AR_RELEASE_REVISION_VERSION_C != CRYPTO_AR_RELEASE_REVISION_VERSION) \
    )
    #error "AutoSar Version Numbers of Crypto_ASRExtension.c and Crypto.h are different"
#endif

/* Check if Crypto_ASRExtension source file and Crypto header file are of the same Software version */
#if ((CRYPTO_ASREXTENSION_SW_MAJOR_VERSION_C != CRYPTO_SW_MAJOR_VERSION) || \
     (CRYPTO_ASREXTENSION_SW_MINOR_VERSION_C != CRYPTO_SW_MINOR_VERSION) || \
     (CRYPTO_ASREXTENSION_SW_PATCH_VERSION_C != CRYPTO_SW_PATCH_VERSION)    \
    )
    #error "Software Version Numbers of Crypto_ASRExtension.c and Crypto.h are different"
#endif

/* Check if Crypto_ASRExtension source file and Crypto Ipw header file are of the same vendor */
#if (CRYPTO_ASREXTENSION_VENDOR_ID_C != CRYPTO_VENDOR_ID_IPW_H)
    #error "Crypto_ASRExtension.c and Crypto_Ipw.h have different vendor ids"
#endif

/* Check if Crypto_ASRExtension source file and Crypto Ipw header file are of the same Autosar version */
#if ((CRYPTO_ASREXTENSION_AR_RELEASE_MAJOR_VERSION_C    != CRYPTO_AR_RELEASE_MAJOR_VERSION_IPW_H) || \
     (CRYPTO_ASREXTENSION_AR_RELEASE_MINOR_VERSION_C    != CRYPTO_AR_RELEASE_MINOR_VERSION_IPW_H) || \
     (CRYPTO_ASREXTENSION_AR_RELEASE_REVISION_VERSION_C != CRYPTO_AR_RELEASE_REVISION_VERSION_IPW_H) \
    )
    #error "AutoSar Version Numbers of Crypto_ASRExtension.c and Crypto_Ipw.h are different"
#endif

/* Check if Crypto_ASRExtension source file and Crypto Ipw header file are of the same Software version */
#if ((CRYPTO_ASREXTENSION_SW_MAJOR_VERSION_C != CRYPTO_SW_MAJOR_VERSION_IPW_H) || \
     (CRYPTO_ASREXTENSION_SW_MINOR_VERSION_C != CRYPTO_SW_MINOR_VERSION_IPW_H) || \
     (CRYPTO_ASREXTENSION_SW_PATCH_VERSION_C != CRYPTO_SW_PATCH_VERSION_IPW_H)    \
    )
    #error "Software Version Numbers of Crypto_ASRExtension.c and Crypto_Ipw.h are different"
#endif

#ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK
    /* Check if Crypto_ASRExtension.c file and Det header file are of the same AutoSar version */
    #if ((CRYPTO_ASREXTENSION_AR_RELEASE_MAJOR_VERSION_C != DET_AR_RELEASE_MAJOR_VERSION) || \
         (CRYPTO_ASREXTENSION_AR_RELEASE_MINOR_VERSION_C != DET_AR_RELEASE_MINOR_VERSION)    \
        )
        #error "AutoSar Version Numbers of Crypto_ASRExtension.c and Det.h are different"
    #endif 
#endif

/*==================================================================================================
*                          LOCAL TYPEDEFS (STRUCTURES, UNIONS, ENUMS)
==================================================================================================*/

/*==================================================================================================
*                                       LOCAL MACROS
==================================================================================================*/
#define    CRYPTO_EXTS_MP_COMP_RESULT_LEN_U32    ((uint32)0x10)
/*==================================================================================================
*                                      LOCAL CONSTANTS
==================================================================================================*/

/*==================================================================================================
*                                      LOCAL VARIABLES
==================================================================================================*/

/*==================================================================================================
*                                      GLOBAL CONSTANTS
==================================================================================================*/

/*==================================================================================================
*                                      GLOBAL VARIABLES
==================================================================================================*/
#define CRYPTO_START_SEC_VAR_INIT_UNSPECIFIED
#include "Crypto_MemMap.h"

extern VAR(Crypto_DriverStateType, CRYPTO_VAR) Crypto_eDriverState;

#define CRYPTO_STOP_SEC_VAR_INIT_UNSPECIFIED
#include "Crypto_MemMap.h"

/*==================================================================================================
*                                   LOCAL FUNCTION PROTOTYPES
==================================================================================================*/

/*==================================================================================================
*                                       LOCAL FUNCTIONS
==================================================================================================*/

/*==================================================================================================
*                                       GLOBAL FUNCTIONS
==================================================================================================*/
/**
* @brief          Initializes the seed value of the PRNG.
* @details        Uses the TRNG to generate a 128-bit seed value for the PRNG.
*
* @param[in]      None
*
* @return         Result of the operation.
* @retval         E_OK                        Request successful.
* @retval         E_NOT_OK                    Request failed.
* @retval         CRYPTO_E_BUSY               Request failed, Crypro Driver Object is Busy.
* @retval         CRYPTO_E_KEY_NOT_VALID      Request failed, the key is not valid.
* @retval         CRYPTO_E_KEY_WRITE_FAIL     Request failed, read access was denied.
* @retval         CRYPTO_E_KEY_NOT_AVAILABLE  Request failed, key is locked due to failed boot measurement or an active debugger.
* @retval         CRYPTO_E_OPERATION_TIMEOUT  Request failed, CSE still busy and counter timeout occurred.
* @retval         CRYPTO_E_PARAM_POINTER      Request failed, output pointer is null.
* @retval         CRYPTO_E_NOT_SUPPORTED      Request failed, the underlying hardware does not support the service requested.
*
* @api
*
* @pre            Driver must be initialized.
*
*/
FUNC(Std_ReturnType, CRYPTO_CODE) Crypto_Exts_InitializeRng(void)
{
    VAR(Std_ReturnType, AUTOMATIC) RetVal = (Std_ReturnType)E_NOT_OK;

#if (STD_ON == CRYPTO_DEV_ERROR_DETECT)
    /* If the module is not yet initialized and if development error detection for the Crypto Driver is enabled, the function shall report CRYPTO_E_UNINIT to the DET and return E_NOT_OK. */
    if (CRYPTO_DRIVER_UNINIT == Crypto_eDriverState)
    {
        (void)Det_ReportError((uint16)CRYPTO_MODULE_ID, (uint8)CRYPTO_INSTANCE_ID, (uint8)CRYPTO_EXTS_INITIALIZERNG_ID, (uint8)CRYPTO_E_UNINIT);
    }
    else
#endif /* (STD_ON == CRYPTO_DEV_ERROR_DETECT) */
    {
        RetVal = Crypto_Ipw_ExtsInitializeRng();
    }

    return RetVal;
}

/**
* @brief          Extends the seed of the PRNG by compressing the former seed value and the supplied entropy into a new seed.
* @details        This function extends the seed of the PRNG by compressing the former seed value and the supplied entropy
*                 into a new seed which will be used to generate the following random numbers.
*
* @param[in]      pEntropy        Pointer to a 128-bit buffer containing the entropy
*
* @return         Result of the operation.
* @retval         E_OK                        Request successful.
* @retval         E_NOT_OK                    Request failed.
* @retval         CRYPTO_E_BUSY               Request failed, Crypro Driver Object is Busy.
* @retval         CRYPTO_E_KEY_NOT_VALID      Request failed, the key is not valid.
* @retval         CRYPTO_E_KEY_WRITE_FAIL     Request failed, read access was denied.
* @retval         CRYPTO_E_KEY_NOT_AVAILABLE  Request failed, key is locked due to failed boot measurement or an active debugger.
* @retval         CRYPTO_E_OPERATION_TIMEOUT  Request failed, CSE still busy and counter timeout occurred.
* @retval         CRYPTO_E_PARAM_POINTER      Request failed, output pointer is null.
* @retval         CRYPTO_E_NOT_SUPPORTED      Request failed, the underlying hardware does not support the service requested.
*
* @api
*
* @pre            Driver must be initialized.
*
*/
FUNC(Std_ReturnType, CRYPTO_CODE) Crypto_Exts_ExtendPrngSeed
(
    P2CONST(uint8, AUTOMATIC, CRYPTO_APPL_CONST) pEntropy
)
{
    VAR(Std_ReturnType, AUTOMATIC) RetVal = (Std_ReturnType)E_NOT_OK;
    
#if (STD_ON == CRYPTO_DEV_ERROR_DETECT)
    /* If the module is not yet initialized and if development error detection for the Crypto Driver is enabled, the function shall report CRYPTO_E_UNINIT to the DET and return E_NOT_OK. */
    if (CRYPTO_DRIVER_UNINIT == Crypto_eDriverState)
    {
        (void)Det_ReportError((uint16)CRYPTO_MODULE_ID, (uint8)CRYPTO_INSTANCE_ID, (uint8)CRYPTO_EXTS_EXTENDPRNGSEED_ID, (uint8)CRYPTO_E_UNINIT);
    }
    else
#endif /* (STD_ON == CRYPTO_DEV_ERROR_DETECT) */
    {
        RetVal = Crypto_Ipw_ExtsExtendPrngSeed(pEntropy);
    }
    
    return RetVal;
}

/**
* @brief          Sets the Secure Boot Finished flag and clears the Secure Boot OK flag.
* @details        Sets the Secure Boot Finished flag and clears the Secure Boot OK flag to disable use of memory slots that have the BOOT_PROT flag set.
*
* @param[in]      None
*
* @return         Result of the operation.
* @retval         E_OK                        Request successful.
* @retval         E_NOT_OK                    Request failed.
* @retval         CRYPTO_E_BUSY               Request failed, Crypro Driver Object is Busy.
* @retval         CRYPTO_E_KEY_NOT_VALID      Request failed, the key is not valid.
* @retval         CRYPTO_E_KEY_WRITE_FAIL     Request failed, read access was denied.
* @retval         CRYPTO_E_KEY_NOT_AVAILABLE  Request failed, key is locked due to failed boot measurement or an active debugger.
* @retval         CRYPTO_E_OPERATION_TIMEOUT  Request failed, CSE still busy and counter timeout occurred.
* @retval         CRYPTO_E_PARAM_POINTER      Request failed, output pointer is null.
* @retval         CRYPTO_E_NOT_SUPPORTED      Request failed, the underlying hardware does not support the service requested.
*
* @api
*
* @pre
*
*/
FUNC(Std_ReturnType, CRYPTO_CODE) Crypto_Exts_BootFailure(void)
{
    VAR(Std_ReturnType, AUTOMATIC) RetVal = (Std_ReturnType)E_NOT_OK;
    
#if (STD_ON == CRYPTO_DEV_ERROR_DETECT)
    /* If the module is not yet initialized and if development error detection for the Crypto Driver is enabled, the function shall report CRYPTO_E_UNINIT to the DET and return E_NOT_OK. */
    if (CRYPTO_DRIVER_UNINIT == Crypto_eDriverState)
    {
        (void)Det_ReportError((uint16)CRYPTO_MODULE_ID, (uint8)CRYPTO_INSTANCE_ID, (uint8)CRYPTO_EXTS_BOOTFAILURE_ID, (uint8)CRYPTO_E_UNINIT);
    }
    else
#endif /* (STD_ON == CRYPTO_DEV_ERROR_DETECT) */
    {
    
        RetVal = Crypto_Ipw_ExtsBootFailure();
    }
    
    return RetVal;
}

/**
* @brief          Sets the Secure Boot Finished flag and leaves the Secure Boot OK flag set.
* @details        Sets the Secure Boot Finished flag and leaves the Secure Boot OK flag set to confirm successful completion of the secure boot processes.
*                 This enables the use of memory slots that have the BOOT_PROT flag set.
*
* @param[in]      None
*
* @return         Result of the operation.
* @retval         E_OK                        Request successful.
* @retval         E_NOT_OK                    Request failed.
* @retval         CRYPTO_E_BUSY               Request failed, Crypro Driver Object is Busy.
* @retval         CRYPTO_E_KEY_NOT_VALID      Request failed, the key is not valid.
* @retval         CRYPTO_E_KEY_WRITE_FAIL     Request failed, read access was denied.
* @retval         CRYPTO_E_KEY_NOT_AVAILABLE  Request failed, key is locked due to failed boot measurement or an active debugger.
* @retval         CRYPTO_E_OPERATION_TIMEOUT  Request failed, CSE still busy and counter timeout occurred.
* @retval         CRYPTO_E_PARAM_POINTER      Request failed, output pointer is null.
* @retval         CRYPTO_E_NOT_SUPPORTED      Request failed, the underlying hardware does not support the service requested.
*
* @api
*
* @pre
*
*/
FUNC(Std_ReturnType, CRYPTO_CODE) Crypto_Exts_BootOk(void)
{
    VAR(Std_ReturnType, AUTOMATIC) RetVal = (Std_ReturnType)E_NOT_OK;
    
#if (STD_ON == CRYPTO_DEV_ERROR_DETECT)
    /* If the module is not yet initialized and if development error detection for the Crypto Driver is enabled, the function shall report CRYPTO_E_UNINIT to the DET and return E_NOT_OK. */
    if (CRYPTO_DRIVER_UNINIT == Crypto_eDriverState)
    {
        (void)Det_ReportError((uint16)CRYPTO_MODULE_ID, (uint8)CRYPTO_INSTANCE_ID, (uint8)CRYPTO_EXTS_BOOTOK_ID, (uint8)CRYPTO_E_UNINIT);
    }
    else
#endif /* (STD_ON == CRYPTO_DEV_ERROR_DETECT) */
    {
    
        RetVal = Crypto_Ipw_ExtsBootOk();
    }
    
    return RetVal;
}

/**
* @brief          Returns the UID, Status Register and MAC.
* @details        Returns the UID, CSE status register bits[24:31], and a 128-bit MAC calculated over the concatenation of a 128-bit input challenge value.
*
* @param[out]     pUidResultAddr  Pointer to a 128-bit buffer where UID will be stored
* @param[out]     pMacAddr        Pointer to a 128-bit buffer where MAC key will be stored
* @param[out]     pSregAddr       Pointer to a 8-bit buffer where status register will be stored
*
* @return         Result of the operation.
* @retval         E_OK                        Request successful.
* @retval         E_NOT_OK                    Request failed.
* @retval         CRYPTO_E_BUSY               Request failed, Crypro Driver Object is Busy.
* @retval         CRYPTO_E_KEY_NOT_VALID      Request failed, the key is not valid.
* @retval         CRYPTO_E_KEY_WRITE_FAIL     Request failed, read access was denied.
* @retval         CRYPTO_E_KEY_NOT_AVAILABLE  Request failed, key is locked due to failed boot measurement or an active debugger.
* @retval         CRYPTO_E_OPERATION_TIMEOUT  Request failed, CSE still busy and counter timeout occurred.
* @retval         CRYPTO_E_PARAM_POINTER      Request failed, output pointer is null.
* @retval         CRYPTO_E_NOT_SUPPORTED      Request failed, the underlying hardware does not support the service requested.
*
* @api
*
* @pre            Driver must be initialized.
*
*/
FUNC(Std_ReturnType, CRYPTO_CODE) Crypto_Exts_GetId
(
    P2VAR(uint8,  AUTOMATIC, CRYPTO_APPL_DATA) pUidResultAddr,
    P2VAR(uint8,  AUTOMATIC, CRYPTO_APPL_DATA) pMacAddr,
    P2VAR(uint8,  AUTOMATIC, CRYPTO_APPL_DATA) pSregAddr
)
{
    VAR(Std_ReturnType, AUTOMATIC) RetVal = (Std_ReturnType)E_NOT_OK;
    
#if (STD_ON == CRYPTO_DEV_ERROR_DETECT)
    /* If the module is not yet initialized and if development error detection for the Crypto Driver is enabled, the function shall report CRYPTO_E_UNINIT to the DET and return E_NOT_OK. */
    if (CRYPTO_DRIVER_UNINIT == Crypto_eDriverState)
    {
        (void)Det_ReportError((uint16)CRYPTO_MODULE_ID, (uint8)CRYPTO_INSTANCE_ID, (uint8)CRYPTO_EXTS_GETID_ID, (uint8)CRYPTO_E_UNINIT);
    }
    else
#endif /* (STD_ON == CRYPTO_DEV_ERROR_DETECT) */
    {
    
        RetVal = Crypto_Ipw_ExtsGetId(pUidResultAddr,pMacAddr,pSregAddr);
    }
    
    return RetVal;
}

/**
* @brief          Generates random challenge.
* @details        Generates a 128-bit random challenge output value that is used in conjunction with the DEBUG_AUTH command.
*
* @param[out]     pOutChallengeAdress  Pointer to the address where the output challenge will be stored
*
* @return         Result of the operation.
* @retval         E_OK                        Request successful.
* @retval         E_NOT_OK                    Request failed.
* @retval         CRYPTO_E_BUSY               Request failed, Crypro Driver Object is Busy.
* @retval         CRYPTO_E_KEY_NOT_VALID      Request failed, the key is not valid.
* @retval         CRYPTO_E_KEY_WRITE_FAIL     Request failed, read access was denied.
* @retval         CRYPTO_E_KEY_NOT_AVAILABLE  Request failed, key is locked due to failed boot measurement or an active debugger.
* @retval         CRYPTO_E_OPERATION_TIMEOUT  Request failed, CSE still busy and counter timeout occurred.
* @retval         CRYPTO_E_PARAM_POINTER      Request failed, output pointer is null.
* @retval         CRYPTO_E_NOT_SUPPORTED      Request failed, the underlying hardware does not support the service requested.
*
* @api
*
* @pre            Driver must be initialized.
*
*/
FUNC(Std_ReturnType, CRYPTO_CODE) Crypto_Exts_DebugChal
(
    P2VAR(uint8, AUTOMATIC, CRYPTO_APPL_DATA)pOutChallengeAdress
)
{
    VAR(Std_ReturnType, AUTOMATIC) RetVal = (Std_ReturnType)E_NOT_OK;
    
#if (STD_ON == CRYPTO_DEV_ERROR_DETECT)
    /* If the module is not yet initialized and if development error detection for the Crypto Driver is enabled, the function shall report CRYPTO_E_UNINIT to the DET and return E_NOT_OK. */
    if (CRYPTO_DRIVER_UNINIT == Crypto_eDriverState)
    {
        (void)Det_ReportError((uint16)CRYPTO_MODULE_ID, (uint8)CRYPTO_INSTANCE_ID, (uint8)CRYPTO_EXTS_DEBUGCHAL_ID, (uint8)CRYPTO_E_UNINIT);
    }
    else
#endif /* (STD_ON == CRYPTO_DEV_ERROR_DETECT) */
    {
    
        RetVal = Crypto_Ipw_ExtsDebugChal(pOutChallengeAdress);
    }
    
    return RetVal;
}

/**
* @brief          Erases all user keys and enables internal debugging.
* @details        Erases all user keys and sets the Internal Debug flag which enables internal debugging if the 128-bit authorization input value
*                 is valid and no memory slots are write protected.
*
* @param[in]      pAuthorization  Pointer to the address where output challenge was generated with Debug Challenge
*
* @return         Result of the operation.
* @retval         E_OK                        Request successful.
* @retval         E_NOT_OK                    Request failed.
* @retval         CRYPTO_E_BUSY               Request failed, Crypro Driver Object is Busy.
* @retval         CRYPTO_E_KEY_NOT_VALID      Request failed, the key is not valid.
* @retval         CRYPTO_E_KEY_WRITE_FAIL     Request failed, read access was denied.
* @retval         CRYPTO_E_KEY_NOT_AVAILABLE  Request failed, key is locked due to failed boot measurement or an active debugger.
* @retval         CRYPTO_E_OPERATION_TIMEOUT  Request failed, CSE still busy and counter timeout occurred.
* @retval         CRYPTO_E_PARAM_POINTER      Request failed, output pointer is null.
* @retval         CRYPTO_E_NOT_SUPPORTED      Request failed, the underlying hardware does not support the service requested.
*
* @api
*
* @pre            Driver must be initialized.
*
*/
FUNC(Std_ReturnType, CRYPTO_CODE) Crypto_Exts_DebugAuth
(
    P2VAR(uint8, AUTOMATIC, CRYPTO_APPL_DATA)pAuthorization
)
{
    VAR(Std_ReturnType, AUTOMATIC) RetVal = (Std_ReturnType)E_NOT_OK;
    
#if (STD_ON == CRYPTO_DEV_ERROR_DETECT)
    /* If the module is not yet initialized and if development error detection for the Crypto Driver is enabled, the function shall report CRYPTO_E_UNINIT to the DET and return E_NOT_OK. */
    if (CRYPTO_DRIVER_UNINIT == Crypto_eDriverState)
    {
        (void)Det_ReportError((uint16)CRYPTO_MODULE_ID, (uint8)CRYPTO_INSTANCE_ID, (uint8)CRYPTO_EXTS_DEBUGAUTH_ID, (uint8)CRYPTO_E_UNINIT);
    }
    else
#endif /* (STD_ON == CRYPTO_DEV_ERROR_DETECT) */
    {
    
        RetVal = Crypto_Ipw_ExtsDebugAuth(pAuthorization);
    }
    
    return RetVal;
}

/**
* @brief          Generates Random Challenge.
* @details        Outputs a 288-bit value consisting of a 128-bit random challenge value concatenated with the 120-bit UID, 4-bit Certificate ID,
*                 4-bit Challenge Mode, and 32 bits of zero padding.
*
* @param[out]     pOutChallengeAdress  Pointer to start address where the output challenge will be stored
* @param[in]      u8CertificateId      Public key specified
* @param[in]      u8ChallengeMode      0 - No keys are erased
*                                      1 - Erase all symmetric keys, excluding BOOT_MAC_KEY and BOOT_MAC
*                                      2 - Erase all installed public key certificates, including ROOT_PK and CRL
*                                      3 - Erase all installed public key certificates, including ROOT_PK and CRL
*
* @return         Result of the operation.
* @retval         E_OK                        Request successful.
* @retval         E_NOT_OK                    Request failed.
* @retval         CRYPTO_E_BUSY               Request failed, Crypro Driver Object is Busy.
* @retval         CRYPTO_E_KEY_NOT_VALID      Request failed, the key is not valid.
* @retval         CRYPTO_E_KEY_WRITE_FAIL     Request failed, read access was denied.
* @retval         CRYPTO_E_KEY_NOT_AVAILABLE  Request failed, key is locked due to failed boot measurement or an active debugger.
* @retval         CRYPTO_E_OPERATION_TIMEOUT  Request failed, CSE still busy and counter timeout occurred.
* @retval         CRYPTO_E_PARAM_POINTER      Request failed, output pointer is null.
* @retval         CRYPTO_E_NOT_SUPPORTED      Request failed, the underlying hardware does not support the service requested.
*
* @api
*
* @pre            Driver must be initialized.
*
*/
FUNC(Std_ReturnType, CRYPTO_CODE) Crypto_Exts_SecureSesssionChal
(
    P2VAR(uint8,    AUTOMATIC, CRYPTO_APPL_DATA)pOutChallengeAdress,
    VAR  (uint8,    AUTOMATIC                  )u8CertificateId,
    VAR  (uint8,    AUTOMATIC                  )u8ChallengeMode
)
{
    VAR(Std_ReturnType, AUTOMATIC) RetVal = (Std_ReturnType)E_NOT_OK;
    
#if (STD_ON == CRYPTO_DEV_ERROR_DETECT)
    /* If the module is not yet initialized and if development error detection for the Crypto Driver is enabled, the function shall report CRYPTO_E_UNINIT to the DET and return E_NOT_OK. */
    if (CRYPTO_DRIVER_UNINIT == Crypto_eDriverState)
    {
        (void)Det_ReportError((uint16)CRYPTO_MODULE_ID, (uint8)CRYPTO_INSTANCE_ID, (uint8)CRYPTO_EXTS_SECURESESSIONCHAL_ID, (uint8)CRYPTO_E_UNINIT);
    }
    else
#endif /* (STD_ON == CRYPTO_DEV_ERROR_DETECT) */
    {
        RetVal = Crypto_Ipw_ExtsSecureSesssionChal(pOutChallengeAdress,u8CertificateId,u8ChallengeMode);
    }
    
    return RetVal;
}

/**
* @brief          Verifies the RSA signature of the challenge.
* @details        Verifies the RSA signature of the 288-bit challenge output using the public key.
*
* @param[in]      pAuthorization  Pointer to signature.
*
* @return         Result of the operation.
* @retval         E_OK                        Request successful.
* @retval         E_NOT_OK                    Request failed.
* @retval         CRYPTO_E_BUSY               Request failed, Crypro Driver Object is Busy.
* @retval         CRYPTO_E_KEY_NOT_VALID      Request failed, the key is not valid.
* @retval         CRYPTO_E_KEY_WRITE_FAIL     Request failed, read access was denied.
* @retval         CRYPTO_E_KEY_NOT_AVAILABLE  Request failed, key is locked due to failed boot measurement or an active debugger.
* @retval         CRYPTO_E_OPERATION_TIMEOUT  Request failed, CSE still busy and counter timeout occurred.
* @retval         CRYPTO_E_PARAM_POINTER      Request failed, output pointer is null.
* @retval         CRYPTO_E_NOT_SUPPORTED      Request failed, the underlying hardware does not support the service requested.
*
* @api
*
* @pre            Driver must be initialized.
*
*/
FUNC(Std_ReturnType, CRYPTO_CODE) Crypto_Exts_SecureSesssionAuth
(
    P2VAR(uint8, AUTOMATIC, CRYPTO_APPL_DATA)pAuthorization
)
{
    VAR(Std_ReturnType, AUTOMATIC) RetVal = (Std_ReturnType)E_NOT_OK;
    
#if (STD_ON == CRYPTO_DEV_ERROR_DETECT)
    /* If the module is not yet initialized and if development error detection for the Crypto Driver is enabled, the function shall report CRYPTO_E_UNINIT to the DET and return E_NOT_OK. */
    if (CRYPTO_DRIVER_UNINIT == Crypto_eDriverState)
    {
        (void)Det_ReportError((uint16)CRYPTO_MODULE_ID, (uint8)CRYPTO_INSTANCE_ID, (uint8)CRYPTO_EXTS_SECURESESSIONAUTH_ID, (uint8)CRYPTO_E_UNINIT);
    }
    else
#endif /* (STD_ON == CRYPTO_DEV_ERROR_DETECT) */
    {
    
        RetVal = Crypto_Ipw_ExtsSecureSesssionAuth(pAuthorization);
    }
    
    return RetVal;
}

/**
* @brief          Generates a vector of 128 ture random bits.
* @details        The function returns a vector of 128 ture random bits.
*
* @param[out]     pTrueRandomValue: The address where the random value will be stored.
*
* @return         Result of the operation.
* @retval         E_OK                        Request successful.
* @retval         E_NOT_OK                    Request failed.
* @retval         CRYPTO_E_BUSY               Request failed, Crypro Driver Object is Busy.
* @retval         CRYPTO_E_KEY_NOT_VALID      Request failed, the key is not valid.
* @retval         CRYPTO_E_KEY_WRITE_FAIL     Request failed, read access was denied.
* @retval         CRYPTO_E_KEY_NOT_AVAILABLE  Request failed, key is locked due to failed boot measurement or an active debugger.
* @retval         CRYPTO_E_OPERATION_TIMEOUT  Request failed, CSE still busy and counter timeout occurred.
* @retval         CRYPTO_E_PARAM_POINTER      Request failed, output pointer is null.
* @retval         CRYPTO_E_NOT_SUPPORTED      Request failed, the underlying hardware does not support the service requested.
*
* @api
*
* @pre            Driver must be initialized.
*
*/
FUNC(Std_ReturnType, CRYPTO_CODE) Crypto_Exts_GenerateTrueRndNum
(
    P2VAR(uint8, AUTOMATIC, CRYPTO_APPL_DATA) pTrueRandomValue
)
{
    VAR(Std_ReturnType, AUTOMATIC) RetVal = (Std_ReturnType)E_NOT_OK;
    
#if (STD_ON == CRYPTO_DEV_ERROR_DETECT)
    /* If the module is not yet initialized and if development error detection for the Crypto Driver is enabled, the function shall report CRYPTO_E_UNINIT to the DET and return E_NOT_OK. */
    if (CRYPTO_DRIVER_UNINIT == Crypto_eDriverState)
    {
        (void)Det_ReportError((uint16)CRYPTO_MODULE_ID, (uint8)CRYPTO_INSTANCE_ID, (uint8)CRYPTO_EXTS_GENERATETRNGNUM_ID, (uint8)CRYPTO_E_UNINIT);
    }
    else
#endif /* (STD_ON == CRYPTO_DEV_ERROR_DETECT) */
    {
        RetVal = Crypto_Ipw_ExtsGenerateTrueRndNum(pTrueRandomValue);
    }
    
    return RetVal;
}

/**
* @brief          Miyaguchi-Preneel Compression.
* @details        One-way compression function used to derive a 128 bit output from a given message
*
* @param[in]      pInputKey        Message start address
* @param[in]      pInputKeyLen     Message length (bytes) address
* @param[out]     pResult          Output address
* @param[in]      pResultLen       Message length (bytes) for output buffer
*
* @return         Result of the operation.
* @retval         E_OK                        Request successful.
* @retval         E_NOT_OK                    Request failed.
* @retval         CRYPTO_E_BUSY               Request failed, Crypro Driver Object is Busy.
* @retval         CRYPTO_E_KEY_NOT_VALID      Request failed, the key is not valid.
* @retval         CRYPTO_E_KEY_WRITE_FAIL     Request failed, read access was denied.
* @retval         CRYPTO_E_KEY_NOT_AVAILABLE  Request failed, key is locked due to failed boot measurement or an active debugger.
* @retval         CRYPTO_E_OPERATION_TIMEOUT  Request failed, CSE still busy and counter timeout occurred.
* @retval         CRYPTO_E_PARAM_POINTER      Request failed, output pointer is null.
* @retval         CRYPTO_E_PARAM_HANDLE       Request failed, invalid parameter (out of range).
* @retval         CRYPTO_E_NOT_SUPPORTED      Request failed, the underlying hardware does not support the service requested.
*
* @api
*
* @pre            Driver must be initialized.
*
*/
FUNC(Std_ReturnType, CRYPTO_CODE) Crypto_Exts_MPCompression
(
    P2CONST(uint8,  AUTOMATIC, CRYPTO_APPL_CONST) pInputKey,
    P2VAR  (uint64, AUTOMATIC, CRYPTO_APPL_DATA ) pInputKeyLen,
    P2VAR  (uint8,  AUTOMATIC, CRYPTO_APPL_DATA ) pResult,
    P2VAR  (uint32, AUTOMATIC, CRYPTO_APPL_DATA ) pResultLen
)
{
    VAR(Std_ReturnType, AUTOMATIC) RetVal = (Std_ReturnType)E_NOT_OK;
    
#if (STD_ON == CRYPTO_DEV_ERROR_DETECT)
    /* If the module is not yet initialized and if development error detection for the Crypto Driver is enabled, the function shall report CRYPTO_E_UNINIT to the DET and return E_NOT_OK. */
    if (CRYPTO_DRIVER_UNINIT == Crypto_eDriverState)
    {
        (void)Det_ReportError((uint16)CRYPTO_MODULE_ID, (uint8)CRYPTO_INSTANCE_ID, (uint8)CRYPTO_EXTS_MPCOMPRESSION_ID, (uint8)CRYPTO_E_UNINIT);
    }
    else
#endif /* (STD_ON == CRYPTO_DEV_ERROR_DETECT) */
    {
        if(CRYPTO_EXTS_MP_COMP_RESULT_LEN_U32 <= *pResultLen)
        {
            RetVal = Crypto_Ipw_ExtsMPCompression(pInputKey,pInputKeyLen,pResult); /* Trigger synchronous command*/
        }
    }

    return RetVal;
}

/**
* @brief          Configure Secure Counter
* @details        Using the provided ID and Rollover Value CSE will associate a secure counter with the given id and set its Rollover Value.
*                 A status will be returned after the execution of the command to inform if a new counter is used or an existing one is reused.
*
* @param[in]      u32CounterId      The id of the secure counter
* @param[in]      u32RolloverValue  Defines the secure counter value at which point the RP is stored in flash memory
* @param[out]     pStatus           Informs if a new secure counter is used
*
* @return         Result of the operation.
* @retval         E_OK                        Request successful.
* @retval         E_NOT_OK                    Request failed.
* @retval         CRYPTO_E_BUSY               Request failed, Crypro Driver Object is Busy.
* @retval         CRYPTO_E_KEY_NOT_VALID      Request failed, the key is not valid.
* @retval         CRYPTO_E_KEY_WRITE_FAIL     Request failed, read access was denied.
* @retval         CRYPTO_E_KEY_NOT_AVAILABLE  Request failed, key is locked due to failed boot measurement or an active debugger.
* @retval         CRYPTO_E_OPERATION_TIMEOUT  Request failed, CSE still busy and counter timeout occurred.
* @retval         CRYPTO_E_PARAM_POINTER      Request failed, output pointer is null.
* @retval         CRYPTO_E_NOT_SUPPORTED      Request failed, the underlying hardware does not support the service requested.
*
* @api
*
* @pre            Driver must be initialized.
*
*/
FUNC(Std_ReturnType, CRYPTO_CODE) Crypto_Exts_CfgSecCounter
(
    VAR(uint32,   AUTOMATIC                  ) u32CounterId,
    VAR(uint32,   AUTOMATIC                  ) u32RolloverValue,
    P2VAR(uint32, AUTOMATIC, CRYPTO_APPL_DATA) pStatus
)
{
    VAR(Std_ReturnType, AUTOMATIC) RetVal = (Std_ReturnType)E_NOT_OK;
    
#if (STD_ON == CRYPTO_DEV_ERROR_DETECT)
    /* If the module is not yet initialized and if development error detection for the Crypto Driver is enabled, the function shall report CRYPTO_E_UNINIT to the DET and return E_NOT_OK. */
    if (CRYPTO_DRIVER_UNINIT == Crypto_eDriverState)
    {
        (void)Det_ReportError((uint16)CRYPTO_MODULE_ID, (uint8)CRYPTO_INSTANCE_ID, (uint8)CRYPTO_EXTS_CFGSECURECNT_ID, (uint8)CRYPTO_E_UNINIT);
    }
    /* If pointer to status is null pointer and if development error detection for the Crypto Driver is enabled, the function shall report CRYPTO_E_PARAM_POINTER to the DET and return E_NOT_OK.*/
    else if (NULL_PTR == pStatus)
    {
        (void)Det_ReportError((uint16)CRYPTO_MODULE_ID, (uint8)CRYPTO_INSTANCE_ID, (uint8)CRYPTO_EXTS_CFGSECURECNT_ID, (uint8)CRYPTO_E_PARAM_POINTER);
    }
    else
#endif /* (STD_ON == CRYPTO_DEV_ERROR_DETECT) */
    {
        RetVal = Crypto_Ipw_ExtsCfgSecCounter(u32CounterId, u32RolloverValue, pStatus);
    }

    return RetVal;
}

/**
* @brief          Backup Restore Cleanup Status 
* @details        The BRCS provides 4 separate functions based on the mode input value.
*
* @param[in]      eBrcsMode           Mode
* @param[inout]   pImageAddress       Backup image address
* @param[out]     pKeySlotStatus      Slot usage status
* @param[out]     pCounterSlotStatus  Status of counter slots
*
* @return         Result of the operation.
* @retval         E_OK                        Request successful.
* @retval         E_NOT_OK                    Request failed.
* @retval         CRYPTO_E_BUSY               Request failed, Crypro Driver Object is Busy.
* @retval         CRYPTO_E_KEY_NOT_VALID      Request failed, the key is not valid.
* @retval         CRYPTO_E_KEY_WRITE_FAIL     Request failed, read access was denied.
* @retval         CRYPTO_E_KEY_NOT_AVAILABLE  Request failed, key is locked due to failed boot measurement or an active debugger.
* @retval         CRYPTO_E_OPERATION_TIMEOUT  Request failed, CSE still busy and counter timeout occurred.
* @retval         CRYPTO_E_PARAM_POINTER      Request failed, output pointer is null.
* @retval         CRYPTO_E_NOT_SUPPORTED      Request failed, the underlying hardware does not support the service requested.
*
* @api
*
* @pre            Driver must be initialized.
*
*/
FUNC (Std_ReturnType, CRYPTO_CODE) Crypto_Exts_BRCS
(
    VAR  (Crypto_BrcsModeType, AUTOMATIC              )eBrcsMode,
    P2VAR(uint32,           AUTOMATIC,CRYPTO_APPL_DATA)pImageAddress,
    P2VAR(uint32,           AUTOMATIC,CRYPTO_APPL_DATA)pKeySlotStatus,
    P2VAR(uint32,           AUTOMATIC,CRYPTO_APPL_DATA)pCounterSlotStatus
)
{
    VAR(Std_ReturnType, AUTOMATIC) RetVal = (Std_ReturnType)E_NOT_OK;

#if (STD_ON == CRYPTO_DEV_ERROR_DETECT)
    /* If the module is not yet initialized and if development error detection for the Crypto Driver is enabled, the function shall report CRYPTO_E_UNINIT to the DET and return E_NOT_OK. */
    if (CRYPTO_DRIVER_UNINIT == Crypto_eDriverState)
    {
        (void)Det_ReportError((uint16)CRYPTO_MODULE_ID, (uint8)CRYPTO_INSTANCE_ID, (uint8)CRYPTO_EXTS_BACKUPRESTORE_ID, (uint8)CRYPTO_E_UNINIT);
    }
    /* If the mode is not backup and if the pointer to image address is NULL pointer or pointer to slot or pointer to counter is null pointer  and if development error detection for the Crypto Driver is enabled, the function shall report CRYPTO_E_PARAM_POINTER to the DET and return E_NOT_OK.*/
    else if ( 
                (((Crypto_BrcsModeType)BACKUP != eBrcsMode) && (NULL_PTR == pImageAddress)) || \
                (NULL_PTR == pKeySlotStatus) || \
                (NULL_PTR == pCounterSlotStatus)
            )
    {
        (void)Det_ReportError((uint16)CRYPTO_MODULE_ID, (uint8)CRYPTO_INSTANCE_ID, (uint8)CRYPTO_EXTS_BACKUPRESTORE_ID, (uint8)CRYPTO_E_PARAM_POINTER);
    }
    else
#endif /* (STD_ON == CRYPTO_DEV_ERROR_DETECT) */
    {
        RetVal = Crypto_Ipw_Exts_BRCS(eBrcsMode,pImageAddress,pKeySlotStatus,pCounterSlotStatus);
    }

    return RetVal;
}

/**
* @brief          Delete plain text key.
* @details        Clears plaintext key from RAM
*
* @param[in]      u8KeyId         The input key ID
*
* @return         Result of the operation.
* @retval         E_OK                        Request successful.
* @retval         E_NOT_OK                    Request failed.
* @retval         CRYPTO_E_BUSY               Request failed, Crypro Driver Object is Busy.
* @retval         CRYPTO_E_KEY_NOT_VALID      Request failed, the key is not valid.
* @retval         CRYPTO_E_KEY_WRITE_FAIL     Request failed, read access was denied.
* @retval         CRYPTO_E_KEY_NOT_AVAILABLE  Request failed, key is locked due to failed boot measurement or an active debugger.
* @retval         CRYPTO_E_OPERATION_TIMEOUT  Request failed, CSE still busy and counter timeout occurred.
* @retval         CRYPTO_E_PARAM_POINTER      Request failed, output pointer is null.
* @retval         CRYPTO_E_NOT_SUPPORTED      Request failed, the underlying hardware does not support the service requested.
*
* @api
*
* @pre            Driver must be initialized.
*
*/
FUNC(Std_ReturnType, CRYPTO_CODE) Crypto_Exts_DeletePlainTextKey
(
    VAR (uint8,  AUTOMATIC) u8KeyId
)
{
    VAR(Std_ReturnType, AUTOMATIC) RetVal = (Std_ReturnType)E_NOT_OK;
    
#if (STD_ON == CRYPTO_DEV_ERROR_DETECT)
    /* If the module is not yet initialized and if development error detection for the Crypto Driver is enabled, the function shall report CRYPTO_E_UNINIT to the DET and return E_NOT_OK. */
    if (CRYPTO_DRIVER_UNINIT == Crypto_eDriverState)
    {
        (void)Det_ReportError((uint16)CRYPTO_MODULE_ID, (uint8)CRYPTO_INSTANCE_ID, (uint8)CRYPTO_EXTS_DELETEPLAINTEXTKEY_ID, (uint8)CRYPTO_E_UNINIT);
    }
    else
#endif /* (STD_ON == CRYPTO_DEV_ERROR_DETECT) */
    {
    
        RetVal = Crypto_Ipw_ExtsDeletePlainTextKey(u8KeyId);
    }
    
    return RetVal;
}

/**
* @brief          CMAC Generation with Secure Counter
* @details        Calculates the MAC of a given input message concatenated with the incremented value of the selected secure counter, using the parameters provided.
*
* @param[in]      u32KeyId          KeyID used to perform the cryptographic operation.
* @param[in]      u8CounterId       The secure counter ID that will be used.
* @param[in]      u32MessageLength  Number of bytes of message on which CMAC is to be computed.
* @param[in]      pMessage          Pointer to the message buffer.
* @param[out]     pMac              Pointer to the 128-bit buffer containing the result of the CMAC generation.
* @param[out]     u32MacLen         The output buffer length for MAC.
* @param[out]     pVolatileCounter  Pointer to the the current VC.
*
* @return         Result of the operation.
* @retval         E_OK                        Request successful.
* @retval         E_NOT_OK                    Request failed.
* @retval         CRYPTO_E_BUSY               Request failed, Crypro Driver Object is Busy.
* @retval         CRYPTO_E_KEY_NOT_VALID      Request failed, the key is not valid.
* @retval         CRYPTO_E_KEY_WRITE_FAIL     Request failed, read access was denied.
* @retval         CRYPTO_E_KEY_NOT_AVAILABLE  Request failed, key is locked due to failed boot measurement or an active debugger.
* @retval         CRYPTO_E_OPERATION_TIMEOUT  Request failed, CSE still busy and counter timeout occurred.
* @retval         CRYPTO_E_PARAM_POINTER      Request failed, output pointer is null.
* @retval         CRYPTO_E_NOT_SUPPORTED      Request failed, the underlying hardware does not support the service requested.
*
* @api
*
* @pre            Driver must be initialized.
*
*/
FUNC(Std_ReturnType, CRYPTO_CODE) Crypto_Exts_MacGenerateSecCounter
(
    VAR    (uint32,        AUTOMATIC                   ) u32KeyId,
    VAR    (uint8,         AUTOMATIC                   ) u8CounterId,
    VAR    (uint32,        AUTOMATIC                   ) u32MessageLength,
    P2CONST(uint8,         AUTOMATIC, CRYPTO_APPL_CONST) pMessage,
    P2VAR  (uint8,         AUTOMATIC, CRYPTO_APPL_DATA ) pMac,
    VAR    (uint32,        AUTOMATIC                   ) u32MacLen,
    P2VAR  (uint32,        AUTOMATIC, CRYPTO_APPL_DATA ) pVolatileCounter
)
{
    VAR(Std_ReturnType, AUTOMATIC) RetVal = (Std_ReturnType)E_NOT_OK;

#if (STD_ON == CRYPTO_DEV_ERROR_DETECT)
    /* If the module is not yet initialized and if development error detection for the Crypto Driver is enabled, the function shall report CRYPTO_E_UNINIT to the DET and return E_NOT_OK. */
    if (CRYPTO_DRIVER_UNINIT == Crypto_eDriverState)
    {
        (void)Det_ReportError((uint16)CRYPTO_MODULE_ID, (uint8)CRYPTO_INSTANCE_ID, (uint8)CRYPTO_EXTS_MACGENSECCOUNTER_ID, (uint8)CRYPTO_E_UNINIT);
    }
    /* If the output parameter pVolatileCounter is Null pointer and if development error detection for the Crypto Driver is enabled, the function shall report CRYPTO_E_PARAM_POINTER and return E_NOT_OK.*/
    else if (NULL_PTR == pVolatileCounter)
    {
        (void)Det_ReportError((uint16)CRYPTO_MODULE_ID, (uint8)CRYPTO_INSTANCE_ID, (uint8)CRYPTO_EXTS_MACGENSECCOUNTER_ID, (uint8)CRYPTO_E_PARAM_POINTER);
    }
    else
#endif /* (STD_ON == CRYPTO_DEV_ERROR_DETECT) */
    {
        RetVal = Crypto_Ipw_ExtsMacGenerateSecCounter(u32KeyId, u8CounterId, u32MessageLength, pMessage, pMac, u32MacLen, pVolatileCounter);
    }
    return RetVal;
}

/**
* @brief          Update firmware
* @details        Provides a secure method to update CSE firmware in the field.
*
* @param[in]      pFirmwareAddr        The firmware address input must point to the new encrypted firmware image.
* @param[in]      pSignatureAddr       Signature address.
* @param[in]      u8AuthCertifId       The public key certificate to use for signature verification of the firmware update image.
* @param[out]     pNewFirmVersion      New firmware version
* @param[out]     pCurrentFirmVersion  Old firmware version
*
* @return         Result of the operation.
* @retval         E_OK                        Request successful.
* @retval         E_NOT_OK                    Request failed.
* @retval         CRYPTO_E_BUSY               Request failed, Crypro Driver Object is Busy.
* @retval         CRYPTO_E_KEY_NOT_VALID      Request failed, the key is not valid.
* @retval         CRYPTO_E_KEY_WRITE_FAIL     Request failed, read access was denied.
* @retval         CRYPTO_E_KEY_NOT_AVAILABLE  Request failed, key is locked due to failed boot measurement or an active debugger.
* @retval         CRYPTO_E_OPERATION_TIMEOUT  Request failed, CSE still busy and counter timeout occurred.
* @retval         CRYPTO_E_PARAM_POINTER      Request failed, output pointer is null.
* @retval         CRYPTO_E_NOT_SUPPORTED      Request failed, the underlying hardware does not support the service requested.
*
* @api
*
* @pre            Driver must be initialized.
*
*/
FUNC (Std_ReturnType, CRYPTO_CODE) Crypto_Exts_UpdateFirmware
(
    P2VAR(uint32, AUTOMATIC, CRYPTO_APPL_DATA) pFirmwareAddr,
    P2VAR(uint32, AUTOMATIC, CRYPTO_APPL_DATA) pSignatureAddr,
    VAR  (uint8,  AUTOMATIC                  ) u8AuthCertifId,
    P2VAR(uint32, AUTOMATIC, CRYPTO_APPL_DATA) pNewFirmVersion,
    P2VAR(uint32, AUTOMATIC, CRYPTO_APPL_DATA) pCurrentFirmVersion
)
{
    VAR(Std_ReturnType, AUTOMATIC) RetVal = (Std_ReturnType)E_NOT_OK;

#if (STD_ON == CRYPTO_DEV_ERROR_DETECT)
    /* If the module is not yet initialized and if development error detection for the Crypto Driver is enabled, the function shall report CRYPTO_E_UNINIT to the DET and return E_NOT_OK. */
    if (CRYPTO_DRIVER_UNINIT == Crypto_eDriverState)
    {
        (void)Det_ReportError((uint16)CRYPTO_MODULE_ID, (uint8)CRYPTO_INSTANCE_ID, (uint8)CRYPTO_EXTS_UPDATEFIRMWARE_ID, (uint8)CRYPTO_E_UNINIT);
    }
    /* If the pointer to firmware version is null pointer or the pointer to current version is null pointer and if development error detection for the Crypto Driver is enabled, the function shall report CRYPTO_E_PARAM_POINTER to the DET and return E_NOT_OK.*/
    else if ((NULL_PTR == pNewFirmVersion) || (NULL_PTR == pCurrentFirmVersion))
    {
        (void)Det_ReportError((uint16)CRYPTO_MODULE_ID, (uint8)CRYPTO_INSTANCE_ID, (uint8)CRYPTO_EXTS_UPDATEFIRMWARE_ID, (uint8)CRYPTO_E_PARAM_POINTER);
    }
    else
#endif /* (STD_ON == CRYPTO_DEV_ERROR_DETECT) */
    {
        RetVal = Crypto_Ipw_ExtsUpdateFirmware(pFirmwareAddr,pSignatureAddr,u8AuthCertifId,pNewFirmVersion,pCurrentFirmVersion);
    }

    return RetVal;
}

/**
* @brief          CMAC Verification with Secure Counter.
* @details        Verifies the MAC of a given input message, concatenated with the implied value of the selected secure counter.
*
* @param[in]       u32KeyId             KeyID used to perform the cryptographic operation.
* @param[in]       u8CounterId          The secure counter ID that will be used.
* @param[in]       u8RlvPrtOffset       Rollover protection offset.
* @param[in]       u32MessageLength     Number of bytes of message on which CMAC is to be computed.
* @param[in]       pMessage             Pointer to the message buffer.
* @param[in]       pMac                 Pointer to the 128-bit buffer containing the the CMAC.
* @param[in]       u32MacLength         The length of the MAC.
* @param[in]       u32VolatileCounter   Implied value of the Volatile Counter.
* @param[out]      pVrfStatus           Verification status.
*
* @return         Result of the operation.
* @retval         E_OK                        Request successful.
* @retval         E_NOT_OK                    Request failed.
* @retval         CRYPTO_E_BUSY               Request failed, Crypro Driver Object is Busy.
* @retval         CRYPTO_E_KEY_NOT_VALID      Request failed, the key is not valid.
* @retval         CRYPTO_E_KEY_WRITE_FAIL     Request failed, read access was denied.
* @retval         CRYPTO_E_KEY_NOT_AVAILABLE  Request failed, key is locked due to failed boot measurement or an active debugger.
* @retval         CRYPTO_E_OPERATION_TIMEOUT  Request failed, CSE still busy and counter timeout occurred.
* @retval         CRYPTO_E_PARAM_POINTER      Request failed, output pointer is null.
* @retval         CRYPTO_E_NOT_SUPPORTED      Request failed, the underlying hardware does not support the service requested.
*
* @api
*
* @pre            Driver must be initialized.
*
*/
FUNC(Std_ReturnType, CRYPTO_CODE) Crypto_Exts_MacVerifySecCounter
(
    VAR    (uint32, AUTOMATIC                   ) u32KeyId,
    VAR    (uint8,  AUTOMATIC                   ) u8CounterId,
    VAR    (uint8,  AUTOMATIC                   ) u8RlvPrtOffset,
    VAR    (uint32, AUTOMATIC                   ) u32MessageLength,
    P2CONST(uint8,  AUTOMATIC, CRYPTO_APPL_CONST) pMessage,
    P2VAR  (uint8,  AUTOMATIC, CRYPTO_APPL_DATA ) pMac,
    VAR    (uint8,  AUTOMATIC                   ) u32MacLength,
    VAR    (uint32, AUTOMATIC                   ) u32VolatileCounter,
    P2VAR  (uint32, AUTOMATIC, CRYPTO_APPL_DATA ) pVrfStatus
)
{
    VAR(Std_ReturnType, AUTOMATIC) RetVal = (Std_ReturnType)E_NOT_OK;

#if (STD_ON == CRYPTO_DEV_ERROR_DETECT)
    /* If the module is not yet initialized and if development error detection for the Crypto Driver is enabled, the function shall report CRYPTO_E_UNINIT to the DET and return E_NOT_OK. */
    if (CRYPTO_DRIVER_UNINIT == Crypto_eDriverState)
    {
        (void)Det_ReportError((uint16)CRYPTO_MODULE_ID, (uint8)CRYPTO_INSTANCE_ID, (uint8)CRYPTO_EXTS_MACVERIFSECCOUNTER_ID, (uint8)CRYPTO_E_UNINIT);
    }
    /* If verification status is null pointer and if development error detection for the Crypto Driver is enabled, the function shall report CRYPTO_E_PARAM_POINTER to the DET and return E_NOT_OK. */
    else if (NULL_PTR == pVrfStatus)
    {
        (void)Det_ReportError((uint16)CRYPTO_MODULE_ID, (uint8)CRYPTO_INSTANCE_ID, (uint8)CRYPTO_EXTS_MACVERIFSECCOUNTER_ID, (uint8)CRYPTO_E_PARAM_POINTER);
    }
    else
#endif /* (STD_ON == CRYPTO_DEV_ERROR_DETECT) */
    {
        RetVal = Crypto_Ipw_ExtsMacVerifySecCounter(u32KeyId, u8CounterId, u8RlvPrtOffset, u32MessageLength, pMessage, pMac, u32MacLength, u32VolatileCounter, pVrfStatus);
    }

    return RetVal;
}

/**
* @brief          Install Certificate
* @details        Authenticates a public key certificate stored in system flash memory and enables the public key to be used 
*                 for subsequent operations.
*
* @param[in]      u8CertifId      Certificate ID
* @param[in]      u8AuthCertifId  Authorization certificate ID
* @param[in]      pCertifAddr     Certificate Address
* @param[in]      u8CertifType    Certificate Type
*
* @return         Result of the operation.
* @retval         E_OK                        Request successful.
* @retval         E_NOT_OK                    Request failed.
* @retval         CRYPTO_E_BUSY               Request failed, Crypro Driver Object is Busy.
* @retval         CRYPTO_E_KEY_NOT_VALID      Request failed, the key is not valid.
* @retval         CRYPTO_E_KEY_WRITE_FAIL     Request failed, read access was denied.
* @retval         CRYPTO_E_KEY_NOT_AVAILABLE  Request failed, key is locked due to failed boot measurement or an active debugger.
* @retval         CRYPTO_E_OPERATION_TIMEOUT  Request failed, CSE still busy and counter timeout occurred.
* @retval         CRYPTO_E_PARAM_POINTER      Request failed, output pointer is null.
* @retval         CRYPTO_E_NOT_SUPPORTED      Request failed, the underlying hardware does not support the service requested.
*
* @api
*
* @pre            Driver must be initialized.
*
*/
FUNC (Std_ReturnType, CRYPTO_CODE) Crypto_Exts_InstallCertificate
(
    VAR    (uint8, AUTOMATIC                   ) u8CertifId,
    VAR    (uint8, AUTOMATIC                   ) u8AuthCertifId,
    P2CONST(uint8, AUTOMATIC, CRYPTO_APPL_CONST) pCertifAddr,
    VAR    (uint8, AUTOMATIC                   ) u8CertifType
)
{
    VAR(Std_ReturnType, AUTOMATIC) RetVal = (Std_ReturnType)E_NOT_OK;

#if (STD_ON == CRYPTO_DEV_ERROR_DETECT)
    /* If the module is not yet initialized and if development error detection for the Crypto Driver is enabled, the function shall report CRYPTO_E_UNINIT to the DET and return E_NOT_OK. */
    if (CRYPTO_DRIVER_UNINIT == Crypto_eDriverState)
    {
        (void)Det_ReportError((uint16)CRYPTO_MODULE_ID, (uint8)CRYPTO_INSTANCE_ID, (uint8)CRYPTO_EXTS_INSTALLCERTIFICATE_ID, (uint8)CRYPTO_E_UNINIT);
    }
    else
#endif /* (STD_ON == CRYPTO_DEV_ERROR_DETECT) */
    {
        RetVal = Crypto_Ipw_Exts_InstallCertificate(u8CertifId,u8AuthCertifId,pCertifAddr,u8CertifType);
    }

    return RetVal;
}

/**
* @brief          Verify Signature
* @details        Verifies a signed message using the RSA SSA- PKCS1-V1_5 standard.
*
* @param[in]      u8AuthCertifId  Authorization certificate ID
* @param[in]      pMessAddr       Message Address
* @param[in]      u32MessLen      Message Length (bytes)
* @param[in]      pSignatureAddr  Signature Address
* @param[out]     pVerifStatus    Verification Status
* @param[in]      bClearBootMac   Clear BOOT_MAC
*
* @return         Result of the operation.
* @retval         E_OK                        Request successful.
* @retval         E_NOT_OK                    Request failed.
* @retval         CRYPTO_E_BUSY               Request failed, Crypro Driver Object is Busy.
* @retval         CRYPTO_E_KEY_NOT_VALID      Request failed, the key is not valid.
* @retval         CRYPTO_E_KEY_WRITE_FAIL     Request failed, read access was denied.
* @retval         CRYPTO_E_KEY_NOT_AVAILABLE  Request failed, key is locked due to failed boot measurement or an active debugger.
* @retval         CRYPTO_E_OPERATION_TIMEOUT  Request failed, CSE still busy and counter timeout occurred.
* @retval         CRYPTO_E_PARAM_POINTER      Request failed, output pointer is null.
* @retval         CRYPTO_E_NOT_SUPPORTED      Request failed, the underlying hardware does not support the service requested.
*
* @api
*
* @pre            Driver must be initialized.
*
*/
FUNC (Std_ReturnType, CRYPTO_CODE) Crypto_Exts_VerifySignature
(
    VAR    (uint8,   AUTOMATIC                   ) u8AuthCertifId,
    P2CONST(uint8,   AUTOMATIC, CRYPTO_APPL_CONST) pMessAddr,
    VAR    (uint32,  AUTOMATIC                   ) u32MessLen,
    P2CONST(uint8,   AUTOMATIC, CRYPTO_APPL_CONST) pSignatureAddr,
    P2VAR  (uint32,  AUTOMATIC, CRYPTO_APPL_DATA ) pVerifStatus,
    VAR    (boolean, AUTOMATIC                   ) bClearBootMac
)
{
    VAR(Std_ReturnType, AUTOMATIC) RetVal = (Std_ReturnType)E_NOT_OK;

#if (STD_ON == CRYPTO_DEV_ERROR_DETECT)
    /* If the module is not yet initialized and if development error detection for the Crypto Driver is enabled, the function shall report CRYPTO_E_UNINIT to the DET and return E_NOT_OK. */
    if (CRYPTO_DRIVER_UNINIT == Crypto_eDriverState)
    {
        (void)Det_ReportError((uint16)CRYPTO_MODULE_ID, (uint8)CRYPTO_INSTANCE_ID, (uint8)CRYPTO_EXTS_VERIFYSIGNATURE_ID, (uint8)CRYPTO_E_UNINIT);
    }
    else
#endif /* (STD_ON == CRYPTO_DEV_ERROR_DETECT) */
    {
        RetVal = Crypto_Ipw_Exts_VerifySignature(u8AuthCertifId,pMessAddr,u32MessLen,pSignatureAddr,pVerifStatus,bClearBootMac);
    }

    return RetVal;
}


#ifdef __cplusplus
}
#endif

/** @} */