/* * * Copyright (c) CompanyNameMagicTag 2018-2019. All rights reserved. * Description: boot security * Author: CompanyName * Create: 2018-10-31 */ #include "boot_check_secure_info.h" #ifdef PRODUCT_CFG_SECURE_UPG td_u8 g_boot_key_n[256] = { /* length 256 */ 0xb1, 0xd7, 0x94, 0x0d, 0x16, 0xc3, 0xef, 0x0e, 0x94, 0x5c, 0x93, 0xc2, 0xc8, 0xe3, 0x61, 0x9e, 0x7c, 0xa1, 0x35, 0x87, 0x71, 0xbe, 0x01, 0xc3, 0x68, 0xf2, 0x6e, 0xa2, 0x6d, 0xb4, 0x50, 0x24, 0x5a, 0xea, 0xfe, 0x18, 0x73, 0x47, 0x98, 0xf6, 0x46, 0xe7, 0xb3, 0xdb, 0xce, 0xaf, 0x79, 0x8f, 0xf3, 0xe0, 0x7c, 0xcd, 0xdb, 0x60, 0xb1, 0xa9, 0x8f, 0x72, 0xa0, 0x14, 0xde, 0x4f, 0xa0, 0xad, 0x05, 0x70, 0xbf, 0xae, 0xbf, 0x65, 0xce, 0x61, 0x97, 0x42, 0xc6, 0xf9, 0x46, 0xbb, 0x1a, 0x19, 0x0c, 0x50, 0x11, 0x54, 0xb0, 0x5e, 0x2a, 0xfe, 0xab, 0xcf, 0xe2, 0xb6, 0x3f, 0x37, 0x0e, 0x4d, 0x0e, 0x1d, 0x69, 0xdb, 0xf1, 0xd0, 0x7d, 0x46, 0x6e, 0x18, 0x19, 0x59, 0x8e, 0x3d, 0xdd, 0xbd, 0x9d, 0x9a, 0x6b, 0x4d, 0x5d, 0x22, 0x5c, 0xed, 0xfa, 0x07, 0xbf, 0xfa, 0x4a, 0x60, 0xb8, 0x38, 0xee, 0x1c, 0x92, 0x7c, 0x11, 0x01, 0x2a, 0x1b, 0xc1, 0x17, 0x7c, 0x25, 0x47, 0x5f, 0xe7, 0x61, 0x3f, 0x77, 0xc7, 0x1b, 0x85, 0x2a, 0x83, 0xdd, 0xe4, 0xd7, 0x7e, 0x45, 0x4c, 0x73, 0x75, 0x6f, 0x28, 0x08, 0xe9, 0x40, 0xb8, 0x1a, 0x51, 0x52, 0x13, 0xdd, 0xc3, 0xfb, 0xee, 0x48, 0x83, 0xec, 0x7a, 0x68, 0x2c, 0xaf, 0x2f, 0xef, 0xdc, 0x5e, 0xda, 0xf2, 0x91, 0x0e, 0xc1, 0xcd, 0xc9, 0xab, 0x62, 0x34, 0xdd, 0xe6, 0x87, 0x15, 0x29, 0xd8, 0x81, 0x5b, 0xa2, 0xdf, 0x0d, 0x65, 0xcd, 0xa6, 0xfc, 0xfe, 0x51, 0xe1, 0xb4, 0xaf, 0x0a, 0xf0, 0x6e, 0xd9, 0xa0, 0xfb, 0x50, 0xf7, 0xfb, 0xbb, 0x33, 0xf0, 0xed, 0xf9, 0x01, 0xcd, 0xe3, 0x57, 0xc7, 0x4a, 0xae, 0xce, 0x90, 0xa1, 0x29, 0xd7, 0xe1, 0xa0, 0x52, 0x1b, 0x9c, 0x37, 0x81, 0x65, 0x92, 0x5c, 0xf3, 0x32, 0xd2, 0x23, 0xdf, 0x33 }; td_void uapi_secure_save_key_pos(td_void) { uintptr_t key_flash_addr = ((uintptr_t)(&g_boot_key_n[0]) - (uintptr_t)(&__data_begin__)) + ((uintptr_t)(&__data_flash_begin__) - 0x1000000); *(volatile unsigned int *)(EXT_SYSCTRL_REG_BASE + REG_RSA_KEY_ADDR) = key_flash_addr; } EXT_PRV td_bool uapi_is_secure_start(td_void) { td_u8 data = { 0 }; td_u32 ret; ret = (td_u32)uapi_efuse_read(EXT_EFUSE_SECURE_BOOT_RW_ID, &data); if (ret != EXT_ERR_SUCCESS) { return TD_TRUE; } if (data & 0x1) { boot_msg0("secure boot"); return TD_TRUE; } else { boot_msg0("unsecure boot"); return TD_FALSE; } } td_u32 boot_start_check_tbl_secure_info(td_void) { ext_start_tbl *start_tbl = ext_start_tbl_get_tbl(); if (g_start_ctrl.start_tbl == TD_NULL || g_start_ctrl.start_tbl->section == TD_NULL) { return EXT_ERR_FAILURE; } ext_start_tbl_section *start_tbl_sections = ext_start_tbl_get_sections(); ext_upg_secure_info secure_info = { 0 }; uintptr_t addr[1] = { 0 }; td_u32 size[1] = { 0 }; td_bool flash[1] = { 0 }; td_u32 ret; /* insecure check efuse. return success immediately */ if (!uapi_is_secure_start()) { return EXT_ERR_SUCCESS; } /* without secure head, return fail immediately */ if (start_tbl->secure_info_offset == 0 || start_tbl->secure_info_size == 0) { return EXT_ERR_UPG_SECURE_BOOT_28; } /* read secure head */ ret = uapi_flash_read(g_start_ctrl.flash_addr_ker + start_tbl->secure_info_offset, sizeof(ext_upg_secure_info), (td_u8 *)(&secure_info)); if (ret != EXT_ERR_SUCCESS) { return ret; } /* using the public key in boot code. verify the signature of public key in secure head */ addr[0] = (uintptr_t)secure_info.key_n_2; size[0] = 256; /* size 256 */ flash[0] = TD_FALSE; verify_flash_content_params params1 = { g_boot_key_n, secure_info.signature_1, secure_info.sign_alg }; ret = uapi_rsa_verify_flash_content(addr, size, 1, flash, ¶ms1); if (ret != EXT_ERR_SUCCESS) { return ret; } /* using the public key in secure head. verify the content, kernel, conducted by starting info list */ addr[0] = g_start_ctrl.flash_addr_ker + start_tbl_sections[0].offset; size[0] = start_tbl_sections[0].size; flash[0] = TD_TRUE; verify_flash_content_params params2 = { secure_info.key_n_2, secure_info.signature_2, secure_info.sign_alg }; ret = uapi_rsa_verify_flash_content(addr, size, 1, flash, ¶ms2); if (ret != EXT_ERR_SUCCESS) { return ret; } return EXT_ERR_SUCCESS; } td_u32 boot_upg_check_secure_head(td_void) { td_u32 ret; ext_21_upg_head *upg_head = ext_upg_head_get_head(); ext_upg_secure_info secure_info = { 0 }; size_t addr[2] = { 0 }; /* length 2*4 */ size_t size[2] = { 0 }; /* length 2*4 */ td_bool flash[2] = { 0 }; /* length 2 */ /* insecure check efuse. return success immediately */ if (!uapi_is_secure_start()) { return EXT_ERR_SUCCESS; } /* without secure head, return fail immediately */ if (upg_head->secure_info_offset == 0 || upg_head->secure_info_size == 0) { return EXT_ERR_UPG_SECURE_BOOT_27; } /* read secure head */ ret = uapi_flash_read(g_start_ctrl.flash_addr_upg + upg_head->secure_info_offset, sizeof(ext_upg_secure_info), (td_u8 *)(&secure_info)); if (ret != EXT_ERR_SUCCESS) { return ret; } boot_msg4("upg sig_1 ", secure_info.signature_1[0], secure_info.signature_1[1], secure_info.signature_1[254], secure_info.signature_1[255]); /* index 254&255 */ boot_msg4("upg sig_2 ", secure_info.signature_2[0], secure_info.signature_2[1], secure_info.signature_2[254], secure_info.signature_2[255]); /* index 254&255 */ boot_msg4("upg key_n_2 ", secure_info.key_n_2[0], secure_info.key_n_2[1], secure_info.key_n_2[254], secure_info.key_n_2[255]); /* index 254&255 */ /* using the public key in boot code. verify the signature of public key in secure head */ addr[0] = (uintptr_t)secure_info.key_n_2; size[0] = 256; /* size 256 */ flash[0] = TD_FALSE; verify_flash_content_params params1 = { g_boot_key_n, secure_info.signature_1, secure_info.sign_alg }; ret = uapi_rsa_verify_flash_content(addr, size, 1, flash, ¶ms1); if (ret != EXT_ERR_SUCCESS) { return ret; } /* using the public key in secure head. checking upgrade file. * Checking includes: all the content except secure head and file hash . * file splited into 2 pieces by secure head , so need sectional check. (check sum, secure head) partial check. */ addr[0] = g_start_ctrl.flash_addr_upg + EXT_UPG_HEAD_CHECK_SUM_START_OFFSET; size[0] = upg_head->secure_info_offset - EXT_UPG_HEAD_CHECK_SUM_START_OFFSET; flash[0] = TD_TRUE; /* (secure head, file tail ) partial check */ addr[1] = g_start_ctrl.flash_addr_upg + upg_head->secure_info_offset + upg_head->secure_info_size; size[1] = upg_head->file_len - (upg_head->secure_info_offset + upg_head->secure_info_size); flash[1] = TD_TRUE; verify_flash_content_params params2 = { secure_info.key_n_2, secure_info.signature_2, secure_info.sign_alg }; ret = uapi_rsa_verify_flash_content(addr, size, 2, flash, ¶ms2); /* buffer count :2 */ if (ret != EXT_ERR_SUCCESS) { return ret; } return EXT_ERR_SUCCESS; } td_u32 boot_upg_check_secure_boot(td_void) { td_u32 ret; ext_start_ctrl *start_ctrl = &g_start_ctrl; ext_21_upg_head_section *section_info = TD_NULL; /* insecure check efuse. return success immediately */ if (!uapi_is_secure_start()) { return EXT_ERR_SUCCESS; } /* boot security check */ if (g_start_ctrl.upg_sections == TD_NULL) { return EXT_ERR_FAILURE; } section_info = ext_upg_head_get_section(0); ret = flash_boot_security_boot_verify( (td_pvoid)(uintptr_t)(0x1000000 + start_ctrl->flash_addr_upg + section_info->offset)); if (ret != EXT_ERR_SUCCESS) { return ret; } return EXT_ERR_SUCCESS; } #endif /* PRODUCT_CFG_SECURE_UPG */