/**
@defgroup hcu_v1 Hardware Cryptography Unit V1 (HCU_V1)
@brief The YTMicro SDK provides a host Peripheral Driver interfacing with the Hardware Cryptography Unit (HCU).

<p>
    The HCU implements security features. By using an embedded processor, firmware and hardware assisted
    AES-128 sub-block, the HCU enables encryption, decryption and message authentication algorithms for
    secure applications. Additionally a TRNG enables true random number generation 
    (entropy generator for PRNG in AES sub-block).
</p>
## Hardware background ##
<p>
    Features of the HCU module include:
        - Support 128, 192 and 256-bit key length
        - Support both encryption and decryption
        - Support secure hardware key and flexible software key
        - Support several algorithm engines
        – AES(ECB,CBC,CTR,CCM,CMAC) – SM4(ECB)
        – SHA(SHA-256,SHA-384)
        - All data is in big-endian format
        - Support 1,8 and 16-bit data swap
        - Sizeof input/output FIFOis upto 32*32 bits
        - The inputFIFO data is processed in 128bits
        - Support DMA transport between chip memory and input/outputFIFO
        - Support several interrupts
        – Operation done interrupt
        – InputFIFO empty interrupt
        – OutputFIFO full interrupt
        – InputFIFO overflow interrupt
        – OutputFIFO underflow interrupt
        – Input/outputFIFO watermark interrupt
        - Clock gating strategy is applied for engine core when input/output FIFO is not ready
</p>
*/

/**
@defgroup hcu_driver_v1 HCU Driver V1
@ingroup hcu_v1

@brief How to use the HCU driver in your application

<p>
    The driver implements the host interface, running on the application cores, and assumes the firmware
    has been written to flash memory and HCU module has been enabled through the DCF entries.
    The driver sends commands to the HCU, as specified in the security firmware block guide, and
    retrieves the results in a synchronous way (using synchronization semaphores updated in the
    HCU command complete ISR). For encryption/decryption and MAC generation/verification, the
    HCU driver also offers asynchronous API - in this case, the functions return right after sending
    the command to the HCU firmware; the result of the asynchronous commands can be retrieved by
    calling <b>HCU_DRV_GetAsyncCmdStatus</b> function.
</p>
<p>
    In order to use the HCU driver in your application, the <b>HCU_DRV_Init</b> function
    should be called prior to using the rest of the API. The parameter of this function
    is used for holding the internal state of the driver throughout the lifetime of the
    application.
</p>

## Key/seed/random number generation ##
<p>
    This is the high level flow in which to initialize and generate random numbers.
    1. Run <b>HCU_DRV_InitRNG</b> to initialize a random seed from the internal TRNG
        - <b>HCU_DRV_InitRNG</b> must be run after every POR, and
        before the first execution of HCU_DRV_GenerateRND
    2. Run <b>HCU_DRV_GenerateRND</b> to generate a random number
    The PRNG uses the PRNG_STATE/KEY and Seed per SHE spec and the AIS20
    standard.
    3. For additional random numbers the user may continue executing <b>HCU_DRV_GenerateRND</b> unless
    a POR event occurred.
</p>
## Memory update protocol ##
<p>
    In order to update a key, the user must have knowledge of a valid authentication secret,
    i.e. another key (AuthID). If the key AuthID is empty, the key update will only work if
    AuthID = ID (the key that will be updated will represent the AuthID from now on), otherwise
    <b>STATUS_SEC_KEY_EMPTY</b> is returned.
    </p>
    The M1-M3 values need to be computed according to the SHE Specification in order to update a
    key slot; in order to obtain the M1-M3 values, the driver offers a software implementation of the
    Miyaguchi-Preneel compression. The <b>HCU_DRV_LoadKey</b> function will require those values.
    After successfully updating the key slot, two verification values will be returned: M4 and M5.
    The user can compute the two values and compare them with the ones returned by the 
    <b>HCU_DRV_LoadKey</b> function in order to ensure the slot was updated as desired.
</p>
<p>
    In order to update the RAM key slot, <b>HCU_DRV_LoadPlainKey</b> function can be used, taking a reference
    to the plaintext key as parameter. This key can later be used for encryption or MAC algorithms,
    but needs to be updated after each reset cycle.
</p>
## Encryption/Decryption ##
<p>
    The driver supports symmetrical crypto algorithms (AES ECB/CBC). The ID of the key to be used must be 
    provided as parameter to the dedicated functions; the application must make sure the appropriate keys
    had been loaded prior to calling encryption/decryption functions, otherwise an error is returned.
    For AES-ECB, <b>HCU_DRV_EncryptECB</b> and <b>HCU_DRV_DecryptECB</b> functions take the key ID and
    references to the plaintext and ciphertext buffers as parameters. Additionally, for CBC mode, 
    <b>HCU_DRV_EncryptCBC</b> and <b>HCU_DRV_DecryptCBC</b> also require a reference to the initialization
    vector.
</p>
## MAC generation/verification ##
<p>
<b>HCU_DRV_GenerateMAC</b> function can be used for computing the MAC over any number of bits for
    a given message, as supported by the security firmware. <b>HCU_DRV_VerifyMAC</b> function checks whether
    the MAC received as parameter is valid for a given message, updating the boolean output parameter 
    <b>verifStatus</b> accordingly.
</p>
## Important Notes ##
<p>
    All the functions mentioned in the previous two sections require a timeout parameter; in case the
    encryption/decryption/MAC generation/MAC verification takes longer than the number of ms specified,
    a timeout error is returned. As per SHE specification, <i>the latency of the AES must remain below 2us 
    per encryption/decryption of a single block, including the key schedule</i> - depending on the number of
    blocks to be processed by the command, the timeout parameter should be computed considering this 
    maximum period for a block.
</p>
<p>
    The mentioned synchronous functions also have an asynchronous equivalent, which returns right after the command
    is issued; it is then the responsibility of the application to poll the command status (the result of
    the crypto operation is valid only upon command completion).
</p>
<p>
    For the other functions in the driver API, the timeout parameter is used only as a fallback mechanism,
    in case the HCU status bits are not updated (to avoid infinite loops in code). In a normal flow, no
    function besides <b>HCU_DRV_EncryptECB</b>, <b>HCU_DRV_DecryptECB</b>, <b>HCU_DRV_EncryptCBC</b>,
    <b>HCU_DRV_DecryptCBC</b>, <b>HCU_DRV_GenerateMAC</b> and <b>HCU_DRV_VerifyMAC</b> will return
    <b>STATUS_TIMEOUT</b>, thus it is safe to provide the minimum timeout period of 1ms.</br>
    \note A value of 0 should never be passed for the timeout parameter, as it may result in unexpected
    behaviour (depending on the clocking setup, the functions may still return success).
</p>
*/