/**
 * @file HostCryptoAPIOpenSSL.c
 * @author NXP Semiconductors
 * @version 1.0
 * @par License
 *
 * Copyright 2017 NXP
 * SPDX-License-Identifier: Apache-2.0
 *
 * @par Description
 * Host Crypto OpenSSL wrapper implementation
 *
 * @par HISTORY
 *
 */

#include "HostCryptoAPI.h"
//#include "ax_util.h"
//#include "sm_types.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>

#ifdef OPENSSL

#include <openssl/sha.h>
#include <openssl/aes.h>
#include <openssl/cmac.h>
#include <openssl/rand.h>
#include <openssl/des.h>
#include <openssl/ecdsa.h>


HLSE_RET_CODE   HLCRYPT_GetSupportedMechanisms(HLSE_MECHANISM_TYPE* mechanism, U32* mechanismLen)
{
#ifndef HLSE_IGNORE_PARAM_CHECK
    if (mechanismLen == NULL)
        return HLSE_ERR_API_ERROR;
#endif

    if (mechanism == NULL) {
        *mechanismLen = 11;
        return HLSE_SW_OK;
    }
    if (mechanism != NULL && mechanismLen != NULL && *mechanismLen < 11) {
        *mechanismLen = 11;
        return HLSE_ERR_BUF_TOO_SMALL;
    }

    *mechanismLen = 11;

    *mechanism++ = HLSE_SHA1;
    *mechanism++ = HLSE_SHA256;
    *mechanism++ = HLSE_AES_CMAC;
    *mechanism++ = HLSE_AES_ECB_ENCRYPT;
    *mechanism++ = HLSE_AES_ECB_DECRYPT;
    *mechanism++ = HLSE_AES_CBC_ENCRYPT;
    *mechanism++ = HLSE_AES_CBC_DECRYPT;
    *mechanism++ = HLSE_DES_ECB_ENCRYPT;
    *mechanism++ = HLSE_DES_ECB_DECRYPT;
    *mechanism++ = HLSE_DES_CBC_ENCRYPT;
    *mechanism++ = HLSE_DES_CBC_DECRYPT;

    return HLSE_SW_OK;

}

HLSE_RET_CODE HLCRYPT_Single_DES_CBC_Encrypt(U8 *key, U32 keylen,
    U8 *iv,
    U16 ivlen,
    U8 *inData,
    U32 inDatalen,
    U8 * outData,
    U32 *outDatalen)
{
    int nRet = HOST_CRYPTO_NOT_SUPPORTED;
#ifndef HLSE_IGNORE_PARAM_CHECK
    if (key == NULL || inData == NULL || outData == NULL || outDatalen == NULL) {
        return HLSE_ERR_API_ERROR;
    }
#endif
    return nRet;
}

