| // SPDX-License-Identifier: GPL-2.0-or-later |
| /* |
| * Copyright (C) 2023 MediaTek Inc. |
| * |
| * Author: Chris.Chou <chris.chou@mediatek.com> |
| * Ren-Ting Wang <ren-ting.wang@mediatek.com> |
| */ |
| |
| #include <crypto/aes.h> |
| #include <crypto/hash.h> |
| #include <crypto/hmac.h> |
| #include <crypto/md5.h> |
| #include <linux/delay.h> |
| |
| #include <crypto-eip/ddk/slad/api_pcl.h> |
| #include <crypto-eip/ddk/slad/api_pcl_dtl.h> |
| #include <crypto-eip/ddk/slad/api_pec.h> |
| #include <crypto-eip/ddk/slad/api_driver197_init.h> |
| |
| #include "crypto-eip/crypto-eip.h" |
| #include "crypto-eip/ddk-wrapper.h" |
| #include "crypto-eip/internal.h" |
| #include "crypto-eip/crypto-eip197-inline-ddk.h" |
| |
| static bool crypto_iotoken_create(IOToken_Input_Dscr_t * const dscr_p, |
| void * const ext_p, u32 *data_p, |
| PEC_CommandDescriptor_t * const pec_cmd_dscr) |
| { |
| int IOTokenRc; |
| |
| dscr_p->InPacket_ByteCount = pec_cmd_dscr->SrcPkt_ByteCount; |
| dscr_p->Ext_p = ext_p; |
| |
| IOTokenRc = IOToken_Create(dscr_p, data_p); |
| if (IOTokenRc < 0) { |
| CRYPTO_ERR("IOToken_Create error %d\n", IOTokenRc); |
| return false; |
| } |
| |
| pec_cmd_dscr->InputToken_p = data_p; |
| |
| return true; |
| } |
| |
| unsigned int crypto_pe_get_one(IOToken_Output_Dscr_t *const OutTokenDscr_p, |
| u32 *OutTokenData_p, |
| PEC_ResultDescriptor_t *RD_p) |
| { |
| int LoopCounter = MTK_EIP197_INLINE_NOF_TRIES; |
| int IOToken_Rc; |
| PEC_Status_t pecres; |
| |
| ZEROINIT(*OutTokenDscr_p); |
| ZEROINIT(*RD_p); |
| |
| /* Link data structures */ |
| RD_p->OutputToken_p = OutTokenData_p; |
| |
| while (LoopCounter > 0) { |
| /* Try to get the processed packet from the driver */ |
| unsigned int Counter = 0; |
| |
| pecres = PEC_Packet_Get(PEC_INTERFACE_ID, RD_p, 1, &Counter); |
| if (pecres != PEC_STATUS_OK) { |
| /* IO error */ |
| CRYPTO_ERR("PEC_Packet_Get error %d\n", pecres); |
| return 0; |
| } |
| |
| if (Counter) { |
| IOToken_Rc = IOToken_Parse(OutTokenData_p, OutTokenDscr_p); |
| if (IOToken_Rc < 0) { |
| /* IO error */ |
| CRYPTO_ERR("IOToken_Parse error %d\n", IOToken_Rc); |
| return 0; |
| } |
| |
| if (OutTokenDscr_p->ErrorCode != 0) { |
| /* Packet process error */ |
| CRYPTO_ERR("Result descriptor error 0x%x\n", |
| OutTokenDscr_p->ErrorCode); |
| return 0; |
| } |
| |
| /* packet received */ |
| return Counter; |
| } |
| |
| /* Wait for MTK_EIP197_PKT_GET_TIMEOUT_MS milliseconds */ |
| udelay(MTK_EIP197_PKT_GET_TIMEOUT_MS * 1000); |
| LoopCounter--; |
| } |
| |
| CRYPTO_ERR("Timeout when reading packet\n"); |
| |
| /* IO error (timeout, not result packet received) */ |
| return 0; |
| } |
| |
| |
| bool crypto_basic_hash(SABuilder_Auth_t HashAlgo, uint8_t *Input_p, |
| unsigned int InputByteCount, uint8_t *Output_p, |
| unsigned int OutputByteCount, bool fFinalize) |
| { |
| SABuilder_Params_Basic_t ProtocolParams; |
| SABuilder_Params_t params; |
| unsigned int SAWords = 0; |
| static uint8_t DummyAuthKey[64]; |
| int rc; |
| |
| DMABuf_Properties_t DMAProperties = {0, 0, 0, 0}; |
| DMABuf_HostAddress_t TokenHostAddress; |
| DMABuf_HostAddress_t PktHostAddress; |
| DMABuf_HostAddress_t SAHostAddress; |
| DMABuf_Status_t DMAStatus; |
| |
| DMABuf_Handle_t TokenHandle = {0}; |
| DMABuf_Handle_t PktHandle = {0}; |
| DMABuf_Handle_t SAHandle = {0}; |
| |
| unsigned int TokenMaxWords = 0; |
| unsigned int TokenHeaderWord; |
| unsigned int TokenWords = 0; |
| unsigned int TCRWords = 0; |
| void *TCRData = 0; |
| |
| TokenBuilder_Params_t TokenParams; |
| PEC_CommandDescriptor_t Cmd; |
| PEC_ResultDescriptor_t Res; |
| unsigned int count; |
| |
| u32 OutputToken[IOTOKEN_IN_WORD_COUNT]; |
| u32 InputToken[IOTOKEN_IN_WORD_COUNT]; |
| IOToken_Output_Dscr_t OutTokenDscr; |
| IOToken_Input_Dscr_t InTokenDscr; |
| void *InTokenDscrExt_p = NULL; |
| |
| #ifdef CRYPTO_IOTOKEN_EXT |
| IOToken_Input_Dscr_Ext_t InTokenDscrExt; |
| |
| ZEROINIT(InTokenDscrExt); |
| InTokenDscrExt_p = &InTokenDscrExt; |
| #endif |
| ZEROINIT(InTokenDscr); |
| ZEROINIT(OutTokenDscr); |
| |
| rc = SABuilder_Init_Basic(¶ms, &ProtocolParams, SAB_DIRECTION_OUTBOUND); |
| if (rc) { |
| CRYPTO_ERR("SABuilder_Init_Basic failed: %d\n", rc); |
| goto error_exit; |
| } |
| |
| params.AuthAlgo = HashAlgo; |
| params.AuthKey1_p = DummyAuthKey; |
| |
| if (!fFinalize) |
| params.flags |= SAB_FLAG_HASH_SAVE | SAB_FLAG_HASH_INTERMEDIATE; |
| params.flags |= SAB_FLAG_SUPPRESS_PAYLOAD; |
| ProtocolParams.ICVByteCount = OutputByteCount; |
| |
| rc = SABuilder_GetSizes(¶ms, &SAWords, NULL, NULL); |
| if (rc) { |
| CRYPTO_ERR("SA not created because of size errors: %d\n", rc); |
| goto error_exit; |
| } |
| |
| DMAProperties.fCached = true; |
| DMAProperties.Alignment = MTK_EIP197_INLINE_DMA_ALIGNMENT_BYTE_COUNT; |
| DMAProperties.Bank = MTK_EIP197_INLINE_BANK_TRANSFORM; |
| DMAProperties.Size = MAX(4*SAWords, 256); |
| |
| DMAStatus = DMABuf_Alloc(DMAProperties, &SAHostAddress, &SAHandle); |
| if (DMAStatus != DMABUF_STATUS_OK) { |
| rc = 1; |
| CRYPTO_ERR("Allocation of SA failed: %d\n", DMAStatus); |
| goto error_exit; |
| } |
| |
| rc = SABuilder_BuildSA(¶ms, (u32 *)SAHostAddress.p, NULL, NULL); |
| if (rc) { |
| CRYPTO_ERR("SA not created because of errors: %d\n", rc); |
| goto error_exit; |
| } |
| |
| rc = TokenBuilder_GetContextSize(¶ms, &TCRWords); |
| if (rc) { |
| CRYPTO_ERR("TokenBuilder_GetContextSize returned errors: %d\n", rc); |
| goto error_exit; |
| } |
| |
| TCRData = kmalloc(4 * TCRWords, GFP_KERNEL); |
| if (!TCRData) { |
| rc = 1; |
| CRYPTO_ERR("Allocation of TCR failed\n"); |
| goto error_exit; |
| } |
| |
| rc = TokenBuilder_BuildContext(¶ms, TCRData); |
| if (rc) { |
| CRYPTO_ERR("TokenBuilder_BuildContext failed: %d\n", rc); |
| goto error_exit; |
| } |
| |
| rc = TokenBuilder_GetSize(TCRData, &TokenMaxWords); |
| if (rc) { |
| CRYPTO_ERR("TokenBuilder_GetSize failed: %d\n", rc); |
| goto error_exit; |
| } |
| |
| DMAProperties.fCached = true; |
| DMAProperties.Alignment = MTK_EIP197_INLINE_DMA_ALIGNMENT_BYTE_COUNT; |
| DMAProperties.Bank = MTK_EIP197_INLINE_BANK_TOKEN; |
| DMAProperties.Size = 4*TokenMaxWords; |
| |
| DMAStatus = DMABuf_Alloc(DMAProperties, &TokenHostAddress, &TokenHandle); |
| if (DMAStatus != DMABUF_STATUS_OK) { |
| rc = 1; |
| CRYPTO_ERR("Allocation of token builder failed: %d\n", DMAStatus); |
| goto error_exit; |
| } |
| |
| DMAProperties.fCached = true; |
| DMAProperties.Alignment = MTK_EIP197_INLINE_DMA_ALIGNMENT_BYTE_COUNT; |
| DMAProperties.Bank = MTK_EIP197_INLINE_BANK_PACKET; |
| DMAProperties.Size = MAX(InputByteCount, OutputByteCount); |
| |
| DMAStatus = DMABuf_Alloc(DMAProperties, &PktHostAddress, &PktHandle); |
| if (DMAStatus != DMABUF_STATUS_OK) { |
| rc = 1; |
| CRYPTO_ERR("Allocation of source packet buffer failed: %d\n", |
| DMAStatus); |
| goto error_exit; |
| } |
| |
| rc = PEC_SA_Register(PEC_INTERFACE_ID, SAHandle, DMABuf_NULLHandle, |
| DMABuf_NULLHandle); |
| if (rc != PEC_STATUS_OK) { |
| CRYPTO_ERR("PEC_SA_Register failed: %d\n", rc); |
| goto error_exit; |
| } |
| |
| memcpy(PktHostAddress.p, Input_p, InputByteCount); |
| |
| ZEROINIT(TokenParams); |
| TokenParams.PacketFlags |= (TKB_PACKET_FLAG_HASHFIRST |
| | TKB_PACKET_FLAG_HASHAPPEND); |
| if (fFinalize) |
| TokenParams.PacketFlags |= TKB_PACKET_FLAG_HASHFINAL; |
| |
| rc = TokenBuilder_BuildToken(TCRData, (u8 *) PktHostAddress.p, |
| InputByteCount, &TokenParams, |
| (u32 *) TokenHostAddress.p, |
| &TokenWords, &TokenHeaderWord); |
| if (rc != TKB_STATUS_OK) { |
| CRYPTO_ERR("Token builder failed: %d\n", rc); |
| goto error_exit_unregister; |
| } |
| |
| ZEROINIT(Cmd); |
| Cmd.Token_Handle = TokenHandle; |
| Cmd.Token_WordCount = TokenWords; |
| Cmd.SrcPkt_Handle = PktHandle; |
| Cmd.SrcPkt_ByteCount = InputByteCount; |
| Cmd.DstPkt_Handle = PktHandle; |
| Cmd.SA_Handle1 = SAHandle; |
| Cmd.SA_Handle2 = DMABuf_NULLHandle; |
| |
| |
| #if defined(CRYPTO_IOTOKEN_EXT) |
| InTokenDscrExt.HW_Services = IOTOKEN_CMD_PKT_LAC; |
| #endif |
| InTokenDscr.TknHdrWordInit = TokenHeaderWord; |
| |
| if (!crypto_iotoken_create(&InTokenDscr, |
| InTokenDscrExt_p, |
| InputToken, |
| &Cmd)) { |
| rc = 1; |
| goto error_exit_unregister; |
| } |
| |
| rc = PEC_Packet_Put(PEC_INTERFACE_ID, &Cmd, 1, &count); |
| if (rc != PEC_STATUS_OK && count != 1) { |
| rc = 1; |
| CRYPTO_ERR("PEC_Packet_Put error: %d\n", rc); |
| goto error_exit_unregister; |
| } |
| |
| if (crypto_pe_get_one(&OutTokenDscr, OutputToken, &Res) < 1) { |
| rc = 1; |
| CRYPTO_ERR("error from crypto_pe_get_one\n"); |
| goto error_exit_unregister; |
| } |
| memcpy(Output_p, PktHostAddress.p, OutputByteCount); |
| |
| error_exit_unregister: |
| PEC_SA_UnRegister(PEC_INTERFACE_ID, SAHandle, DMABuf_NULLHandle, |
| DMABuf_NULLHandle); |
| |
| error_exit: |
| DMABuf_Release(SAHandle); |
| DMABuf_Release(TokenHandle); |
| DMABuf_Release(PktHandle); |
| |
| if (TCRData != NULL) |
| kfree(TCRData); |
| |
| return rc == 0; |
| } |
| |
| bool crypto_hmac_precompute(SABuilder_Auth_t AuthAlgo, |
| uint8_t *AuthKey_p, |
| unsigned int AuthKeyByteCount, |
| uint8_t *Inner_p, |
| uint8_t *Outer_p) |
| { |
| SABuilder_Auth_t HashAlgo; |
| unsigned int blocksize, hashsize, digestsize; |
| static uint8_t pad_block[128], hashed_key[128]; |
| unsigned int i; |
| |
| switch (AuthAlgo) { |
| case SAB_AUTH_HMAC_MD5: |
| HashAlgo = SAB_AUTH_HASH_MD5; |
| blocksize = 64; |
| hashsize = 16; |
| digestsize = 16; |
| break; |
| case SAB_AUTH_HMAC_SHA1: |
| HashAlgo = SAB_AUTH_HASH_SHA1; |
| blocksize = 64; |
| hashsize = 20; |
| digestsize = 20; |
| break; |
| case SAB_AUTH_HMAC_SHA2_224: |
| HashAlgo = SAB_AUTH_HASH_SHA2_224; |
| blocksize = 64; |
| hashsize = 28; |
| digestsize = 32; |
| break; |
| case SAB_AUTH_HMAC_SHA2_256: |
| HashAlgo = SAB_AUTH_HASH_SHA2_256; |
| blocksize = 64; |
| hashsize = 32; |
| digestsize = 32; |
| break; |
| case SAB_AUTH_HMAC_SHA2_384: |
| HashAlgo = SAB_AUTH_HASH_SHA2_384; |
| blocksize = 128; |
| hashsize = 48; |
| digestsize = 64; |
| break; |
| case SAB_AUTH_HMAC_SHA2_512: |
| HashAlgo = SAB_AUTH_HASH_SHA2_512; |
| blocksize = 128; |
| hashsize = 64; |
| digestsize = 64; |
| break; |
| default: |
| CRYPTO_ERR("Unknown HMAC algorithm\n"); |
| return false; |
| } |
| |
| memset(hashed_key, 0, blocksize); |
| if (AuthKeyByteCount <= blocksize) { |
| memcpy(hashed_key, AuthKey_p, AuthKeyByteCount); |
| } else { |
| if (!crypto_basic_hash(HashAlgo, AuthKey_p, AuthKeyByteCount, |
| hashed_key, hashsize, true)) |
| return false; |
| } |
| |
| for (i = 0; i < blocksize; i++) |
| pad_block[i] = hashed_key[i] ^ 0x36; |
| |
| if (!crypto_basic_hash(HashAlgo, pad_block, blocksize, |
| Inner_p, digestsize, false)) |
| return false; |
| |
| for (i = 0; i < blocksize; i++) |
| pad_block[i] = hashed_key[i] ^ 0x5c; |
| |
| if (!crypto_basic_hash(HashAlgo, pad_block, blocksize, |
| Outer_p, digestsize, false)) |
| return false; |
| |
| return true; |
| } |
| |
| static SABuilder_Crypto_t set_crypto_algo(struct xfrm_algo *ealg) |
| { |
| if (strcmp(ealg->alg_name, "cbc(des)") == 0) |
| return SAB_CRYPTO_DES; |
| else if (strcmp(ealg->alg_name, "cbc(aes)") == 0) |
| return SAB_CRYPTO_AES; |
| else if (strcmp(ealg->alg_name, "cbc(des3_ede)") == 0) |
| return SAB_CRYPTO_3DES; |
| |
| return SAB_CRYPTO_NULL; |
| } |
| |
| static bool set_auth_algo(struct xfrm_algo_auth *aalg, SABuilder_Params_t *params, |
| uint8_t *inner, uint8_t *outer) |
| { |
| if (strcmp(aalg->alg_name, "hmac(sha1)") == 0) { |
| params->AuthAlgo = SAB_AUTH_HMAC_SHA1; |
| inner = kcalloc(SHA1_DIGEST_SIZE, sizeof(uint8_t), GFP_KERNEL); |
| outer = kcalloc(SHA1_DIGEST_SIZE, sizeof(uint8_t), GFP_KERNEL); |
| crypto_hmac_precompute(SAB_AUTH_HMAC_SHA1, &aalg->alg_key[0], |
| aalg->alg_key_len / 8, inner, outer); |
| |
| params->AuthKey1_p = inner; |
| params->AuthKey2_p = outer; |
| } else if (strcmp(aalg->alg_name, "hmac(sha256)") == 0) { |
| params->AuthAlgo = SAB_AUTH_HMAC_SHA2_256; |
| inner = kcalloc(SHA256_DIGEST_SIZE, sizeof(uint8_t), GFP_KERNEL); |
| outer = kcalloc(SHA256_DIGEST_SIZE, sizeof(uint8_t), GFP_KERNEL); |
| crypto_hmac_precompute(SAB_AUTH_HMAC_SHA2_256, &aalg->alg_key[0], |
| aalg->alg_key_len / 8, inner, outer); |
| params->AuthKey1_p = inner; |
| params->AuthKey2_p = outer; |
| } else if (strcmp(aalg->alg_name, "hmac(sha384)") == 0) { |
| params->AuthAlgo = SAB_AUTH_HMAC_SHA2_384; |
| inner = kcalloc(SHA384_DIGEST_SIZE, sizeof(uint8_t), GFP_KERNEL); |
| outer = kcalloc(SHA384_DIGEST_SIZE, sizeof(uint8_t), GFP_KERNEL); |
| crypto_hmac_precompute(SAB_AUTH_HMAC_SHA2_384, &aalg->alg_key[0], |
| aalg->alg_key_len / 8, inner, outer); |
| params->AuthKey1_p = inner; |
| params->AuthKey2_p = outer; |
| } else if (strcmp(aalg->alg_name, "hmac(sha512)") == 0) { |
| params->AuthAlgo = SAB_AUTH_HMAC_SHA2_512; |
| inner = kcalloc(SHA512_DIGEST_SIZE, sizeof(uint8_t), GFP_KERNEL); |
| outer = kcalloc(SHA512_DIGEST_SIZE, sizeof(uint8_t), GFP_KERNEL); |
| crypto_hmac_precompute(SAB_AUTH_HMAC_SHA2_512, &aalg->alg_key[0], |
| aalg->alg_key_len / 8, inner, outer); |
| params->AuthKey1_p = inner; |
| params->AuthKey2_p = outer; |
| } else if (strcmp(aalg->alg_name, "hmac(md5)") == 0) { |
| params->AuthAlgo = SAB_AUTH_HMAC_MD5; |
| inner = kcalloc(MD5_DIGEST_SIZE, sizeof(uint8_t), GFP_KERNEL); |
| outer = kcalloc(MD5_DIGEST_SIZE, sizeof(uint8_t), GFP_KERNEL); |
| crypto_hmac_precompute(SAB_AUTH_HMAC_MD5, &aalg->alg_key[0], |
| aalg->alg_key_len / 8, inner, outer); |
| params->AuthKey1_p = inner; |
| params->AuthKey2_p = outer; |
| } else { |
| return false; |
| } |
| |
| return true; |
| } |
| |
| u32 *mtk_ddk_tr_ipsec_build(struct mtk_xfrm_params *xfrm_params, u32 ipsec_mode) |
| { |
| struct xfrm_state *xs = xfrm_params->xs; |
| SABuilder_Params_IPsec_t ipsec_params; |
| SABuilder_Status_t sa_status; |
| SABuilder_Params_t params; |
| bool set_auth_success = false; |
| unsigned int SAWords = 0; |
| uint8_t *inner, *outer; |
| |
| DMABuf_Status_t dma_status; |
| DMABuf_Properties_t dma_properties = {0, 0, 0, 0}; |
| DMABuf_HostAddress_t sa_host_addr; |
| |
| DMABuf_Handle_t sa_handle = {0}; |
| |
| sa_status = SABuilder_Init_ESP(¶ms, |
| &ipsec_params, |
| be32_to_cpu(xs->id.spi), |
| ipsec_mode, |
| SAB_IPSEC_IPV4, |
| xfrm_params->dir); |
| |
| if (sa_status != SAB_STATUS_OK) { |
| pr_err("SABuilder_Init_ESP failed\n"); |
| sa_handle.p = NULL; |
| return (u32 *) sa_handle.p; |
| } |
| |
| /* No support for aead now */ |
| if (xs->aead) { |
| CRYPTO_ERR("AEAD not supported\n"); |
| sa_handle.p = NULL; |
| return (u32 *) sa_handle.p; |
| } |
| |
| /* Add crypto key and parameters */ |
| params.CryptoAlgo = set_crypto_algo(xs->ealg); |
| params.CryptoMode = SAB_CRYPTO_MODE_CBC; |
| params.KeyByteCount = xs->ealg->alg_key_len / 8; |
| params.Key_p = xs->ealg->alg_key; |
| |
| /* Add authentication key and parameters */ |
| set_auth_success = set_auth_algo(xs->aalg, ¶ms, inner, outer); |
| if (set_auth_success != true) { |
| CRYPTO_ERR("Set Auth Algo failed\n"); |
| sa_handle.p = NULL; |
| return (u32 *) sa_handle.p; |
| } |
| |
| ipsec_params.IPsecFlags |= (SAB_IPSEC_PROCESS_IP_HEADERS |
| | SAB_IPSEC_EXT_PROCESSING); |
| if (ipsec_mode == SAB_IPSEC_TUNNEL) { |
| ipsec_params.SrcIPAddr_p = (uint8_t *) &xs->props.saddr.a4; |
| ipsec_params.DestIPAddr_p = (uint8_t *) &xs->id.daddr.a4; |
| } |
| |
| sa_status = SABuilder_GetSizes(¶ms, &SAWords, NULL, NULL); |
| if (sa_status != SAB_STATUS_OK) { |
| CRYPTO_ERR("SA not created because of size errors\n"); |
| sa_handle.p = NULL; |
| return (u32 *) sa_handle.p; |
| } |
| |
| dma_properties.fCached = true; |
| dma_properties.Alignment = MTK_EIP197_INLINE_DMA_ALIGNMENT_BYTE_COUNT; |
| dma_properties.Bank = MTK_EIP197_INLINE_BANK_TRANSFORM; |
| dma_properties.Size = SAWords * sizeof(u32); |
| |
| dma_status = DMABuf_Alloc(dma_properties, &sa_host_addr, &sa_handle); |
| if (dma_status != DMABUF_STATUS_OK) { |
| CRYPTO_ERR("Allocation of SA failed\n"); |
| /* goto error_exit; */ |
| sa_handle.p = NULL; |
| return (u32 *) sa_handle.p; |
| } |
| |
| sa_status = SABuilder_BuildSA(¶ms, (u32 *) sa_host_addr.p, NULL, NULL); |
| if (sa_status != SAB_STATUS_OK) { |
| CRYPTO_ERR("SA not created because of errors\n"); |
| sa_handle.p = NULL; |
| return (u32 *) sa_handle.p; |
| } |
| |
| kfree(inner); |
| kfree(outer); |
| return (u32 *) sa_host_addr.p; |
| } |
| |
| int mtk_ddk_pec_init(void) |
| { |
| PEC_InitBlock_t pec_init_blk = {0, 0, false}; |
| PEC_Capabilities_t pec_cap; |
| PEC_Status_t pec_sta; |
| u32 i = MTK_EIP197_INLINE_NOF_TRIES; |
| |
| while (i) { |
| pec_sta = PEC_Init(PEC_INTERFACE_ID, &pec_init_blk); |
| if (pec_sta == PEC_STATUS_OK) { |
| CRYPTO_INFO("PEC_INIT ok!\n"); |
| break; |
| } else if (pec_sta != PEC_STATUS_OK && pec_sta != PEC_STATUS_BUSY) { |
| return pec_sta; |
| } |
| |
| mdelay(MTK_EIP197_INLINE_RETRY_DELAY_MS); |
| i--; |
| } |
| |
| if (!i) { |
| CRYPTO_ERR("PEC could not be initialized: %d\n", pec_sta); |
| return pec_sta; |
| } |
| |
| pec_sta = PEC_Capabilities_Get(&pec_cap); |
| if (pec_sta != PEC_STATUS_OK) { |
| CRYPTO_ERR("PEC capability could not be obtained: %d\n", pec_sta); |
| return pec_sta; |
| } |
| |
| CRYPTO_INFO("PEC Capabilities: %s\n", pec_cap.szTextDescription); |
| |
| return 0; |
| } |
| |
| void mtk_ddk_pec_deinit(void) |
| { |
| } |