From c28117a281e4541c499e93d72e68ebf522d772b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joachim=20Str=C3=B6mbergson?= Date: Tue, 19 Mar 2024 13:17:14 +0100 Subject: [PATCH] Change name of cpu_monitor to security_monitor and include RAM access violations. --- hw/application_fpga/core/tk1/README.md | 42 +++++++++++++++----------- hw/application_fpga/core/tk1/rtl/tk1.v | 35 +++++++++++++++------ 2 files changed, 51 insertions(+), 26 deletions(-) diff --git a/hw/application_fpga/core/tk1/README.md b/hw/application_fpga/core/tk1/README.md index f0ad8e16..d4622ea2 100644 --- a/hw/application_fpga/core/tk1/README.md +++ b/hw/application_fpga/core/tk1/README.md @@ -129,7 +129,7 @@ data itself is scrambled. FW writes random values to these registers during boot. -### Execution monitor +### Security monitor ``` ADDR_CPU_MON_CTRL: 0x60 @@ -137,36 +137,44 @@ during boot. ADDR_CPU_MON_LAST: 0x62 ``` -These registers control the execution monitor related to the RAM. Once -enabled, by writing to ADDR_CPU_MON_CTRL, the memory are defined by -ADDR_CPU_MON_FIRST and ADDR_CPU_MON_LAST inclusive will be protected -against execution. Typically this will be the application stack and, -or heap. +Monitors events and state changes in the SoC, and handle security +violations. Currently checks for: -Applications can write to these registers to define the area and then -enable the monitor. One enabled, the monitor can't be disabled, and -the ADDR_CPU_MON_FIRST and ADDR_CPU_MON_LAST registers can't be +1. Trying to exectute instructions in FW-RAM. +2. Trying to access RAM outside of the physical memory. +3. Trying to execute instructions from a memory area in RAM defined by +the application. + +The first and second point in the bullet list above, is always +enabled. The third is set and enabled by the application. Once +enabled, by writing to ADDR_CPU_MON_CTRL, the memory defined by +ADDR_CPU_MON_FIRST and ADDR_CPU_MON_LAST will be protected against +execution. Typically this will be the application stack and, or heap. + +An application can write to these registers to define the area and +then enable the monitor. Once enabled, the monitor can't be disabled, +and the ADDR_CPU_MON_FIRST and ADDR_CPU_MON_LAST registers can't be changes. This means that an application that wants to use the monitor must define the area first before enabling the monitor. Once enabled, if the CPU tries to read an instruction from the defined area, the core will force the CPU to instead read an all zero, illegal instruction. This illegal instruction will trigger the CPU to enter -its TRAP state, from which it can't returned unless the TKey is power +its TRAP state, from which it can't return unless the TKey is power cycled. -The FW will not write to these registers as part of loading an -app. The app developer must define the area and enable the monitor to -get the protection. +The FW will not write to these registers as part of loading an app. +The app developer must define the area and enable the monitor to get +the protection. Note that there is a second memory area that is under the protection -of the execution monitor - the FW_RAM. The execution protection of -this memory is always anabled and the definition of the area is hard +of the Security monitor - the FW_RAM. The execution protection of +this memory is always enabled and the definition of the area is hard coded into the FPGA design. One feature not obvious from the API is that when the CPU traps, the -core will detect that and start flashing the RGB LED with a red -light - indicating that the CPU is its trap state and no further +core will detect that and start flashing the RGB LED with a red light +- indicating that the CPU is in a trapped state and no further execution is possible. diff --git a/hw/application_fpga/core/tk1/rtl/tk1.v b/hw/application_fpga/core/tk1/rtl/tk1.v index e696e7dd..9a412258 100644 --- a/hw/application_fpga/core/tk1/rtl/tk1.v +++ b/hw/application_fpga/core/tk1/rtl/tk1.v @@ -325,23 +325,40 @@ module tk1( //---------------------------------------------------------------- - // cpu_monitor + // security_monitor + // + // Monitor events and state changes in the SoC, and handle + // security violations. We currently check for: + // + // Any access to RAM but outside of the size of the physical mem. + // + // Trying to execute instructions in FW-RAM. + // + // Trying to execute code in mem area set to be data access only. + // This requires execution monitor to have been setup and + // enabled. //---------------------------------------------------------------- always @* - begin : cpu_monitor + begin : security_monitor force_trap_set = 1'h0; - if (cpu_valid && cpu_instr) begin - if ((cpu_addr >= FW_RAM_FIRST) && - (cpu_addr <= FW_RAM_LAST)) begin - force_trap_set = 1'h1; + if (cpu_valid) begin + if (cpu_addr[31 : 30] == 2'h01 & |cpu_addr[29 : 17]) begin + force_trap_set = 1'h1; end - if (cpu_mon_en_reg) begin - if ((cpu_addr >= cpu_mon_first_reg) && - (cpu_addr <= cpu_mon_last_reg)) begin + if (cpu_instr) begin + if ((cpu_addr >= FW_RAM_FIRST) && + (cpu_addr <= FW_RAM_LAST)) begin force_trap_set = 1'h1; end + + if (cpu_mon_en_reg) begin + if ((cpu_addr >= cpu_mon_first_reg) && + (cpu_addr <= cpu_mon_last_reg)) begin + force_trap_set = 1'h1; + end + end end end end