【海思篇】【Hi3516DV300】九、根据OTP实现加密芯⽚功
为了保护硬件flash上的数据,防⽌被HACKED,我们产品⼤都需要⼀个加密芯⽚。⽽海思本⾝就有OTP功能,我们完全可以把它利⽤起来。此外, 我们可以在OTP⾥保存⼀些特定的信息,例如设备信息、秘钥等信息。
⽬录
本⽂代码实现参考《Hi35xx Camera Soc ⽤户指南.pdf》
1 相关寄存器定义
主要有otp时钟和otp_ctrl寄存器组
#define HAL_SET_BIT(src, bit)              ((src) |= (1<<bit))
#define HAL_CLEAR_BIT(src,bit)              ((src) &= ~(1<<bit))
#define REG_SYS_OTP_CLK_ADDR_PHY    (0x120101BC)
#define OTP_CRG_CLOCK_BIT          (0x01 << 1)
#define OTP_REG_BASE_ADDR_PHY      (0x100B0000)
#define OTP_USER_IF_BASE            g_pOtpRegBase
#define OTP_USER_WORK_MODE          (OTP_USER_IF_BASE+0x0000)
#define OTP_USER_OP_START          (OTP_USER_IF_BASE+0x0004)
#define OTP_USER_KEY_INDEX          (OTP_USER_IF_BASE+0x0008)
#define OTP_USER_KEY_DATA0          (OTP_USER_IF_BASE+0x000c)
#define OTP_USER_KEY_DATA1          (OTP_USER_IF_BASE+0x0010)
#define OTP_USER_KEY_DATA2          (OTP_USER_IF_BASE+0x0014)
#define OTP_USER_KEY_DATA3          (OTP_USER_IF_BASE+0x0018)
#define OTP_USER_KEY_DATA4          (OTP_USER_IF_BASE+0x001c)
#define OTP_USER_KEY_DATA5          (OTP_USER_IF_BASE+0x0020)
#define OTP_USER_KEY_DATA6          (OTP_USER_IF_BASE+0x0024)
长安福特多少钱#define OTP_USER_KEY_DATA7          (OTP_USER_IF_BASE+0x0028)
#define OTP_USER_KEY_DATA8          (OTP_USER_IF_BASE+0x002c)
#define OTP_USER_FLAG_VALUE        (OTP_USER_IF_BASE+0x0030)
#define OTP_USER_FLAG_INDEX        (OTP_USER_IF_BASE+0x0034)
#define OTP_USER_REV_ADDR          (OTP_USER_IF_BASE+0x0038)
#define OTP_USER_REV_WDATA          (OTP_USER_IF_BASE+0x003c)
#define OTP_USER_REV_RDATA          (OTP_USER_IF_BASE+0x0040)
#define OTP_USER_LOCK_STA0          (OTP_USER_IF_BASE+0x0044)
#define OTP_USER_LOCK_STA1          (OTP_USER_IF_BASE+0x0048)
#define OTP_USER_CTRL_STA          (OTP_USER_IF_BASE+0x004c)
2 寄存器读写函数
#define PAGE_SIZE_MASK (~(0xfff))
#define PAGE_SIZE 0x1000
#define HAL_CIPHER_ReadReg(addr, result)    (*(result) = *(volatile unsigned int *)(addr))
#define HAL_CIPHER_WriteReg(addr,result)    (*(volatile unsigned int *)(addr) = (result))
HI_VOID *g_pOtpRegBase = NULL;
static const char dev[]="/dev/mem";
HI_VOID * COMM_MMAP(HI_U32 u32RetAddr)
{
HI_S32 fd = open (dev, O_RDWR | O_SYNC);
if (fd < 0)
{
printf("open %s error!\n", dev);
return NULL;
}
/* addr align in page_size(4K) */
HI_U32 phy_addr_in_page;
HI_U32 page_diff;
phy_addr_in_page = u32RetAddr & PAGE_SIZE_MASK;
page_diff = u32RetAddr - phy_addr_in_page;
/* size in page_size */
HI_U32 size_in_page;
HI_U32 size = PAGE_SIZE;
size_in_page =((size + page_diff - 1) & PAGE_SIZE_MASK) + PAGE_SIZE;
HI_VOID *addr = mmap((void *)0, size_in_page, PROT_READ|PROT_WRITE, MAP_SHARED, fd, phy_addr_in_page); if (addr == MAP_FAILED)
{无证驾驶怎么处罚
printf("mmap @ 0x%x error!\n", phy_addr_in_page);
close(fd);
return NULL;
}
return addr+page_diff;
}
HI_VOID COMM_MUNMAP(HI_U32 u32RegAddr)
{
munmap((HI_VOID*)u32RegAddr, PAGE_SIZE);
}
3 otp初始化实现
/* OTP init */
HI_S32 HI_OTPMNG_Init(HI_VOID)
{
HI_U32 CrgValue = 0;
HI_U32 *pu32SysAddr = HI_NULL;
pu32SysAddr = COMM_MMAP(REG_SYS_OTP_CLK_ADDR_PHY);    if (pu32SysAddr == HI_NULL)
{
printf("[ERROR] u32SysAddr ioremap with nocache failed!!\n");
return HI_FAILURE;
}
HAL_CIPHER_ReadReg(pu32SysAddr, &CrgValue);
//printf("clk 0x%x\n", CrgValue);
CrgValue |= OTP_CRG_CLOCK_BIT;  /* set the bit 0, clock opened */    HAL_CIPHER_WriteReg(pu32SysAddr, CrgValue);
COMM_MUNMAP((HI_U32)pu32SysAddr);
g_pOtpRegBase = COMM_MMAP(OTP_REG_BASE_ADDR_PHY);    if (g_pOtpRegBase == HI_NULL)
{
printf("[ERROR] osal_ioremap_nocache for OTP failed!!\n");
return HI_FAILURE;
}
return HI_SUCCESS;
}
HI_VOID HI_OTPMNG_Uninit(HI_VOID)
{
if(g_pOtpRegBase)
{
COMM_MUNMAP((HI_U32)g_pOtpRegBase);
g_pOtpRegBase = NULL;
lite车}
}
4 读取otp的lock状态
HI_S32 HI_OTPMNG_GetLockStat(HI_U32 *pu32LockSta)
{
if(HI_FAILURE == HI_OTPMNG_WaitFree())
{
return HI_FAILURE;
}
if(HI_OTPMNG_SetMode(OTP_READ_LOCK_STA_MODE))
{
return HI_FAILURE;
}
HI_OTPMNG_OP_Start();
if(HI_OTPMNG_Wait_OP_done())
{
return HI_FAILURE;
在汽贸公司买车有质保吗}
HAL_CIPHER_ReadReg(OTP_USER_LOCK_STA0, pu32LockSta);    return HI_SUCCESS;
}
5 加在otp的key到加密模块
HI_S32 HI_OTPMNG_LoadCipherKey(HI_U32 opt_id)
{
奥迪s5价格if(opt_id > OTP_USER_KEY3)
{
opt_id = OTP_USER_KEY0;
}
if(HI_FAILURE == HI_OTPMNG_WaitFree())
{
return HI_FAILURE;
}
HI_OTPMNG_CHOOSE_OTP_key(opt_id);
if(HI_OTPMNG_SetMode(OTP_LOCK_CIPHER_KEY_MODE))
{
return HI_FAILURE;
}
HI_OTPMNG_OP_Start();
if(HI_FAILURE == HI_OTPMNG_Wait_OP_done())
{
return HI_FAILURE;
}
return  HI_SUCCESS;
}
6 烧写KEY、JTAGID、PASSWORD到OTP
HI_S32 HI_OTPMNG_WriteKey(HI_U32 enWhichKey, HI_U32 *pu32key, HI_U32 u32KeyArrayLen) {
HI_U32 u32LockStatus;
HI_S32 i;
if(HI_OTPMNG_GetLockStat(&u32LockStatus))
{
return HI_FAILURE;
}
if(HI_OTPMNG_Is_Locked(enWhichKey,u32LockStatus))
{
return HI_FAILURE;
}
雷诺小型suv
if(HI_OTPMNG_WaitFree())
{
return HI_FAILURE;
}
HI_OTPMNG_CHOOSE_OTP_key(enWhichKey);
for(i = 0; i < u32KeyArrayLen; i++)
{
HAL_CIPHER_WriteReg(OTP_USER_KEY_DATA0+i*4, pu32key[i]);
}
if(HI_OTPMNG_SetMode(OTP_WRITE_KEY_ID_OR_PASSWD_MODE))
{
return HI_FAILURE;
}
HI_OTPMNG_OP_Start();
return HI_OTPMNG_Wait_OP_done();
}
7 KEY、JTAGID、PASSWORD的CRC校验