nt9856x/BSP/u-boot/board/novatek/common/nvt_ivot_crypto_cmd.c
2023-03-28 15:07:53 +08:00

338 lines
10 KiB
C
Executable File

/*
* Copyright (c) 2021 Novatek Inc.
*
*/
#include <common.h>
#include <memalign.h>
#include <asm/arch/nvt_crypto.h>
DECLARE_GLOBAL_DATA_PTR;
#define _ALIGNED(x) __attribute__((aligned(x)))
#define CACHE_LINE_SIZE CONFIG_SYS_CACHELINE_SIZE
static uint8_t AES_IV[] = {
0x0B, 0x7C, 0xFC, 0x71, 0x08, 0x11, 0xC2, 0x21, 0x6F, 0x4F, 0xAC, 0xBA, 0xBF, 0x4F, 0x28, 0x8B
};
static uint8_t AES_KEY[] = {
0x31, 0xD1, 0x32, 0x61, 0xBB, 0xA9, 0x28, 0xFD, 0xF6, 0x9D, 0x8D, 0xD3, 0xFB, 0xE1, 0x23, 0xEC,
0x6A, 0xAD, 0x01, 0x7D, 0x1C, 0xFC, 0xE9, 0x36, 0x05, 0x9C, 0x60, 0x1A, 0x33, 0xA5, 0x14, 0x09
};
static uint8_t _ALIGNED(CACHE_LINE_SIZE) AES_PLAINTEXT[] = {
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00
};
static uint8_t _ALIGNED(CACHE_LINE_SIZE) AES128_ECB_CIPHERTEXT[] = {
0xCB, 0x4E, 0x39, 0x2D, 0xAC, 0x11, 0x40, 0xFB, 0x4E, 0xD6, 0x31, 0xCD, 0xCC, 0x2C, 0x21, 0x7B,
0x30, 0xCF, 0xCF, 0xB5, 0xAB, 0xFD, 0x1B, 0x99, 0x19, 0xB6, 0x9F, 0x1A, 0x37, 0x51, 0x5A, 0xCA
};
static uint8_t _ALIGNED(CACHE_LINE_SIZE) AES128_CBC_CIPHERTEXT[] = {
0x83, 0xC3, 0xEF, 0x24, 0xE4, 0xD4, 0x19, 0xEE, 0x64, 0x3E, 0x8C, 0xA3, 0x98, 0x16, 0x05, 0x20,
0xBA, 0x8D, 0x5F, 0x5D, 0x13, 0xBA, 0x30, 0x5F, 0xC5, 0x4F, 0x70, 0x5C, 0x89, 0x3C, 0x3A, 0x5A
};
static uint8_t _ALIGNED(CACHE_LINE_SIZE) AES256_ECB_CIPHERTEXT[] = {
0xC6, 0xE6, 0x0C, 0xC6, 0xF1, 0x3D, 0x6C, 0x73, 0x93, 0x5A, 0x80, 0x92, 0x12, 0x14, 0x0F, 0xC5,
0xA0, 0x07, 0xDB, 0xFD, 0x63, 0xD3, 0xD2, 0x5E, 0x0B, 0x08, 0xD0, 0xD3, 0x6C, 0xA7, 0x23, 0xC3
};
static uint8_t _ALIGNED(CACHE_LINE_SIZE) AES256_CBC_CIPHERTEXT[] = {
0x3A, 0xBD, 0xEB, 0x54, 0xAA, 0x71, 0x78, 0xC8, 0xC2, 0x5E, 0xC4, 0x88, 0xA5, 0x63, 0x35, 0xBB,
0x96, 0x51, 0x5B, 0x8C, 0x84, 0x5C, 0x56, 0x1B, 0x1E, 0x94, 0x1F, 0xF3, 0x1E, 0x0B, 0x13, 0x4B
};
#ifdef CONFIG_NVT_FPGA_EMULATION
/* efuse test key */
static uint32_t EFUSE_TEST_KEY[20] = {
0x01020304, 0x05060708, 0x09101112, 0x13141516, ///< Key#0
0x9b0daa24, 0xb431aef1, 0xc4e45128, 0x1e1d71d1, ///< Key#1
0xc5814d95, 0xe52bcc5a, 0xc374c8dd, 0x5ccfaf9f, ///< Key#2
0x00000000, 0x00000000, 0x00000000, 0x00000000, ///< Key#3
0x00000000, 0x00000000, 0x00000000, 0x00000000 ///< Key#4
};
#endif
#define EFUSE_KEY_0_OFFSET 0
#define EFUSE_KEY_1_OFFSET 4
#define EFUSE_KEY_2_OFFSET 8
#define EFUSE_KEY_3_OFFSET 12
#define EFUSE_KEY_4_OFFSET 16
/******************************************************************
NA51090 efuse key section 640bit => 20 word
=============================================================
key# offset word[0] word[1] word[2] word[3]
=============================================================
key#0 [ 0] xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx => 128bit
key#1 [ 4] xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx => 128bit
key#2 [ 8] xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx => 128bit
key#3 [12] xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx => 128bit
key#4 [16] xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx => 128bit
*******************************************************************/
/**
* do_nvt_crypto() - Handle the "nvt_crypto" command-line command
* @cmdtp: Command data struct pointer
* @flag: Command flag
* @argc: Command-line argument count
* @argv: Array of command-line arguments
*
* Returns zero on success, CMD_RET_USAGE in case of misuse and negative
* on error.
*/
static int do_nvt_crypto(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
int ret = 0;
int key_size;
int opmode;
int dma_mode;
NVT_CRYPTO_KEY_SRC_T key_src;
uint32_t key_ofs;
uint8_t *ciphertext;
uint8_t _ALIGNED(CACHE_LINE_SIZE) dst_buf[32]; ///< start address must alignment to 64 for cache operation in dma mode
struct nvt_crypto_pio_t crypto;
/* Check argument */
if (argc < 6)
return CMD_RET_USAGE;
/* Key Length */
if (!strncmp(argv[1], "aes128", 6))
key_size = NVT_CRYPTO_AES_128_KEY_SIZE;
else if (!strncmp(argv[1], "aes256", 6))
key_size = NVT_CRYPTO_AES_256_KEY_SIZE;
else
return CMD_RET_USAGE;
/* OPmode */
if (!strncmp(argv[2], "ecb", 3)) {
opmode = NVT_CRYPTO_OPMODE_ECB;
ciphertext = (key_size == NVT_CRYPTO_AES_128_KEY_SIZE) ? AES128_ECB_CIPHERTEXT : AES256_ECB_CIPHERTEXT;
}
else if (!strncmp(argv[2], "cbc", 3)) {
opmode = NVT_CRYPTO_OPMODE_CBC;
ciphertext = (key_size == NVT_CRYPTO_AES_128_KEY_SIZE) ? AES128_CBC_CIPHERTEXT : AES256_CBC_CIPHERTEXT;
}
else
return CMD_RET_USAGE;
/* Key Source */
if (key_size == NVT_CRYPTO_AES_128_KEY_SIZE) {
if (!strncmp(argv[3], "ekey0", 5)) {
key_src = NVT_CRYPTO_KEY_SRC_EFUSE;
key_ofs = EFUSE_KEY_0_OFFSET;
}
else if (!strncmp(argv[3], "ekey1", 5)) {
key_src = NVT_CRYPTO_KEY_SRC_EFUSE;
key_ofs = EFUSE_KEY_1_OFFSET;
}
else if (!strncmp(argv[3], "ekey2", 5)) {
key_src = NVT_CRYPTO_KEY_SRC_EFUSE;
key_ofs = EFUSE_KEY_2_OFFSET;
}
else if (!strncmp(argv[3], "ekey3", 5)) {
key_src = NVT_CRYPTO_KEY_SRC_EFUSE;
key_ofs = EFUSE_KEY_3_OFFSET;
}
else if (!strncmp(argv[3], "ekey4", 5)) {
key_src = NVT_CRYPTO_KEY_SRC_EFUSE;
key_ofs = EFUSE_KEY_4_OFFSET;
}
else if (!strncmp(argv[3], "ukey", 4)) {
key_src = NVT_CRYPTO_KEY_SRC_DATA;
key_ofs = 0;
}
else
return CMD_RET_USAGE;
}
else {
if (!strncmp(argv[3], "ukey", 4)) {
key_src = NVT_CRYPTO_KEY_SRC_DATA;
key_ofs = 0;
}
else
return CMD_RET_USAGE;
}
/* PIO/DMA */
if (!strncmp(argv[4], "pio", 3)) {
dma_mode = 0;
}
else if (!strncmp(argv[4], "dma", 3)) {
dma_mode = 1;
}
else
return CMD_RET_USAGE;
/* Command */
if (strncmp(argv[5], "verify", 6))
return CMD_RET_USAGE;
/* Open Crypto Device */
ret = nvt_crypto_open();
if (ret < 0) {
printf("nvt crypto open failed!\n");
return CMD_RET_FAILURE;
}
if (key_src == NVT_CRYPTO_KEY_SRC_DATA) {
/* AES Encryption */
crypto.encrypt = 1;
crypto.opmode = opmode;
crypto.src = AES_PLAINTEXT;
crypto.dst = dst_buf;
crypto.key = AES_KEY;
crypto.iv = (opmode == NVT_CRYPTO_OPMODE_CBC) ? AES_IV : NULL;
crypto.key_src = key_src;
crypto.key_ofs = key_ofs;
crypto.src_size = sizeof(AES_PLAINTEXT);
crypto.dst_size = sizeof(dst_buf);
crypto.key_size = key_size;
crypto.iv_size = (opmode == NVT_CRYPTO_OPMODE_CBC) ? sizeof(AES_IV) : 0;
ret = (dma_mode) ? nvt_crypto_dma_aes(&crypto) : nvt_crypto_pio_aes(&crypto);
if (ret < 0) {
printf("nvt crypto %s %s encrypt failed!\n", argv[1], argv[2]);
ret = CMD_RET_FAILURE;
goto exit;
}
/* Output Data Compare */
if (memcmp(dst_buf, ciphertext, sizeof(dst_buf))) {
printf("nvt crypto %s %s encryption compare failed!\n", argv[1], argv[2]);
ret = CMD_RET_FAILURE;
goto exit;
}
/* AES Decryption */
crypto.encrypt = 0;
crypto.opmode = opmode;
crypto.src = ciphertext;
crypto.dst = dst_buf;
crypto.key = AES_KEY;
crypto.iv = (opmode == NVT_CRYPTO_OPMODE_CBC) ? AES_IV : NULL;
crypto.key_src = key_src;
crypto.key_ofs = key_ofs;
crypto.src_size = sizeof(dst_buf);
crypto.dst_size = sizeof(dst_buf);
crypto.key_size = key_size;
crypto.iv_size = (opmode == NVT_CRYPTO_OPMODE_CBC) ? sizeof(AES_IV) : 0;
ret = (dma_mode) ? nvt_crypto_dma_aes(&crypto) : nvt_crypto_pio_aes(&crypto);
if (ret < 0) {
printf("nvt crypto %s %s decrypt failed!\n", argv[1], argv[2]);
ret = CMD_RET_FAILURE;
goto exit;
}
/* Output Data Compare */
if (memcmp(dst_buf, AES_PLAINTEXT, sizeof(dst_buf))) {
printf("nvt crypto %s %s decryption compare failed!\n", argv[1], argv[2]);
ret = CMD_RET_FAILURE;
goto exit;
}
}
else {
uint8_t *src = NULL;
uint8_t *dst = NULL;
uint32_t data_size = 0x2000;
/* allocate source data buffer */
src = malloc_cache_aligned(data_size);
if (!src) {
printf("nvt crypto %s %s ekey verify to allocate source buffer failed!\n", argv[1], argv[2]);
ret = CMD_RET_FAILURE;
goto freemem;
}
/* allocate destination data buffer */
dst = malloc_cache_aligned(data_size);
if (!dst) {
printf("nvt crypto %s %s ekey verify to allocate destination buffer failed!\n", argv[1], argv[2]);
ret = CMD_RET_FAILURE;
goto freemem;
}
/* AES Encryption with efuse key */
crypto.encrypt = 1;
crypto.opmode = opmode;
crypto.src = src;
crypto.dst = dst;
crypto.key = NULL;
crypto.iv = (opmode == NVT_CRYPTO_OPMODE_CBC) ? AES_IV : NULL;
crypto.key_src = key_src;
crypto.key_ofs = key_ofs;
crypto.src_size = data_size;
crypto.dst_size = data_size;
crypto.key_size = key_size;
crypto.iv_size = (opmode == NVT_CRYPTO_OPMODE_CBC) ? sizeof(AES_IV) : 0;
ret = (dma_mode) ? nvt_crypto_dma_aes(&crypto) : nvt_crypto_pio_aes(&crypto);
if (ret < 0) {
printf("nvt crypto %s %s ekey encrypt failed!\n", argv[1], argv[2]);
ret = CMD_RET_FAILURE;
goto freemem;
}
/* AES Decryption with efuse test key */
crypto.encrypt = 0;
crypto.opmode = opmode;
crypto.src = dst;
crypto.dst = dst;
#ifdef CONFIG_NVT_FPGA_EMULATION
crypto.key = (uint8_t *)&EFUSE_TEST_KEY[key_ofs];
crypto.iv = (opmode == NVT_CRYPTO_OPMODE_CBC) ? AES_IV : NULL;
crypto.key_src = NVT_CRYPTO_KEY_SRC_DATA;
crypto.key_ofs = 0;
#else
crypto.key = NULL;
crypto.iv = (opmode == NVT_CRYPTO_OPMODE_CBC) ? AES_IV : NULL;
crypto.key_src = key_src;
crypto.key_ofs = key_ofs;
#endif
crypto.src_size = data_size;
crypto.dst_size = data_size;
crypto.key_size = key_size;
crypto.iv_size = (opmode == NVT_CRYPTO_OPMODE_CBC) ? sizeof(AES_IV) : 0;
ret = (dma_mode) ? nvt_crypto_dma_aes(&crypto) : nvt_crypto_pio_aes(&crypto);
if (ret < 0) {
printf("nvt crypto %s %s ekey decrypt failed!\n", argv[1], argv[2]);
ret = CMD_RET_FAILURE;
goto freemem;
}
/* Output Data Compare */
if (memcmp(src, dst, data_size)) {
printf("nvt crypto %s %s ekey decryption compare failed!\n", argv[1], argv[2]);
ret = CMD_RET_FAILURE;
goto freemem;
}
freemem:
if (src)
free(src);
if (dst)
free(dst);
if (ret != 0)
goto exit;
}
printf("nvt crypto %s %s verify passed!\n", argv[1], argv[2]);
exit:
/* Close Crypto Device */
nvt_crypto_close();
return ret;
}
/***************************************************/
U_BOOT_CMD(
nvt_crypto, 6, 0, do_nvt_crypto,
"nvt_crypto operation",
"\nnvt_crypto aes128 [ecb/cbc] [ekey0-4/ukey] [pio/dma] verify - for verify aes128 encryption/decryption"
"\nnvt_crypto aes256 [ecb/cbc] [ekey0-4/ukey] [pio/dma] verify - for verify aes256 encryption/decryption"
);