PoC: Make sensitive assets only readable/writable before system_mode is set

After the first time system_mode is set to one, the assets will no
longer be read- or writeable, even if system_mode is set to zero at a
later syscall. This is to make sure syscalls does not have the same
privilege as the firmware has at first boot.

We need to monitor when system_mode is set to one, otherwise we might
accedentially lock the assets before actually leaving firmware, for
example if firmware would use a function set in any of the registers
used in system_mode_ctrl.

Co-authored-by: Mikael Ågren <mikael@tillitis.se>
This commit is contained in:
Daniel Jobson 2024-11-15 11:19:40 +01:00 committed by Mikael Ågren
parent eacfd6eddc
commit 833bf63bc8
No known key found for this signature in database
GPG Key ID: E02DA3D397792C46
5 changed files with 44 additions and 24 deletions

View File

@ -132,17 +132,36 @@ Interrupts can be enabled/disabled using the PicoRV32 specific
The following table shows resource availablility for each execution The following table shows resource availablility for each execution
mode: mode:
| *Execution Mode* | *ROM* | *FW RAM* | *SPI* | | *Execution Mode* | *ROM* | *FW RAM* | *SPI* | *Sensitive assets* |
|---------------------|--------|----------|-------| |------------------|--------|----------|-------|--------------------|
| Firmware mode | r/x | r/w | r/w | | Firmware mode | r/x | r/w | r/w | r/w* |
| IRQ_SYSCALL | r/x | r/w | r/w | | IRQ_SYSCALL | r/x | r/w | r/w | r* |
| Application mode | r | i | i | | Application mode | r | i | i | r* |
Legend: Legend:
r = readable r = readable
w = writeable w = writeable
x = executable x = executable
i = invisible i = invisible
* = read-/writeability varies, see below
These sensitive assets are only readable and/or writeable in firmware
mode:
- APP_START
- APP_SIZE
- CDI_FIRST
- CDI_LAST
- RAM_ADDR_RAND
- RAM_DATA_RAND
- UDI_FIRST
- UDI_LAST
- UDS_FIRST
- UDS_LAST
Note that these assets have different properties, some are read-only
and some are write-only. The list above only shows if they are
restricted in app mode. See each individual API to find out more about
their properties.
## `tk1` ## `tk1`

View File

@ -20,7 +20,7 @@ module tk1 #(
input wire reset_n, input wire reset_n,
input wire cpu_trap, input wire cpu_trap,
output wire system_mode, output wire rw_locked,
input wire [31 : 0] cpu_addr, input wire [31 : 0] cpu_addr,
input wire cpu_instr, input wire cpu_instr,
@ -185,14 +185,14 @@ module tk1 #(
wire rom_exec_en; wire rom_exec_en;
wire system_mode;
//---------------------------------------------------------------- //----------------------------------------------------------------
// Concurrent connectivity for ports etc. // Concurrent connectivity for ports etc.
//---------------------------------------------------------------- //----------------------------------------------------------------
assign read_data = tmp_read_data; assign read_data = tmp_read_data;
assign ready = tmp_ready; assign ready = tmp_ready;
assign system_mode = system_mode_reg;
assign force_trap = force_trap_reg; assign force_trap = force_trap_reg;
assign gpio3 = gpio3_reg; assign gpio3 = gpio3_reg;
@ -203,9 +203,12 @@ module tk1 #(
assign system_reset = system_reset_reg; assign system_reset = system_reset_reg;
assign system_mode = system_mode_reg;
assign rom_exec_en = !system_mode | access_level_hi; assign rom_exec_en = !system_mode | access_level_hi;
assign fw_ram_en = !system_mode | access_level_hi; assign fw_ram_en = !system_mode | access_level_hi;
assign spi_access_en = !system_mode | access_level_hi; assign spi_access_en = !system_mode | access_level_hi;
assign rw_locked = system_mode;
//---------------------------------------------------------------- //----------------------------------------------------------------
// Module instance. // Module instance.
@ -539,13 +542,13 @@ module tk1 #(
end end
if (address == ADDR_APP_START) begin if (address == ADDR_APP_START) begin
if (!system_mode_reg) begin if (!rw_locked) begin
app_start_we = 1'h1; app_start_we = 1'h1;
end end
end end
if (address == ADDR_APP_SIZE) begin if (address == ADDR_APP_SIZE) begin
if (!system_mode_reg) begin if (!rw_locked) begin
app_size_we = 1'h1; app_size_we = 1'h1;
end end
end end
@ -555,19 +558,19 @@ module tk1 #(
end end
if ((address >= ADDR_CDI_FIRST) && (address <= ADDR_CDI_LAST)) begin if ((address >= ADDR_CDI_FIRST) && (address <= ADDR_CDI_LAST)) begin
if (!system_mode_reg) begin if (!rw_locked) begin
cdi_mem_we = 1'h1; cdi_mem_we = 1'h1;
end end
end end
if (address == ADDR_RAM_ADDR_RAND) begin if (address == ADDR_RAM_ADDR_RAND) begin
if (!system_mode_reg) begin if (!rw_locked) begin
ram_addr_rand_we = 1'h1; ram_addr_rand_we = 1'h1;
end end
end end
if (address == ADDR_RAM_DATA_RAND) begin if (address == ADDR_RAM_DATA_RAND) begin
if (!system_mode_reg) begin if (!rw_locked) begin
ram_data_rand_we = 1'h1; ram_data_rand_we = 1'h1;
end end
end end
@ -645,7 +648,7 @@ module tk1 #(
end end
if ((address >= ADDR_UDI_FIRST) && (address <= ADDR_UDI_LAST)) begin if ((address >= ADDR_UDI_FIRST) && (address <= ADDR_UDI_LAST)) begin
if (!system_mode_reg) begin if (!rw_locked) begin
tmp_read_data = udi_rdata; tmp_read_data = udi_rdata;
end end
end end