HLSE_RET_CODE   HLCRYPT_Encrypt(HLSE_MECHANISM_INFO* pMechanismType, U8* inKey, U32 inKeyLen,
    U8* inData, U32 inDataLen,
    U8* outEncryptedData, U32* outEncryptedDataLen)
{
#ifndef HLSE_IGNORE_PARAM_CHECK
    if (pMechanismType == NULL || inKey == NULL || inData == NULL || outEncryptedDataLen == NULL) {
        return HLSE_ERR_API_ERROR;
    }
#endif

    // { Check if user requests to obtain the length only
    if (outEncryptedData == NULL) {
        if ((pMechanismType->mechanism == HLSE_AES_ECB_ENCRYPT) || (pMechanismType->mechanism == HLSE_AES_CBC_ENCRYPT))
        {
            *outEncryptedDataLen = 16;
            return HLSE_SW_OK;
        }
        else if ((pMechanismType->mechanism == HLSE_DES_ECB_ENCRYPT) || (pMechanismType->mechanism == HLSE_DES_CBC_ENCRYPT))
        {
            *outEncryptedDataLen = 8;
            return HLSE_SW_OK;
        }
        else {
            // type requested not found
            return HLSE_ERR_API_ERROR;
        }
    }
    // } end section obtaining only the length

    if (pMechanismType->mechanism == HLSE_AES_ECB_ENCRYPT) {
        AES_KEY keyLocal;
        int keyLenBits = inKeyLen * 8;
        int nRet = 0;

        // This works assuming the plaintext has the same size as the key
        // NOTE: AES_set_encrypt_key returns 0 upon success
        nRet = AES_set_encrypt_key(inKey, keyLenBits, &keyLocal);
        if (nRet != 0)
        {
            return HOST_CRYPTO_ERROR;
        }

        // AES_ecb_encrypt has return type void
        AES_ecb_encrypt(inData, outEncryptedData, &keyLocal, AES_ENCRYPT);

        return HOST_CRYPTO_OK;
    }
    else if (pMechanismType->mechanism == HLSE_AES_CBC_ENCRYPT) {
        // int outLen = 0;
        int nRet;
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
        EVP_CIPHER_CTX aesCtx;
#else
        EVP_CIPHER_CTX *aesCtx = NULL;
#endif
        int outEncryptedDataLenInt = (int)(*outEncryptedDataLen);

#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
        EVP_CIPHER_CTX_init(&aesCtx);
#else
        aesCtx = EVP_CIPHER_CTX_new();
        if (aesCtx == NULL) {
            return HOST_CRYPTO_ERROR;
        }
#endif

        if (inKeyLen != AES_BLOCK_SIZE) {
            // printf("Unsupported key length for HOST_AES_CBC_Process\r\n");
            return HLSE_ERR_API_ERROR;
        }

        // iv is passed in the pParameter
        if (pMechanismType->pParameter == NULL) {
            return HLSE_ERR_API_ERROR;
        }

        if ((inDataLen % AES_BLOCK_SIZE) != 0) {
            // printf("Input data are not block aligned for HOST_AES_CBC_Process\r\n");
            return HLSE_ERR_API_ERROR;
        }
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
        // EVP_EncryptInit_ex returns 0 on failure and 1 upon success
        if (!EVP_EncryptInit_ex(&aesCtx, EVP_aes_128_cbc(), NULL, inKey, pMechanismType->pParameter)) {
            return HOST_CRYPTO_ERROR;
        }

        if (!EVP_EncryptUpdate(&aesCtx, outEncryptedData, &outEncryptedDataLenInt, inData, inDataLen)) {
            *outEncryptedDataLen = (U32)outEncryptedDataLenInt;
            return HOST_CRYPTO_ERROR;
        }
#else
        // EVP_EncryptInit_ex returns 0 on failure and 1 upon success
        if (!EVP_EncryptInit_ex(aesCtx, EVP_aes_128_cbc(), NULL, inKey, pMechanismType->pParameter)) {
            return HOST_CRYPTO_ERROR;
        }

        if (!EVP_EncryptUpdate(aesCtx, outEncryptedData, &outEncryptedDataLenInt, inData, inDataLen)) {
            *outEncryptedDataLen = (U32)outEncryptedDataLenInt;
            return HOST_CRYPTO_ERROR;
        }
#endif

        *outEncryptedDataLen = (U32)outEncryptedDataLenInt;
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
        nRet = EVP_CIPHER_CTX_cleanup(&aesCtx);
#else
        EVP_CIPHER_CTX_free(aesCtx);
        nRet = 1;
#endif
        return nRet;
    }
    else if (pMechanismType->mechanism == HLSE_DES_ECB_ENCRYPT) {
        int nRet = 0;
        // DES_cblock key1, key2, key3;
        DES_key_schedule ks1, ks2, ks3;
        U32 i;

        if (inKeyLen >= 8) {
            nRet = DES_set_key((DES_cblock *)inKey, &ks1);
            if (nRet != 0) {
                return HOST_CRYPTO_ERROR;
            }
        }
        if (inKeyLen >= 16) {
            nRet = DES_set_key((DES_cblock *)(&inKey[8]), &ks2);
            if (nRet != 0) {
                return HOST_CRYPTO_ERROR;
            }
        }
        if (inKeyLen == 24) {
            nRet = DES_set_key((DES_cblock *)(&inKey[16]), &ks3);
            if (nRet != 0) {
                return HOST_CRYPTO_ERROR;
            }
        }

        for (i = 0; i < inDataLen; i += 8) {
            if (inKeyLen == 24) {
                DES_ecb3_encrypt((DES_cblock *)(inData + i), (DES_cblock *)(outEncryptedData + i), &ks1, &ks2, &ks3, DES_ENCRYPT);
            }
            else if (inKeyLen == 16) {
                DES_ecb2_encrypt((DES_cblock *)(inData + i), (DES_cblock *)(outEncryptedData + i), &ks1, &ks2, DES_ENCRYPT);
            }
            else {
                DES_ecb_encrypt((DES_cblock *)(inData + i), (DES_cblock *)(outEncryptedData + i), &ks1, DES_ENCRYPT);
            }
        }

        return HOST_CRYPTO_OK;
    }
    else if (pMechanismType->mechanism == HLSE_DES_CBC_ENCRYPT) {
        int nRet = 0;
        // DES_cblock key1, key2, key3;
        DES_key_schedule ks1, ks2, ks3;

        // iv is passed in the pParameter
        if (pMechanismType->pParameter == NULL) {
            return HLSE_ERR_API_ERROR;
        }

        if (inKeyLen >= 8) {
            nRet = DES_set_key((DES_cblock *)inKey, &ks1);
            if (nRet != 0) {
                return HOST_CRYPTO_ERROR;
            }
        }
        if (inKeyLen >= 16) {
            nRet = DES_set_key((DES_cblock *)(&inKey[8]), &ks2);
            if (nRet != 0) {
                return HOST_CRYPTO_ERROR;
            }
        }
        if (inKeyLen == 24) {
            nRet = DES_set_key((DES_cblock *)(&inKey[16]), &ks3);
            if (nRet != 0) {
                return HOST_CRYPTO_ERROR;
            }
        }

        if (inKeyLen == 24) {
            DES_ede3_cbc_encrypt(inData, outEncryptedData, inDataLen, &ks1, &ks2, &ks3, pMechanismType->pParameter, DES_ENCRYPT);
        }
        else if (inKeyLen == 16) {
            DES_ede2_cbc_encrypt(inData, outEncryptedData, inDataLen, &ks1, &ks2, pMechanismType->pParameter, DES_ENCRYPT);
        }
        else {
            DES_cbc_encrypt(inData, outEncryptedData, inDataLen, &ks1, pMechanismType->pParameter, DES_ENCRYPT);
        }

        return HOST_CRYPTO_OK;
    }

    return HLSE_ERR_API_ERROR;
}

