/** * @file axHostCryptoStubs.c * @author NXP Semiconductors * @version 1.0 * @par License * * Copyright 2016 NXP * SPDX-License-Identifier: Apache-2.0 * * @par Description * Host Crypto stub implementation for the A7-series * * @par HISTORY * */ #include "axHostCrypto.h" #include "ax_util.h" #include "sm_types.h" #include "sm_printf.h" #include #include #include #include #include #include #ifdef MBEDTLS_CMAC_C # include #endif #include #include #include "mbedtls/entropy_poll.h" #include static mbedtls_cipher_context_t cipher_ctx; // Provide here your own implementation (In case crypto is required and OpenSSL is not available) S32 HOST_SHA1_Get(const U8 *msg, U32 msgLen, U8 *pHash) { mbedtls_sha1_context sha1_ctx; mbedtls_sha1_init(&sha1_ctx); #if (MBEDTLS_VERSION_NUMBER <= 0x02060000) mbedtls_sha1_starts(&sha1_ctx); mbedtls_sha1_update(&sha1_ctx,msg,msgLen); mbedtls_sha1_finish(&sha1_ctx,pHash); #else mbedtls_sha1_starts_ret(&sha1_ctx); mbedtls_sha1_update_ret(&sha1_ctx,msg,msgLen); mbedtls_sha1_finish_ret(&sha1_ctx,pHash); #endif mbedtls_sha1_free(&sha1_ctx); return HOST_CRYPTO_OK; } S32 HOST_SHA256_Get(const U8 *msg, U32 msgLen, U8 *pHash) { mbedtls_sha256_context sha256_ctx; #if (MBEDTLS_VERSION_NUMBER <= 0x02060000) mbedtls_sha256_init(&sha256_ctx); mbedtls_sha256_starts(&sha256_ctx,0); mbedtls_sha256_update(&sha256_ctx,msg,msgLen); mbedtls_sha256_finish(&sha256_ctx,pHash); mbedtls_sha256_free(&sha256_ctx); #else mbedtls_sha256_init(&sha256_ctx); mbedtls_sha256_starts_ret(&sha256_ctx,0); mbedtls_sha256_update_ret(&sha256_ctx,msg,msgLen); mbedtls_sha256_finish_ret(&sha256_ctx,pHash); mbedtls_sha256_free(&sha256_ctx); #endif return HOST_CRYPTO_OK; } S32 HOST_AES_ECB_DECRYPT(U8 *plainText, const U8 *cipherText, const U8 *decryptKey, U32 decryptKeyLen) { mbedtls_aes_context ctx; int keyLenBits = decryptKeyLen * 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 = mbedtls_aes_setkey_dec(&ctx, decryptKey, keyLenBits); if (nRet != 0) { return HOST_CRYPTO_ERROR; } nRet = mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_DECRYPT, cipherText, plainText); if (nRet != 0) { return HOST_CRYPTO_ERROR; } return HOST_CRYPTO_OK; } S32 HOST_AES_ECB_ENCRYPT(const U8 *plainText, U8 *cipherText, const U8 *encryptKey, U32 encryptKeyLen) { mbedtls_aes_context ctx; int keyLenBits = encryptKeyLen * 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 = mbedtls_aes_setkey_enc(&ctx, encryptKey, keyLenBits); if (nRet != 0) { return HOST_CRYPTO_ERROR; } nRet = mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_ENCRYPT, plainText, cipherText); if (nRet != 0) { return HOST_CRYPTO_ERROR; } return HOST_CRYPTO_OK; } S32 HOST_CMAC_Get(const U8 *pKey, U8 keySizeInBytes, const U8* pMsg, U32 msgLen, U8 *pMac) { int ret; axHcCmacCtx_t *ctx; ret = HOST_CMAC_Init(&ctx, pKey, keySizeInBytes); if (ret == HOST_CRYPTO_OK) { ret = HOST_CMAC_Update(ctx, pMsg, msgLen); if (ret == HOST_CRYPTO_OK) { ret = HOST_CMAC_Finish(ctx,pMac); } } return ret; } S32 HOST_CMAC_Init(axHcCmacCtx_t **ctx, const U8 *pKey, U8 keySizeInBytes) { int ret; const mbedtls_cipher_info_t *cipher_info; *ctx = &cipher_ctx; /*TODO CHECK mbedtls cmac does not suppot cbc but only ecb. mbedtls_cipher_cmac_starts returns error */ cipher_info = mbedtls_cipher_info_from_type( MBEDTLS_CIPHER_AES_128_ECB); if (cipher_info != NULL) { mbedtls_cipher_init(*ctx); ret = mbedtls_cipher_setup( *ctx, cipher_info ); if (ret == 0) { #ifdef MBEDTLS_CMAC_C ret = mbedtls_cipher_cmac_starts(*ctx,pKey,(keySizeInBytes * 8)); #else ret = 1; #endif if (ret == 0) { ret = HOST_CRYPTO_OK; } } } else { return ERR_MEMORY; } return ret; } S32 HOST_CMAC_Update(axHcCmacCtx_t *ctx, const U8 *pMsg, U32 msgLen) { int ret = 1; #ifdef MBEDTLS_CMAC_C ret = mbedtls_cipher_cmac_update(ctx, pMsg, msgLen); #endif if (ret == 0) { ret = HOST_CRYPTO_OK; } return ret; } S32 HOST_CMAC_Finish(axHcCmacCtx_t *ctx, U8 *pMac) { int ret = 1; #ifdef MBEDTLS_CMAC_C ret = mbedtls_cipher_cmac_finish(ctx,pMac); #endif if (ret == 0) { ret = HOST_CRYPTO_OK; } mbedtls_cipher_free(ctx); return ret; } S32 HOST_AES_CBC_Process(const U8 *pKey, U32 keyLen, const U8 *pIv, U8 dir, const U8 *pIn, U32 inLen, U8 *pOut) { int ret = HOST_CRYPTO_ERROR; mbedtls_aes_context aes_ctx; if (dir == HOST_ENCRYPT) { ret = mbedtls_aes_setkey_enc( &aes_ctx, pKey, 128 ); if (ret == 0) { ret = mbedtls_aes_crypt_cbc(&aes_ctx, MBEDTLS_AES_ENCRYPT, inLen, (unsigned char *)pIv, pIn, pOut); if (ret == 0) { ret = HOST_CRYPTO_OK; } } } else if (dir == HOST_DECRYPT) { ret = mbedtls_aes_setkey_dec( &aes_ctx, pKey, 128 ); if (ret == 0) { ret = mbedtls_aes_crypt_cbc(&aes_ctx, MBEDTLS_AES_DECRYPT, inLen, (unsigned char *)pIv, pIn, pOut); if (ret == 0) { ret = HOST_CRYPTO_OK; } } } return ret; } S32 HOST_AES_ECB_Process(const U8 *pKey, U32 keyLen, const U8 *pIv, U8 dir, const U8 *pIn, U32 inLen, U8 *pOut) { int ret = HOST_CRYPTO_ERROR; mbedtls_aes_context aes_ctx; if (dir == HOST_ENCRYPT) { ret = mbedtls_aes_setkey_enc(&aes_ctx, pKey, 128); if (ret == 0) { ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, pIn, pOut); if (ret == 0) { ret = HOST_CRYPTO_OK; } } } else if (dir == HOST_DECRYPT) { ret = mbedtls_aes_setkey_dec(&aes_ctx, pKey, 128); if (ret == 0) { ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_DECRYPT, pIn, pOut); if (ret == 0) { ret = HOST_CRYPTO_OK; } } } return ret; } S32 HOST_CMAC_Get_Des(const U8 *pKey, U8 keySizeInBytes, const U8 *pMsg, U32 msgLen, U8* pMac) { return HOST_CRYPTO_ERROR; } S32 HOST_3DES_CBC_Process(const U8 *pKey, U32 keyLen, const U8 *pIv, U8 dir, const U8 *pIn, U32 inLen, U8 *pOut) { return HOST_CRYPTO_ERROR; } S32 HOST_3DES_ECB_Process(const U8 *pKey, U32 keyLen, const U8 *pIv, U8 dir, const U8 *pIn, U32 inLen, U8 *pOut) { return HOST_CRYPTO_ERROR; } S32 HOST_GetRandom(U32 inLen, U8 *pRandom) { int nRet; #ifdef MBEDTLS_CTR_DRBG_C mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; mbedtls_entropy_init( &entropy ); mbedtls_ctr_drbg_init( &ctr_drbg ); nRet = mbedtls_ctr_drbg_seed( &ctr_drbg , mbedtls_entropy_func, &entropy, NULL, 0); if (nRet == 0) { nRet = mbedtls_ctr_drbg_random((void*)&ctr_drbg,pRandom,inLen); if (nRet == 0) { nRet = HOST_CRYPTO_OK; } } #elif AX_EMBEDDED size_t olen = 0; mbedtls_hardware_poll(NULL, pRandom, inLen, &olen); nRet = HOST_CRYPTO_OK; #else nRet = HOST_CRYPTO_ERROR; #endif return nRet; }