nt9856x/rtos/BSP/u-boot/drivers/crypto/nvt/na51103/na51103_rsa.c
2023-03-28 15:07:53 +08:00

360 lines
10 KiB
C
Executable File

/*
* RSA API.
*
* Support for Novatek NVT RSA Hardware acceleration.
*
* Copyright (c) 2021 Novatek Inc.
*
*/
#ifdef CONFIG_NVT_RSA
#include <common.h>
#include <asm/io.h>
#include <asm/arch/IOAddress.h>
#include <asm/arch/nvt_rsa.h>
/*************************************************************************************
* IO Read/Write Definition
*************************************************************************************/
#define IO_REG_RD(_base, _ofs) readl(_base+_ofs)
#define IO_REG_WR(_base, _ofs, _v) writel(_v, (_base+_ofs))
/*************************************************************************************
* Global Definition
*************************************************************************************/
//#define NVT_RSA_DEBUG
#define NVT_RSA_OUTPUT_REVERSE 1
#define NVT_RSA_BUFFER_LEN 512 ///< bytes, hardware internal SRAM size
#ifdef CONFIG_NVT_FPGA_EMULATION
#define NVT_RSA_TIMEOUT_USEC (1000000*60)
#else
#define NVT_RSA_TIMEOUT_USEC (1000000*10)
#endif
/*************************************************************************************
* Debug Message Print Definition
*************************************************************************************/
#ifdef NVT_RSA_DEBUG
#define rsa_dbg(...) printf("[RSA_DBG]: " __VA_ARGS__)
#else
#define rsa_dbg(...)
#endif
#define rsa_err(...) printf("[RSA_ERR]: " __VA_ARGS__)
#define rsa_inf(...) printf("[RSA_INF]: " __VA_ARGS__)
/*************************************************************************************
* Register read/write Definition
*************************************************************************************/
#define rsa_read(_oft) IO_REG_RD(IOADDR_RSA_REG_BASE, _oft)
#define rsa_write(_oft, _v) IO_REG_WR(IOADDR_RSA_REG_BASE, _oft, _v)
/*************************************************************************************
* Register Definition
*************************************************************************************/
#define NVT_RSA_CFG_REG 0x00 ///< configuration
#define NVT_RSA_CTRL_REG 0x04 ///< control
#define NVT_RSA_INT_ENB_REG 0x08 ///< interrupt enable
#define NVT_RSA_INT_STS_REG 0x0C ///< interrupt status
#define NVT_RSA_KEY_N_REG 0x10 ///< key N register
#define NVT_RSA_KEY_N_ADDR_REG 0x14 ///< key N config ram address
#define NVT_RSA_KEY_ED_REG 0x18 ///< key E/D register
#define NVT_RSA_KEY_ED_ADDR_REG 0x1C ///< key E/D config ram address
#define NVT_RSA_DATA_REG 0x20 ///< input data register
#define NVT_RSA_DATA_ADDR_REG 0x24 ///< input data config ram address
#define NVT_RSA_KEY_READ_REG 0x28 ///< rsa key readable control
#define NVT_RSA_CRC32_DEFAULT_REG 0x30 ///< crc32 default value
#define NVT_RSA_CRC32_POLY_REG 0x34 ///< crc32 polynomial parameter
#define NVT_RSA_CRC32_OUTPUT_REG 0x38 ///< rsa key crc32 result
/*************************************************************************************
* Local Definition
*************************************************************************************/
static int nvt_rsa_opened = 0;
static void nvt_rsa_platform_init(void)
{
uint32_t tmp;
/* RSA clock select, 0:PLL2(400MHz) 1:PLL13(350MHz) */
tmp = IO_REG_RD(IOADDR_CG_REG_BASE, 0x24);
tmp &= ~(0x1<<9);
IO_REG_WR(IOADDR_CG_REG_BASE, 0x24, tmp);
/* RSA master clock enable */
tmp = IO_REG_RD(IOADDR_CG_REG_BASE, 0x70);
tmp |= (0x1<<30);
IO_REG_WR(IOADDR_CG_REG_BASE, 0x70, tmp);
/* RSA program clock enable */
tmp = IO_REG_RD(IOADDR_CG_REG_BASE, 0xE0);
tmp |= (0x1<<18);
IO_REG_WR(IOADDR_CG_REG_BASE, 0xE0, tmp);
/* RSA reset disable */
tmp = IO_REG_RD(IOADDR_CG_REG_BASE, 0x94);
tmp |= (0x1<<21);
IO_REG_WR(IOADDR_CG_REG_BASE, 0x94, tmp);
/* RSA SRAM shutdown disable */
tmp = IO_REG_RD(IOADDR_TOP_REG_BASE, 0x1004);
tmp &= ~(0x1<<29);
IO_REG_WR(IOADDR_TOP_REG_BASE, 0x1004, tmp);
}
static void nvt_rsa_platform_exit(void)
{
uint32_t tmp;
/* RSA SRAM shutdown enable */
tmp = IO_REG_RD(IOADDR_TOP_REG_BASE, 0x1004);
tmp |= (0x1<<29);
IO_REG_WR(IOADDR_TOP_REG_BASE, 0x1004, tmp);
/* RSA reset enable */
tmp = IO_REG_RD(IOADDR_CG_REG_BASE, 0x94);
tmp &= ~(0x1<<21);
IO_REG_WR(IOADDR_CG_REG_BASE, 0x94, tmp);
/* RSA master clock disable */
tmp = IO_REG_RD(IOADDR_CG_REG_BASE, 0x70);
tmp &= ~(0x1<<30);
IO_REG_WR(IOADDR_CG_REG_BASE, 0x70, tmp);
}
static void nvt_rsa_reset(void)
{
uint32_t value = 0;
uint32_t cnt = 0;
/* disable rsa */
rsa_write(NVT_RSA_CTRL_REG, 0);
rsa_write(NVT_RSA_CFG_REG, 0);
/* set reset, hardware will auto clear */
rsa_write(NVT_RSA_CFG_REG, 0x01);
/* check reset done */
while ((value = rsa_read(NVT_RSA_CFG_REG)) & 0x1) {
if(cnt++ >= 3000000) ///< 3sec
break;
udelay(1);
}
/* clear status */
rsa_write(NVT_RSA_INT_STS_REG, 0x1);
if (value & 0x1) {
rsa_err("rsa hardware reset failed!!\n");
}
}
int nvt_rsa_open(void)
{
if (!nvt_rsa_opened) {
/* platform pmu init for rsa engine */
nvt_rsa_platform_init();
/* rsa engine software reset */
nvt_rsa_reset();
nvt_rsa_opened = 1;
}
return 0;
}
void nvt_rsa_close(void)
{
if (nvt_rsa_opened) {
nvt_rsa_platform_exit();
nvt_rsa_opened = 0;
}
}
int nvt_rsa_pio_normal(struct nvt_rsa_pio_t *p_rsa)
{
int i, j;
int buf_len;
uint32_t cnt;
uint32_t block_size;
uint32_t reg_value;
if (!nvt_rsa_opened) {
rsa_err("rsa engine not opened!\n");
return -1;
}
/* check parameter */
if (!p_rsa) {
rsa_err("invalid parameter\n");
return -1;
}
/* RSA internal SRAM buffer length */
buf_len = NVT_RSA_BUFFER_LEN;
rsa_dbg("RSA => key%d\n", 256<<p_rsa->key_w);
rsa_dbg("Src => addr:0x%08lx size:%u\n", (uintptr_t)p_rsa->src, p_rsa->src_size);
rsa_dbg("Dst => addr:0x%08lx size:%u\n", (uintptr_t)p_rsa->dst, p_rsa->dst_size);
rsa_dbg("Key_N => addr:0x%08lx size:%u\n", (uintptr_t)p_rsa->key_n, p_rsa->key_n_size);
rsa_dbg("Key_ED => addr:0x%08lx size:%u\n", (uintptr_t)p_rsa->key_ed, p_rsa->key_ed_size);
/* check key width */
switch (p_rsa->key_w) {
case NVT_RSA_KEY_WIDTH_256:
block_size = NVT_RSA_256_KEY_SIZE;
break;
case NVT_RSA_KEY_WIDTH_512:
block_size = NVT_RSA_512_KEY_SIZE;
break;
case NVT_RSA_KEY_WIDTH_1024:
block_size = NVT_RSA_1024_KEY_SIZE;
break;
case NVT_RSA_KEY_WIDTH_2048:
block_size = NVT_RSA_2048_KEY_SIZE;
break;
case NVT_RSA_KEY_WIDTH_4096:
block_size = NVT_RSA_4096_KEY_SIZE;
break;
default:
rsa_err("key width=%d not support\n", 256<<p_rsa->key_w);
return -1;
}
/* check source buffer and size */
if (!p_rsa->src || !p_rsa->src_size || (p_rsa->src_size > block_size)) {
rsa_err("source buffer=0x%08lx size:%u invalid\n", (uintptr_t)p_rsa->src, p_rsa->src_size);
return -1;
}
/* check destination buffer and size */
if (!p_rsa->dst || !p_rsa->dst_size || (p_rsa->dst_size < block_size)) {
rsa_err("destination buffer=0x%08lx size:%u invalid\n", (uintptr_t)p_rsa->dst, p_rsa->dst_size);
return -1;
}
/* check key_n buffer and size */
if (!p_rsa->key_n || !p_rsa->key_n_size || (p_rsa->key_n_size > block_size)) {
rsa_err("key_n buffer=0x%08lx size:%u invalid\n", (uintptr_t)p_rsa->key_n, p_rsa->key_n_size);
return -1;
}
/* check key_ed buffer and size */
if (!p_rsa->key_ed || !p_rsa->key_ed_size || (p_rsa->key_ed_size > block_size)) {
rsa_err("key_ed buffer=0x%08lx size:%u invalid\n", (uintptr_t)p_rsa->key_ed, p_rsa->key_ed_size);
return -1;
}
/* check pio busy */
if (rsa_read(NVT_RSA_INT_STS_REG) & 0x2) {
rsa_err("rsa PIO mode busy!!\n");
return -1;
}
/*
* RSA Input data byte order => big endian
* [0000] 0F 0E 0D 0C 0B 0A 09 08 07 06 05 04 03 02 01 00
*
* RSA SRAM data byte order => little endian
* [0000] 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
*/
/* set input data */
rsa_write(NVT_RSA_DATA_ADDR_REG, 0);
for (i=0; i<buf_len; i+=4) {
if (i < p_rsa->src_size) {
reg_value = 0;
for (j=0; j<4; j++) {
reg_value |= (((uint32_t)(((i+j) >= p_rsa->src_size) ? 0 : p_rsa->src[p_rsa->src_size-(i+j)-1]))<<(j*8));
}
rsa_write(NVT_RSA_DATA_REG, reg_value);
rsa_dbg("RSA In => 0x%08x\n", reg_value);
}
else {
rsa_write(NVT_RSA_DATA_REG, 0);
rsa_dbg("RSA In => 0x%08x\n", 0);
}
}
/* set key_n */
rsa_write(NVT_RSA_KEY_N_ADDR_REG, 0);
for (i=0; i<buf_len; i+=4) {
if (i < p_rsa->key_n_size) {
reg_value = 0;
for (j=0; j<4; j++) {
reg_value |= (((uint32_t)(((i+j) >= p_rsa->key_n_size) ? 0 : p_rsa->key_n[p_rsa->key_n_size-(i+j)-1]))<<(j*8));
}
rsa_write(NVT_RSA_KEY_N_REG, reg_value);
rsa_dbg("RSA Key_N => 0x%08x\n", reg_value);
}
else {
rsa_write(NVT_RSA_KEY_N_REG, 0);
rsa_dbg("RSA Key_N => 0x%08x\n", 0);
}
}
/* set key_ed */
rsa_write(NVT_RSA_KEY_ED_ADDR_REG, 0);
for (i=0; i<buf_len; i+=4) {
if (i < p_rsa->key_ed_size) {
reg_value = 0;
for (j=0; j<4; j++) {
reg_value |= (((uint32_t)(((i+j) >= p_rsa->key_ed_size) ? 0 : p_rsa->key_ed[p_rsa->key_ed_size-(i+j)-1]))<<(j*8));
}
rsa_write(NVT_RSA_KEY_ED_REG, reg_value);
rsa_dbg("RSA Key_ED=> 0x%08x\n", reg_value);
}
else {
rsa_write(NVT_RSA_KEY_ED_REG, 0);
rsa_dbg("RSA Key_ED=> 0x%08x\n", 0);
}
}
/* set key width and mode */
rsa_write(NVT_RSA_CFG_REG, ((NVT_RSA_MODE_NORMAL<<4) | (p_rsa->key_w<<1)));
/* clear status */
rsa_write(NVT_RSA_INT_STS_REG, 0x1);
/* trigger transfer */
rsa_write(NVT_RSA_CTRL_REG, 0x1);
/* polling status */
cnt = 0;
reg_value = rsa_read(NVT_RSA_INT_STS_REG);
while ((reg_value & 0x1) == 0) {
udelay(2);
reg_value = rsa_read(NVT_RSA_INT_STS_REG);
cnt++;
if ((cnt%500000) == 0)
rsa_inf("wait rsa data complete...\n");
if (cnt > NVT_RSA_TIMEOUT_USEC)
break;
}
/* copy output data to destination buffer */
if (reg_value & 0x1) {
rsa_write(NVT_RSA_DATA_ADDR_REG, 0);
for (i=0; i<block_size; i+=4) {
reg_value = rsa_read(NVT_RSA_DATA_REG);
for (j=0; j<4; j++) {
#ifdef NVT_RSA_OUTPUT_REVERSE
p_rsa->dst[block_size-(i+j)-1] = (reg_value>>(j*8))&0xff; ///< data reverse
#else
p_rsa->dst[i+j] = (reg_value>>(j*8))&0xff;
#endif
}
rsa_dbg("RSA Out => 0x%08x\n", reg_value);
}
}
else {
rsa_err("rsa PIO mode timeout!!\n");
return -1;
}
return 0;
}
#endif /* CONFIG_NVT_RSA */