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
This commit is contained in:
Martin Vychodil 2021-10-04 06:37:56 +02:00
parent e35a87f723
commit 5344de34c3
2 changed files with 72 additions and 71 deletions

View File

@ -19,7 +19,7 @@
#include "riscv/interrupt.h"
#include "esp32c3/rom/ets_sys.h"
#include "esp_log.h"
#include "esp_fault.h"
#include "soc/cpu.h"
extern int _iram_text_end;
@ -94,18 +94,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();
}
}
@ -430,9 +430,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;
}
}
@ -526,63 +526,65 @@ void esp_memprot_set_prot_int(bool invoke_panic_handler, bool lock_feature, void
esp_memprot_set_monitor_en(MEMPROT_DRAM0_SRAM, false);
}
// do not enable if being debugged
//if being debugged check we are not glitched and dont enable Memprot
if (esp_cpu_in_ocd_debug_mode()) {
return;
}
ESP_FAULT_ASSERT(esp_cpu_in_ocd_debug_mode());
} else {
//panic handling
if (invoke_panic_handler) {
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 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)));
//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);
}
//reenable the protection
if (use_iram0) {
esp_memprot_set_intr_matrix(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_intr_matrix(MEMPROT_DRAM0_SRAM);
esp_memprot_monitor_clear_intr(MEMPROT_DRAM0_SRAM);
esp_memprot_set_monitor_en(MEMPROT_DRAM0_SRAM, 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)));
//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);
}
//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);
}
//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);
//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);
}
}
}
}

View File

@ -802,11 +802,10 @@ esp_err_t esp_memprot_set_prot(bool invoke_panic_handler, bool lock_feature, uin
return ret;
}
//connect to intr. matrix if not being debugged
if (!esp_cpu_in_ocd_debug_mode()) {
ESP_FAULT_ASSERT(!esp_cpu_in_ocd_debug_mode());
//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 {
//initialize for specific buses (any memory type does the job)
if (invoke_panic_handler) {
if (use_iram0 && (ret = esp_memprot_intr_init(MEMPROT_IRAM0_SRAM)) != ESP_OK) {