HLSE_RET_CODE   HLCRYPT_Decrypt(HLSE_MECHANISM_INFO* pMechanismType, U8* inKey, U32 inKeyLen,
    U8* inData, U32 inDataLen,
    U8* outDecryptedData, U32* outDecryptedDataLen)
{
#ifndef HLSE_IGNORE_PARAM_CHECK
    if (pMechanismType == NULL || inKey == NULL || inData == NULL || outDecryptedDataLen == NULL) {
        return HLSE_ERR_API_ERROR;
    }
#endif

    // { Check if user requets to obtain the length only
    if (outDecryptedData == NULL) {
        if ((pMechanismType->mechanism == HLSE_AES_ECB_DECRYPT) || (pMechanismType->mechanism == HLSE_AES_CBC_DECRYPT))
        {
            *outDecryptedDataLen = 16;
            return HLSE_SW_OK;
        }
        else if ((pMechanismType->mechanism == HLSE_DES_ECB_DECRYPT) || (pMechanismType->mechanism == HLSE_DES_CBC_DECRYPT))
        {
            *outDecryptedDataLen = 8;
            return HLSE_SW_OK;
        }
        else {
            // type requested not found
            return HLSE_ERR_API_ERROR;
        }
    }
    // } end section obtaining only the length

    if (pMechanismType->mechanism == HLSE_AES_ECB_DECRYPT) {
        AES_KEY keyLocal;
        int keyLenBits = inKeyLen * 8;
        int nRet = 0;

        // This works assuming the plaintext has the same size as the key
        // NOTE: AES_set_encrypt_key returns 0 upon success
        nRet = AES_set_decrypt_key(inKey, keyLenBits, &keyLocal);
        if (nRet != 0)
        {
            return HOST_CRYPTO_ERROR;
        }

        // AES_ecb_encrypt has return type void
        AES_ecb_encrypt(inData, outDecryptedData, &keyLocal, AES_DECRYPT);

        return HOST_CRYPTO_OK;
    }
    else if (pMechanismType->mechanism == HLSE_AES_CBC_DECRYPT) {
        // int outLen = 0;
        int nRet;
        int outDecryptedDataLenInt = (int)(*outDecryptedDataLen);
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
        EVP_CIPHER_CTX aesCtx;
#else
        EVP_CIPHER_CTX *aesCtx = NULL;
#endif

#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
        EVP_CIPHER_CTX_init(&aesCtx);
#else
        aesCtx = EVP_CIPHER_CTX_new();
        if (aesCtx == NULL) {
            return HOST_CRYPTO_ERROR;
        }
#endif

        if (inKeyLen != AES_BLOCK_SIZE) {
            // printf("Unsupported key length for HOST_AES_CBC_Process\r\n");
            return HLSE_ERR_API_ERROR;
        }

        // iv is passed in the pParameter
        if (pMechanismType->pParameter == NULL) {
            return HLSE_ERR_API_ERROR;
        }

        if ((inDataLen % AES_BLOCK_SIZE) != 0) {
            // printf("Input data are not block aligned for HOST_AES_CBC_Process\r\n");
            return HLSE_ERR_API_ERROR;
        }
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
        // EVP_EncryptInit_ex returns 0 on failure and 1 upon success
        if (!EVP_DecryptInit_ex(&aesCtx, EVP_aes_128_cbc(), NULL, inKey, pMechanismType->pParameter)) {
            return HOST_CRYPTO_ERROR;
        }

        if (!EVP_DecryptUpdate(&aesCtx, outDecryptedData, &outDecryptedDataLenInt, inData, inDataLen)) {
            *outDecryptedDataLen = outDecryptedDataLenInt;
            return HOST_CRYPTO_ERROR;
        }
#else
        // EVP_EncryptInit_ex returns 0 on failure and 1 upon success
        if (!EVP_DecryptInit_ex(aesCtx, EVP_aes_128_cbc(), NULL, inKey, pMechanismType->pParameter)) {
            return HOST_CRYPTO_ERROR;
        }

        if (!EVP_DecryptUpdate(aesCtx, outDecryptedData, &outDecryptedDataLenInt, inData, inDataLen)) {
            *outDecryptedDataLen = outDecryptedDataLenInt;
            return HOST_CRYPTO_ERROR;
        }
#endif

        *outDecryptedDataLen = outDecryptedDataLenInt;
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
        nRet = EVP_CIPHER_CTX_cleanup(&aesCtx);
#else
        EVP_CIPHER_CTX_free(aesCtx);
        nRet = 1;
#endif
        return nRet;
    }
    else if (pMechanismType->mechanism == HLSE_DES_ECB_DECRYPT) {
        int nRet = 0;
        // DES_cblock key1, key2, key3;
        DES_key_schedule ks1, ks2, ks3;
        U32 i;

        if (inKeyLen >= 8) {
            nRet = DES_set_key((DES_cblock *)inKey, &ks1);
            if (nRet != 0) {
                return HOST_CRYPTO_ERROR;
            }
        }
        if (inKeyLen >= 16) {
            nRet = DES_set_key((DES_cblock *)(&inKey[8]), &ks2);
            if (nRet != 0) {
                return HOST_CRYPTO_ERROR;
            }
        }
        if (inKeyLen == 24) {
            nRet = DES_set_key((DES_cblock *)(&inKey[16]), &ks3);
            if (nRet != 0) {
                return HOST_CRYPTO_ERROR;
            }
        }

        for (i = 0; i < inDataLen; i += 8) {
            if (inKeyLen == 24) {
                DES_ecb3_encrypt((DES_cblock *)(inData + i), (DES_cblock *)(outDecryptedData + i), &ks1, &ks2, &ks3, DES_DECRYPT);
            }
            else if (inKeyLen == 16) {
                DES_ecb2_encrypt((DES_cblock *)(inData + i), (DES_cblock *)(outDecryptedData + i), &ks1, &ks2, DES_DECRYPT);
            }
            else {
                DES_ecb_encrypt((DES_cblock *)(inData + i), (DES_cblock *)(outDecryptedData + i), &ks1, DES_DECRYPT);
            }
        }

        return HOST_CRYPTO_OK;
    }
    else if (pMechanismType->mechanism == HLSE_DES_CBC_DECRYPT) {
        int nRet = 0;
        // DES_cblock key1, key2, key3;
        DES_key_schedule ks1, ks2, ks3;

        // iv is passed in the pParameter
        if (pMechanismType->pParameter == NULL) {
            return HLSE_ERR_API_ERROR;
        }

        if (inKeyLen >= 8) {
            nRet = DES_set_key((DES_cblock *)inKey, &ks1);
            if (nRet != 0) {
                return HOST_CRYPTO_ERROR;
            }
        }
        if (inKeyLen >= 16) {
            nRet = DES_set_key((DES_cblock *)(&inKey[8]), &ks2);
            if (nRet != 0) {
                return HOST_CRYPTO_ERROR;
            }
        }
        if (inKeyLen == 24) {
            nRet = DES_set_key((DES_cblock *)(&inKey[16]), &ks3);
            if (nRet != 0) {
                return HOST_CRYPTO_ERROR;
            }
        }

        if (inKeyLen == 24) {
            DES_ede3_cbc_encrypt(inData, outDecryptedData, inDataLen, &ks1, &ks2, &ks3, pMechanismType->pParameter, DES_DECRYPT);
        }
        else if (inKeyLen == 16) {
            DES_ede2_cbc_encrypt(inData, outDecryptedData, inDataLen, &ks1, &ks2, pMechanismType->pParameter, DES_DECRYPT);
        }
        else {
            DES_cbc_encrypt(inData, outDecryptedData, inDataLen, &ks1, pMechanismType->pParameter, DES_DECRYPT);
        }

        return HOST_CRYPTO_OK;
    }

    return HLSE_ERR_API_ERROR;
}

