From 7689a801d4ae2fa80bd3654c6808659de6e348fc Mon Sep 17 00:00:00 2001 From: Martin Vychodil Date: Mon, 4 Oct 2021 19:25:32 +0200 Subject: [PATCH] System/Memprot: fixed voltage glitching detection logic When the application is being debugged it should check the call result (esp_cpu_in_ocd_debug_mode()) is not given volt.glitch attack - so the result is triple-checked by ESP_FAULT_ASSERT macro. In case the check fails, the system is reset immediately IDF-4014 --- components/esp32c3/memprot.c | 149 +++++++++++++++++++---------------- components/esp32s2/memprot.c | 48 ++++++----- 2 files changed, 102 insertions(+), 95 deletions(-) diff --git a/components/esp32c3/memprot.c b/components/esp32c3/memprot.c index ec3bd69521..b3d819284a 100644 --- a/components/esp32c3/memprot.c +++ b/components/esp32c3/memprot.c @@ -26,6 +26,8 @@ #include "esp32c3/memprot.h" #include "riscv/interrupt.h" #include "esp32c3/rom/ets_sys.h" +#include "esp_fault.h" +#include "soc/cpu.h" extern int _iram_text_end; @@ -99,18 +101,18 @@ void *esp_memprot_get_default_main_split_addr() uint32_t *esp_memprot_get_split_addr(split_line_t line_type) { switch ( line_type ) { - case MEMPROT_IRAM0_DRAM0_SPLITLINE: - return memprot_ll_get_iram0_split_line_main_I_D(); - case MEMPROT_IRAM0_LINE_0_SPLITLINE: - return memprot_ll_get_iram0_split_line_I_0(); - case MEMPROT_IRAM0_LINE_1_SPLITLINE: - return memprot_ll_get_iram0_split_line_I_1(); - case MEMPROT_DRAM0_DMA_LINE_0_SPLITLINE: - return memprot_ll_get_dram0_split_line_D_0(); - case MEMPROT_DRAM0_DMA_LINE_1_SPLITLINE: - return memprot_ll_get_dram0_split_line_D_1(); - default: - abort(); + case MEMPROT_IRAM0_DRAM0_SPLITLINE: + return memprot_ll_get_iram0_split_line_main_I_D(); + case MEMPROT_IRAM0_LINE_0_SPLITLINE: + return memprot_ll_get_iram0_split_line_I_0(); + case MEMPROT_IRAM0_LINE_1_SPLITLINE: + return memprot_ll_get_iram0_split_line_I_1(); + case MEMPROT_DRAM0_DMA_LINE_0_SPLITLINE: + return memprot_ll_get_dram0_split_line_D_0(); + case MEMPROT_DRAM0_DMA_LINE_1_SPLITLINE: + return memprot_ll_get_dram0_split_line_D_1(); + default: + abort(); } } @@ -397,9 +399,9 @@ pms_world_t esp_memprot_get_violate_world(mem_type_prot_t mem_type) } switch ( world ) { - case 0x01: return MEMPROT_PMS_WORLD_0; - case 0x10: return MEMPROT_PMS_WORLD_1; - default: return MEMPROT_PMS_WORLD_INVALID; + case 0x01: return MEMPROT_PMS_WORLD_0; + case 0x10: return MEMPROT_PMS_WORLD_1; + default: return MEMPROT_PMS_WORLD_INVALID; } } @@ -469,74 +471,81 @@ void esp_memprot_set_prot(bool invoke_panic_handler, bool lock_feature, uint32_t void esp_memprot_set_prot_int(bool invoke_panic_handler, bool lock_feature, void *split_addr, uint32_t *mem_type_mask) { - uint32_t required_mem_prot = mem_type_mask == NULL ? (uint32_t)MEMPROT_ALL : *mem_type_mask; - bool use_iram0 = required_mem_prot & MEMPROT_IRAM0_SRAM; - bool use_dram0 = required_mem_prot & MEMPROT_DRAM0_SRAM; + //if being debugged check we are not glitched and dont enable Memprot + if (esp_cpu_in_ocd_debug_mode()) { + ESP_FAULT_ASSERT(esp_cpu_in_ocd_debug_mode()); + } else { + uint32_t required_mem_prot = mem_type_mask == NULL ? (uint32_t) MEMPROT_ALL : *mem_type_mask; + bool use_iram0 = required_mem_prot & MEMPROT_IRAM0_SRAM; + bool use_dram0 = required_mem_prot & MEMPROT_DRAM0_SRAM; - if (required_mem_prot == MEMPROT_NONE) { - return; - } + if (required_mem_prot == MEMPROT_NONE) { + return; + } - //disable protection - if (use_iram0) { - esp_memprot_set_monitor_en(MEMPROT_IRAM0_SRAM, false); - } - if (use_dram0) { - esp_memprot_set_monitor_en(MEMPROT_DRAM0_SRAM, false); - } - - //panic handling - if (invoke_panic_handler) { + //disable protection if (use_iram0) { - esp_memprot_set_intr_matrix(MEMPROT_IRAM0_SRAM); + esp_memprot_set_monitor_en(MEMPROT_IRAM0_SRAM, false); } if (use_dram0) { - esp_memprot_set_intr_matrix(MEMPROT_DRAM0_SRAM); + esp_memprot_set_monitor_en(MEMPROT_DRAM0_SRAM, false); } - } - //set split lines (must-have for all mem_types) - const void *line_addr = split_addr == NULL ? esp_memprot_get_default_main_split_addr() : split_addr; - esp_memprot_set_split_line(MEMPROT_IRAM0_LINE_1_SPLITLINE, line_addr); - esp_memprot_set_split_line(MEMPROT_IRAM0_LINE_0_SPLITLINE, line_addr); - esp_memprot_set_split_line(MEMPROT_IRAM0_DRAM0_SPLITLINE, line_addr); - esp_memprot_set_split_line(MEMPROT_DRAM0_DMA_LINE_0_SPLITLINE, (void *)(MAP_IRAM_TO_DRAM((uint32_t)line_addr))); - esp_memprot_set_split_line(MEMPROT_DRAM0_DMA_LINE_1_SPLITLINE, (void *)(MAP_IRAM_TO_DRAM((uint32_t)line_addr))); + //panic handling + if (invoke_panic_handler) { + if (use_iram0) { + esp_memprot_set_intr_matrix(MEMPROT_IRAM0_SRAM); + } + if (use_dram0) { + esp_memprot_set_intr_matrix(MEMPROT_DRAM0_SRAM); + } + } - //set permissions - if (required_mem_prot & MEMPROT_IRAM0_SRAM) { - esp_memprot_iram_set_pms_area(MEMPROT_IRAM0_PMS_AREA_0, true, false, true); - esp_memprot_iram_set_pms_area(MEMPROT_IRAM0_PMS_AREA_1, true, false, true); - esp_memprot_iram_set_pms_area(MEMPROT_IRAM0_PMS_AREA_2, true, false, true); - esp_memprot_iram_set_pms_area(MEMPROT_IRAM0_PMS_AREA_3, true, true, false); - } - if (required_mem_prot & MEMPROT_DRAM0_SRAM) { - esp_memprot_dram_set_pms_area( MEMPROT_DRAM0_PMS_AREA_0, true, false ); - esp_memprot_dram_set_pms_area(MEMPROT_DRAM0_PMS_AREA_1, true, true); - esp_memprot_dram_set_pms_area(MEMPROT_DRAM0_PMS_AREA_2, true, true); - esp_memprot_dram_set_pms_area(MEMPROT_DRAM0_PMS_AREA_3, true, true); - } + //set split lines (must-have for all mem_types) + const void *line_addr = split_addr == NULL ? esp_memprot_get_default_main_split_addr() : split_addr; + esp_memprot_set_split_line(MEMPROT_IRAM0_LINE_1_SPLITLINE, line_addr); + esp_memprot_set_split_line(MEMPROT_IRAM0_LINE_0_SPLITLINE, line_addr); + esp_memprot_set_split_line(MEMPROT_IRAM0_DRAM0_SPLITLINE, line_addr); + esp_memprot_set_split_line(MEMPROT_DRAM0_DMA_LINE_0_SPLITLINE, + (void *) (MAP_IRAM_TO_DRAM((uint32_t) line_addr))); + esp_memprot_set_split_line(MEMPROT_DRAM0_DMA_LINE_1_SPLITLINE, + (void *) (MAP_IRAM_TO_DRAM((uint32_t) line_addr))); - //reenable protection - if (use_iram0) { - esp_memprot_monitor_clear_intr(MEMPROT_IRAM0_SRAM); - esp_memprot_set_monitor_en(MEMPROT_IRAM0_SRAM, true); - } - if (use_dram0) { - esp_memprot_monitor_clear_intr(MEMPROT_DRAM0_SRAM); - esp_memprot_set_monitor_en(MEMPROT_DRAM0_SRAM, true); - } + //set permissions + if (required_mem_prot & MEMPROT_IRAM0_SRAM) { + esp_memprot_iram_set_pms_area(MEMPROT_IRAM0_PMS_AREA_0, true, false, true); + esp_memprot_iram_set_pms_area(MEMPROT_IRAM0_PMS_AREA_1, true, false, true); + esp_memprot_iram_set_pms_area(MEMPROT_IRAM0_PMS_AREA_2, true, false, true); + esp_memprot_iram_set_pms_area(MEMPROT_IRAM0_PMS_AREA_3, true, true, false); + } + if (required_mem_prot & MEMPROT_DRAM0_SRAM) { + esp_memprot_dram_set_pms_area(MEMPROT_DRAM0_PMS_AREA_0, true, false); + esp_memprot_dram_set_pms_area(MEMPROT_DRAM0_PMS_AREA_1, true, true); + esp_memprot_dram_set_pms_area(MEMPROT_DRAM0_PMS_AREA_2, true, true); + esp_memprot_dram_set_pms_area(MEMPROT_DRAM0_PMS_AREA_3, true, true); + } - //lock if required - if (lock_feature) { - esp_memprot_set_split_line_lock(); + //reenable protection if (use_iram0) { - esp_memprot_set_pms_lock(MEMPROT_IRAM0_SRAM); - esp_memprot_set_monitor_lock(MEMPROT_IRAM0_SRAM); + esp_memprot_monitor_clear_intr(MEMPROT_IRAM0_SRAM); + esp_memprot_set_monitor_en(MEMPROT_IRAM0_SRAM, true); } if (use_dram0) { - esp_memprot_set_pms_lock(MEMPROT_DRAM0_SRAM); - esp_memprot_set_monitor_lock(MEMPROT_DRAM0_SRAM); + esp_memprot_monitor_clear_intr(MEMPROT_DRAM0_SRAM); + esp_memprot_set_monitor_en(MEMPROT_DRAM0_SRAM, true); + } + + //lock if required + if (lock_feature) { + esp_memprot_set_split_line_lock(); + if (use_iram0) { + esp_memprot_set_pms_lock(MEMPROT_IRAM0_SRAM); + esp_memprot_set_monitor_lock(MEMPROT_IRAM0_SRAM); + } + if (use_dram0) { + esp_memprot_set_pms_lock(MEMPROT_DRAM0_SRAM); + esp_memprot_set_monitor_lock(MEMPROT_DRAM0_SRAM); + } } } } diff --git a/components/esp32s2/memprot.c b/components/esp32s2/memprot.c index 96ce98c8eb..31b764b6f7 100644 --- a/components/esp32s2/memprot.c +++ b/components/esp32s2/memprot.c @@ -30,7 +30,6 @@ static const char *TAG = "memprot"; #include "hal/memprot_ll.h" #include "hal/memprot_peri_ll.h" #include "esp_fault.h" - #include "soc/cpu.h" extern int _iram_text_end; @@ -650,33 +649,32 @@ void esp_memprot_set_prot_peri2(mem_type_prot_t mem_type, uint32_t *split_addr, void esp_memprot_set_prot(bool invoke_panic_handler, bool lock_feature, uint32_t *mem_type_mask) { - //any IRAM0/DRAM0 enable/disable call applies to all memory modules connected - uint32_t required_mem_prot = mem_type_mask == NULL ? (uint32_t)MEMPROT_ALL : *mem_type_mask; - bool use_iram0 = required_mem_prot & MEMPROT_IRAM0_SRAM || required_mem_prot & MEMPROT_IRAM0_RTCFAST; - bool use_dram0 = required_mem_prot & MEMPROT_DRAM0_SRAM || required_mem_prot & MEMPROT_DRAM0_RTCFAST; - bool use_peri1 = required_mem_prot & MEMPROT_PERI1_RTCSLOW; - bool use_peri2 = required_mem_prot & MEMPROT_PERI2_RTCSLOW_0 || required_mem_prot & MEMPROT_PERI2_RTCSLOW_1; + //if being debugged check we are not glitched and dont enable Memprot + if (esp_cpu_in_ocd_debug_mode()) { + ESP_FAULT_ASSERT(esp_cpu_in_ocd_debug_mode()); + } else { - //disable protection - if (use_iram0) { - esp_memprot_intr_ena(MEMPROT_IRAM0_SRAM, false); - } - if (use_dram0) { - esp_memprot_intr_ena(MEMPROT_DRAM0_SRAM, false); - } - if (use_peri1) { - esp_memprot_intr_ena(MEMPROT_PERI1_RTCSLOW, false); - } - if (use_peri2) { - esp_memprot_intr_ena(MEMPROT_PERI2_RTCSLOW_0, false); - } + //any IRAM0/DRAM0 enable/disable call applies to all memory modules connected + uint32_t required_mem_prot = mem_type_mask == NULL ? (uint32_t)MEMPROT_ALL : *mem_type_mask; + bool use_iram0 = required_mem_prot & MEMPROT_IRAM0_SRAM || required_mem_prot & MEMPROT_IRAM0_RTCFAST; + bool use_dram0 = required_mem_prot & MEMPROT_DRAM0_SRAM || required_mem_prot & MEMPROT_DRAM0_RTCFAST; + bool use_peri1 = required_mem_prot & MEMPROT_PERI1_RTCSLOW; + bool use_peri2 = required_mem_prot & MEMPROT_PERI2_RTCSLOW_0 || required_mem_prot & MEMPROT_PERI2_RTCSLOW_1; - //connect to intr. matrix if not being debugged - if (!esp_cpu_in_ocd_debug_mode()) { + //disable protection + if (use_iram0) { + esp_memprot_intr_ena(MEMPROT_IRAM0_SRAM, false); + } + if (use_dram0) { + esp_memprot_intr_ena(MEMPROT_DRAM0_SRAM, false); + } + if (use_peri1) { + esp_memprot_intr_ena(MEMPROT_PERI1_RTCSLOW, false); + } + if (use_peri2) { + esp_memprot_intr_ena(MEMPROT_PERI2_RTCSLOW_0, false); + } - ESP_FAULT_ASSERT(!esp_cpu_in_ocd_debug_mode()); - - //initialize for specific buses (any memory type does the job) if (invoke_panic_handler) { if (use_iram0) { esp_memprot_intr_init(MEMPROT_IRAM0_SRAM);