mirror of
https://github.com/revyos/th1520-vendor-uboot.git
synced 2026-09-18 05:12:09 +02:00
Linux_SDK_V2.0.2
Signed-off-by: devops_admin <devops_admin@alibabacloud.com>
This commit is contained in:
@@ -135,6 +135,14 @@ config FASTBOOT_CMD_OEM_FORMAT
|
||||
relies on the env variable partitions to contain the list of
|
||||
partitions as required by the gpt command.
|
||||
|
||||
config FASTBOOT_CMD_OEM_NV_OPERATION
|
||||
bool "Enable the 'oem nv get/set' command"
|
||||
help
|
||||
Add support for the "oem get/set" command from a client.
|
||||
|
||||
config FASTBOOT_ECIES_AUTH
|
||||
bool "Enabled ecies fastboot auth"
|
||||
|
||||
endif # FASTBOOT
|
||||
|
||||
endmenu
|
||||
|
||||
@@ -3,5 +3,7 @@
|
||||
obj-y += fb_common.o
|
||||
obj-y += fb_getvar.o
|
||||
obj-y += fb_command.o
|
||||
obj-$(CONFIG_FASTBOOT_ECIES_AUTH) += fb_ecies.o
|
||||
obj-$(CONFIG_FASTBOOT_FLASH_MMC) += fb_mmc.o
|
||||
obj-$(CONFIG_FASTBOOT_FLASH_NAND) += fb_nand.o
|
||||
obj-$(CONFIG_FASTBOOT_CMD_OEM_NV_OPERATION) += fb_nv_operation.o
|
||||
@@ -45,6 +45,19 @@ static void oem_format(char *, char *);
|
||||
static void oem_command(char *, char *);
|
||||
int image_have_head(unsigned long img_src_addr);
|
||||
|
||||
#if CONFIG_FASTBOOT_CMD_OEM_NV_OPERATION
|
||||
void oem_nv_get_proccess(char *cmd_parameter, char *response);
|
||||
void oem_nv_set_proccess(char *cmd_parameter, char *response);
|
||||
void oem_nv_factory_recovery_process(char *cmd_parameter, char *response);
|
||||
static void oem_nv_get(char *cmd_parameter, char *response);
|
||||
static void oem_nv_set(char *cmd_parameter, char *response);
|
||||
static void oem_fcty(char *cmd_parameter, char *response);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FASTBOOT_ECIES_AUTH
|
||||
int ecies_process_data(uint8_t * data, int data_size,char *response);
|
||||
#endif
|
||||
|
||||
static const struct {
|
||||
const char *command;
|
||||
void (*dispatch)(char *cmd_parameter, char *response);
|
||||
@@ -97,6 +110,20 @@ static const struct {
|
||||
.command = "oem command",
|
||||
.dispatch = oem_command,
|
||||
},
|
||||
#if CONFIG_FASTBOOT_CMD_OEM_NV_OPERATION
|
||||
[FASTBOOT_COMMAND_OEM_NV_GET] = {
|
||||
.command = "oem nv get",
|
||||
.dispatch = oem_nv_get,
|
||||
},
|
||||
[FASTBOOT_COMMAND_OEM_NV_SET] = {
|
||||
.command = "oem nv set",
|
||||
.dispatch = oem_nv_set,
|
||||
},
|
||||
[FASTBOOT_COMMAND_OEM_FCTY] = {
|
||||
.command = "oem fcty",
|
||||
.dispatch = oem_fcty,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -294,7 +321,90 @@ int check_image_board_id(uint8_t *image_data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hibernate_image_cleaned_flag = 0;
|
||||
void clean_hibernate_image_header(char *response)
|
||||
{
|
||||
struct blk_desc *dev_desc;
|
||||
disk_partition_t info;
|
||||
if(0x03 == hibernate_image_cleaned_flag) //already erased all
|
||||
{
|
||||
return;
|
||||
}
|
||||
dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
|
||||
if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
|
||||
fastboot_fail("invalid mmc device", response);
|
||||
return;
|
||||
}
|
||||
char * buf = memalign(CONFIG_SYS_CACHELINE_SIZE,4096);
|
||||
if(!buf) {
|
||||
printf(" mem alloc for hibernate partition header failed!\n");
|
||||
return;
|
||||
}
|
||||
/* if fastresume partition exists, earse the old image header */
|
||||
if(part_get_info_by_name(dev_desc, "fastresume", &info)) {
|
||||
printf(" find fastresume partition , erase the header:\n");
|
||||
memset(buf,0xff,4096);
|
||||
if(blk_dwrite(dev_desc, info.start, 4096/info.blksz, buf) != 4096/info.blksz)
|
||||
{
|
||||
printf(" fastresume header write failed!\n");
|
||||
hibernate_image_cleaned_flag = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
hibernate_image_cleaned_flag |= 0x1;
|
||||
}
|
||||
}
|
||||
/* if swap partition exists, earse the old image header */
|
||||
if(part_get_info_by_name(dev_desc, "swap", &info)) {
|
||||
printf(" find swap partition , erase the header:\n");
|
||||
memset(buf,0xff,4096);
|
||||
if(blk_dwrite(dev_desc, info.start, 4096/info.blksz, buf) != 4096/info.blksz)
|
||||
{
|
||||
printf(" swap header write failed!\n");
|
||||
hibernate_image_cleaned_flag = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
hibernate_image_cleaned_flag |= 0x2;
|
||||
}
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
|
||||
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
|
||||
void fasboot_uboot_write_process(void *buf, char *response)
|
||||
{
|
||||
char cmdbuf[32];
|
||||
u32 block_cnt;
|
||||
struct blk_desc *dev_desc;
|
||||
int ret = 0;
|
||||
disk_partition_t info;
|
||||
|
||||
ret = check_image_board_id(buf);
|
||||
if (ret != 0) {
|
||||
fastboot_fail("U-BOOT image does not match the type of BOARD", response);
|
||||
return;
|
||||
}
|
||||
|
||||
dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
|
||||
if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
|
||||
fastboot_fail("invalid mmc device", response);
|
||||
return;
|
||||
}
|
||||
|
||||
run_command("mmc partconf 0 1 0 1", 0);
|
||||
|
||||
block_cnt = image_size / BLOCK_SIZE;
|
||||
if (image_size % BLOCK_SIZE) {
|
||||
block_cnt = block_cnt +1;
|
||||
}
|
||||
|
||||
sprintf(cmdbuf, "mmc write 0x%p 0 %x", buf, block_cnt);
|
||||
|
||||
run_command(cmdbuf, 0);
|
||||
run_command("mmc partconf 0 1 0 0", 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* flash() - write the downloaded image to the indicated partition.
|
||||
*
|
||||
@@ -308,36 +418,10 @@ static void flash(char *cmd_parameter, char *response)
|
||||
{
|
||||
#ifdef THEAD_LIGHT_FASTBOOT
|
||||
char cmdbuf[32];
|
||||
u32 block_cnt;
|
||||
struct blk_desc *dev_desc;
|
||||
disk_partition_t info;
|
||||
int ret = 0;
|
||||
|
||||
if (strcmp(cmd_parameter, "uboot") == 0) {
|
||||
ret = check_image_board_id(fastboot_buf_addr);
|
||||
if (ret != 0) {
|
||||
fastboot_fail("U-BOOT image does not match the type of BOARD", response);
|
||||
return;
|
||||
}
|
||||
|
||||
dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
|
||||
if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
|
||||
fastboot_fail("invalid mmc device", response);
|
||||
return;
|
||||
}
|
||||
|
||||
run_command("mmc partconf 0 1 0 1", 0);
|
||||
|
||||
block_cnt = image_size / BLOCK_SIZE;
|
||||
if (image_size % BLOCK_SIZE) {
|
||||
block_cnt = block_cnt +1;
|
||||
}
|
||||
|
||||
sprintf(cmdbuf, "mmc write 0x%p 0 %x", fastboot_buf_addr, block_cnt);
|
||||
|
||||
run_command(cmdbuf, 0);
|
||||
run_command("mmc partconf 0 1 0 0", 0);
|
||||
|
||||
fasboot_uboot_write_process(fastboot_buf_addr, response);
|
||||
} else if ((strcmp(cmd_parameter, "fw") == 0)) {
|
||||
memcpy((void *)LIGHT_FW_ADDR, fastboot_buf_addr, image_size);
|
||||
} else if ((strcmp(cmd_parameter, "uImage") == 0)) {
|
||||
@@ -352,13 +436,15 @@ static void flash(char *cmd_parameter, char *response)
|
||||
memcpy((void *)LIGHT_TF_FW_ADDR, fastboot_buf_addr, image_size);
|
||||
} else if ((strcmp(cmd_parameter, TEE_PART_NAME) == 0)) {
|
||||
memcpy((void *)LIGHT_TEE_FW_ADDR, fastboot_buf_addr, image_size);
|
||||
} else if ((strcmp(cmd_parameter, "boot") == 0)) {
|
||||
}
|
||||
#ifdef CONFIG_RV_BOOK
|
||||
else if ((strcmp(cmd_parameter, "boot") == 0)) {
|
||||
dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
|
||||
if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
|
||||
fastboot_fail("invalid mmc device", response);
|
||||
return;
|
||||
}
|
||||
/* if fastresume partition exists, earse the old image header */
|
||||
fastboot_fail("invalid mmc device", response);
|
||||
return;
|
||||
}
|
||||
/* if fastresume partition exists, earse the old image header */
|
||||
if(part_get_info_by_name(dev_desc, "fastresume", &info)) {
|
||||
printf(" find fastresume partition , erase the header:\n");
|
||||
char * buf = memalign(CONFIG_SYS_CACHELINE_SIZE,4096);
|
||||
@@ -371,6 +457,22 @@ static void flash(char *cmd_parameter, char *response)
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_FASTBOOT_ECIES_AUTH
|
||||
else if ((strcmp(cmd_parameter, "ecies") == 0)) {
|
||||
ecies_process_data(fastboot_buf_addr, image_size,response);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
//If version is updated, hibernate image may not compatible with current,erase it.
|
||||
if ((strcmp(cmd_parameter, "boot") == 0)
|
||||
|| (strcmp(cmd_parameter, "uboot") == 0)
|
||||
|| (strcmp(cmd_parameter, "root") == 0)) {
|
||||
|
||||
clean_hibernate_image_header(response);
|
||||
}
|
||||
|
||||
if(strcmp(cmd_parameter, "uboot") == 0 || (strcmp(cmd_parameter, "fw") == 0) ||
|
||||
(strcmp(cmd_parameter, "uImage") == 0) || (strcmp(cmd_parameter, "dtb") == 0) ||
|
||||
(strcmp(cmd_parameter, "rootfs") == 0) || (strcmp(cmd_parameter, "aon") == 0)) {
|
||||
@@ -380,54 +482,7 @@ static void flash(char *cmd_parameter, char *response)
|
||||
#endif
|
||||
|
||||
#if CONFIG_IS_ENABLED(LIGHT_SEC_UPGRADE)
|
||||
if(strcmp(cmd_parameter, TF_IMG_UPD_NAME) == 0) {
|
||||
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
|
||||
/* tee/tf/uboot image must be written into stash partition */
|
||||
sprintf(cmdbuf, "%s", STASH_PART_NAME);
|
||||
fastboot_mmc_flash_write(cmdbuf, fastboot_buf_addr, image_size, response);
|
||||
#endif
|
||||
/* Send ACK to host */
|
||||
fastboot_okay(NULL, response);
|
||||
|
||||
/* set secure upgrade flag to indicate it is TF image upgrade*/
|
||||
sprintf(cmdbuf,"env set sec_upgrade_mode 0x%x", TF_SEC_UPGRADE_FLAG);
|
||||
run_command(cmdbuf, 0);
|
||||
run_command("saveenv", 0);
|
||||
run_command("reset", 0);
|
||||
return;
|
||||
} else if (strcmp(cmd_parameter, TEE_IMG_UPD_NAME) == 0) {
|
||||
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
|
||||
/* tee/tf/uboot image must be written into stash partition */
|
||||
sprintf(cmdbuf, "%s", STASH_PART_NAME);
|
||||
fastboot_mmc_flash_write(cmdbuf, fastboot_buf_addr, image_size, response);
|
||||
#endif
|
||||
|
||||
/* Send ACK to host */
|
||||
fastboot_okay(NULL, response);
|
||||
|
||||
/* set secure upgrade flag to indicate it is TEE image upgrade*/
|
||||
sprintf(cmdbuf,"env set sec_upgrade_mode 0x%x", TEE_SEC_UPGRADE_FLAG);
|
||||
run_command(cmdbuf, 0);
|
||||
run_command("saveenv", 0);
|
||||
run_command("reset", 0);
|
||||
return;
|
||||
} else if (strcmp(cmd_parameter, SBMETA_IMG_UPD_NAME) == 0) {
|
||||
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
|
||||
/* tee/tf/uboot image must be written into stash partition */
|
||||
sprintf(cmdbuf, "%s", STASH_PART_NAME);
|
||||
fastboot_mmc_flash_write(cmdbuf, fastboot_buf_addr, image_size, response);
|
||||
#endif
|
||||
|
||||
/* Send ACK to host */
|
||||
fastboot_okay(NULL, response);
|
||||
|
||||
/* set secure upgrade flag to indicate it is TEE image upgrade*/
|
||||
sprintf(cmdbuf,"env set sec_upgrade_mode 0x%x", SBMETA_SEC_UPGRADE_FLAG);
|
||||
run_command(cmdbuf, 0);
|
||||
run_command("saveenv", 0);
|
||||
run_command("reset", 0);
|
||||
return;
|
||||
} else if (strcmp(cmd_parameter, UBOOT_IMG_UPD_NAME) == 0) {
|
||||
if (strcmp(cmd_parameter, UBOOT_IMG_UPD_NAME) == 0) {
|
||||
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
|
||||
|
||||
env_set_hex("ubootupdsize", image_size);
|
||||
@@ -530,3 +585,38 @@ static void oem_command(char *cmd_parameter, char *response)
|
||||
else
|
||||
fastboot_okay(NULL, response);
|
||||
}
|
||||
|
||||
#if CONFIG_FASTBOOT_CMD_OEM_NV_OPERATION
|
||||
/**
|
||||
* oem_nv_get() - Execute the OEM NV GET command
|
||||
*
|
||||
* @cmd_parameter: Pointer to command parameter
|
||||
* @response: Pointer to fastboot response buffer
|
||||
*/
|
||||
static void oem_nv_get(char *cmd_parameter, char *response)
|
||||
{
|
||||
oem_nv_get_proccess(cmd_parameter,response);
|
||||
}
|
||||
|
||||
/**
|
||||
* oem_nv_set() - Execute the OEM NV Set command
|
||||
*
|
||||
* @cmd_parameter: Pointer to command parameter
|
||||
* @response: Pointer to fastboot response buffer
|
||||
*/
|
||||
static void oem_nv_set(char *cmd_parameter, char *response)
|
||||
{
|
||||
oem_nv_set_proccess(cmd_parameter,response);
|
||||
}
|
||||
|
||||
/**
|
||||
* oem_fcty() - Execute the OEM fcty command
|
||||
*
|
||||
* @cmd_parameter: Pointer to command parameter
|
||||
* @response: Pointer to fastboot response buffer
|
||||
*/
|
||||
static void oem_fcty(char *cmd_parameter, char *response)
|
||||
{
|
||||
oem_nv_factory_recovery_process(cmd_parameter,response);
|
||||
}
|
||||
#endif
|
||||
198
drivers/fastboot/fb_ecies.c
Normal file
198
drivers/fastboot/fb_ecies.c
Normal file
@@ -0,0 +1,198 @@
|
||||
#include <sec_ecies_session.h>
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <env.h>
|
||||
#include <fastboot.h>
|
||||
#include <fastboot-internal.h>
|
||||
#include <fb_mmc.h>
|
||||
#include <fb_nand.h>
|
||||
#include <part.h>
|
||||
#include <stdlib.h>
|
||||
#include <csi_sec_img_verify.h>
|
||||
|
||||
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
|
||||
extern void fasboot_uboot_write_process(void *buf, char *response);
|
||||
#define MAX_ECIES_IMAGE_SIZE (9*1024*1024)
|
||||
#define ECIES_MALLOC_START (MAX_ECIES_IMAGE_SIZE * 2)
|
||||
|
||||
typedef struct {
|
||||
uint32_t magic;
|
||||
uint32_t file_size;
|
||||
char partition_name[64];
|
||||
} __attribute__((__packed__)) send_file_info_t;
|
||||
|
||||
static uint32_t ecies_file_pos = 0;
|
||||
static int slave_init = 0;
|
||||
|
||||
static int current_pos = 0;
|
||||
|
||||
void *csi_ecies_malloc(uint32_t size)
|
||||
{
|
||||
void * ptr = NULL;
|
||||
|
||||
if (current_pos + size >= CONFIG_FASTBOOT_BUF_SIZE) {
|
||||
current_pos = 0;
|
||||
}
|
||||
|
||||
ptr = (void *)(long)(CONFIG_FASTBOOT_BUF_ADDR + ECIES_MALLOC_START + current_pos);
|
||||
current_pos += size;
|
||||
return ptr;
|
||||
};
|
||||
|
||||
void csi_ecies_free(void *buffer)
|
||||
{
|
||||
return;
|
||||
};
|
||||
|
||||
static int ecies_data_write(uint8_t *buf,uint8_t *data,int data_len)
|
||||
{
|
||||
char response[FASTBOOT_RESPONSE_LEN];
|
||||
|
||||
if (data_len == 0 || buf == NULL || data == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(buf + ecies_file_pos,data,data_len);
|
||||
ecies_file_pos += data_len;
|
||||
if (ecies_file_pos == sizeof(send_file_info_t) + ((send_file_info_t *)buf)->file_size) {
|
||||
if (strcmp(((send_file_info_t *)buf)->partition_name, TEE_PART_NAME) == 0) {
|
||||
memcpy((void *)LIGHT_TEE_FW_ADDR, buf + sizeof(send_file_info_t), ((send_file_info_t *)buf)->file_size);
|
||||
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
|
||||
fastboot_mmc_flash_write(((send_file_info_t *)buf)->partition_name, buf + sizeof(send_file_info_t), ((send_file_info_t *)buf)->file_size,
|
||||
response);
|
||||
#endif
|
||||
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
|
||||
fastboot_nand_flash_write(((send_file_info_t *)buf)->partition_name, buf + sizeof(send_file_info_t), ((send_file_info_t *)buf)->file_size,
|
||||
response);
|
||||
#endif
|
||||
} else if (strcmp(((send_file_info_t *)buf)->partition_name, UBOOT_PART_NAME) == 0) {
|
||||
fasboot_uboot_write_process(buf + sizeof(send_file_info_t),response);
|
||||
} else {
|
||||
printf("unknown partition name\n");
|
||||
return -2;
|
||||
}
|
||||
|
||||
ecies_file_pos = 0;
|
||||
} else if(ecies_file_pos > sizeof(send_file_info_t) + ((send_file_info_t *)buf)->file_size) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hex_to_str(char *dest, const uint8_t *src, int len)
|
||||
{
|
||||
char ddl = 0;
|
||||
char ddh = 0;
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
ddh = 48 + src[i] / 16;
|
||||
ddl = 48 + src[i] % 16;
|
||||
|
||||
if (ddh > 57) {
|
||||
ddh = ddh + 7;
|
||||
}
|
||||
|
||||
if (ddl > 57) {
|
||||
ddl = ddl + 7;
|
||||
}
|
||||
|
||||
dest[i * 2] = ddh;
|
||||
dest[i * 2 + 1] = ddl;
|
||||
}
|
||||
|
||||
dest[len * 2] = '\0';
|
||||
}
|
||||
|
||||
int ecies_process_data(uint8_t * data, int data_size,char *response)
|
||||
{
|
||||
static ecies_session_t ss_slave;
|
||||
char apduResponse[ECIES_INIT_RESPONSE_LEN] = {0};
|
||||
uint8_t *plaintext = csi_ecies_malloc(MAX_ECIES_IMAGE_SIZE);
|
||||
uint32_t plaintextLen = 0;
|
||||
uint32_t apduResponseLen = 0;
|
||||
int ret = 0;
|
||||
uint8_t cla = 0;
|
||||
uint8_t errcode = 0;
|
||||
|
||||
if (plaintext == NULL) {
|
||||
ret = -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!slave_init) {
|
||||
csi_sec_library_init();
|
||||
ret = hal_ecies_slave_init(&ss_slave);
|
||||
if (ret != 0) {
|
||||
strcpy(response,"hal_ecies_slave_init ERROR");
|
||||
ret = -2;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
ret = hal_ecies_slave_session_comm(&ss_slave, data, data_size, (uint8_t *)apduResponse, &apduResponseLen, plaintext, &plaintextLen);
|
||||
if (ret != 0) {
|
||||
ret = hal_ecies_status_get((uint8_t *)apduResponse, apduResponseLen, &cla, &errcode);
|
||||
if (ret != 0) {
|
||||
strcpy(response,"hal_ecies_errcode_get ERROR");
|
||||
ret = -3;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (cla == ECIES_CLA_INITIALIZE_UPDATE_RESPONSE && errcode == ECIES_RESPONSE_SESSION_OPENED_ERROR) {
|
||||
slave_init = 0;
|
||||
ecies_file_pos = 0;
|
||||
hal_ecies_slave_uninit(&ss_slave);
|
||||
ret = hal_ecies_slave_init(&ss_slave);
|
||||
if (ret != 0) {
|
||||
strcpy(response,"hal_ecies_slave_init ERROR");
|
||||
ret = -4;
|
||||
goto end;
|
||||
}
|
||||
ret = hal_ecies_slave_session_comm(&ss_slave, data, data_size, (uint8_t*)apduResponse, &apduResponseLen, plaintext, &plaintextLen);
|
||||
if (ret != 0) {
|
||||
strcpy(response,"hal_ecies_slave_session_comm ERROR");
|
||||
ret = -5;
|
||||
goto end;
|
||||
}
|
||||
} else if(errcode != ECIES_RESPONSE_OK) {
|
||||
if (errcode == ECIES_CLA_SDATA_SEND_RESPONSE) {
|
||||
strcpy(response,"ECIES_CLA_SDATA_SEND_RESPONSE ERROR");
|
||||
ret = -6;
|
||||
goto end;
|
||||
} else if (errcode == ECIES_CLA_SESSION_CLOSE) {
|
||||
strcpy(response,"ECIES_CLA_SESSION_CLOSE ERROR");
|
||||
ret = -7;
|
||||
goto end;
|
||||
} else if (errcode == ECIES_CLA_INITIALIZE_UPDATE) {
|
||||
strcpy(response,"ECIES_CLA_INITIALIZE_UPDATE ERROR");
|
||||
ret = -8;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (slave_init && plaintextLen) {
|
||||
ret = ecies_data_write((uint8_t*)(long)(CONFIG_FASTBOOT_BUF_ADDR + MAX_ECIES_IMAGE_SIZE),plaintext,plaintextLen);
|
||||
if (ret != 0) {
|
||||
strcpy(response,"ecies_data_write ERROR");
|
||||
ret = -8;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
slave_init = 1;
|
||||
|
||||
strcpy(response,"SUCCESS:");
|
||||
hex_to_str(response + strlen(response),(uint8_t*)apduResponse,apduResponseLen);
|
||||
ret = 0;
|
||||
end:
|
||||
if (plaintext) {
|
||||
csi_ecies_free(plaintext);
|
||||
plaintext = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
342
drivers/fastboot/fb_nv_operation.c
Normal file
342
drivers/fastboot/fb_nv_operation.c
Normal file
@@ -0,0 +1,342 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <common.h>
|
||||
#include <fb_mmc.h>
|
||||
#include <command.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/types.h>
|
||||
#include <configs/light-c910.h>
|
||||
#include <thead/clock_config.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <asm/arch-thead/light-iopmp.h>
|
||||
#include "../lib/sec_library/include/soc.h"
|
||||
|
||||
#define MAX_NV_NUMBER_SIZE 32
|
||||
#define MAX_NV_DATA_SIZE 128
|
||||
#define NV_BLOCK_SIZE 512
|
||||
|
||||
extern int32_t wj_efuse_get_lc(long unsigned int, int *lc);
|
||||
|
||||
typedef enum {
|
||||
FB_SYS_ACTION_FACTORY_RECOVER,
|
||||
FB_SYS_ACTION_READ_EFUSE,
|
||||
} fb_sys_action_t;
|
||||
|
||||
static int nv_get(uint8_t *data,int offset,int data_len)
|
||||
{
|
||||
struct blk_desc *dev_desc;
|
||||
struct disk_partition part_info;
|
||||
ulong block_start;
|
||||
uint8_t data_nv[NV_BLOCK_SIZE] = {0};
|
||||
int ret;
|
||||
int n;
|
||||
|
||||
dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
|
||||
if (dev_desc == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = part_get_info_by_name(dev_desc, NV_PARTITION_NAME, &part_info);
|
||||
if (ret < 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
if(NV_BLOCK_SIZE != dev_desc->blksz) {
|
||||
return -4;
|
||||
}
|
||||
|
||||
block_start = part_info.start + offset / dev_desc->blksz;
|
||||
n = blk_dread(dev_desc, block_start, 1, data_nv);
|
||||
if (n != 1) {
|
||||
return -5;
|
||||
}
|
||||
|
||||
memcpy(data,data_nv + offset % NV_BLOCK_SIZE,data_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nv_set(uint8_t *data,int offset,int data_len)
|
||||
{
|
||||
struct blk_desc *dev_desc;
|
||||
struct disk_partition part_info;
|
||||
ulong block_start;
|
||||
uint8_t data_nv[NV_BLOCK_SIZE] = {0};
|
||||
int ret;
|
||||
int n;
|
||||
|
||||
|
||||
dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
|
||||
if (dev_desc == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = part_get_info_by_name(dev_desc, NV_PARTITION_NAME, &part_info);
|
||||
if (ret < 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (NV_BLOCK_SIZE != dev_desc->blksz) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
block_start = part_info.start + offset / dev_desc->blksz;
|
||||
|
||||
n = blk_dread(dev_desc, block_start, 1, data_nv);
|
||||
if (n != 1) {
|
||||
return -4;
|
||||
}
|
||||
memcpy(data_nv + offset % NV_BLOCK_SIZE,data,data_len);
|
||||
n = blk_dwrite(dev_desc, block_start, 1, data_nv);
|
||||
if (n != 1) {
|
||||
return -5;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int factory_recovery(char *response)
|
||||
{
|
||||
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
|
||||
fastboot_mmc_erase("metadata", response);
|
||||
if (strcmp(response, "OKAY") != 0) {
|
||||
return -1;
|
||||
}
|
||||
fastboot_mmc_erase("misc", response);
|
||||
if (strcmp(response, "OKAY") != 0) {
|
||||
return -2;
|
||||
}
|
||||
#endif
|
||||
#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
|
||||
fastboot_nand_erase("metadata", response);
|
||||
if (strcmp(response, "OKAY") != 0) {
|
||||
return -3;
|
||||
}
|
||||
fastboot_nand_erase("misc", response);
|
||||
if (strcmp(response, "OKAY") != 0) {
|
||||
return -4;
|
||||
}
|
||||
#endif
|
||||
|
||||
strcpy(response,"OKAY");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_efuse_status(char *response)
|
||||
{
|
||||
int ret;
|
||||
int lc = 0;
|
||||
ret = wj_efuse_get_lc(WJ_EFUSE_BASE, &lc);
|
||||
if (ret) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(lc == 0) {
|
||||
strcpy(response,"LC_INIT");
|
||||
} else {
|
||||
strcpy(response,"LC_BLOWNED");
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int sys_action(int flag,char *response)
|
||||
{
|
||||
if (flag == FB_SYS_ACTION_FACTORY_RECOVER) {
|
||||
return factory_recovery(response);
|
||||
} else if (flag == FB_SYS_ACTION_READ_EFUSE) {
|
||||
return read_efuse_status(response);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int toupper(int c)
|
||||
{
|
||||
if (c >= 'a' && c <= 'z') {
|
||||
return c - 32;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static void str_to_hex(uint8_t *dest, const char *src, int len)
|
||||
{
|
||||
char h1, h2;
|
||||
unsigned char s1, s2;
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
h1 = src[2 * i];
|
||||
h2 = src[2 * i + 1];
|
||||
s1 = toupper(h1) - 48;
|
||||
s2 = toupper(h2) - 48;
|
||||
if (s1 > 9) {
|
||||
s1 = s1 - 7;
|
||||
}
|
||||
|
||||
if (s2 > 9) {
|
||||
s2 = s2 - 7;
|
||||
}
|
||||
|
||||
dest[i] = s1 * 16 + s2;
|
||||
}
|
||||
}
|
||||
|
||||
static void hex_to_str(char *dest, const uint8_t *src, int len)
|
||||
{
|
||||
char ddl = 0;
|
||||
char ddh = 0;
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
ddh = 48 + src[i] / 16;
|
||||
ddl = 48 + src[i] % 16;
|
||||
|
||||
if (ddh > 57) {
|
||||
ddh = ddh + 7;
|
||||
}
|
||||
|
||||
if (ddl > 57) {
|
||||
ddl = ddl + 7;
|
||||
}
|
||||
|
||||
dest[i * 2] = ddh;
|
||||
dest[i * 2 + 1] = ddl;
|
||||
}
|
||||
|
||||
dest[len * 2] = '\0';
|
||||
}
|
||||
|
||||
static int char_to_int(char *data,int *out)
|
||||
{
|
||||
*out = 0;
|
||||
while(*data) {
|
||||
if(*data < '0' || *data > '9')
|
||||
return -1;
|
||||
|
||||
*out = *out * 10 + (*data - '0');
|
||||
++data;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#if CONFIG_FASTBOOT_CMD_OEM_NV_OPERATION
|
||||
void oem_nv_factory_recovery_process(char *cmd_parameter, char *response)
|
||||
{
|
||||
int ret = 0;
|
||||
int flag = 0;
|
||||
|
||||
ret = char_to_int(cmd_parameter,&flag);
|
||||
if (ret != 0) {
|
||||
strcpy(response,"ERROR FLAG INVALID");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = sys_action(flag,response);
|
||||
if (ret != 0) {
|
||||
strcpy(response,"ERROR SYS ACTION FAILED");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void oem_nv_get_proccess(char *cmd_parameter, char *response)
|
||||
{
|
||||
char *sep = NULL;
|
||||
char offset[MAX_NV_NUMBER_SIZE] = {0};
|
||||
char len[MAX_NV_NUMBER_SIZE] = {0};
|
||||
int sep_pos = 0;
|
||||
uint8_t nv_data[MAX_NV_DATA_SIZE + 32] = {0};
|
||||
char nv_data_str[MAX_NV_DATA_SIZE * 2 + 1] = {0};
|
||||
int ret;
|
||||
int offset_int = 0;
|
||||
int len_int = 0;
|
||||
|
||||
sep = strstr(cmd_parameter, ":");
|
||||
if (sep == NULL) {
|
||||
strcpy(response,"ERROR INVALID PARAM");
|
||||
return;
|
||||
}
|
||||
|
||||
sep_pos = sep - cmd_parameter;
|
||||
memcpy(offset,cmd_parameter,sep - cmd_parameter);
|
||||
memcpy(len,cmd_parameter + (sep - cmd_parameter) + 1,strlen(cmd_parameter) - sep_pos - 1);
|
||||
|
||||
ret = char_to_int(offset,&offset_int);
|
||||
if (ret != 0) {
|
||||
strcpy(response,"ERROR OFFSET INVALID");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = char_to_int(len,&len_int);
|
||||
if (ret != 0) {
|
||||
strcpy(response,"ERROR LEN INVALID");
|
||||
return;
|
||||
}
|
||||
|
||||
if (len_int > MAX_NV_DATA_SIZE) {
|
||||
strcpy(response,"ERROR NV SIZE TOO LARGE");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = nv_get(nv_data, offset_int, len_int);
|
||||
if (ret != 0) {
|
||||
printf("nv_get failed:%d\n",ret);
|
||||
strcpy(response,"ERROR NV GET FAILED");
|
||||
return;
|
||||
}
|
||||
|
||||
hex_to_str(nv_data_str,nv_data,len_int);
|
||||
strcpy(response,"SUCCESS:");
|
||||
strcat(response,nv_data_str);
|
||||
}
|
||||
|
||||
void oem_nv_set_proccess(char *cmd_parameter, char *response)
|
||||
{
|
||||
char *sep = NULL;
|
||||
char offset[MAX_NV_NUMBER_SIZE] = {0};
|
||||
uint8_t nv_data[MAX_NV_DATA_SIZE + 32] = {0};
|
||||
char *nv_data_str;
|
||||
int data_len;
|
||||
int ret;
|
||||
int offset_int = 0;
|
||||
|
||||
sep = strstr(cmd_parameter, ":");
|
||||
if (sep == NULL) {
|
||||
strcpy(response,"ERROR INVALID PARAM");
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(offset,cmd_parameter,sep - cmd_parameter);
|
||||
nv_data_str = cmd_parameter + (sep - cmd_parameter) + 1;
|
||||
|
||||
data_len = strlen(nv_data_str) / 2;
|
||||
|
||||
ret = char_to_int(offset,&offset_int);
|
||||
if (ret != 0) {
|
||||
strcpy(response,"ERROR OFFSET INVALID");
|
||||
return;
|
||||
}
|
||||
|
||||
if (data_len > MAX_NV_DATA_SIZE) {
|
||||
strcpy(response,"ERROR NV SIZE TOO LARGE");
|
||||
return;
|
||||
}
|
||||
|
||||
str_to_hex(nv_data,nv_data_str,data_len);
|
||||
|
||||
ret = nv_set(nv_data, offset_int, data_len);
|
||||
if (ret != 0) {
|
||||
strcpy(response,"ERROR NV SET FAILED");
|
||||
return;
|
||||
}
|
||||
|
||||
strcpy(response,"OKAY");
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user