blob: dc1b9e1a5cccf0e686a65bb72bce641f7847af9a [file] [log] [blame]
/**
* @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