forked from espressif/esp-idf
refactor(esp_tee): Add argument count checks for secure services in the dispatcher
Also: - Unified the TEE build system-related scripts into a single script
This commit is contained in:
@@ -82,57 +82,38 @@ else()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(secure_service_hdr_py
|
||||
${COMPONENT_DIR}/scripts/secure_service_hdr.py ${CMAKE_CURRENT_BINARY_DIR}/secure_service.tbl
|
||||
)
|
||||
set(secure_service_tbl_parser_py
|
||||
${COMPONENT_DIR}/scripts/secure_service_tbl_parser.py ${CMAKE_CURRENT_BINARY_DIR}/secure_service.tbl
|
||||
)
|
||||
|
||||
set(secure_service_tbl_py
|
||||
${COMPONENT_DIR}/scripts/secure_service_tbl.py ${CMAKE_CURRENT_BINARY_DIR}/secure_service.tbl
|
||||
)
|
||||
|
||||
set(secure_service_wrap_py
|
||||
${COMPONENT_DIR}/scripts/secure_service_wrap.py ${CMAKE_CURRENT_BINARY_DIR}/secure_service.tbl
|
||||
)
|
||||
|
||||
set(secure_service_num_h
|
||||
${CONFIG_DIR}/secure_service_num.h
|
||||
)
|
||||
set(secure_service_dec_h
|
||||
${CONFIG_DIR}/secure_service_dec.h)
|
||||
|
||||
set(secure_service_h
|
||||
set(secure_service_gen_headers
|
||||
${CONFIG_DIR}/secure_service_num.h ${CONFIG_DIR}/secure_service_dec.h
|
||||
${CONFIG_DIR}/secure_service.h
|
||||
)
|
||||
)
|
||||
|
||||
if(CONFIG_SECURE_ENABLE_TEE)
|
||||
execute_process(COMMAND cat ${COMPONENT_DIR}/scripts/${target}/secure_service.tbl ${custom_secure_service_tbl}
|
||||
if(CONFIG_SECURE_ENABLE_TEE AND NOT esp_tee_build)
|
||||
execute_process(
|
||||
COMMAND cat ${COMPONENT_DIR}/scripts/${target}/secure_service.tbl ${custom_secure_service_tbl}
|
||||
OUTPUT_FILE secure_service.tbl
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
)
|
||||
|
||||
execute_process(COMMAND python ${secure_service_hdr_py} ${secure_service_num_h} ${secure_service_dec_h}
|
||||
execute_process(
|
||||
COMMAND python ${secure_service_tbl_parser_py} ${secure_service_gen_headers}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
)
|
||||
|
||||
execute_process(COMMAND python ${secure_service_tbl_py} ${secure_service_h}
|
||||
set_property(DIRECTORY ${COMPONENT_DIR} APPEND PROPERTY
|
||||
ADDITIONAL_MAKE_CLEAN_FILES ${secure_service_gen_headers}
|
||||
)
|
||||
|
||||
execute_process(
|
||||
COMMAND python ${secure_service_tbl_parser_py} "--wrap"
|
||||
OUTPUT_VARIABLE wrap_list
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
set_property(DIRECTORY "${COMPONENT_DIR}" APPEND PROPERTY
|
||||
ADDITIONAL_MAKE_CLEAN_FILES ${secure_service_num_h} ${secure_service_dec_h} ${secure_service_h})
|
||||
|
||||
# For TEE implementation, we don't wrap the APIs since the TEE would also internally use the same API and
|
||||
# it shouldn't route to secure service API.
|
||||
# Instead of wrapping, we append _ss_* to the API name and then it must be defined in esp_secure_services.c
|
||||
if(NOT esp_tee_build)
|
||||
execute_process(COMMAND python ${secure_service_wrap_py}
|
||||
OUTPUT_VARIABLE wrap_list
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
string(STRIP ${wrap_list} wrap_list)
|
||||
|
||||
target_link_libraries(${COMPONENT_LIB} INTERFACE "${wrap_list}")
|
||||
endif()
|
||||
string(STRIP "${wrap_list}" wrap_list)
|
||||
target_link_libraries(${COMPONENT_LIB} INTERFACE "${wrap_list}")
|
||||
endif()
|
||||
|
@@ -1,76 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
import argparse
|
||||
import re
|
||||
from typing import List
|
||||
from typing import Tuple
|
||||
|
||||
|
||||
def parse_services(secure_service_tbl: str) -> List[Tuple[str, str, str]]:
|
||||
services: List[Tuple[str, str, str]] = []
|
||||
pattern: re.Pattern = re.compile(r'^([0-9A-Fa-fXx]+)\s+\S+\s+(\S+)\s+(\d+)')
|
||||
with open(secure_service_tbl, 'r') as f:
|
||||
for line in f:
|
||||
if match := pattern.match(line):
|
||||
services.append((match.group(1), match.group(2), match.group(3)))
|
||||
return sorted(services, key=lambda x: int(x[0]))
|
||||
|
||||
|
||||
def generate_num_header(services: List[Tuple[str, str, str]], output_file: str) -> None:
|
||||
header_text: str = '''/**
|
||||
* This header file is used to generate secure service number macros.
|
||||
*
|
||||
* THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT!
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
'''
|
||||
with open(output_file, 'w') as f:
|
||||
f.write(header_text)
|
||||
for nr, name, _ in services:
|
||||
f.write(f'#define SS_{name.upper()}\t{nr}\n')
|
||||
total: int = int(services[-1][0]) + 1 if services else 0
|
||||
f.write(f'\n#define MAX_SECURE_SERVICES\t{total}\n\n')
|
||||
|
||||
|
||||
def generate_dec_header(services: List[Tuple[str, str, str]], output_file: str) -> None:
|
||||
header_text: str = '''/**
|
||||
* This header file is used to provide function declarations
|
||||
* for compiling secure_service_table.c source file. Please do not
|
||||
* use it in application.
|
||||
*
|
||||
* THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT!
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
'''
|
||||
with open(output_file, 'w') as f:
|
||||
f.write(header_text)
|
||||
for _, name, _ in services:
|
||||
f.write(f'void _ss_{name}(void);\n')
|
||||
f.write('''
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
''')
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description='Generate secure service headers')
|
||||
parser.add_argument('secure_service_tbl', type=str, help='Path to secure_service.tbl generated in build directory')
|
||||
parser.add_argument('secure_service_num_h', type=str, help='Path to secure_service_num.h header file')
|
||||
parser.add_argument('secure_service_dec_h', type=str, help='Path to secure_service_dec.h header file')
|
||||
args = parser.parse_args()
|
||||
|
||||
services: List[Tuple[str, str, str]] = parse_services(args.secure_service_tbl)
|
||||
generate_num_header(services, args.secure_service_num_h)
|
||||
generate_dec_header(services, args.secure_service_dec_h)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@@ -1,50 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
import argparse
|
||||
import re
|
||||
import sys
|
||||
from typing import Dict
|
||||
from typing import Tuple
|
||||
|
||||
|
||||
def emit(nr: int, entry: str, nargs: str) -> str:
|
||||
return f'__SECURE_SERVICE({nr}, {entry}, {nargs})'
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description='Generate secure service table')
|
||||
parser.add_argument('input_file', type=str, help='Path to input file')
|
||||
parser.add_argument('output_file', type=str, help='Path to output file')
|
||||
args = parser.parse_args()
|
||||
|
||||
services: Dict[int, Tuple[str, str, str]] = {}
|
||||
pattern: re.Pattern = re.compile(r'^([0-9A-Fa-fXx]+)\s+(\S+)\s+(\S+)\s+(\d+)')
|
||||
|
||||
# Single pass through file to collect services and check duplicates
|
||||
with open(args.input_file, 'r') as f:
|
||||
for line in f:
|
||||
if match := pattern.match(line):
|
||||
nr = int(match.group(1))
|
||||
if nr in services:
|
||||
print('ERROR: Found duplicate secure service numbers, exiting...')
|
||||
sys.exit(1)
|
||||
services[nr] = (match.group(2), match.group(3), match.group(4))
|
||||
|
||||
# Generate output
|
||||
with open(args.output_file, 'w') as f:
|
||||
f.write('''/**
|
||||
* This header file is used to define secure services.
|
||||
*
|
||||
* THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT!
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
''')
|
||||
for nr in sorted(services):
|
||||
_, name, nargs = services[nr]
|
||||
f.write(emit(nr, name, nargs) + '\n')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
104
components/esp_tee/scripts/secure_service_tbl_parser.py
Normal file
104
components/esp_tee/scripts/secure_service_tbl_parser.py
Normal file
@@ -0,0 +1,104 @@
|
||||
# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
import argparse
|
||||
import re
|
||||
from typing import List
|
||||
from typing import Tuple
|
||||
|
||||
|
||||
def parse_services(secure_service_tbl: str) -> List[Tuple[int, str, int]]:
|
||||
services, service_ids = [], set()
|
||||
pattern = re.compile(r'^([0-9A-Fa-fXx]+)\s+\S+\s+(\S+)\s+(\d+)')
|
||||
|
||||
with open(secure_service_tbl, 'r') as f:
|
||||
for line in f:
|
||||
if match := pattern.match(line):
|
||||
service_id = int(match.group(1), 0)
|
||||
if service_id in service_ids:
|
||||
raise ValueError(f'Duplicate service call ID found: 0x{service_id:X}')
|
||||
service_ids.add(service_id)
|
||||
services.append((service_id, match.group(2), int(match.group(3))))
|
||||
|
||||
return sorted(services, key=lambda x: x[0])
|
||||
|
||||
|
||||
def generate_num_header(services: List[Tuple[int, str, int]], output_file: str) -> None:
|
||||
header = '''/**
|
||||
* THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT!
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
'''
|
||||
body = '\n'.join(f'#define SS_{name.upper()}\t{nr}' for nr, name, _ in services)
|
||||
footer = f'\n#define MAX_SECURE_SERVICES_ID\t{services[-1][0] + 1 if services else 0}\n'
|
||||
footer += f'#define SECURE_SERVICES_NUM\t{len(services)}\n\n'
|
||||
footer += '''typedef void (*secure_service_t)(void);
|
||||
typedef struct { int id; secure_service_t func; int nargs; } secure_service_entry_t;
|
||||
'''
|
||||
footer += '\n#ifdef __cplusplus\n}\n#endif\n'
|
||||
with open(output_file, 'w') as f:
|
||||
f.write(header + body + footer)
|
||||
|
||||
|
||||
def generate_dec_header(services: List[Tuple[int, str, int]], output_file: str) -> None:
|
||||
header = '''/**
|
||||
* THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT!
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
'''
|
||||
body = '\n'.join(f'void _ss_{name}(void);' for _, name, _ in services)
|
||||
footer = '\n#ifdef __cplusplus\n}\n#endif\n'
|
||||
with open(output_file, 'w') as f:
|
||||
f.write(header + body + footer)
|
||||
|
||||
|
||||
def generate_table(services: List[Tuple[int, str, int]], output_file: str) -> None:
|
||||
header = '''/**
|
||||
* THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT!
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
'''
|
||||
body = '\n'.join(f'__SECURE_SERVICE({nr}, {name}, {nargs})' for nr, name, nargs in services)
|
||||
with open(output_file, 'w') as f:
|
||||
f.write(header + body)
|
||||
|
||||
|
||||
def generate_wrap_list(secure_service_tbl: str) -> None:
|
||||
pattern = re.compile(r'^[0-9A-Fa-fXx]+\s+IDF\s+(\S+)\s+\d+')
|
||||
with open(secure_service_tbl, 'r') as f:
|
||||
wrap_list = [f'-Wl,--wrap={match.group(1)}' for line in f if (match := pattern.match(line))]
|
||||
print(' '.join(wrap_list), end='')
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description='Generate secure service outputs')
|
||||
parser.add_argument('--wrap', action='store_true', help='Generate linker wrap options')
|
||||
parser.add_argument('secure_service_tbl', type=str, help='Path to secure service table file')
|
||||
parser.add_argument('output_files', nargs='*', help='Output files: [secure_service_num.h, secure_service_dec.h, secure_service.h]')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.wrap:
|
||||
generate_wrap_list(args.secure_service_tbl)
|
||||
else:
|
||||
if len(args.output_files) != 3:
|
||||
parser.error('Missing output header files!')
|
||||
services = parse_services(args.secure_service_tbl)
|
||||
generate_num_header(services, args.output_files[0])
|
||||
generate_dec_header(services, args.output_files[1])
|
||||
generate_table(services, args.output_files[2])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@@ -1,24 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
import argparse
|
||||
import re
|
||||
from typing import List
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description='Generate secure service wrap list')
|
||||
parser.add_argument('secure_service_tbl', type=str, help='Path to secure service table file')
|
||||
args = parser.parse_args()
|
||||
|
||||
pattern: re.Pattern = re.compile(r'^[0-9A-Fa-fXx]+\s+IDF\s+(\S+)\s+\d+')
|
||||
|
||||
with open(args.secure_service_tbl, 'r') as f:
|
||||
wrap_list: List[str] = [f'-Wl,--wrap={match.group(1)}'
|
||||
for line in f if (match := pattern.match(line))]
|
||||
|
||||
print(' '.join(wrap_list), end='')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@@ -13,6 +13,34 @@
|
||||
|
||||
static const char *TAG = "esp_tee_sec_disp";
|
||||
|
||||
extern const secure_service_entry_t tee_secure_service_table[];
|
||||
|
||||
/* ---------------------------------------------- Secure Service Dispatcher ------------------------------------------------- */
|
||||
|
||||
const secure_service_entry_t *find_service_by_id(uint32_t id)
|
||||
{
|
||||
if (id >= MAX_SECURE_SERVICES_ID) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t left = 0;
|
||||
size_t right = SECURE_SERVICES_NUM;
|
||||
|
||||
while (left < right) {
|
||||
size_t mid = left + (right - left) / 2;
|
||||
|
||||
if (tee_secure_service_table[mid].id == id) {
|
||||
return &tee_secure_service_table[mid];
|
||||
} else if (tee_secure_service_table[mid].id < id) {
|
||||
left = mid + 1;
|
||||
} else {
|
||||
right = mid;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Entry point to the TEE binary during secure service call. It decipher the call and dispatch it
|
||||
* to corresponding Secure Service API in secure world.
|
||||
@@ -30,19 +58,25 @@ int esp_tee_service_dispatcher(int argc, va_list ap)
|
||||
}
|
||||
|
||||
int ret = -1;
|
||||
void *fp_secure_service;
|
||||
uint32_t argv[ESP_TEE_MAX_INPUT_ARG], *argp;
|
||||
|
||||
uint32_t sid = va_arg(ap, uint32_t);
|
||||
argc--;
|
||||
|
||||
if (sid >= MAX_SECURE_SERVICES) {
|
||||
ESP_LOGE(TAG, "Invalid Service ID!");
|
||||
const secure_service_entry_t *service = find_service_by_id(sid);
|
||||
if (service == NULL) {
|
||||
ESP_LOGE(TAG, "Invalid service ID!");
|
||||
va_end(ap);
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
fp_secure_service = (void *)tee_secure_service_table[sid];
|
||||
if (argc != service->nargs) {
|
||||
ESP_LOGE(TAG, "Invalid number of arguments for service %d!", sid);
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *fp_secure_service = (void *)service->func;
|
||||
|
||||
for (int i = 0; i < argc; i++) {
|
||||
argv[i] = va_arg(ap, uint32_t);
|
||||
@@ -107,4 +141,5 @@ int esp_tee_service_dispatcher(int argc, va_list ap)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#pragma GCC pop_options
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -8,17 +8,13 @@
|
||||
#include "secure_service_num.h"
|
||||
#include "secure_service_dec.h"
|
||||
|
||||
typedef void (*secure_service_t)(void);
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Woverride-init"
|
||||
#endif
|
||||
|
||||
const DRAM_ATTR secure_service_t tee_secure_service_table[] = {
|
||||
[0 ... MAX_SECURE_SERVICES - 1] = (secure_service_t)NULL,
|
||||
|
||||
#define __SECURE_SERVICE(nr, symbol, nargs) [nr] = (secure_service_t)_ss_##symbol,
|
||||
const DRAM_ATTR secure_service_entry_t tee_secure_service_table[] = {
|
||||
#define __SECURE_SERVICE(NR, SYM, ARGC) { .id = NR, .func = _ss_##SYM, .nargs = ARGC },
|
||||
#include "secure_service.h"
|
||||
};
|
||||
#ifdef __GNUC__
|
||||
|
Reference in New Issue
Block a user