HLSE_RET_CODE   HLCRYPT_Digest(HLSE_MECHANISM_INFO* pMechanismType,
    U8* inData, U32 inDataLen,
    U8* outDigest, U32* outDigestLen)
{
#ifndef HLSE_IGNORE_PARAM_CHECK
    if (pMechanismType == NULL || inData == NULL || outDigestLen == NULL) {
        return HLSE_ERR_API_ERROR;
    }
#endif

    // Check for a request for digest Len
    if (outDigest == NULL) {
        if (pMechanismType->mechanism == HLSE_SHA256) {
            *outDigestLen = 32;
            return HLSE_SW_OK;
        }
        else if (pMechanismType->mechanism == HLSE_SHA1) {
            *outDigestLen = 20;
            return HLSE_SW_OK;
        }
        else {
            return HLSE_ERR_API_ERROR;
        }
    }

    if (pMechanismType->mechanism == HLSE_SHA256) {
        SHA256_CTX ctx256;
        int ret;

        ret = SHA256_Init(&ctx256);
        if (ret == HOST_CRYPTO_OK) {
            ret = SHA256_Update(&ctx256, inData, inDataLen);
            if (ret == HOST_CRYPTO_OK)
            {
                ret = SHA256_Final(outDigest, &ctx256);
                *outDigestLen = 32;
            }
        }

        return ret;
    }
    else if (pMechanismType->mechanism == HLSE_SHA1) {
        SHA_CTX ctx;
        int ret;

        ret = SHA1_Init(&ctx);
        if (ret == HOST_CRYPTO_OK)
        {
            ret = SHA1_Update(&ctx, inData, inDataLen);
            if (ret == HOST_CRYPTO_OK)
            {
                ret = SHA1_Final(outDigest, &ctx);
                *outDigestLen = 20;
            }
        }
        return ret;
    }

    return HLSE_ERR_API_ERROR;
}


