HI_S32 HAL_Efuse_WriteKey(HI_U32 * p_key, HI_U32 opt_id) { HI_S32 ret = HI_SUCCESS; HI_U32 kd_ctl_mode = 0; if(s_bIsEfuseBusyFlag) return HI_FAILURE; s_bIsEfuseBusyFlag = HI_TRUE; kd_ctl_mode = KD_CTL_MODE_OPT_KEY_ADDR(opt_id) | KD_CTL_MODE_OPT_KD | KD_CTL_MODE_START; EFUSE_REG(CIPHER_KD_WKEY0) = *p_key; EFUSE_REG(CIPHER_KD_WKEY1) = *(p_key+1); EFUSE_REG(CIPHER_KD_WKEY2) = *(p_key+2); EFUSE_REG(CIPHER_KD_WKEY3) = *(p_key+3); HAL_Efuse_WaitReady(); EFUSE_REG(CIPHER_KD_CTRL) = kd_ctl_mode; if(HAL_Efuse_WaitWriteKey()) { s_bIsEfuseBusyFlag = HI_FALSE; return HI_FAILURE; } if(HAL_Efuse_GetErrStat()) { HI_ERR_CIPHER("func:%s err, efuse key is already write.\n",__FUNCTION__); ret = HI_FAILURE; } s_bIsEfuseBusyFlag = HI_FALSE; return ret; }
HI_S32 HAL_Efuse_WaitReady(HI_VOID) { U_CIPHER_KD_STA efuse_sta; HI_U32 ulStartTime = 0; HI_U32 ulLastTime = 0; HI_U32 ulDuraTime = 0; ulStartTime = osal_get_tickcount(); while(1) { efuse_sta.u32 = EFUSE_REG(CIPHER_KD_STA); if(efuse_sta.bits.ctrl_rdy && (!efuse_sta.bits.ctrl_busy1) && (!efuse_sta.bits.ctrl_busy0)) { break; } ulLastTime = osal_get_tickcount(); ulDuraTime = (ulLastTime - ulStartTime); if (ulDuraTime >= 50000 ) { HI_ERR_CIPHER("Error! efuse load key out!\n"); return HI_FAILURE; } osal_msleep(1); } return HI_SUCCESS; }
HI_S32 HAL_Efuse_WaitWriteKey(HI_VOID) { U_CIPHER_KD_STA efuse_sta; HI_U32 ulStartTime = 0; HI_U32 ulLastTime = 0; HI_U32 ulDuraTime = 0; /* wait for hash_rdy */ ulStartTime = osal_get_tickcount(); while(1) { efuse_sta.u32 = EFUSE_REG(CIPHER_KD_STA); if(efuse_sta.bits.key_wt_finish == 1) { break; } ulLastTime = osal_get_tickcount(); ulDuraTime = ulLastTime - ulStartTime; if (ulDuraTime >= 50000 ) { HI_ERR_CIPHER("Error! efuse write key time out!\n"); return HI_FAILURE; } osal_msleep(1); } return HI_SUCCESS; }
HI_S32 sample_cipher_efuse() { HI_S32 s32Ret = HI_SUCCESS; HI_U32 u32TestDataLen = 16; HI_U32 u32InputAddrPhy = 0; HI_U32 u32OutPutAddrPhy = 0; HI_U32 u32Testcached = 0; HI_U8 *pInputAddrVir = HI_NULL; HI_U8 *pOutputAddrVir = HI_NULL; HI_HANDLE hTestchnid = 0; HI_UNF_CIPHER_KEY_SRC_E enKeySrc; HI_U8 u8Key[32]; s32Ret = HI_UNF_CIPHER_Init(); if(HI_SUCCESS != s32Ret) { return HI_FAILURE; } #ifdef CIPHER_KLAD_SUPPORT enKeySrc = HI_UNF_CIPHER_KEY_SRC_KLAD_1; s32Ret = HI_UNF_CIPHER_KladEncryptKey(HI_UNF_CIPHER_KEY_SRC_EFUSE_1, HI_UNF_CIPHER_KLAD_TARGET_AES, aes_128_cbc_key, u8Key, 16); if(HI_SUCCESS != s32Ret) { HI_ERR_CIPHER("Error: Klad Encrypt Key failed!\n"); return HI_FAILURE; } if ( 0 != memcmp(u8Key, aes_128_enc_key, 16) ) { HI_ERR_CIPHER("Memcmp failed!\n"); printBuffer("clean key", aes_128_cbc_key, 16); printBuffer("encrypt key", u8Key, 16); return HI_FAILURE; } #else enKeySrc = HI_UNF_CIPHER_KEY_SRC_EFUSE_1; #endif s32Ret = HI_UNF_CIPHER_CreateHandle(&hTestchnid); if(HI_SUCCESS != s32Ret) { HI_UNF_CIPHER_DeInit(); return HI_FAILURE; } u32InputAddrPhy = (HI_U32)HI_MMZ_New(u32TestDataLen, 0, NULL, "CIPHER_BufIn"); if (0 == u32InputAddrPhy) { HI_ERR_CIPHER("Error: Get phyaddr for input failed!\n"); goto __CIPHER_EXIT__; } pInputAddrVir = HI_MMZ_Map(u32InputAddrPhy, u32Testcached); u32OutPutAddrPhy = (HI_U32)HI_MMZ_New(u32TestDataLen, 0, NULL, "CIPHER_BufOut"); if (0 == u32OutPutAddrPhy) { HI_ERR_CIPHER("Error: Get phyaddr for outPut failed!\n"); goto __CIPHER_EXIT__; } pOutputAddrVir = HI_MMZ_Map(u32OutPutAddrPhy, u32Testcached); /* For encrypt */ s32Ret = Setconfiginfo(hTestchnid, enKeySrc, HI_UNF_CIPHER_ALG_AES, HI_UNF_CIPHER_WORK_MODE_CBC, HI_UNF_CIPHER_KEY_AES_128BIT, u8Key, aes_128_cbc_IV); if(HI_SUCCESS != s32Ret) { HI_ERR_CIPHER("Set config info failed.\n"); goto __CIPHER_EXIT__; } memset(pInputAddrVir, 0x0, u32TestDataLen); memcpy(pInputAddrVir, aes_128_src_buf, u32TestDataLen); printBuffer("clear text:", aes_128_src_buf, sizeof(aes_128_src_buf)); memset(pOutputAddrVir, 0x0, u32TestDataLen); s32Ret = HI_UNF_CIPHER_Encrypt(hTestchnid, u32InputAddrPhy, u32OutPutAddrPhy, u32TestDataLen); if(HI_SUCCESS != s32Ret) { HI_ERR_CIPHER("Cipher encrypt failed.\n"); s32Ret = HI_FAILURE; goto __CIPHER_EXIT__; } printBuffer("encrypted text:", pOutputAddrVir, sizeof(aes_128_dst_buf)); /* compare */ if ( 0 != memcmp(pOutputAddrVir, aes_128_dst_buf, u32TestDataLen) ) { HI_ERR_CIPHER("Memcmp failed!\n"); s32Ret = HI_FAILURE; goto __CIPHER_EXIT__; } /* For decrypt */ memcpy(pInputAddrVir, aes_128_dst_buf, u32TestDataLen); memset(pOutputAddrVir, 0x0, u32TestDataLen); s32Ret = Setconfiginfo(hTestchnid, enKeySrc, HI_UNF_CIPHER_ALG_AES, HI_UNF_CIPHER_WORK_MODE_CBC, HI_UNF_CIPHER_KEY_AES_128BIT, u8Key, aes_128_cbc_IV); if(HI_SUCCESS != s32Ret) { HI_ERR_CIPHER("Set config info failed.\n"); goto __CIPHER_EXIT__; } printBuffer("before decrypt:", aes_128_dst_buf, sizeof(aes_128_dst_buf)); s32Ret = HI_UNF_CIPHER_Decrypt(hTestchnid, u32InputAddrPhy, u32OutPutAddrPhy, u32TestDataLen); if(HI_SUCCESS != s32Ret) { HI_ERR_CIPHER("Cipher decrypt failed.\n"); s32Ret = HI_FAILURE; goto __CIPHER_EXIT__; } printBuffer("decrypted text:", pOutputAddrVir, u32TestDataLen); /* compare */ if ( 0 != memcmp(pOutputAddrVir, aes_128_src_buf, u32TestDataLen) ) { HI_ERR_CIPHER("Memcmp failed!\n"); s32Ret = HI_FAILURE; goto __CIPHER_EXIT__; } __CIPHER_EXIT__: if (u32InputAddrPhy> 0) { HI_MMZ_Unmap(u32InputAddrPhy); HI_MMZ_Delete(u32InputAddrPhy); } if (u32OutPutAddrPhy > 0) { HI_MMZ_Unmap(u32OutPutAddrPhy); HI_MMZ_Delete(u32OutPutAddrPhy); } HI_UNF_CIPHER_DestroyHandle(hTestchnid); HI_UNF_CIPHER_DeInit(); return s32Ret; }
static HI_S32 DRV_CIPHER_Ioctl(struct file *file, HI_U32 cmd, unsigned long arg) #endif { void __user *argp = (void __user*)arg; HI_S32 Ret = 0; HI_HANDLE Cipherchn = 0; /* cipher handle */ HI_U32 softChnId = 0; /* soft channel ID */ Ret = down_interruptible(&g_CipherMutexKernel); switch(cmd) { case HI_CIPHER_CreateHandle: { HI_U32 i; spin_lock(&cipher_lock); for(i=1;i<8;i++) { if (0 == g_stCipherOsrChn[i].g_bSoftChnOpen) { break; } } if (i >= 8) { spin_unlock(&cipher_lock); Ret = HI_ERR_CIPHER_FAILED_GETHANDLE; HI_ERR_CIPHER("No more cipher chan left.\n"); break; } else /* get a free chn */ { softChnId = i; g_stCipherOsrChn[softChnId].g_bSoftChnOpen = HI_TRUE; } spin_unlock(&cipher_lock); Cipherchn = (HI_U32)((HI_ID_CIPHER <<16)+softChnId); HI_INFO_CIPHER("the softChnId and the handle are %d %#x\n", softChnId, Cipherchn); Ret = DRV_Cipher_OpenChn(softChnId); if (HI_SUCCESS != Ret) { break; } if (copy_to_user(argp, &Cipherchn, sizeof(Cipherchn))) { Ret = HI_FAILURE; break; } g_stCipherOsrChn[softChnId].pWichFile = file; Ret = HI_SUCCESS; break; } case HI_CIPHER_DestroyHandle: { Cipherchn = arg; softChnId = Cipherchn&0x00ff; CIPHER_CHECK_HANDLE(softChnId,Ret); if ((HI_FALSE == g_stCipherOsrChn[softChnId].g_bSoftChnOpen) || (g_stCipherOsrChn[softChnId].pWichFile != file )) { Ret = HI_SUCCESS; /* success on re-Destroy */ break; } g_stCipherOsrChn[softChnId].g_bSoftChnOpen = HI_FALSE; g_stCipherOsrChn[softChnId].pWichFile = NULL; Ret = DRV_Cipher_CloseChn(softChnId); break; } case HI_CIPHER_ConfigHandle: { CIPHER_Config_CTRL CIConfig; if (copy_from_user(&CIConfig, argp, sizeof(CIConfig))) { HI_ERR_CIPHER("copy data from user fail!\n"); Ret = HI_FAILURE; break; } softChnId = CIConfig.CIHandle & 0xffff; CIPHER_CHECK_HANDLE(softChnId,Ret); if ((HI_FALSE == g_stCipherOsrChn[softChnId].g_bSoftChnOpen) || (g_stCipherOsrChn[softChnId].pWichFile != file )) { Ret = HI_ERR_CIPHER_INVALID_HANDLE; break; } Ret = DRV_Cipher_ConfigChn(softChnId, &CIConfig.CIpstCtrl, DRV_CIPHER_UserCommCallBack); break; } case HI_CIPHER_Encrypt: { CIPHER_DATA_S CIData; CIPHER_TASK_S pCITask; if (copy_from_user(&CIData, argp, sizeof(CIData))) { HI_ERR_CIPHER("copy data from user fail!\n"); Ret = HI_FAILURE; break; } softChnId = CIData.CIHandle&0xffff; CIPHER_CHECK_HANDLE(softChnId,Ret); if ((HI_FALSE == g_stCipherOsrChn[softChnId].g_bSoftChnOpen) || (g_stCipherOsrChn[softChnId].pWichFile != file )) { Ret = HI_ERR_CIPHER_INVALID_HANDLE; break; } pCITask.stData2Process.u32src = CIData.ScrPhyAddr; pCITask.stData2Process.u32dest = CIData.DestPhyAddr; pCITask.stData2Process.u32length = CIData.ByteLength; pCITask.stData2Process.bDecrypt = HI_FALSE; pCITask.u32CallBackArg = softChnId; HI_INFO_CIPHER("Start to Encrypt, chnNum = %#x!\n", softChnId); g_stCipherOsrChn[softChnId].g_bDataDone = HI_FALSE; up(&g_CipherMutexKernel); /* ??? */ Ret = DRV_Cipher_CreatTask(softChnId,&pCITask, NULL, NULL); if (HI_SUCCESS != Ret) { return Ret; } //printk("\nencrypt wait channel %d queue event\n", softChnId); if (0 == wait_event_interruptible_timeout(g_stCipherOsrChn[softChnId].cipher_wait_queue, g_stCipherOsrChn[softChnId].g_bDataDone != HI_FALSE, 200)) { HI_ERR_CIPHER("Encrypt time out! \n"); return HI_FAILURE; } if(down_interruptible(&g_CipherMutexKernel)) { return -ERESTARTSYS; } HI_INFO_CIPHER("Encrypt OK, chnNum = %#x!\n", softChnId); Ret = HI_SUCCESS; break; } case HI_CIPHER_Decrypt: { CIPHER_DATA_S CIData; CIPHER_TASK_S pCITask; if (copy_from_user(&CIData, argp, sizeof(CIData))) { HI_ERR_CIPHER("copy data from user fail!\n"); Ret = HI_FAILURE; break; } softChnId = CIData.CIHandle & 0xffff; CIPHER_CHECK_HANDLE(softChnId,Ret); if ((HI_FALSE == g_stCipherOsrChn[softChnId].g_bSoftChnOpen) || (g_stCipherOsrChn[softChnId].pWichFile != file )) { Ret = HI_ERR_CIPHER_INVALID_HANDLE; break; } pCITask.stData2Process.u32src=CIData.ScrPhyAddr; pCITask.stData2Process.u32dest=CIData.DestPhyAddr; pCITask.stData2Process.u32length=CIData.ByteLength; pCITask.stData2Process.bDecrypt=HI_TRUE; pCITask.u32CallBackArg=softChnId; HI_INFO_CIPHER("Start to Decrypt, chnNum = %#x!\n", softChnId); g_stCipherOsrChn[softChnId].g_bDataDone = HI_FALSE; up(&g_CipherMutexKernel); /* ??? */ Ret = DRV_Cipher_CreatTask(softChnId,&pCITask,NULL,NULL); if (HI_SUCCESS != Ret) { return Ret; } //printk("wait channel %d queue event\n", softChnId); if (0== wait_event_interruptible_timeout(g_stCipherOsrChn[softChnId].cipher_wait_queue, g_stCipherOsrChn[softChnId].g_bDataDone != HI_FALSE, 200)) { HI_ERR_CIPHER("Decrypt time out \n"); return HI_FAILURE; } if(down_interruptible(&g_CipherMutexKernel)) { return -ERESTARTSYS; } HI_INFO_CIPHER("Decrypt OK, chnNum = %#x!\n", softChnId); Ret = HI_SUCCESS; break; } default: Ret = HI_FAILURE; HI_ERR_CIPHER("Error: Inappropriate ioctl for device. cmd=%d\n", cmd); break; } up(&g_CipherMutexKernel); return Ret; }