View File

@ -17,8 +17,7 @@ module uds (
input wire clk, input wire clk,
input wire reset_n, input wire reset_n,
input wire system_mode, input wire en,
input wire cs, input wire cs,
input wire [ 2 : 0] address, input wire [ 2 : 0] address,
output wire [31 : 0] read_data, output wire [31 : 0] read_data,
@ -89,7 +88,7 @@ module uds (
if (cs) begin if (cs) begin
tmp_ready = 1'h1; tmp_ready = 1'h1;
if (!system_mode) begin if (en) begin
if (uds_rd_reg[address[2 : 0]] == 1'h0) begin if (uds_rd_reg[address[2 : 0]] == 1'h0) begin
uds_rd_we = 1'h1; uds_rd_we = 1'h1;
end end

View File

@ -154,7 +154,7 @@ module application_fpga (
reg [31 : 0] tk1_write_data; reg [31 : 0] tk1_write_data;
wire [31 : 0] tk1_read_data; wire [31 : 0] tk1_read_data;
wire tk1_ready; wire tk1_ready;
wire system_mode; wire rw_locked;
wire force_trap; wire force_trap;
wire [14 : 0] ram_addr_rand; wire [14 : 0] ram_addr_rand;
wire [31 : 0] ram_data_rand; wire [31 : 0] ram_data_rand;
@ -256,7 +256,6 @@ module application_fpga (
.reset_n(reset_n), .reset_n(reset_n),
.en(fw_ram_en), .en(fw_ram_en),
.cs(fw_ram_cs), .cs(fw_ram_cs),
.we(fw_ram_we), .we(fw_ram_we),
.address(fw_ram_address), .address(fw_ram_address),
@ -295,7 +294,7 @@ module application_fpga (
.clk(clk), .clk(clk),
.reset_n(reset_n), .reset_n(reset_n),
.system_mode(system_mode), .en(~rw_locked),
.cs(uds_cs), .cs(uds_cs),
.address(uds_address), .address(uds_address),
@ -341,7 +340,7 @@ module application_fpga (
.clk(clk), .clk(clk),
.reset_n(reset_n), .reset_n(reset_n),
.system_mode(system_mode), .rw_locked(rw_locked),
.cpu_addr (cpu_addr), .cpu_addr (cpu_addr),
.cpu_instr (cpu_instr), .cpu_instr (cpu_instr),

View File

@ -166,7 +166,7 @@ module application_fpga_sim (
reg [31 : 0] tk1_write_data; reg [31 : 0] tk1_write_data;
wire [31 : 0] tk1_read_data; wire [31 : 0] tk1_read_data;
wire tk1_ready; wire tk1_ready;
wire system_mode; wire rw_locked;
wire force_trap; wire force_trap;
wire [14 : 0] ram_addr_rand; wire [14 : 0] ram_addr_rand;
wire [31 : 0] ram_data_rand; wire [31 : 0] ram_data_rand;
@ -305,7 +305,7 @@ module application_fpga_sim (
.clk(clk), .clk(clk),
.reset_n(reset_n), .reset_n(reset_n),
.system_mode(system_mode), .en(~rw_locked),
.cs(uds_cs), .cs(uds_cs),
.address(uds_address), .address(uds_address),
@ -353,7 +353,7 @@ module application_fpga_sim (
.clk(clk), .clk(clk),
.reset_n(reset_n), .reset_n(reset_n),
.system_mode(system_mode), .rw_locked(rw_locked),
.cpu_addr (cpu_addr), .cpu_addr (cpu_addr),
.cpu_instr (cpu_instr), .cpu_instr (cpu_instr),