static S32 HOST_CMAC_Init_Des(CMAC_CTX **ctx, const U8 *pKey, U8 keySizeInBytes)
{
    int ret;

    *ctx = CMAC_CTX_new();
    if (*ctx == NULL)
    {
        return HLSE_ERR_API_ERROR;
    }

    // CMAC_Init() returns
    //      1 = success
    //      0 = failure
    ret = CMAC_Init(*ctx, pKey, keySizeInBytes, EVP_des_ede3_cbc(), NULL);

    return ret;
}


HLSE_RET_CODE   HLCRYPT_Sign(HLSE_MECHANISM_INFO* pMechanismType, U8* inKey, U32 inKeyLen,
    U8* inData, U32 inDataLen,
    U8* outSignature, U32* outSignatureLen)
{

#ifndef HLSE_IGNORE_PARAM_CHECK
    if (pMechanismType == NULL || inKey == NULL || inData == NULL || outSignatureLen == NULL) {
        return HLSE_ERR_API_ERROR;
    }
#endif

    // Check for a request to get the required signature len
    if (outSignature == NULL) {
        if (pMechanismType->mechanism == HLSE_AES_CMAC) {
            *outSignatureLen = 16; // AES_KEY_LEN_nBYTE
            return HLSE_SW_OK;
        }
        else {
            return HLSE_ERR_API_ERROR;
        }
    }

    if (pMechanismType->mechanism == HLSE_AES_CMAC) {
        int ret;
        CMAC_CTX *ctx;
        size_t outSignatureLenSizeT = (size_t)(*outSignatureLen);

        ctx = CMAC_CTX_new();
        if (ctx == NULL)
        {
            return HLSE_ERR_API_ERROR;
        }

        // CMAC_Init() returns
        //      1 = success
        //      0 = failure
        ret = CMAC_Init(ctx, inKey, inKeyLen, EVP_aes_128_cbc(), NULL);

        if (ret == HOST_CRYPTO_OK)
        {
            ret = CMAC_Update(ctx, inData, inDataLen);
            if (ret == HOST_CRYPTO_OK)
            {
                ret = CMAC_Final(ctx, outSignature, &outSignatureLenSizeT);
                *outSignatureLen = (U32)outSignatureLenSizeT;
            }
        }

        if (ret != HLSE_ERR_MEMORY)
        {
            CMAC_CTX_free(ctx);
        }

        return ret;

    }
    else if (pMechanismType->mechanism == HLSE_DES_CMAC) {
        int ret;
        size_t size;
        CMAC_CTX *ctx;

        ret = HOST_CMAC_Init_Des(&ctx, inKey, inKeyLen);
        if (ret == HOST_CRYPTO_OK)
        {
            ret = CMAC_Update(ctx, inData, inDataLen);
            if (ret == HOST_CRYPTO_OK)
            {
                ret = CMAC_Final(ctx, outSignature, &size);
            }
        }

        if (ret != HLSE_ERR_MEMORY)
        {
            CMAC_CTX_free(ctx);
        }

        return ret;
    }

    else if (pMechanismType->mechanism == HLSE_ECDSA_SIGN)
    {
        unsigned int lclOutSignatureLen = (unsigned int)(*outSignatureLen);
        int status;
        status = ECDSA_sign(0, inData, inDataLen, outSignature, &lclOutSignatureLen, (EC_KEY *)inKey);
        *outSignatureLen = lclOutSignatureLen;
        if (status == 1)
        {
            return HLSE_SW_OK;
        }
        else
        {
            return HLSE_ERR_CRYPTO_ENGINE_FAILED;
        }
    }

    return HLSE_ERR_API_ERROR;
}

