Files
kunlun/pib/src/iot_oem.c

1142 lines
30 KiB
C

/****************************************************************************
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
be copied by any method or incorporated into another program without
the express written consent of Aerospace C.Power. This Information or any portion
thereof remains the property of Aerospace C.Power. The Information contained herein
is believed to be accurate and Aerospace C.Power assumes no responsibility or
liability for its use in any way and conveys no license or title under
any patent or copyright and makes no representation or warranty that this
Information is free from patent or copyright infringement.
****************************************************************************/
/* os shim includes */
#include "os_types.h"
#include "os_mem.h"
#include "iot_dbglog_parser.h"
#include "iot_dbglog_api.h"
#include "iot_errno.h"
#include "iot_mtd.h"
#include "iot_oem.h"
#include "iot_io.h"
#include "iot_crc.h"
#include "os_utils_api.h"
#include "iot_bitmap_api.h"
#include "iot_pib.h"
#include "iot_system.h"
#include "iot_uart_api.h"
#include "iot_crc_api.h"
#include "iot_crypto_dsa_api.h"
#include "iot_string.h"
/**
* user type for iot
* USER_TYPE_SUNSOLAR1 for shenggao
*
*/
typedef struct _iot_oem_obj_t {
uint8_t ready;
uint8_t role_cco;
uint8_t mtd_err;
iot_oem_cfg_t oemcfg;
#if MBEDTLS_LIB_EN
iot_oem_security_cfg_v1_t security_cfg;
#endif
} iot_oem_obj_t;
const uint8_t g_iot_sec_sm2_user_id[IOT_SEC_SM2_USER_ID_LEN] = {
0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
};
const uint8_t g_iot_sec_root_sm2_pub_v1[IOT_SEC_ROOT_SM2_PUB_LEN] = {
0x7A, 0xE7, 0xA1, 0x01, 0x2B, 0x87, 0xC8, 0x91,
0xFC, 0xA7, 0x9A, 0xC8, 0xA7, 0x17, 0xDB, 0xE7,
0xAB, 0x5B, 0xEF, 0x24, 0x49, 0xE0, 0x57, 0x1F,
0xB8, 0xBF, 0x6F, 0x84, 0xB2, 0xF6, 0x16, 0x24,
0x67, 0x28, 0x4F, 0x6E, 0xBB, 0x7D, 0x6A, 0x0F,
0x8E, 0x27, 0xD3, 0x09, 0x4A, 0x8D, 0xFA, 0xBE,
0x6A, 0x5A, 0x55, 0x1E, 0xAD, 0x3F, 0xA8, 0x76,
0xDE, 0x47, 0xE3, 0xBD, 0x6F, 0x02, 0x30, 0x22,
};
const uint8_t bcast_mac[IOT_MAC_ADDR_LEN] = { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF };
// 在偏移 offset 字节之后读取
uint32_t iot_oem_read_mtd(uint8_t *buf, uint32_t size, uint32_t offset)
{
uint32_t ret = ERR_FAIL;
int fd = 0;
int status = 0;
uint8_t oem_prtition = 0;
do {
status = dev_get_oem_part_num(&oem_prtition);
if (status) {
break;
}
iot_printf("%s oem partition id:%d\n", __FUNCTION__, oem_prtition);
//iot_dbglog_input(IOT_PIB_MID, DBGLOG_INFO_LVL_2, IOT_PIB_INFO_ID,
// 3, iot_oem_read_mtd, oem_prtition, 0);
fd = dev_open(oem_prtition, 0);
if (fd < 0) {
fd = 0;
break;
}
status = dev_seek(fd, offset, DEV_SEEK_SET);
if (status < 0) {
break;
}
status = dev_read(fd, buf, size);
if (status < 0) {
break;
}
ret = ERR_OK;
} while (0);
if (fd) {
dev_close(fd);
}
return ret;
}
// 抓取额外的差分oem数据
uint32_t iot_oem_read_mtd_ext(uint8_t *buff,uint32_t buff_size)
{
int oem_size;
int status;
int fw_size;
uint32_t ret = ERR_FAIL;
uint8_t fw_prtition = PART_NUM_FW1;
char str_buff[10]={0};
imgHdr hdr={0};
imgHdr run_fw_hdr={0};
const uint8_t *data;
const char *oem_ext_magic_str = IOT_OEM_EXT_MAGIC_STR;
int oem_ext_magic_str_len = strlen(oem_ext_magic_str);
do {
status = dev_get_boot_fw_part_num(&fw_prtition);
if (status) {
break;
}
mtd_get_hdr(fw_prtition,&hdr);
if(hdr.v1.hdrVer!=hdrVer_10){
break;
}
img_header_construct(&run_fw_hdr,(char *)(hdr.v1.runAddr-HEADER_TOLTAL_SIZE));
fw_size=run_fw_hdr.v1.imgSize;
data=(const uint8_t *)(hdr.v1.runAddr+fw_size-oem_ext_magic_str_len);
os_mem_cpy(str_buff,data,oem_ext_magic_str_len);
if(iot_strcmp(str_buff,oem_ext_magic_str) != 0){
break;
}
data-=4;
oem_size=((data[0]<<24)|(data[1]<<16)|(data[2]<<8)|data[3]);
data=data-oem_size;
if(buff_size<oem_size){
break;
}
os_mem_cpy(buff,data,oem_size);
ret = ERR_OK;
} while(0);
return ret;
}
static uint32_t iot_oem_write_mtd(uint8_t *buf, uint32_t size, uint32_t offset)
{
uint32_t ret = ERR_FAIL;
int fd = 0;
int status = 0;
uint8_t oem_prtition = 0;
do {
status = dev_get_oem_part_num(&oem_prtition);
if (status) {
break;
}
iot_printf("%s oem partition id:%d\n", __FUNCTION__, oem_prtition);
//iot_dbglog_input(IOT_PIB_MID, DBGLOG_INFO_LVL_2, IOT_PIB_INFO_ID,
// 3, iot_oem_read_mtd, oem_prtition, 0);
fd = dev_open(oem_prtition, 0);
if (fd < 0) {
fd = 0;
break;
}
status = dev_seek(fd, offset, DEV_SEEK_SET);
if (status < 0) {
break;
}
status = dev_write(fd, buf, size);
if (status < 0) {
break;
}
ret = ERR_OK;
} while (0);
if (fd) {
dev_close(fd);
}
return ret;
}
static iot_oem_obj_t gbl_oemcfg = { 0 };
uint32_t iot_oem_set_cfg(iot_oem_cfg_t* oemcfg)
{
uint32_t ret = ERR_FAIL;
uint8_t crc8 = 0;
uint8_t* pbuf;
uint32_t size;
if(oemcfg == NULL){
return ret;
}
os_mem_cpy(&gbl_oemcfg.oemcfg, oemcfg, sizeof(iot_oem_cfg_t));
pbuf = &gbl_oemcfg.oemcfg.base_cfg.oem_valid;
size = sizeof(iot_oem_cfg_t) - sizeof(uint8_t);
/* validate crc8 */
crc8 = (uint8_t)iot_getcrc8(pbuf, size);
gbl_oemcfg.oemcfg.base_cfg.oem_crc = crc8;
if (gbl_oemcfg.ready == 1) {
ret = iot_oem_write_mtd((uint8_t*)&gbl_oemcfg.oemcfg, sizeof(iot_oem_cfg_t),
IOT_OEM_SECTION_START_ADDR);
}
return ret;
}
uint32_t iot_oem_get_cert_baund()
{
uint32_t cert_baund;
iot_oem_cfg_t *cfg;
if (iot_oem_get_cfg(&cfg) == ERR_OK) {
cert_baund = cfg->misc_cfg.cert_baund;
if ((cert_baund != 0) && (cert_baund != 0xFFFFFFFF)) {
cert_baund = cert_baund / 10 * 10;
}
} else {
cert_baund = 0xFFFFFFFF;
}
return cert_baund;
}
uint8_t iot_oem_get_cert_uart_parity()
{
uint32_t cert_baud = 0;
uint8_t parity = IOT_UART_PARITY_EVEN;
iot_oem_cfg_t *cfg;
if (iot_oem_get_cfg(&cfg) == ERR_OK) {
cert_baud = cfg->misc_cfg.cert_baund;
if ((cert_baud != 0) && (cert_baud != 0xFFFFFFFF)) {
cert_baud = cert_baud % 10;
if (cert_baud == 1) {
parity = IOT_UART_PARITY_NONE;
} else if (cert_baud == 2) {
parity = IOT_UART_PARITY_EVEN;
}
}
}
return parity;
}
uint32_t iot_oem_get_cfg_ext(iot_oem_obj_t** oem_obj)
{
uint32_t ret = ERR_FAIL;
uint8_t crc8 = 0;
uint8_t* pbuf;
uint32_t size;
uint32_t rand;
uint8_t ahb_mac[IOT_MAC_ADDR_LEN] = { 0 };
// get ahb mac
#if HW_PLATFORM != HW_PLATFORM_SIMU
iot_chip_get_mac_addr(ahb_mac);
if (iot_chip_id_check() == IOT_CHIP_ID_MT) {
/* change mac address vendor for MT */
ahb_mac[0] = 0x70;
ahb_mac[1] = 0xB7;
ahb_mac[2] = 0xE2;
}
#endif
if (gbl_oemcfg.ready != 1) {
// 这里只是读取基础oem配置 没有读取差分配置
ret = iot_oem_read_mtd((uint8_t*)&gbl_oemcfg.oemcfg, sizeof(iot_oem_cfg_t),
IOT_OEM_SECTION_START_ADDR);
if (ret == ERR_OK) {
pbuf = &gbl_oemcfg.oemcfg.base_cfg.oem_valid;
size = sizeof(iot_oem_cfg_t) - sizeof(uint8_t);
/* validate crc8 */
crc8 = (uint8_t)iot_getcrc8(pbuf, size);
if (crc8 == gbl_oemcfg.oemcfg.base_cfg.oem_crc) {
gbl_oemcfg.ready = 1;
*oem_obj = &gbl_oemcfg;
if (!iot_mac_addr_valid(gbl_oemcfg.oemcfg.base_cfg.module_mac)
|| iot_mac_is_bcast(gbl_oemcfg.oemcfg.base_cfg.module_mac)) {
// set oem module mac with ahb mac
iot_mac_addr_cpy(gbl_oemcfg.oemcfg.base_cfg.module_mac,
ahb_mac);
}
#if MBEDTLS_LIB_EN
uint32_t crc32 = 0;
ret = iot_oem_read_mtd((uint8_t *)&gbl_oemcfg.security_cfg,
sizeof(iot_oem_security_cfg_v1_t),
IOT_OEM_SECTION_SEC_ADDR);
if (gbl_oemcfg.security_cfg.hdr.len ==
sizeof(iot_oem_security_param_v1_t)) {
crc32 = iot_getcrc32(
(uint8_t *)&(gbl_oemcfg.security_cfg.hdr.ver),
gbl_oemcfg.security_cfg.hdr.len +
sizeof(iot_oem_security_hdr_t) - sizeof(uint32_t));
if (crc32 != gbl_oemcfg.security_cfg.hdr.crc) {
gbl_oemcfg.security_cfg.hdr.len = 0;
}
} else {
gbl_oemcfg.security_cfg.hdr.len = 0;
}
#endif
}else{
ret = ERR_FAIL;
}
}
} else {
ret = ERR_OK;
}
if (ret != ERR_OK) {
// only read mtd or crc erro hit here.
// make default oemcfg value
gbl_oemcfg.ready = 1;
// random mac
gbl_oemcfg.oemcfg.base_cfg.module_mac[0] = 0x03;
gbl_oemcfg.oemcfg.base_cfg.module_mac[1] = 0x00;
gbl_oemcfg.oemcfg.base_cfg.module_mac[2] = 0x05;
if(gbl_oemcfg.role_cco){
gbl_oemcfg.oemcfg.base_cfg.module_mac[3] = 0x01;
gbl_oemcfg.oemcfg.base_cfg.module_type = MODULE_TYPE_CCO;
}else{
gbl_oemcfg.oemcfg.base_cfg.module_mac[3] = 0x00;
gbl_oemcfg.oemcfg.base_cfg.module_type = MODULE_TYPE_STA;
}
rand = os_rand();
gbl_oemcfg.oemcfg.base_cfg.module_mac[4] = (rand&0xFF00)>>8;
gbl_oemcfg.oemcfg.base_cfg.module_mac[5] = (rand&0xFF);
// set oem module mac with ahb mac
if (iot_mac_addr_valid(ahb_mac) && !iot_mac_is_bcast(ahb_mac)) {
iot_mac_addr_cpy(gbl_oemcfg.oemcfg.base_cfg.module_mac, ahb_mac);
}
gbl_oemcfg.mtd_err = 1;
ret = ERR_OK;
}
*oem_obj = &gbl_oemcfg;
iot_printf("oemcfg iscco_role:%d mtd_err:%d m_t:%x mac:0x%x:%x:%x:%x:%x:%x\n",
gbl_oemcfg.role_cco, gbl_oemcfg.mtd_err, gbl_oemcfg.oemcfg.base_cfg.module_type,
gbl_oemcfg.oemcfg.base_cfg.module_mac[0],gbl_oemcfg.oemcfg.base_cfg.module_mac[1],
gbl_oemcfg.oemcfg.base_cfg.module_mac[2],gbl_oemcfg.oemcfg.base_cfg.module_mac[3],
gbl_oemcfg.oemcfg.base_cfg.module_mac[4],gbl_oemcfg.oemcfg.base_cfg.module_mac[5]);
return ret;
}
uint32_t iot_oem_get_cfg(iot_oem_cfg_t** oemcfg)
{
uint32_t ret;
iot_oem_obj_t* oem_obj;
ret = iot_oem_get_cfg_ext(&oem_obj);
*oemcfg = &oem_obj->oemcfg;
return ret;
}
uint32_t iot_oem_check_burned_mac(void)
{
uint32_t ret = 0;
iot_oem_cfg_t *oemcfg = NULL;
uint8_t ahb_mac[IOT_MAC_ADDR_LEN] = { 0 };
// get ahb mac
#if HW_PLATFORM != HW_PLATFORM_SIMU
iot_chip_get_mac_addr(ahb_mac);
if (iot_chip_id_check() == IOT_CHIP_ID_MT) {
/* change mac address vendor for MT */
ahb_mac[0] = 0x70;
ahb_mac[1] = 0xB7;
ahb_mac[2] = 0xE2;
}
#endif
iot_oem_get_cfg(&oemcfg);
if (oemcfg && !iot_mac_addr_cmp(ahb_mac, oemcfg->base_cfg.module_mac)) {
ret = 1;
}
return ret;
}
uint32_t iot_oem_get_mtd_sts(void)
{
if(gbl_oemcfg.mtd_err)
{
return ERR_FAIL;
}
else{
return ERR_OK;
}
}
uint32_t iot_oem_get_base_cfg(iot_oem_base_cfg_t** base_cfg)
{
uint32_t ret = ERR_OK;
iot_oem_cfg_t *oemcfg = NULL;
if (gbl_oemcfg.ready != 1) {
ret = iot_oem_get_cfg(&oemcfg);
}
*base_cfg = &gbl_oemcfg.oemcfg.base_cfg;
return ret;
}
uint32_t iot_oem_get_cus_cfg(iot_cus_cfg_t** cus_cfg)
{
uint32_t ret = ERR_OK;
iot_oem_cfg_t *oemcfg = NULL;
if (gbl_oemcfg.ready != 1) {
ret = iot_oem_get_cfg(&oemcfg);
}
*cus_cfg = &gbl_oemcfg.oemcfg.cus_cfg;
return ret;
}
uint32_t iot_oem_get_module_mac(uint8_t *mac)
{
uint32_t ret = ERR_FAIL;
iot_oem_cfg_t *oemcfg = NULL;
iot_oem_get_cfg(&oemcfg);
if (oemcfg) {
os_mem_cpy(mac, &oemcfg->base_cfg.module_mac, IOT_MAC_ADDR_LEN);
ret = ERR_OK;
} else {
iot_printf("%s: failed to get module mac\n", __FUNCTION__);
}
return ret;
}
void iot_oem_get_bcd_mac(uint8_t *mac)
{
#if HW_PLATFORM != HW_PLATFORM_SIMU
uint32_t tmp;
uint8_t chip_mac[IOT_MAC_ADDR_LEN];
iot_chip_get_mac_addr(chip_mac);
tmp = (chip_mac[3] << 16)
| (chip_mac[4] << 8)
| chip_mac[5];
iot_uint32_to_bcd(tmp, 4, mac);
if (chip_mac[0] == 0x48 && chip_mac[1] == 0x55 &&
chip_mac[2] == 0x5c) {
mac[4] = 0x00;
} else if (chip_mac[0] == 0xd8 && chip_mac[1] == 0x4d &&
chip_mac[2] == 0xb9) {
mac[4] = 0x01;
} else if (chip_mac[0] == 0xd8 && chip_mac[1] == 0xa6 &&
chip_mac[2] == 0xf0) {
mac[4] = 0x02;
} else if (chip_mac[0] == 0x6c && chip_mac[1] == 0x11 &&
chip_mac[2] == 0xb3) {
mac[4] = 0x03;
} else {
mac[4] = 0x88;
}
mac[5] = 0x88;
#else
os_mem_set(mac, 0, IOT_MAC_ADDR_LEN);
#endif
}
uint32_t iot_oem_get_chip_mmid(uint8_t *buff, uint32_t len)
{
iot_oem_cfg_t *oemcfg = NULL;
iot_oem_get_cfg(&oemcfg);
if (len >= IOT_CHIP_MMID_LEN) {
len = IOT_CHIP_MMID_LEN;
os_mem_cpy(buff, oemcfg->misc_cfg.chip_mmid, len);
} else {
len = 0;
}
return len;
}
uint32_t iot_oem_set_chip_mmid(uint8_t *buff, uint32_t len, uint8_t force)
{
uint32_t ret = ERR_INVAL;
iot_oem_cfg_t *oemcfg = NULL;
iot_oem_get_cfg(&oemcfg);
if (len >= IOT_CHIP_MMID_LEN) {
len = IOT_CHIP_MMID_LEN;
if (force || !iot_bitmap_cbs(oemcfg->misc_cfg.chip_mmid,
IOT_CHIP_MMID_LEN)) {
os_mem_cpy(oemcfg->misc_cfg.chip_mmid, buff, len);
iot_oem_set_cfg(oemcfg);
ret = ERR_OK;
} else {
ret = ERR_EXIST;
}
}
return ret;
}
uint32_t iot_oem_set_base_cfg(iot_oem_base_cfg_t* base_cfg)
{
uint32_t ret = ERR_FAIL;
iot_oem_cfg_t *oemcfg;
if(base_cfg == NULL){
return ret;
}
if (ERR_OK != (ret = iot_oem_get_cfg(&oemcfg)))
{
return ret;
}
os_mem_cpy(&oemcfg->base_cfg, base_cfg, sizeof(iot_oem_base_cfg_t));
ret = iot_oem_set_cfg(oemcfg);
return ret;
}
uint16_t iot_oem_get_module_id()
{
uint16_t module_id = 0;
return module_id;
}
uint16_t iot_oem_get_vendor_id()
{
uint16_t vendor_id = 0;
iot_oem_cfg_t *oemcfg = NULL;
if(gbl_oemcfg.ready != 1){
iot_oem_get_cfg(&oemcfg);
}
if(gbl_oemcfg.ready == 1){
vendor_id = gbl_oemcfg.oemcfg.misc_cfg.vendor_id;
}
if ((0 == vendor_id) || (0xFFFF == vendor_id)) {
/* if vendor id is invalid, let's set vendor id to HT */
vendor_id = 0x4854;
}
return vendor_id;
}
uint32_t iot_oem_get_module_type()
{
uint32_t module_type = 0xFFFFFFFF;
iot_oem_cfg_t *oemcfg = NULL;
if(gbl_oemcfg.ready != 1){
iot_oem_get_cfg(&oemcfg);
}
if(gbl_oemcfg.ready == 1){
module_type = gbl_oemcfg.oemcfg.base_cfg.module_type;
}
return module_type;
}
uint16_t iot_oem_get_passcode()
{
uint16_t passcode = 0;
iot_oem_cfg_t *oemcfg = NULL;
if (gbl_oemcfg.ready != 1) {
iot_oem_get_cfg(&oemcfg);
}
if (gbl_oemcfg.ready == 1) {
if (gbl_oemcfg.oemcfg.misc_cfg.sec_type == IOT_OEM_SEC_TYPE_PASSCODE) {
passcode = gbl_oemcfg.oemcfg.misc_cfg.passcode;
}
}
return passcode;
}
uint8_t iot_oem_get_user_type()
{
uint8_t user_type = 0xFF;
iot_oem_cfg_t *oemcfg = NULL;
iot_pib_r_board_cfg_t *pib_bd;
uint8_t *secion;
uint8_t pib_type;
if(gbl_oemcfg.ready != 1){
iot_oem_get_cfg(&oemcfg);
}
if(gbl_oemcfg.ready == 1){
user_type = gbl_oemcfg.oemcfg.base_cfg.user_type;
}
if (iot_pib_get_section(IOT_PIB_BOARD_ID, &secion, &pib_type,
IOT_PIB_GET_READ_SECTION) == ERR_OK) {
/* user type settings in PIB has higher priority */
pib_bd = (iot_pib_r_board_cfg_t *)secion;
if (pib_bd->user_cfg.user_type_valid) {
user_type = pib_bd->user_cfg.user_type;
}
}
return user_type;
}
uint32_t iot_oem_get_hw_ver_info(iot_oem_hw_ver_info_t *info)
{
iot_oem_cfg_t *oemcfg;
if (info == NULL) {
return ERR_FAIL;
}
iot_oem_get_cfg(&oemcfg);
os_mem_cpy(info, &oemcfg->misc_cfg.hw_ver_info, sizeof(*info));
if (mtd_get_psram_state() && (gbl_oemcfg.role_cco == 0)
&& oemcfg->misc_cfg.vendor_id == 0x544B) {
if ((info->chip_ver[0] == 0)
&& (info->chip_ver[1] == 0)
&& (info->chip_ver[2] == 0)
&& (info->chip_ver[3] == 0)
&& (info->module_version[0] == 0)
&& (info->module_version[1] == 0)) {
/* if chip version is invalid, let's set chip version to 3011 */
info->chip_ver[0] = 0x31;
info->chip_ver[1] = 0x31;
info->chip_ver[2] = 0x30;
info->chip_ver[3] = 0x33;
info->chip_year = 0x17;
info->chip_month = 0x10;
info->chip_day = 0x18;
/* if module version is invalid, let's set module version to 0001 */
info->module_version[0] = 0x01;
info->module_version[1] = 0x00;
info->module_version_year = 0x22;
info->module_version_month = 0x01;
info->module_version_day = 0x26;
}
} else {
if ((info->chip_ver[0] == 0)
&& (info->chip_ver[1] == 0)
&& (info->chip_ver[2] == 0)
&& (info->chip_ver[3] == 0)) {
/* if chip version is invalid, let's set chip version to W002 */
info->chip_ver[0] = 0x32;
info->chip_ver[1] = 0x30;
info->chip_ver[2] = 0x30;
info->chip_ver[3] = 0x57;
info->chip_year = 0x18;
info->chip_month = 0x07;
info->chip_day = 0x30;
}
}
return ERR_OK;
}
uint8_t iot_oem_get_chip_type()
{
return gbl_oemcfg.oemcfg.misc_cfg.chip_type;
}
uint8_t iot_oem_ip_is_enabled()
{
uint8_t ret = IOT_OEM_IP_DISABLE;
iot_oem_cfg_t *oemcfg = NULL;
if(gbl_oemcfg.ready != 1){
iot_oem_get_cfg(&oemcfg);
}
if(gbl_oemcfg.ready == 1){
if(IOT_OEM_IP_ENABLE == gbl_oemcfg.oemcfg.ip_info.ip_enable) {
ret = IOT_OEM_IP_ENABLE;
}
}
return ret;
}
void iot_oem_get_local_ip4_addr(uint8_t *ip4_addr)
{
iot_oem_cfg_t *oemcfg = NULL;
if (NULL == ip4_addr) {
return;
}
os_mem_set(ip4_addr, 0, IOT_IP4_ADDR_LEN);
if(gbl_oemcfg.ready != 1){
iot_oem_get_cfg(&oemcfg);
}
if(gbl_oemcfg.ready == 1){
if(IOT_OEM_IP_VERSION_IP4 == gbl_oemcfg.oemcfg.ip_info.ip_ver) {
os_mem_cpy(ip4_addr, gbl_oemcfg.oemcfg.ip_info.ipv4,
IOT_IP4_ADDR_LEN);
iot_printf("%s: oem ip4_addr is [%d.%d.%d.%d]\n",
__FUNCTION__, ip4_addr[0],
ip4_addr[1],ip4_addr[2],ip4_addr[3]);
}
}
return;
}
void iot_oem_get_local_ip4_netmask(uint8_t *ip4_mask)
{
iot_oem_cfg_t *oemcfg = NULL;
if (NULL == ip4_mask) {
return;
}
os_mem_set(ip4_mask, 0, IOT_IP4_ADDR_LEN);
if(gbl_oemcfg.ready != 1){
iot_oem_get_cfg(&oemcfg);
}
if(gbl_oemcfg.ready == 1){
if(IOT_OEM_IP_VERSION_IP4 == gbl_oemcfg.oemcfg.ip_info.ip_ver) {
os_mem_cpy(ip4_mask, gbl_oemcfg.oemcfg.ip_info.ipv4_mask,
IOT_IP4_ADDR_LEN);
iot_printf("[oem][succ]oem ip4 netmask is [%d.%d.%d.%d]\n",
ip4_mask[0], ip4_mask[1],ip4_mask[2],ip4_mask[3]);
}
}
return;
}
uint32_t iot_oem_ip4_addr_is_valid(uint8_t *ip4_addr)
{
uint32_t ret = IOT_OEM_IP4_IS_INVALID;
if((NULL != ip4_addr) &&
(0 != (ip4_addr[0] || ip4_addr[1] || ip4_addr[2] || ip4_addr[3]))
&& (255 != (ip4_addr[0] & ip4_addr[1] & ip4_addr[2] & ip4_addr[3]))
&& (127 != ip4_addr[0])) {
ret = IOT_OEM_IP4_IS_VALID;
}
return ret;
}
uint32_t iot_oem_ip4_netmask_is_valid(uint8_t *ip4_mask)
{
uint32_t tmp = 0;
if(IOT_OEM_IP4_IS_INVALID == iot_oem_ip4_addr_is_valid(ip4_mask)) {
goto err;
}
for(int i = 0; i < IOT_IP4_ADDR_LEN; i++) {
tmp += ip4_mask[i] << ((IOT_IP4_ADDR_LEN - 1 -i) * 8);
}
tmp = ~tmp + 1;
if(0 != (tmp & (tmp - 1))) {
goto err;
}
return IOT_OEM_IP4_MASK_IS_VALID;
err:
return IOT_OEM_IP4_MASK_IS_INVALID;
}
uint32_t iot_oem_set_local_ip4_info(uint8_t *ip4_addr, uint8_t *ip4_mask)
{
iot_oem_cfg_t *oemcfg = NULL;
uint32_t ret = ERR_FAIL;
if ((NULL == ip4_addr) || (NULL == ip4_mask) ||
(IOT_OEM_IP4_IS_INVALID == iot_oem_ip4_addr_is_valid(ip4_addr)) ||
(IOT_OEM_IP4_MASK_IS_INVALID == iot_oem_ip4_netmask_is_valid(ip4_mask))) {
iot_printf("[oem][err]ip4 info is invalied\n");
return ret;
}
if (ERR_OK != (ret = iot_oem_get_cfg(&oemcfg)))
{
iot_printf("[oem][err]get oem cfg err\n");
return ret;
}
os_mem_cpy(oemcfg->ip_info.ipv4, ip4_addr, IOT_IP4_ADDR_LEN);
os_mem_cpy(oemcfg->ip_info.ipv4_mask, ip4_mask, IOT_IP4_ADDR_LEN);
oemcfg->ip_info.ip_ver = IOT_OEM_IP_VERSION_IP4;
oemcfg->ip_info.ip_enable = IOT_OEM_IP_ENABLE;
oemcfg->ip_info.ip4_method = IOT_OEM_IP_METHOD_CUSTOMER;
ret = iot_oem_set_cfg(oemcfg);
if(ERR_OK != ret) {
iot_printf("[oem][err] set oem cfg failed, ret = %d\n", ret);
}
iot_printf("[oem][succ]set oem ip4 addr[%d:%d:%d:%d]\n", ip4_addr[0],
ip4_addr[1],ip4_addr[2],ip4_addr[3]);
iot_printf("[oem][succ]set oem ip4 netmask[%d:%d:%d:%d]\n", ip4_mask[0],
ip4_mask[1],ip4_mask[2],ip4_mask[3]);
return ret;
}
uint16_t iot_oem_get_local_port()
{
uint16_t local_port = 0;
iot_oem_cfg_t *oemcfg = NULL;
if(gbl_oemcfg.ready != 1){
iot_oem_get_cfg(&oemcfg);
}
if(!iot_oem_get_is_ip6() && (gbl_oemcfg.ready == 1)){
local_port = gbl_oemcfg.oemcfg.ip_info.ipv4_port;
}
return local_port;
}
bool_t iot_oem_get_is_ip6()
{
uint8_t is_ip6 = 0;
uint8_t ip_ver = 0;
iot_oem_cfg_t *oemcfg = NULL;
if(gbl_oemcfg.ready != 1){
iot_oem_get_cfg(&oemcfg);
}
if(gbl_oemcfg.ready == 1){
ip_ver = gbl_oemcfg.oemcfg.ip_info.ip_ver;
}
is_ip6 = (IOT_OEM_IP_VERSION_IP6 == ip_ver? 1:0);
return is_ip6;
}
uint8_t iot_oem_get_ip_method()
{
iot_oem_cfg_t *oemcfg = NULL;
uint8_t ip_method = IOT_OEM_IP_METHOD_TEI;
if(gbl_oemcfg.ready != 1){
iot_oem_get_cfg(&oemcfg);
}
if(gbl_oemcfg.ready == 1){
if(IOT_OEM_IP_METHOD_CUSTOMER == gbl_oemcfg.oemcfg.ip_info.ip4_method) {
ip_method = IOT_OEM_IP_METHOD_CUSTOMER;
}
}
return ip_method;
}
uint16_t iot_oem_get_chip_code()
{
uint16_t chip_code = 0;
iot_oem_cfg_t *oemcfg = NULL;
if(gbl_oemcfg.ready != 1){
iot_oem_get_cfg(&oemcfg);
}
if(gbl_oemcfg.ready == 1){
chip_code = gbl_oemcfg.oemcfg.misc_cfg.chip_code;
}
if (chip_code == 0xFFFF) {
chip_code = 0;
}
return chip_code;
}
uint32_t iot_oem_set_chip_code(uint16_t chip_code)
{
uint32_t ret = ERR_FAIL;
iot_oem_cfg_t *oemcfg;
if (ERR_OK != (ret = iot_oem_get_cfg(&oemcfg)))
return ret;
oemcfg->misc_cfg.chip_code = chip_code;
ret = iot_oem_set_cfg(oemcfg);
return ret;
}
uint32_t iot_oem_set_vendor_id(uint16_t vendor_id)
{
uint32_t ret = ERR_FAIL;
iot_oem_cfg_t *oemcfg;
if (ERR_OK != (ret = iot_oem_get_cfg(&oemcfg)))
return ret;
oemcfg->misc_cfg.vendor_id = vendor_id;
ret = iot_oem_set_cfg(oemcfg);
return ret;
}
uint32_t iot_oem_get_board_id()
{
uint32_t board_id = 0;
iot_oem_cfg_t *oemcfg = NULL;
if(gbl_oemcfg.ready != 1){
iot_oem_get_cfg(&oemcfg);
}
if(gbl_oemcfg.ready == 1){
board_id = gbl_oemcfg.oemcfg.board_id;
}
return board_id;
}
void iot_oem_set_module_type(uint32_t mt)
{
if (gbl_oemcfg.ready == 1) {
if (gbl_oemcfg.oemcfg.base_cfg.module_type == MODULE_TYPE_STA_TEST) {
/* STA TEST correct to CCO only */
if (mt == MODULE_TYPE_CCO ) {
gbl_oemcfg.oemcfg.base_cfg.module_type = mt;
}
} else if (gbl_oemcfg.oemcfg.base_cfg.module_type == MODULE_TYPE_3_PHASE_STA) {
/* 3 PHASE STA correct to CCO and IIC */
if ((mt == MODULE_TYPE_CCO) || (mt == MODULE_TYPE_COLLECTOR_II)) {
gbl_oemcfg.oemcfg.base_cfg.module_type = mt;
}
} else {
gbl_oemcfg.oemcfg.base_cfg.module_type = mt;
}
}
}
uint8_t iot_oem_ca_id_is_valid(iot_oem_security_param_v1_t *data)
{
uint8_t i;
uint8_t *p_sm2_sign = data->sm2_sign;
uint8_t *p_ecc_sign = data->ecc_sign;
BUILD_BUG_ON(IOT_CHIP_SEC_SM2_SIGN_LEN == IOT_CHIP_SEC_ECC_SIGN_LEN);
for (i = 0; i < IOT_CHIP_SEC_SM2_SIGN_LEN; i++) {
if ((p_sm2_sign[i] != 0) || (p_ecc_sign[i] != 0)) {
return 1;
}
}
return 0;
}
iot_oem_security_param_v1_t *iot_oem_get_security_cfg_v1()
{
#if MBEDTLS_LIB_EN
iot_oem_cfg_t *oemcfg = NULL;
if (gbl_oemcfg.ready != 1) {
iot_oem_get_cfg(&oemcfg);
}
if ((gbl_oemcfg.ready == 1) && gbl_oemcfg.security_cfg.hdr.len &&
(gbl_oemcfg.security_cfg.hdr.ver == 1)) {
if (iot_oem_ca_id_is_valid(&gbl_oemcfg.security_cfg.data)) {
return (iot_oem_security_param_v1_t *)&gbl_oemcfg.security_cfg.data;
}
}
#endif
return NULL;
}
uint32_t iot_oem_set_security_cfg_v1(iot_oem_security_param_v1_t *param)
{
uint32_t ret = ERR_FAIL;
(void)param;
#if MBEDTLS_LIB_EN
uint8_t *sign_r, *sign_s;
uint32_t sign_r_len, sign_s_len;
iot_oem_obj_t *oem_obj;
iot_pkt_t *pkt = NULL, *pkt_sign = NULL;
uint8_t *ptr;
uint32_t data_len = IOT_CHIP_MMID_LEN + IOT_CHIP_SEC_ECC_CURVE_LEN +
IOT_CHIP_SEC_ECC_KEY_PUB_LEN;
if (ERR_OK != (ret = iot_oem_get_cfg_ext(&oem_obj))) {
goto out;
}
pkt_sign = iot_pkt_alloc(64, IOT_PIB_MID);
IOT_ASSERT(pkt_sign);
sign_r = iot_pkt_data(pkt_sign);
sign_s = sign_r + 32;
pkt = iot_pkt_alloc(data_len, IOT_PIB_MID);
IOT_ASSERT(pkt);
ptr = iot_pkt_data(pkt);
os_mem_cpy(ptr, oem_obj->oemcfg.misc_cfg.chip_mmid,
sizeof(oem_obj->oemcfg.misc_cfg.chip_mmid));
iot_data_reverse(ptr, sizeof(oem_obj->oemcfg.misc_cfg.chip_mmid));
os_mem_cpy(ptr + IOT_CHIP_MMID_LEN, &param->ecc_curve_type,
sizeof(param->ecc_curve_type));
os_mem_cpy(ptr + IOT_CHIP_MMID_LEN + IOT_CHIP_SEC_ECC_CURVE_LEN,
param->ecc_key_pub, sizeof(param->ecc_key_pub));
//data valid check
ret = iot_crypto_sm2_verify(ptr, data_len,
(uint8_t *)g_iot_sec_sm2_user_id, sizeof(g_iot_sec_sm2_user_id),
(uint8_t *)g_iot_sec_root_sm2_pub_v1, sizeof(g_iot_sec_root_sm2_pub_v1),
param->ecc_sign, sizeof(param->ecc_sign) >> 1,
param->ecc_sign + (sizeof(param->ecc_sign) >> 1),
sizeof(param->ecc_sign) >> 1);
if (ret) {
goto out;
}
os_mem_cpy(ptr + IOT_CHIP_MMID_LEN, &param->sm2_curve_type,
sizeof(param->sm2_curve_type));
os_mem_cpy(ptr + IOT_CHIP_MMID_LEN + IOT_CHIP_SEC_ECC_CURVE_LEN,
param->sm2_key_pub, sizeof(param->sm2_key_pub));
ret = iot_crypto_sm2_verify(ptr, data_len,
(uint8_t *)g_iot_sec_sm2_user_id, sizeof(g_iot_sec_sm2_user_id),
(uint8_t *)g_iot_sec_root_sm2_pub_v1, sizeof(g_iot_sec_root_sm2_pub_v1),
param->sm2_sign, sizeof(param->sm2_sign) >> 1,
param->sm2_sign + (sizeof(param->sm2_sign) >> 1),
sizeof(param->sm2_sign) >> 1);
if (ret) {
goto out;
}
ret = iot_crypto_ecdsa_with_sha256_sign(ecdsa_ecp_bp256r1,
(uint8_t *)g_iot_sec_root_sm2_pub_v1, sizeof(g_iot_sec_root_sm2_pub_v1),
param->ecc_key_pri, sizeof(param->ecc_key_pri),
sign_r, &sign_r_len, sign_s, &sign_s_len);
if (ret) {
goto out;
}
ret = iot_crypto_ecdsa_with_sha256_sign_verify(ecdsa_ecp_bp256r1,
(uint8_t *)g_iot_sec_root_sm2_pub_v1, sizeof(g_iot_sec_root_sm2_pub_v1),
param->ecc_key_pub, sizeof(param->ecc_key_pub),
sign_r, sign_r_len, sign_s, sign_s_len);
if (ret) {
goto out;
}
ret = iot_crypto_sm2_sign(
(uint8_t *)g_iot_sec_root_sm2_pub_v1, sizeof(g_iot_sec_root_sm2_pub_v1),
(uint8_t *)g_iot_sec_sm2_user_id, sizeof(g_iot_sec_sm2_user_id),
param->sm2_key_pub, sizeof(param->sm2_key_pub),
sign_r, &sign_r_len, sign_s, &sign_s_len,
param->sm2_key_pri, sizeof(param->sm2_key_pri));
if (ret) {
goto out;
}
ret = iot_crypto_sm2_verify(
(uint8_t *)g_iot_sec_root_sm2_pub_v1, sizeof(g_iot_sec_root_sm2_pub_v1),
(uint8_t *)g_iot_sec_sm2_user_id, sizeof(g_iot_sec_sm2_user_id),
param->sm2_key_pub, sizeof(param->sm2_key_pub),
sign_r, sign_r_len, sign_s, sign_s_len);
if (ret) {
goto out;
}
//write data to oem
oem_obj->security_cfg.hdr.ver = 1;
oem_obj->security_cfg.hdr.rsvd = 0;
oem_obj->security_cfg.hdr.len = sizeof(*param);
os_mem_cpy((uint8_t *)&(oem_obj->security_cfg.data), param,
oem_obj->security_cfg.hdr.len);
oem_obj->security_cfg.hdr.crc =
iot_getcrc32((uint8_t *)&oem_obj->security_cfg.hdr.ver,
oem_obj->security_cfg.hdr.len + sizeof(iot_oem_security_hdr_t) -
sizeof(uint32_t));
ret = iot_oem_write_mtd((uint8_t *)&gbl_oemcfg.security_cfg,
sizeof(iot_oem_security_cfg_v1_t), IOT_OEM_SECTION_SEC_ADDR);
out:
if (pkt) {
iot_pkt_free(pkt);
}
if (pkt_sign) {
iot_pkt_free(pkt_sign);
}
#endif
return ret;
}
uint32_t iot_oem_set_module_mac(uint8_t *module_mac)
{
iot_oem_cfg_t *oemcfg;
if(iot_oem_get_cfg(&oemcfg)) {
return ERR_FAIL;
}
os_mem_cpy(oemcfg->base_cfg.module_mac, module_mac, IOT_MAC_ADDR_LEN);
return iot_oem_set_cfg(oemcfg);
}
void iot_oem_init(bool_t role_cco)
{
if(role_cco){
gbl_oemcfg.role_cco = 1;
}else{
gbl_oemcfg.role_cco = 0;
}
}