/* * * Copyright 2019-2020 NXP * SPDX-License-Identifier: Apache-2.0 */ /* Common, Re-Usable main implementation */ /* Include this header file only once in the application for concurrent access. * This header file will not open the session to SE. * Application should ensure sss_session_open() api is called. */ /* * Applications control the boot flow by defining these macros. * * * - EX_SSS_BOOT_PCONTEXT : Pointer to ex_sss_boot_ctx_t * This allows that boot framework do not blindly rely on * global variables. * * - EX_SSS_BOOT_DO_ERASE : Delete all objects on boot up if 1 * Few examples expect the IC is *empty*, and few examples * expect to work with previously provisioned/persisted data. * This variable allows to over-ride that behaviour. * * - EX_SSS_BOOT_EXPOSE_ARGC_ARGV : Expose ARGC & ARGV from Command * line to Application. * When running from PC/Linux/OSX, command line arguments allow * to choose extra command line parameters, e.g. Input/Output * certificate or signing/verifying data. * But on embedded platforms, such feature is not possible to * achieve. * * Optional variables: * * - EX_SSS_BOOT_RTOS_STACK_SIZE : For RTOS based system, * this is over-ridden and passed to RTOS based example * boot up. It sets value needed for new task. * Please note, FREE RTOS will reserve * EX_SSS_BOOT_RTOS_STACK_SIZE * sizeof(UBaseType_t) * bytes. * * - EX_SSS_BOOT_OPEN_HOST_SESSION : For examples that do not * need host side implementation, his allows to skip opening * the host session. (Host session is needed to either re-verify * test data at host, or for SCP03). * By default this is enabled. * * */ #if defined(FRDM_KW41Z) || defined(FRDM_K64F) || defined(IMX_RT) || defined(LPC_55x) || defined(QN9090DK6) #define HAVE_KSDK #endif #ifdef HAVE_KSDK #include "ex_sss_main_inc_ksdk.h" #endif #if defined(__linux__) && defined(T1oI2C) #if SSS_HAVE_APPLET_SE05X_IOT #include "ex_sss_main_inc_linux.h" #endif #endif #include /* memset */ #include "PlugAndTrust_Pkg_Ver.h" #include "string.h" /* memset */ #if AX_EMBEDDED && defined(USE_RTOS) && USE_RTOS == 1 #ifndef INC_FREERTOS_H /* Header guard of FreeRTOS */ #include "FreeRTOS.h" #include "FreeRTOSConfig.h" #endif /* INC_FREERTOS_H */ #include "task.h" #endif #if SSS_HAVE_A71CH || SSS_HAVE_A71CH_SIM #include "ex_a71ch_scp03.h" #endif #ifdef EX_SSS_BOOT_PCONTEXT #define PCONTEXT EX_SSS_BOOT_PCONTEXT #else #define PCONTEXT (NULL) #endif #if !defined(EX_SSS_BOOT_DO_ERASE) #error EX_SSS_BOOT_DO_ERASE must be set to 0 or 1 #endif #if !defined(EX_SSS_BOOT_EXPOSE_ARGC_ARGV) #error EX_SSS_BOOT_EXPOSE_ARGC_ARGV must be set to 0 or 1 #endif #if EX_SSS_BOOT_EXPOSE_ARGC_ARGV static int gex_sss_argc; static const char **gex_sss_argv; #endif #if !defined(EX_SSS_BOOT_OPEN_HOST_SESSION) #define EX_SSS_BOOT_OPEN_HOST_SESSION 1 #endif #if !defined(EX_SSS_BOOT_RTOS_STACK_SIZE) #define EX_SSS_BOOT_RTOS_STACK_SIZE 8500 #endif #if AX_EMBEDDED && defined(USE_RTOS) && USE_RTOS == 1 static TaskHandle_t gSSSExRtosTaskHandle = NULL; static void sss_ex_rtos_task(void *ctx); #if INCLUDE_uxTaskGetStackHighWaterMark void sss_ex_rtos_stack_size(const char *when); #endif // INCLUDE_uxTaskGetStackHighWaterMark #endif /* No RTOS, No Embedded */ int main(int argc, const char *argv[]) { int ret; sss_status_t status = kStatus_SSS_Fail; // const char *portName; #if EX_SSS_BOOT_EXPOSE_ARGC_ARGV gex_sss_argc = argc; gex_sss_argv = argv; #endif // EX_SSS_BOOT_EXPOSE_ARGC_ARGV #ifdef HAVE_KSDK ex_sss_main_ksdk_bm(); #endif // HAVE_KSDK #if defined(__linux__) && defined(T1oI2C) && SSS_HAVE_APPLET_SE05X_IOT ex_sss_main_linux_conf(); #endif // defined(__linux__) && defined(T1oI2C) && SSS_HAVE_APPLET_SE05X_IOT LOG_I(PLUGANDTRUST_PROD_NAME_VER_FULL); #ifdef EX_SSS_BOOT_PCONTEXT memset((EX_SSS_BOOT_PCONTEXT), 0, sizeof(*(EX_SSS_BOOT_PCONTEXT))); #endif // EX_SSS_BOOT_PCONTEXT #if defined(EX_SSS_BOOT_SKIP_SELECT_APPLET) && (EX_SSS_BOOT_SKIP_SELECT_APPLET == 1) (PCONTEXT)->se05x_open_ctx.skip_select_applet = 1; #endif #if AX_EMBEDDED && defined(USE_RTOS) && USE_RTOS == 1 if (xTaskCreate(&sss_ex_rtos_task, "sss_ex_rtos_task", EX_SSS_BOOT_RTOS_STACK_SIZE, (void *)portName, (tskIDLE_PRIORITY), &gSSSExRtosTaskHandle) != pdPASS) { LOG_E("Task creation failed!.\r\n"); while (1) ; } /* Run RTOS */ vTaskStartScheduler(); #else /* No RTOS, No Embedded */ //Session to SE is opened inside the Demo #if (SSS_HAVE_A71CH || SSS_HAVE_A71CH_SIM) && SSS_HAVE_A71CH_AUTH_SCP03 LOG_I("A71CH SCP03 add-on"); { // Variables used by calls to legacy API U8 sCounter[3]; U16 sCounterLen = sizeof(sCounter); U16 sw = 0; U8 scpKeyEncBase[SCP_KEY_SIZE]; U8 scpKeyMacBase[SCP_KEY_SIZE]; U8 scpKeyDekBase[SCP_KEY_SIZE]; LOG_I("** Establish SCP03 session: Start **"); status = ex_a71ch_FetchRandomScp03Keys(scpKeyEncBase, scpKeyMacBase, scpKeyDekBase); ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success); status = ex_a71ch_SetSeScp03Keys(scpKeyEncBase, scpKeyMacBase, scpKeyDekBase); ENSURE_OR_GO_CLEANUP(status == kStatus_SSS_Success); LOG_I("Clear host-side SCP03 channel state"); DEV_ClearChannelState(); LOG_I("SCP_Authenticate()"); sw = SCP_Authenticate(scpKeyEncBase, scpKeyMacBase, scpKeyDekBase, SCP_KEY_SIZE, sCounter, &sCounterLen); status = (sw == SW_OK) ? kStatus_SSS_Success : kStatus_SSS_Fail; ENSURE_OR_GO_CLEANUP(sw == SW_OK); LOG_I("** Establish SCP03 session: End **"); } #endif // SSS_HAVE_A71CH && SSS_HAVE_A71CH_AUTH_SCP03 status = ex_sss_entry((PCONTEXT)); LOG_I("ex_sss Finished"); if (kStatus_SSS_Success != status) { LOG_E("ex_sss_entry Failed"); goto cleanup; } #endif /* No RTOS, No Embedded */ goto cleanup; cleanup: #ifdef EX_SSS_BOOT_PCONTEXT ex_sss_session_close((EX_SSS_BOOT_PCONTEXT)); #endif if (kStatus_SSS_Success == status) { ret = 0; #if defined(HAVE_KSDK) && HAVE_KSDK_LED_APIS == 1 ex_sss_main_ksdk_success(); #endif #if defined(__linux__) && defined(T1oI2C) && SSS_HAVE_APPLET_SE05X_IOT ex_sss_main_linux_unconf(); #endif // defined(__linux__) && defined(T1oI2C) && SSS_HAVE_APPLET_SE05X_IOT } else { LOG_E("!ERROR! ret != 0."); ret = 1; #if defined(HAVE_KSDK) && HAVE_KSDK_LED_APIS == 1 ex_sss_main_ksdk_failure(); #endif } return ret; } #if AX_EMBEDDED && defined(USE_RTOS) && USE_RTOS == 1 static void sss_ex_rtos_task(void *ctx) { sss_status_t status; #if INCLUDE_uxTaskGetStackHighWaterMark sss_ex_rtos_stack_size("Boot"); #endif // INCLUDE_uxTaskGetStackHighWaterMark ex_sss_main_ksdk_boot_rtos_task(); status = ex_sss_boot_open(PCONTEXT, (const char *)ctx); if (kStatus_SSS_Success != status) { LOG_E("ex_sss_session_open Failed."); goto exit; } status = ex_sss_key_store_and_object_init((PCONTEXT)); if (kStatus_SSS_Success != status) { LOG_E("ex_sss_key_store_and_object_init Failed"); goto exit; } #if INCLUDE_uxTaskGetStackHighWaterMark sss_ex_rtos_stack_size("Before:ex_sss_entry"); #endif // INCLUDE_uxTaskGetStackHighWaterMark #if EX_SSS_BOOT_DO_ERASE status = ex_sss_boot_factory_reset((PCONTEXT)); if (kStatus_SSS_Success != status) { LOG_W("ex_sss_boot_factory_reset Failed"); } #if INCLUDE_uxTaskGetStackHighWaterMark sss_ex_rtos_stack_size("after:erase"); #endif // INCLUDE_uxTaskGetStackHighWaterMark #endif #if SSS_HAVE_A71CH || SSS_HAVE_A71CH_SIM #if EX_SSS_BOOT_OPEN_HOST_SESSION ex_sss_boot_open_host_session((PCONTEXT)); #endif #endif status = ex_sss_entry((PCONTEXT)); LOG_I("ex_sss Finished"); if (kStatus_SSS_Success != status) { LOG_E("ex_sss_entry Failed"); } #if INCLUDE_uxTaskGetStackHighWaterMark sss_ex_rtos_stack_size("After:ex_sss_entry"); #endif // INCLUDE_uxTaskGetStackHighWaterMark exit: vTaskDelete(NULL); } #if INCLUDE_uxTaskGetStackHighWaterMark void sss_ex_rtos_stack_size(const char *when) { #if LOG_INFO_ENABLED UBaseType_t stackused; stackused = EX_SSS_BOOT_RTOS_STACK_SIZE - uxTaskGetStackHighWaterMark(gSSSExRtosTaskHandle); LOG_I("STACK USED [%s] %d", when, sizeof(UBaseType_t) * stackused); #endif } #endif /* INCLUDE_uxTaskGetStackHighWaterMark */ #endif /* No RTOS, No Embedded */