HLSE_RET_CODE   HLCRYPT_Verify(HLSE_MECHANISM_INFO* pMechanismType, U8* inKey, U32 inKeyLen,
                            U8* inData, U32 inDataLen,
                            U8* inSignature, U32 inSignatureLen)
{
#ifndef HLSE_IGNORE_PARAM_CHECK
    if (pMechanismType == NULL || inKey == NULL || inData == NULL || inSignature == NULL ) {
        return HLSE_ERR_API_ERROR;
    }
#endif

    if (pMechanismType->mechanism == HLSE_ECDSA_VERIFY)
    {
        int status;
        status = ECDSA_verify(0, inData, inDataLen, inSignature, inSignatureLen, (EC_KEY *)inKey);
        if (status == 1)
        {
            return HLSE_SW_OK;
        }
        else
        {
            return HLSE_ERR_CRYPTO_ENGINE_FAILED;
        }

    }
    else
    {
        return HLSE_ERR_API_ERROR;
    }
}

HLSE_RET_CODE   HLCRYPT_SignInit(HLSE_MECHANISM_INFO* pMechanismType, U8* inKey, U32 inKeyLen, HLSE_CONTEXT_HANDLE* hContext)
{
#ifndef HLSE_IGNORE_PARAM_CHECK
    if (pMechanismType == NULL || inKey == NULL || hContext == NULL) {
        return HLSE_ERR_API_ERROR;
    }
#endif

    if (pMechanismType->mechanism == HLSE_AES_CMAC) {
        int ret;

        *hContext = CMAC_CTX_new();
        if (*hContext == NULL)
        {
            return HLSE_ERR_MEMORY;
        }

        // CMAC_Init() returns
        //      1 = success
        //      0 = failure
        ret = CMAC_Init(*hContext, inKey, inKeyLen, EVP_aes_128_cbc(), NULL);

        return ret;
    }

    return HLSE_ERR_API_ERROR;
}

