/** | |
* @file tstHostCrypto.c | |
* @author NXP Semiconductors | |
* @version 1.0 | |
* @par License | |
* | |
* Copyright 2016,2020 NXP | |
* SPDX-License-Identifier: Apache-2.0 | |
* | |
* @par Description | |
* Module implementing host based crypto functionality used in example programs. | |
* This module relies on the availability of mbed TLS on the Host plaform. | |
* @par HISTORY | |
* | |
*/ | |
/******************************************************************* | |
* project specific include files | |
*******************************************************************/ | |
#ifndef MBEDTLS | |
# define MBEDTLS | |
#endif | |
#include "tstHostCrypto.h" | |
#include "tst_sm_util.h" | |
#include "sm_printf.h" | |
#include "string.h" | |
#include "mbedtls/aes.h" | |
#include "hkdf_mbedtls.h" | |
#include "mbedtls/error.h" | |
#include "mbedtls/pk.h" | |
#include "mbedtls/ecdsa.h" | |
#include "mbedtls/rsa.h" | |
#include "mbedtls/error.h" | |
#include "mbedtls/entropy.h" | |
#include "mbedtls/ctr_drbg.h" | |
#include "mbedtls/ecdh.h" | |
#include "mbedtls/md.h" | |
#include "mbedtls/platform.h" | |
#include "assert.h" | |
#include "HostCryptoAPI.h" | |
#include "string.h" /* For size_t */ | |
#if defined(FSL_FEATURE_SOC_TRNG_COUNT) && (FSL_FEATURE_SOC_TRNG_COUNT > 0) | |
#include "fsl_trng.h" | |
#elif defined(FSL_FEATURE_SOC_RNG_COUNT) && (FSL_FEATURE_SOC_RNG_COUNT > 0) | |
#include "fsl_rnga.h" | |
#elif defined(FSL_FEATURE_SOC_LPC_RNG_COUNT) && (FSL_FEATURE_SOC_LPC_RNG_COUNT > 0) | |
#include "fsl_rng.h" | |
#endif | |
/******************************************************************* | |
* global variables and struct definitions | |
*******************************************************************/ | |
int fast_aes_wrap(const uint8_t *kek, int n, const uint8_t *plain, uint8_t *cipher); | |
#if AX_EMBEDDED | |
static int HOSTCRYPTO_GetRandom(void *pCtx, unsigned char *output, size_t len); | |
#endif | |
static mbedtls_ecp_group_id curveType2GroupID (ECCCurve_t curveType) { | |
switch (curveType) { | |
case ECCCurve_NIST_P192: | |
return MBEDTLS_ECP_DP_SECP192R1; | |
case ECCCurve_NIST_P224: | |
return MBEDTLS_ECP_DP_SECP224R1; | |
case ECCCurve_NIST_P256: | |
return MBEDTLS_ECP_DP_SECP256R1; | |
case ECCCurve_BrainPoolP256r1: | |
return MBEDTLS_ECP_DP_BP256R1; | |
default: | |
assert(0); | |
} | |
return MBEDTLS_ECP_DP_NONE; | |
} | |
// TODO: Check on buffer size passed as argument | |
U16 HOSTCRYPTO_Sign(EC_KEY* pKey, U8* pInputData, U16 inputLength, U8* pSignature, U16* pSignatureLength, U8 signatureFormat) | |
{ | |
#ifdef __FUNCTION__ | |
sm_printf(CONSOLE, "Not Implemented => '" __FUNCTION__ "'.\n"); | |
#endif | |
return 0; | |
} | |
U16 HOSTCRYPTO_ECC_ComputeSharedSecret(EC_KEY *pKey, U8 *pubKey, U16 pubKeyLen, U8 *pSharedSecretData, U16 *pSharedSecretDataLen) | |
{ | |
int retval; | |
int keyLen = 0; // # byte | |
int sharedSecretLen; // # bits | |
int sharedSecretLen_Derived; // # bits | |
U16 nStatus = SW_OK; | |
mbedtls_mpi rawSharedData; | |
mbedtls_ecp_point ecp_point; | |
const mbedtls_ecp_curve_info *p_curve_info = NULL; | |
if (pKey == NULL) { | |
return ERR_NO_PRIVATE_KEY; | |
} | |
mbedtls_ecp_keypair * pEcCtx = mbedtls_pk_ec( *pKey ); | |
mbedtls_ecp_point_init(&ecp_point); | |
mbedtls_mpi_init(&rawSharedData); | |
/* Compute the size of the shared secret */ | |
p_curve_info = mbedtls_ecp_curve_info_from_grp_id(pEcCtx->grp.id); | |
keyLen = ((p_curve_info->bit_size + 7)) / 8; | |
sharedSecretLen = keyLen * 8; | |
if (keyLen > *pSharedSecretDataLen) | |
{ | |
return ERR_BUF_TOO_SMALL; | |
} | |
// NOTE: alternative approach to get #byte shared secret (based upon bitsize of EC curve) | |
// (pEcCtx->grp.pbits + 7) / 8 | |
// convert external public key data to POINT | |
// external public key curve == local curve | |
// data has leading 0x04 (uncompressed point representation) | |
retval = mbedtls_ecp_point_read_binary( &(pEcCtx->grp), &ecp_point, | |
pubKey, pubKeyLen ); | |
if (retval != 0) | |
{ | |
return ERR_GENERAL_ERROR; | |
} | |
/* Compute the shared secret, no KDF is applied */ | |
retval = mbedtls_ecdh_compute_shared( &(pEcCtx->grp), &rawSharedData, | |
&ecp_point, &(pEcCtx->d), | |
NULL, | |
NULL ); | |
if (retval != 0) | |
{ | |
return ERR_GENERAL_ERROR; | |
} | |
mbedtls_ecp_point_free(&ecp_point); | |
sharedSecretLen_Derived = mbedtls_mpi_size( &(rawSharedData) ); | |
if (sharedSecretLen_Derived > sharedSecretLen) | |
{ | |
// Unclear what error would trigger this code. | |
mbedtls_mpi_free(&(rawSharedData)); | |
return ERR_GENERAL_ERROR; | |
} | |
*pSharedSecretDataLen = keyLen; | |
retval = mbedtls_mpi_write_binary(&rawSharedData,pSharedSecretData, keyLen); | |
if (retval != 0) | |
{ | |
return ERR_GENERAL_ERROR; | |
} | |
mbedtls_mpi_free(&(rawSharedData)); | |
return nStatus; | |
} | |
/** | |
* Extract the public key - as a byte array in uncompress format - from an ECC key | |
* @param[in] pKey Reference to ECC key. | |
* @param[in,out] pPublicKeyData IN: Buffer to contain public key; OUT: Public key | |
* @param[out] pPublicKeyLen Length of public key \p pPublicKeyData retrieved | |
* @param[in] maxPublicKeyLen Size of buffer (\p pPublicKeyData) provided to contain public key | |
*/ | |
U16 HOSTCRYPTO_GetPublicKey(EC_KEY *pKey, U8 *pPublicKeyData, U16 *pPublicKeyLen, U16 maxPublicKeyLen) | |
{ | |
int res; | |
size_t keylen = 0; | |
mbedtls_ecp_keypair * pEcCtx; | |
if ( pKey == NULL) { | |
return ERR_CRYPTO_ENGINE_FAILED; | |
} | |
pEcCtx = mbedtls_pk_ec( *pKey ); | |
res = mbedtls_ecp_check_pubkey( &(pEcCtx->grp), &(pEcCtx->Q) ); | |
if ((res != 0) || (pPublicKeyData == NULL) || (pPublicKeyLen == NULL)) | |
{ | |
return ERR_CRYPTO_ENGINE_FAILED; | |
} | |
res = mbedtls_ecp_point_write_binary(&(pEcCtx->grp),&(pEcCtx->Q),MBEDTLS_ECP_PF_UNCOMPRESSED,&keylen,pPublicKeyData,maxPublicKeyLen); | |
*pPublicKeyLen = (U16)keylen; | |
if ((*pPublicKeyLen == 0) || (res != 0)) | |
{ | |
return ERR_CRYPTO_ENGINE_FAILED; | |
} | |
return SW_OK; | |
} | |
/** | |
* Extract the private key - as a byte array restored to nominal key size by sign extension - from an ECC key (in an mbed TLS specific format) | |
* @param[in] pKey Reference to ECC key. | |
* @param[in,out] pPrivateKeyData IN: Buffer to contain private key; OUT: Private key | |
* @param[out] pPrivateKeyLen Length of private key \p pPrivateKeyData retrieved | |
* @param[in] maxPrivateKeyLen Size of buffer (\p pPrivateKeyData) provided to contain private key | |
*/ | |
U16 HOSTCRYPTO_GetPrivateKey(EC_KEY *pKey, U8 *pPrivateKeyData, U16 *pPrivateKeyLen, U16 maxPrivateKeyLen) | |
{ | |
int significantBytes = 0; | |
int keyLen = 0; | |
U16 res = SW_OK; | |
U8 keyArray[256]; | |
const mbedtls_ecp_curve_info *p_curve_info = NULL; | |
mbedtls_ecp_keypair * pEcCtx; | |
if ( pKey == NULL) { | |
return ERR_CRYPTO_ENGINE_FAILED; | |
} | |
pEcCtx = mbedtls_pk_ec( *pKey ); | |
/*TODO check sign extension part */ | |
res = mbedtls_ecp_check_privkey( &(pEcCtx->grp), &(pEcCtx->d)); | |
if ((res != 0) || (pPrivateKeyData == NULL) || (pPrivateKeyLen == NULL)) | |
{ | |
return ERR_CRYPTO_ENGINE_FAILED; | |
} | |
significantBytes = mbedtls_mpi_size( &(pEcCtx->d) ); | |
p_curve_info = mbedtls_ecp_curve_info_from_grp_id( pEcCtx->grp.id ); | |
keyLen = ((p_curve_info->bit_size + 7))/8; | |
if (keyLen > maxPrivateKeyLen) | |
{ | |
return ERR_BUF_TOO_SMALL; | |
} | |
res = mbedtls_mpi_write_binary(&(pEcCtx->d),keyArray,keyLen); | |
if (res == 0) | |
{ | |
// Extend byte array with leading 0x00 byte in case private key had | |
// been truncated because the MSB were not significant | |
if (significantBytes > 0) | |
{ | |
res = axZeroSignExtend(keyArray, (U16)significantBytes, (U16)keyLen); | |
if (res == SW_OK) | |
{ | |
memcpy(pPrivateKeyData, keyArray, keyLen); | |
*pPrivateKeyLen = (U16)keyLen; | |
} | |
else | |
{ | |
*pPrivateKeyLen = 0; | |
} | |
} | |
else | |
{ | |
*pPrivateKeyLen = 0; | |
res = ERR_GENERAL_ERROR; | |
} | |
} | |
else | |
{ | |
res = ERR_CRYPTO_ENGINE_FAILED; | |
} | |
return res; | |
} | |
void HOSTCRYPTO_FreeEccKey(EC_KEY** ppKey) { | |
if ( ppKey == NULL ) | |
{ | |
; /* Nothing to do */ | |
} | |
else | |
{ | |
if ( *ppKey != NULL) | |
{ | |
mbedtls_pk_free(*ppKey); | |
free(*ppKey); | |
} | |
*ppKey = NULL; | |
} | |
} | |
/** | |
* Create an ECC key (in an mbedTLS specific format) on the requested curve | |
* @param[in] curveType E.g. ECCCurve_NIST_P256. Not all curves defined in ::ECCCurve_t are always supported | |
by the underlying mbed TLS crypto library. | |
* @param[out] ppKey Double indirection to EC_KEY data structure. In case *ppKey already points | |
to a key object, that object is freed first. | |
*/ | |
U16 HOSTCRYPTO_GenerateEccKey(ECCCurve_t curveType, EC_KEY** ppKey) | |
{ | |
int32_t ret = 0; | |
#if !AX_EMBEDDED | |
mbedtls_entropy_context entropy; | |
mbedtls_ctr_drbg_context ctr_drbg; | |
#endif | |
/*TODO check how to consume and destroy */ | |
mbedtls_pk_context * pKey; | |
if ( ppKey != NULL && *ppKey != NULL ) | |
{ | |
HOSTCRYPTO_FreeEccKey(ppKey); | |
*ppKey = NULL; | |
} | |
pKey = (mbedtls_pk_context *)malloc(sizeof(*pKey)); | |
mbedtls_pk_init( pKey ); | |
#if !AX_EMBEDDED | |
mbedtls_ctr_drbg_init( &ctr_drbg ); | |
mbedtls_entropy_init( &entropy ); | |
ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, | |
NULL, | |
0 ); | |
#endif | |
if (ret == 0) | |
{ | |
ret = mbedtls_pk_setup( pKey, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY) ); | |
if (ret == 0) | |
{ | |
#if !AX_EMBEDDED | |
ret = mbedtls_ecp_gen_key( curveType2GroupID(curveType), mbedtls_pk_ec( *pKey ), | |
mbedtls_ctr_drbg_random, &ctr_drbg ); | |
#else | |
ret = mbedtls_ecp_gen_key( curveType2GroupID(curveType), mbedtls_pk_ec( *pKey ), | |
&HOSTCRYPTO_GetRandom, NULL ); | |
#endif | |
if (ret == 0) | |
{ | |
*ppKey = pKey; | |
#if !AX_EMBEDDED | |
mbedtls_ctr_drbg_free( &ctr_drbg ); | |
mbedtls_entropy_free( &entropy ); | |
#endif | |
return SW_OK; | |
} | |
} | |
} | |
mbedtls_pk_free( pKey ); | |
free(pKey); | |
if ( ppKey != NULL && *ppKey != NULL ) { | |
HOSTCRYPTO_FreeEccKey(ppKey); | |
*ppKey = NULL; | |
} | |
#if !AX_EMBEDDED | |
mbedtls_ctr_drbg_free( &ctr_drbg ); | |
mbedtls_entropy_free( &entropy ); | |
#endif | |
return ERR_CRYPTO_ENGINE_FAILED; | |
} | |
/** | |
* Create an mbed TLS specific key structure and fill it up with the ECC key material contained | |
* in the crypto library agnostic \p eccKc data structure. In case \p eccKc does not contain a | |
* private key, only the public part will be copied into the mbed TLS specific key structure. | |
* | |
* @param[out] eccRef Double indirection to EC_KEY data structure. | |
* In case *ppKey already points to a key object, that object is freed first. | |
* @param[in] eccKc Data structure containing ECC key material. | |
*/ | |
U16 HOSTCRYPTO_EccCreateOpenSslEccFromComponents(EC_KEY **ppKey, eccKeyComponents_t *eccKc) | |
{ | |
int ret; | |
mbedtls_pk_context * pKey; | |
if ( ppKey != NULL && *ppKey != NULL ) | |
{ | |
HOSTCRYPTO_FreeEccKey(ppKey); | |
*ppKey = NULL; | |
} | |
pKey = (mbedtls_pk_context *) malloc(sizeof(*pKey)); | |
mbedtls_pk_init( pKey ); | |
ret = mbedtls_pk_setup( pKey, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY) ); | |
if (ret == 0) | |
{ | |
mbedtls_ecp_keypair * pEcCtx = mbedtls_pk_ec( *pKey ); | |
*ppKey = pKey; //mbedtls_pk_ec( *pKey ); | |
ret = mbedtls_ecp_group_load( &(pEcCtx->grp), curveType2GroupID(eccKc->curve) ); | |
if (ret == 0) | |
{ | |
ret = mbedtls_ecp_point_read_binary( &(pEcCtx->grp), &(pEcCtx->Q), | |
eccKc->pub, eccKc->pubLen ); | |
if (ret == 0) | |
{ | |
ret = mbedtls_mpi_read_binary( &(pEcCtx->d), eccKc->priv, eccKc->privLen ); | |
if (ret == 0) | |
{ | |
return SW_OK; | |
} | |
} | |
} | |
} | |
/* Error */ | |
free(pKey); | |
return ERR_CRYPTO_ENGINE_FAILED; | |
} | |
/** | |
* Key unwrapping according to RFC3394 (https://tools.ietf.org/html/rfc3394) | |
* \note Only tested with an 128 bits wrapKey. | |
* @param[in] wrapKey Secret key used to unwrap \p in with. Also called KEK (key encryption key) | |
* @param[in] wrapKeyLen Length in byte of wrapKey | |
* @param[in,out] out IN: buffer of at least \p outLen byte; OUT: unwrapped key | |
* @param[in,out] outLen IN: size of buffer \p out provided; OUT: actual length of unwrapped key | |
* @param[in] in Wrapped key to be unwrapped | |
* @param[in] inLen Length in byte of key to be unwrapped | |
*/ | |
U16 HOSTCRYPTO_AesUnwrapKeyRFC3394(const U8 *wrapKey, U16 wrapKeyLen, U8 *out, U16 *outLen, const U8 *in, U16 inLen) | |
{ | |
#ifdef __FUNCTION__ | |
sm_printf(CONSOLE, "Not Implemented => '" __FUNCTION__ "'.\n"); | |
#endif | |
return 0; | |
} | |
/** | |
* Key wrapping according to RFC3394 (https://tools.ietf.org/html/rfc3394) | |
* \note Only tested with an 128 bits wrapKey. When wrapping a 128 bit key (16 byte), the resulting | |
* wrapped key is 24 byte long. | |
* @param[in] wrapKey Secret key used to wrap \p in. Also called KEK (key encryption key) | |
* @param[in] wrapKeyLen Length in byte of wrapKey | |
* @param[in,out] out IN: buffer of at least \p outLen byte; OUT: wrapped key | |
* @param[in,out] outLen IN: size of buffer \p out provided; OUT: actual length of wrapped key | |
* @param[in] in Key to be wrapped | |
* @param[in] inLen Length in byte of key to be wrapped | |
*/ | |
U16 HOSTCRYPTO_AesWrapKeyRFC3394(const U8 *wrapKey, U16 wrapKeyLen, U8 *out, U16 *outLen, const U8 *in, U16 inLen) | |
{ | |
int retval = 0; | |
//mbedtls_aes_context *ctx = NULL; | |
//int keybits = wrapKeyLen * 8; | |
/*TODO Borrowed check license */ | |
retval = fast_aes_wrap(wrapKey,((inLen * 8) >> 6),in,out); | |
return retval; | |
} | |
#ifdef TGT_A71CH | |
U16 HOSTCRYPTO_HkdfExpandSha256(const U8 *secret, U16 secretLen, const U8 *info, U16 infoLen, U8 *derivedData, U16 derivedDataLen) | |
{ | |
U16 sw = SW_OK; | |
int ret; | |
const mbedtls_md_info_t *md = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); | |
ret = mbedtls_hkdf_expand(md, | |
secret, secretLen, | |
info, infoLen, | |
derivedData, derivedDataLen); | |
if (ret != 0) | |
{ | |
sw = ERR_CRYPTO_ENGINE_FAILED; | |
} | |
return sw; | |
} | |
U16 HOSTCRYPTO_HkdfFullSha256(const U8 *salt, U16 saltLen, const U8 *secret, U16 secretLen, const U8 *info, U16 infoLen, U8 *derivedData, U16 derivedDataLen) | |
{ | |
U16 sw = SW_OK; | |
int ret; | |
const mbedtls_md_info_t *md = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); | |
ret = mbedtls_hkdf(md, | |
salt, saltLen, | |
secret, secretLen, | |
info, infoLen, | |
derivedData, derivedDataLen); | |
if (ret != 0) | |
{ | |
sw = ERR_CRYPTO_ENGINE_FAILED; | |
} | |
return sw; | |
} | |
// Implements the CreatePremasterSecret functionality of RFC4279 | |
U16 HOSTCRYPTO_TlsPskCreatePremasterSecret(const U8 *secret, U16 secretLen, U8 *premasterSecret, U16 *premasterSecretLen) | |
{ | |
U16 targetLen = 0; | |
// Ensure buffer premasterSecret is big enough | |
targetLen = 2 * 2 + 2 * secretLen; | |
if (*premasterSecretLen < targetLen) | |
{ | |
return ERR_BUF_TOO_SMALL; | |
} | |
premasterSecret[0] = (U8)(secretLen >> 8); | |
premasterSecret[1] = (U8)secretLen; | |
memset(&premasterSecret[2], 0x00, secretLen); | |
premasterSecret[2+secretLen] = (U8)(secretLen >> 8); | |
premasterSecret[3+secretLen] = (U8)secretLen; | |
memcpy(&premasterSecret[4+secretLen], secret, secretLen); | |
*premasterSecretLen = targetLen; | |
return SW_OK; | |
} | |
// Implements the CreatePremasterSecret functionality of RFC5489 | |
U16 HOSTCRYPTO_TlsEcdhPskCreatePremasterSecret(const U8 *ecdhSS, U16 ecdhSSLen, const U8 *secret, U16 secretLen, U8 *premasterSecret, U16 *premasterSecretLen) | |
{ | |
U16 targetLen = 0; | |
// Ensure buffer premasterSecret is big enough | |
targetLen = 2 * 2 + ecdhSSLen + secretLen; | |
if (*premasterSecretLen < targetLen) | |
{ | |
return ERR_BUF_TOO_SMALL; | |
} | |
premasterSecret[0] = (U8)(ecdhSSLen >> 8); | |
premasterSecret[1] = (U8)ecdhSSLen; | |
memcpy(&premasterSecret[2], ecdhSS, ecdhSSLen); | |
premasterSecret[2+ecdhSSLen] = (U8)(secretLen >> 8); | |
premasterSecret[3+ecdhSSLen] = (U8)secretLen; | |
memcpy(&premasterSecret[4+ecdhSSLen], secret, secretLen); | |
*premasterSecretLen = targetLen; | |
return SW_OK; | |
} | |
U16 HOSTCRYPTO_HmacSha256(const U8 *secret, U16 secretLen, const U8 *data, U16 dataLen, U8 *hmacData) | |
{ | |
int ret; | |
U16 sw = SW_OK; | |
const mbedtls_md_info_t *md = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); | |
ret = mbedtls_md_hmac(md, secret, secretLen, data, dataLen, hmacData); | |
if (ret != 0) | |
{ | |
sw = ERR_CRYPTO_ENGINE_FAILED; | |
} | |
return sw; | |
} | |
U16 HOSTCRYPTO_Tls1_2_P_Sha256(const U8 *secret, U16 secretLen, const U8 *seed, U16 seedLen, U8 *derivedData, U16 derivedDataLen) | |
{ | |
unsigned int nPos = 0; | |
unsigned char hashed0[MBEDTLS_MD_MAX_SIZE]; | |
unsigned char hashed1[MBEDTLS_MD_MAX_SIZE]; | |
const mbedtls_md_info_t *p_mbedtls_md_info = NULL; | |
mbedtls_md_context_t ctx; | |
mbedtls_md_type_t md_type = MBEDTLS_MD_SHA256; | |
U16 bytesToCopy; | |
unsigned char digLen = 0; | |
p_mbedtls_md_info = mbedtls_md_info_from_type(md_type); | |
digLen = mbedtls_md_get_size( p_mbedtls_md_info ); | |
mbedtls_md_init(&ctx); | |
if ((mbedtls_md_setup(&ctx, p_mbedtls_md_info , 1))) //use hmac | |
goto err; | |
// First compute A(1) = HMAC(secret, SEED) | |
if ((mbedtls_md_hmac_starts(&ctx, secret, secretLen))) | |
goto err; | |
if ((mbedtls_md_hmac_update(&ctx, (const unsigned char *) seed, seedLen))) | |
goto err; | |
if ((mbedtls_md_hmac_finish(&ctx, hashed0))) | |
goto err; | |
while (derivedDataLen) | |
{ | |
// Now compute P(N) = HMAC(secret, A(N) | seed) # N > 0 | |
if (mbedtls_md_hmac_reset(&ctx)) | |
goto err; | |
if ((mbedtls_md_hmac_update(&ctx, (const unsigned char *) hashed0, digLen))) | |
goto err; | |
if ((mbedtls_md_hmac_update(&ctx, (const unsigned char *) seed, seedLen))) | |
goto err; | |
if ((mbedtls_md_hmac_finish(&ctx, hashed1 ))) | |
goto err; | |
bytesToCopy = (derivedDataLen < digLen) ? derivedDataLen : (U16)digLen; | |
memcpy(&derivedData[nPos], hashed1, bytesToCopy); | |
derivedDataLen -= bytesToCopy; | |
nPos += bytesToCopy; | |
// Compute A(N+1) and store for next round | |
if (mbedtls_md_hmac_reset(&ctx)) | |
goto err; | |
if ((mbedtls_md_hmac_update(&ctx, (const unsigned char *) hashed0, digLen))) | |
goto err; | |
if ((mbedtls_md_hmac_finish(&ctx, hashed0 ))) | |
goto err; | |
} | |
mbedtls_md_free(&ctx); | |
return SW_OK; | |
err: | |
mbedtls_md_free(&ctx); | |
return ERR_CRYPTO_ENGINE_FAILED; | |
} | |
#endif // TGT_A71CH | |
#if AX_EMBEDDED | |
#include "mbedtls/entropy_poll.h" | |
int HOSTCRYPTO_GetRandom(void *pCtx, unsigned char *output, size_t len) | |
{ | |
status_t result = kStatus_Success; | |
#if defined(FSL_FEATURE_SOC_TRNG_COUNT) && (FSL_FEATURE_SOC_TRNG_COUNT > 0) | |
#ifndef TRNG0 | |
#define TRNG0 TRNG | |
#endif | |
result = TRNG_GetRandomData(TRNG0, output, len); | |
#elif defined(FSL_FEATURE_SOC_RNG_COUNT) && (FSL_FEATURE_SOC_RNG_COUNT > 0) | |
result = RNGA_GetRandomData(RNG, (void *)output, len); | |
#elif defined(FSL_FEATURE_SOC_LPC_RNG_COUNT) && (FSL_FEATURE_SOC_LPC_RNG_COUNT > 0) | |
uint32_t rn; | |
size_t length; | |
int i; | |
length = len; | |
while (length > 0) | |
{ | |
rn = RNG_GetRandomData(); | |
if (length >= sizeof(uint32_t)) | |
{ | |
memcpy(output, &rn, sizeof(uint32_t)); | |
length -= sizeof(uint32_t); | |
output += sizeof(uint32_t); | |
} | |
else | |
{ | |
memcpy(output, &rn, length); | |
output += length; | |
len = 0U; | |
} | |
/* Discard next 32 random words for better entropy */ | |
for (i = 0; i < 32; i++) | |
{ | |
RNG_GetRandomData(); | |
} | |
} | |
result = kStatus_Success; | |
#endif | |
if (result == kStatus_Success) | |
{ | |
return 0; | |
} | |
else | |
{ | |
return result; | |
} | |
} | |
#endif |