HLSE_RET_CODE   HLCRYPT_SignUpdate(HLSE_CONTEXT_HANDLE hContext, U8* inDataPart, U32 inDataPartLen)
{
    int ret;
#ifndef HLSE_IGNORE_PARAM_CHECK
    if (inDataPart == NULL) {
        return HLSE_ERR_API_ERROR;
    }
#endif


    // CMAC_Update() returns
    //      1 = success
    //      0 = failure
    ret = CMAC_Update(hContext, inDataPart, inDataPartLen);

    return ret;
}

HLSE_RET_CODE   HLCRYPT_SignFinal(HLSE_CONTEXT_HANDLE hContext, U8* outSignature, U32* outSignatureLen)
{
    int ret;
    size_t outSignatureLenSizeT;

#ifndef HLSE_IGNORE_PARAM_CHECK
    if (outSignatureLen == NULL) {
        return HLSE_ERR_API_ERROR;
    }
#endif

    outSignatureLenSizeT = (size_t)(*outSignatureLen);

    // Check for a request to get the required signature len
    if (outSignature == NULL)
    {
        *outSignatureLen = 16;
        return HLSE_SW_OK;
    }

    // CMAC_Final() returns
    //      1 = success
    //      0 = failure
    ret = CMAC_Final(hContext, outSignature, &outSignatureLenSizeT);
    *outSignatureLen = (U32)outSignatureLenSizeT;

    CMAC_CTX_free(hContext);

    return ret;
}

HLSE_RET_CODE    HLCRYPT_GetRandom(U32 inLen, U8 * pRandom)
{
    int nRet;
#ifndef HLSE_IGNORE_PARAM_CHECK
    if (pRandom == NULL) {
        return HLSE_ERR_API_ERROR;
    }
#endif


    nRet = RAND_bytes(pRandom, inLen);
    return nRet;
}

#endif // OPENSSL
